Wikibooks enwikibooks https://en.wikibooks.org/wiki/Main_Page MediaWiki 1.47.0-wmf.18 first-letter Media Special Talk User User talk Wikibooks Wikibooks talk File File talk MediaWiki MediaWiki talk Template Template talk Help Help talk Category Category talk Cookbook Cookbook talk Transwiki Transwiki talk Wikijunior Wikijunior talk Subject Subject talk TimedText TimedText talk Module Module talk Event Event talk Wikibooks:Requests for deletion 4 385 4668985 4666899 2026-09-05T18:48:29Z Omphalographer 3427146 /* Suicide */ Reply 4668985 wikitext text/x-wiki __NEWSECTIONLINK__ [[Category:Wikibooks deletion|{{PAGENAME}}]] {{Discussion Rooms}} {{TOCleft}} {{shortcut|WB:RFD}} {{Requests for deletion/New deletion}} {{Requests for deletion/Deletion intro}} <!-- New deletion nominations go at the bottom of page. --> == [[Salute, Jonathan!]] and its translations == <div style="column-count: 7;"> * [[Salute, Jonathan!|Interlingue/Occidental]] ([[w:en:Occidental|w]], original) * [[Òla, Ionatà!|Audià]] * [[Holo, Jonathan!|Cristianés]] * [[Terve, Jonathan!|Ekumenski]] * [[Hej, Jonathan! (Germanisch)|Germanisch]] * [[Salom, Jonatan!|Globasa]] * [[Àlŏ, Jonathan!|Guosa]] ([[w:en:Guosa|w]]) * [[Salut, Jonathan!|Idiom Neutral]] ([[w:en:Idiom Neutral|w]]) * [[Saluto, Jonathan! (Ido)|Ido]] ([[w:en:Ido|w]]) * [[Hallo, Jonathan!|Interlingua]] ([[w:en:Interlingua|w]]) * [[Salut, Jonathan! (Interocidental)|Interocidental]] * [[Bune Ğonatan!|Lingaust]] * [[Oila, Jonatan!|Lingue Simple]] * [[Haloo, Jonatan!|Lingwa de Planeta]] ([[w:en:Lingwa de Planeta|w]]) * [[Sin Chao, Jonathan!|Masa Tang]] * [[Salut, ionatano!|Meteza]] * [[Salu, Jon!|Mini]] * [[Hay, Jonathan!|Mirad]] * [[Hai, Jon!|Monav]] * [[Sesan Jon!|Monkel]] * [[Salam, Jonathan!|Mundeze]] * [[Dag, Jonathan!|Negerhollands]] ([[w:en:Negerhollands|w]]) * [[Salut Jonathan!|Neo]] ([[w:en:Neo|w]]) * [[Hej, Jonathan!|Nordien]] * [[Saluto, Jonathan!|Novial]] ([[w:en:Novial|w]]) * [[Salute, Jonathan! (Novlingue)|Novlingue]] * [[Alo, Jonathan!|Numo]] * [[Hela, Jonathan!|Proyo]] * [[Salute, Jonathan! (Romanica)|Romanica]] ([[w:en:Romanica|w]]) * [[Simi, Jonathan!|Solresol]] ([[w:en:Solresol|w]]) * [[Toki a, jan Jonatan!|Toki Pona]] ([[w:en:Toki Pona|w]]) * [[Glidis, o Jonathan!|Volapük]] ([[w:en:Volapük|w]]) </div> There are a couple of issues here: # Beyond their introductions, all of these books are written in languages which are not English, making them out of scope for the English Wikibooks. # All but one of these books are in fact written in constructed languages, most of them in recently created conlangs. In some cases (e.g. [[Sin Chao, Jonathan!]]), I can't find any reliable sources describing the target language outside of the translation itself. # Most of the translations (i.e. other than [[Salute, Jonathan!]] itself) were abandoned within the first five or so chapters (out of 100); none of them are complete, and there seems to be little effort to complete any of them. While I recognize that this is an unusual project, and potentially one which could have some value, it's not at all clear to me that the English Wikibooks is the right place for it. — [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 00:24, 29 September 2024 (UTC) : I'm really not sure what to do about these ones. While I recognize that this approach is certainly one method of teaching a language, I'm not sure that it constitutes an educational textbook. We do require that the English Wikibooks be written in English—for language-learning books, this typically means that the instructional parts are in English while the exercises are in the language being taught. I do think that if the language doesn't have much supporting evidence outside the book itself, it can safely be deleted. — [[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 01:01, 29 September 2024 (UTC) : Author of the book here. I originally wanted to put it in the Interlingue Wikibooks https://ie.wikibooks.org/wiki/Principal_p%C3%A1gine but it somehow got locked when I wasn't paying attention and so I ended up putting it here. Getting it unlocked requires going through the process of starting an Incubator and all the rest so I opted for here and then started putting some English-only content once it was done. It's sort of in the same vein as books like Lingua Latina per se Illustrata that have separate versions with teacher notes and whatnot. [[Salute, Jonathan!/Capitul 1 - with notes]] After it was done the auxlang community really took to it which was a nice surprise. I think Ido has the largest number of chapters at the moment at 15. :If the vast content of this book could be used to justify a quick reopening of the Interlingue Wikibooks to move it there, I'd love to do that. I imagine that an incubator with 100+ book chapters would be enough to open a Wikibooks and that's what this is. — [[User:Mithridates|Mithridates]] ([[User talk:Mithridates|discuss]] • [[Special:Contributions/Mithridates|contribs]]) 06:02, 29 September 2024 (UTC) : Ah, I just realized that we do have a proposal to reopen the Interlingue Wikibooks: https://meta.wikimedia.org/wiki/Requests_for_new_languages/Wikibooks_Interlingue along with an Incubator page here. https://incubator.wikimedia.org/wiki/Wb/ie/Principal_p%C3%A1gine : How easy would it be to migrate the entirety of Salute Jonathan to there? — [[User:Mithridates|Mithridates]] ([[User talk:Mithridates|discuss]] • [[Special:Contributions/Mithridates|contribs]]) 06:30, 29 September 2024 (UTC) :: Hi @[[User:Mithridates|Mithridates]]! I'm not sure how incubator projects work, but I fully support migrating these books there. You may want to inquire over there and link to this discussion to support your request to move the content over there. Cheers! — [[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 13:16, 29 September 2024 (UTC) ::: Hi! Actually I have a third idea to propose after thinking about this again today (haven't been here much since I finished the book): I noticed that there is more English content than I remember and that might make it an awkward fit for the Interlingue Wikibooks. I definitely agree that having all the auxlang translations for new auxlang projects goes well beyond the scope of this Wikibooks. Finally, there are some auxlangs that are notable with their own Wikipedias. ::: So the idea is the following: :::# Leave the original here and I can continue the work on the version with English notes and grammar. That will make it the same as Lingua Latina per se Illustrata, English by the Nature Method, Athenaze and all the rest. :::# The Interlingua one can move to the Interlingua Wikibooks (maybe Romanica too if they want as it is sort of a dialect of Interlingua). :::# For Ido and Lingua Franca Nova which have a Wikipedia but not a Wikibooks, I'm a little bit unsure...technically they could have their own version like the original one but would require English explanations. I could let them know and see if they are willing to do so and see what they think (work on adding English to the books vs. move the content elsewhere). :::# The rest can move to a Github repo, then be deleted, and the front page of this book can have a single link to the repo. ::: Any thoughts on that? Adding the extra English content will be easy as it is my book and I know it inside and out. ::: Edit: [https://en.wikibooks.org/wiki/Salute,_Jonathan!/Grammar_(pronouns) this page] I just added. — [[User:Mithridates|Mithridates]] ([[User talk:Mithridates|discuss]] • [[Special:Contributions/Mithridates|contribs]]) 13:50, 29 September 2024 (UTC) :::: Thanks for taking the time to consider this! Here are my responses/questions: ::::* Is the original [[Salute, Jonathan!]] (Occidental)? Since that one is quite fleshed out, I agree that if you edit it so the primary language of the book (e.g. headers, instructions, etc) are written in English while leaving the actual story in Occidental, it would be okay and fit in more with instructional language textbooks. ::::* For your points 2 and 3, I'm not sure how those other projects work, so I'll leave it up to them. I'm not quite sure why they would need to move, since in theory they could be revised with English as the language of instruction? Although, they have been left incomplete for a long time. ::::* For your point 4, I have no problem with that. Cheers! — [[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 16:51, 29 September 2024 (UTC) ::::: Hello again, it's the weekend so I have a bit more time to work on this. I've decided to merge the extra content from the following five chapters since the difference is fairly small and the original chapters should now have this English content. Could you delete these five pages now that they are no longer needed? [[User:Mithridates|Mithridates]] ([[User talk:Mithridates|discuss]] • [[Special:Contributions/Mithridates|contribs]]) 14:02, 5 October 2024 (UTC) ::::: [[Salute, Jonathan!/Capitul 1 - with notes]] ::::: [[Salute, Jonathan!/Capitul 2 - with notes]] ::::: [[Salute, Jonathan!/Capitul 3 - with notes]] ::::: [[Salute, Jonathan!/Capitul 4 - with notes]] ::::: [[Salute, Jonathan!/Capitul 5 - with notes]] [[User:Mithridates|Mithridates]] ([[User talk:Mithridates|discuss]] • [[Special:Contributions/Mithridates|contribs]]) 14:02, 5 October 2024 (UTC) :::::: [[File:Yes_check.svg|{{#ifeq:|small|8|15}}px|link=|alt=]] {{#ifeq:|small|<small>|}}'''Done'''{{#ifeq:|small|</small>|}} — [[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 23:34, 5 October 2024 (UTC) ::::::: Hi again! No luck trying to find a home for the random language translations on other auxlang wikis, can't find one that is actively maintained. ::::::: The thought struck me that maybe I could just put those ones on a sub page of my user page, would that be permitted? If not, I think I'll just stick them somewhere in GitHub and call it a day since none of the people who started the translations seem to care enough to do anything about them. I'd rather not see them outright disappear but since they aren't mine I don't care enough about them to do much more work than copy and paste them somewhere. ::::::: (I would leave the ones in languages with an ISO-639 code and Wikipedia here, of course) — [[User:Mithridates|Mithridates]] ([[User talk:Mithridates|discuss]] • [[Special:Contributions/Mithridates|contribs]]) 14:13, 9 November 2024 (UTC) :::::::: Thank you for checking! I don't personally see an issue with moving them to your user space right now. Cheers — [[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 17:21, 9 November 2024 (UTC) ::::::::: Thanks a lot! I've started a single page where I will put them all here [[User:Mithridates/SJ]] and will proceed slowly due to lack of time and also to avoid stepping on any toes / asking you to delete too much at a time and possibly deleting the wrong content. ::::::::: For this week I have put the content for the languages Audia, Cristianès, Guosa, Lingaust, Mini, Mirad, and Monav on that page as they all have a single page of content and didn't take much time to move. Please delete those. Once they are gone I will add a note on the main page letting people know where they have gone (in addition to a thank you for their interest in the book! I do love how many people have recognized it as a good source material for teaching a language). — [[User:Mithridates|Mithridates]] ([[User talk:Mithridates|discuss]] • [[Special:Contributions/Mithridates|contribs]]) 04:09, 10 November 2024 (UTC) : {{keep}} the translations for languages that have an article on the English Wikipedia, i.e. Guosa, Idiom Neutral, Ido, Interlingua, Lingwa de Planeta, Negerhollands, Neo, Novial, Occidental, Romanica, Solresol, Toki Pona, and Volapük. : Translations for languages that don't have an article can be kept if they have reliable sources, which I was able to find for the following languages (if you think they are not reliable, please let me know): :* Globasa: [https://www.languagesandnumbers.com/how-to-count-in-globasa/en/globasa/] [https://greyson.conlang.org/2020/01/29/shouting-out-globasa-and-pandunia/] :* Mini: [https://jprogr.github.io/mini] [https://www.omniglot.com/language/phrases/mini.htm] [https://www.languagesandnumbers.com/how-to-count-in-mini/en/mini/] : {{del}} and move to [[User:Mithridates/SJ]] the rest of the translations, i.e. Audià/Audian, Cristianés, Ekumenski, Germanisch, Interocidental, Lingaust, Lingue Simple, Masa Tang, Mirad, Monav, Monkel, Mundeze, Nordien, Novlingue, Numo, Proyo, and Scuian/Meteza. If you can find reliable sources for those languages, please let me know. : In particular, I could not find resources for Audià/Audian and Monav after searching through 15 and 17 pages on Google, respectively. It doesn't help that [[Òla, Ionatà!|their]] [[Hai, Jon!|translations]] don't explain what those languages are and where to find resources for them. This makes contributing to those translations almost impossible until @[[User:Caro de Segeda|Caro de Segeda]] can provide resources to us. It's possible that the resources may have disappared from the Internet, or that those languages were created by Caro de Segeda him/herself. If you can find resources for Audià/Audian and Monav, please let me know. : I'm notifying the primary contributors of the translations: @[[User:Caro de Segeda|Caro de Segeda]], @[[User:Frzzl|Frzzl]], @[[User:Greatscotteh|Greatscotteh]], @[[User:IHateNumbers234|IHateNumbers234]], @[[User:Jayeless2|Jayeless2]], @[[User:Morozof|Morozof]], @[[User:Omnihom|Omnihom]], @[[User:Omoutuazn|Omoutuazn]], @[[User:PovriNaivon|PovriNaivon]], @[[User:Sir Beluga|Sir Beluga]] and @[[User:Tyoyafud|Tyoyafud]]. — [[User:EJPPhilippines|EJPPhilippines]] ([[User talk:EJPPhilippines|discuss]] • [[Special:Contributions/EJPPhilippines|contribs]]) 09:52, 30 June 2025 (UTC) :: Caro de Segeda said on [https://www.reddit.com/r/conlangs/comments/1lcnz9g/comment/n0sc3wx/ Reddit] that Monav was created by him/her and that he/she didn't publish any resources about it other than [[Hai, Jon!]]. With '''zero''' other resources to rely on for contributing to the translation, and the fact that Monav is in [[User:Mithridates/SJ]], [[Hai, Jon!]] should be speedy deleted. — [[User:EJPPhilippines|EJPPhilippines]] ([[User talk:EJPPhilippines|discuss]] • [[Special:Contributions/EJPPhilippines|contribs]]) 01:38, 3 July 2025 (UTC) ::: I've undone the speedy deletion as Caro de Segeda posted a [https://prexins.wordpress.com/2025/07/04/monav/ resource] for Monav. — [[User:EJPPhilippines|EJPPhilippines]] ([[User talk:EJPPhilippines|discuss]] • [[Special:Contributions/EJPPhilippines|contribs]]) 07:18, 4 July 2025 (UTC) :::: You can delete all the ones that I have created myself, I have already moved them to other places. — [[User:Caro de Segeda|Caro de Segeda]] ([[User talk:Caro de Segeda|discuss]] • [[Special:Contributions/Caro de Segeda|contribs]]) 12:39, 5 July 2025 (UTC) {{outdent|::::}}I don't know if this is helpful since it wouldn't apply to most of these, but [[s:mul:]] could hold some of these. — [[User:Arlo Barnes|Arlo Barnes]] ([[User talk:Arlo Barnes|discuss]] • [[Special:Contributions/Arlo Barnes|contribs]]) 09:18, 30 November 2025 (UTC) : I don't think that would be within the scope of that project. I'm not aware of any other situation where Wikisource publishes translations of texts created on Wikimedia projects - that's usually left up to other language editions of the same project. — [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 05:34, 1 December 2025 (UTC) :: In this situation there isn't a separate [[s:ie:]] distinct from Multilingual Wikisource (see [[meta:Wikisource#List of Wikisources]]). In fact, there are very few multilingual wikis in the Wikimedia sphere; while this project ''could'' move to a Miraheze-hosted or similar wiki farm location, I think it would be a missed opportunity. I suppose an [[Interlingue]] book could be started in [[shelf:Constructed languages]] which would have all 100 chapters as an appendix (and likewise for the other languages), but that also seems non-ideal since it requires an English-language text that doesn't currently exist to be created. [[WB:AT]] seems to describe a similar situation to this one and prescribe Wikisource as the solution, and [[WB:SOURCE]] mentions fiction as out-of-scope for Wikibooks (even as in this case, language-educational fiction). [[s:mul:Wikisource:about Wikisource]] simply speaks of source texts and doesn't mention publication requirements, so maybe that is specific to some of the monolingual editions? — [[User:Arlo Barnes|Arlo Barnes]] ([[User talk:Arlo Barnes|discuss]] • [[Special:Contributions/Arlo Barnes|contribs]]) 22:28, 5 December 2025 (UTC) :{{keep}} 100% keep. These books are a core part of language textbooks on Wikibooks and have been for years. Not sure why this is even being debated.--[[User:Xania|Xania]] [[Image:Flag_of_Estonia.svg|15px]] [[Image:Flag_of_Ukraine.svg|15px]] [[User talk:Xania|<sup>talk</sup>]] 17:55, 16 May 2026 (UTC) ::With all due respect, some of the books included in this nomination (like [[Sin Chao, Jonathan!]]) are written in constructed languages which are not substantially attested anywhere else. I struggle to imagine any educational purpose for such a book. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 00:12, 17 May 2026 (UTC) == [[International Baccalaureate]] == Not actually a book in and of itself; rather, it is just a compilation of links to other books —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 23:24, 18 October 2024 (UTC) : Could this be salvaged as a shelf? [[User:Pppery|Pppery]] ([[User talk:Pppery|discuss]] • [[Special:Contributions/Pppery|contribs]]) 05:23, 27 January 2025 (UTC) ::Probably, but are the linked books even useful? IB exams change from year to year - sometimes quite dramatically - so an old exam guide is of very limited value. Many of these books were written 10-15 years ago, and some of them (like [[IB French]]) even have comments indicating that they're no longer applicable. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 02:18, 8 December 2025 (UTC) == [[Character List for Baxter&Sagart]] == Seems completely out of scope as an educational book; it's just a list of characters and outlinks —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 23:53, 18 October 2024 (UTC) :Adding [[Character List for Karlgren's GSR]] and [[Character List for Schuessler's CGSR]] for the same reason —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 23:55, 18 October 2024 (UTC) :These three books do make a package and I agree they should be considered together. However, I strongly object to deleting them. They are really extremely useful resources. I use them every week and I know that many people who do work on Old Chinese phonology do so. There are lots of books out there that are lists of characters, these are called dictionaries. For example Axel Schuessler's ABC Etymological Dictionary of Old Chinese, or Pulleyblank's Lexicon of Reconstructed Pronunciation in Early Middle Chinese, Late Middle Chinese, and Early Mandarin. I see it as entirely a good thing for reference works of this kind to be available free online rather than only in expensive books in university research libraries. If this is in violation of a Wikibooks policy, I would at least like that policy to be drawn to my attention and to have some constructive comment offered about which Wikiproject such a resource should fall under. I will also say on a personal note that I have put literally hundreds of hours of work into these projects and it would grieve me a lot to see this work simply vanish, in particular when I know that colleagues around the world use these books. --[[User:Tibetologist|Tibetologist]] ([[User talk:Tibetologist|discuss]] • [[Special:Contributions/Tibetologist|contribs]]) 07:27, 1 November 2024 (UTC) ::Hi @[[User:Tibetologist|Tibetologist]], and thank you for the feedback! Official Wikibooks policy does not permit standalone dictionaries (see [[WB:DICT]]), though I understand the argument that it is a useful resource. I am wondering if there might be a home for it at [[Wiktionary:Wiktionary:Welcome, newcomers|Wiktionary]] or [[Wikiversity:Wikiversity:SHARE|Wikiversity]]? Cheers —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 12:14, 1 November 2024 (UTC) :::The policy says to use Wiktionary, but these books cannot be moved there. In fact they link there, you can understand me as having made an index to wiktionary, if you like, where the ORDER of the characters is extremely important, information that would be lost in Wiktionary. :::Wikiversity is not a project I participate in, and in any event my books here are older than it, so this option was not available for me at the relevant moment. If you are offering to move my books to Wikiversity, that is very kind of you and I will very graciously accept. [[User:Tibetologist|Tibetologist]] ([[User talk:Tibetologist|discuss]] • [[Special:Contributions/Tibetologist|contribs]]) 14:10, 1 November 2024 (UTC) ::::I have pinged over at Wikiversity Colloquium to ask about suitability and have looped you into the conversation over there. Cheers —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 18:20, 1 November 2024 (UTC) ::I concur. I'm just an undergrad who tries to learn about Sino-Tibetan historical linguistics in his free time but I've found this wikibook to be incredibly useful, and I keep it open in one tab while I watch Professor Nathan Hill's lectures that he uploads to youtube in another tab, and another tab for taking notes. In fact if I remember correctly Professor Hill actually pointed his students to this wikibook. ::I'm not familiar with [[wikiversity:Wikiversity:SHARE|Wikiversity]] but if all the content were as accessible there as it is here then I think that could work. [[User:ChromeBones|ChromeBones]] ([[User talk:ChromeBones|discuss]] • [[Special:Contributions/ChromeBones|contribs]]) 02:43, 9 July 2025 (UTC) :Per [[:v:Wikiversity:Colloquium#Import_Resource_From_Wikibooks?]], I recommend copying and pasting, including attribution via the edit summary and talk page, add appropriate categories and links, and then it could be deleted locally. —[[User:Koavf|Justin (<span style="color:grey">ko'''a'''vf</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 22:32, 3 November 2024 (UTC) == [[Suomen kieli käyttöön]] == Multiple pages in this book are written entirely in Finnish, which is out of the enWB scope. —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 00:09, 19 October 2024 (UTC) :I was going to say whether we should ask any fiwikibooks sysop to maybe see if this could be transwikied to fiwb if it's within the scope there. But [[:fi:Toiminnot:Käyttäjät/sysop]] indicates that there are only 3 sysops, and only {{u|Anr}} and {{u|Zache}} have made edits this ''year''. If they deem it to be salvageable, then transwiki + delete, otherwise straight-up delete. --[[User:SHB2000|SHB2000]] ([[User talk:SHB2000|discuss]] • [[Special:Contributions/SHB2000|contribs]]) 11:24, 14 November 2024 (UTC) ::It seems that the idea behind the book was for the pages to be bilingual, as it’s a language learning book. That’s why there are Finnish texts included intentionally even on the pages that are complete. There are similar books in dewikibooks and ruwikibooks as well. For the English version, I think the easiest way to proceed would be to clean up and adjust the page layout to fit enwikibooks better, and then translate the missing parts. By the way, if anyone wants to update the book’s name in English, it can be titled ''"Using the Finnish Language"'' or ''"Put Finnish Language into Use"'' for a direct translation. [[User:Zache|Zache]] ([[User talk:Zache|discuss]] • [[Special:Contributions/Zache|contribs]]) 11:57, 14 November 2024 (UTC) == [[AT&T Mobility FAQ]] == * [[AT&T Mobility FAQ]] * [[AT&T Mobility FAQ/MEdia Net Configuration]] * [[AT&T Mobility FAQ/Data Connect Configuration]] An ''extremely'' outdated FAQ on AT&T's cell phone services. Most of this document was written 20+ years ago as a Usenet FAQ; very little of it is accurate or useful anymore (particularly the two subpages, which have to do with obsolete configurations for "tethering" a computer to a cell phone). No objection if someone wants to update it, but there's clearly been no appetite to do that. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 22:20, 30 December 2024 (UTC) :I'm wondering if it might make sense for us to develop some kind of policy on archiving books here. There are many like this one that have a good deal of content but are extremely out of date and just not useful as originally intended. ——[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 22:34, 30 December 2024 (UTC) ::@[[User:Kittycataclysm|Kittycataclysm]]: See the newly developed [[Wikibooks:Outdated books]]. [[User:JJPMaster|JJP]]<sub>[[User talk:JJPMaster|Mas]]<sub>[[Special:Contributions/JJPMaster|ter]]</sub></sub> ([[wikt:she|she]]/[[wikt:they|they]]) 00:16, 31 December 2024 (UTC) :::Ooh, thanks - something like that seems like it could be an appropriate way to handle this book. A lot of the other outdated books I've tagged have been so incomplete that they wouldn't have been particularly useful even as historical references; this one might at least have some interest. :::Any chance we can get a separate namespace (maybe "Archive:") set up for archived book content? That'd make it possible to do things like exclude them from on-site search by default. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 21:07, 31 December 2024 (UTC) ::::I think this might be a more extended discussion, so I'll bump it over to the [[Wikibooks talk:Outdated books|talk page of the draft policy]]! —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 21:54, 31 December 2024 (UTC) == Algebra/Chapter 10/Symmetric Polynomials == I personally believe that [[Algebra/Chapter 10/Symmetric Polynomials|this]], and all of the sections should be deleted for the fact that this goes WAY beyond the scope of what was intended for the Chapter (Algebra II level polynomials). [[User:GoreyCat|GoreyCat]] ([[User talk:GoreyCat|discuss]] • [[Special:Contributions/GoreyCat|contribs]]) 15:07, 6 February 2025 (UTC) :'''Split''': Deletion here is not the best solution (see [[w:WP:ATD]]). Instead, this page and its subpages should be moved to another book, most likely [[Abstract Algebra]]. [[User:JJPMaster|JJP]]<sub>[[User talk:JJPMaster|Mas]]<sub>[[Special:Contributions/JJPMaster|ter]]</sub></sub> ([[wikt:she|she]]/[[wikt:they|they]]) 17:35, 6 February 2025 (UTC) :{{keep}} since there is a good amount of content. If [[Abstract Algebra]] is appropriate, it seems like a fine idea to move there. —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 22:59, 7 February 2025 (UTC) ::Eh, yeah, I supposed moving it is better. I just don't think it's suitable for where it appears. [[User:GoreyCat|GoreyCat]] ([[User talk:GoreyCat|discuss]] • [[Special:Contributions/GoreyCat|contribs]]) 01:40, 8 February 2025 (UTC) == [[Puredyne]] == Development of Puredyne Linux was discontinued in 2012, and the software no longer appears to be available for download anywhere. (An archive of the web site is still up - with a bunch of embedded spam links - but the download links are all dead.) Is this a suitable candidate for archival (cf. [[Wikibooks:Outdated books]]), or should it just be deleted? [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 04:35, 5 March 2025 (UTC) :I'd just archive stuff like this. Looks like a decent bit of work went into it, and you never know when someone might need to use Puredyne for some obscure project. I'd be willing to bet mirrors exist of it somewhere, or someone has it on a drive. If you want to find some stuff worth deleting, comb through [[:Category:Allbooks categories]]. [[User:MediaKyle|MediaKyle]] ([[User talk:MediaKyle|discuss]] • [[Special:Contributions/MediaKyle|contribs]]) 11:30, 5 March 2025 (UTC) == [[Template:Qr-twwp]] == This isn't exactly a request to delete the template, but rather to merge it with {{tlx|Copypaste}}. The {{tlx|Qr-twwp}} template serves the same purpose as {{tlx|Copypaste}}, but without the seven-day period after which the page is deleted. This leads to confusion, as well as a perpetually full [[:Category:Queried pages]]. [[User:JJPMaster|JJP]]<sub>[[User talk:JJPMaster|Mas]]<sub>[[Special:Contributions/JJPMaster|ter]]</sub></sub> ([[wikt:she|she]]/[[wikt:they|they]]) 17:37, 30 March 2025 (UTC) == [[Ghouls of the Miskatonic]] == I don't think that a plot summary of a book is in-scope here. —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 18:43, 20 August 2025 (UTC) :{{vd}} - at least, not a summary of ''this'' book. A summary and/or study guide to a notable work of literature might be in scope, but this is certainly not one. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 21:23, 25 August 2025 (UTC) ::Hi. I am the creator of the pages of this book. If I understand correctly, it has to be a summary of a notable work of literature? So what exactly is defined as such? I only started this as I thought it would be fun, interesting and encouraging to others who read the Arkham Horror novels, and I thought it was permitted as I've seen other summaries of books on wikibooks. [[User:Dayne90|Dayne90]] ([[User talk:Dayne90|discuss]] • [[Special:Contributions/Dayne90|contribs]]) 13:27, 26 August 2025 (UTC) :::Your problem is it is just the plot... it needs to include an educational textual analysis to be in scope [[User:MarcGarver|MarcGarver]] ([[User talk:MarcGarver|discuss]] • [[Special:Contributions/MarcGarver|contribs]]) 12:47, 28 August 2025 (UTC) ::::And ideally it'd be a text which has ''already'' been the subject of literary analysis, such that the analysis on Wikibooks isn't original research. A notable work of literature like ''Frankenstein'' or ''Moby-Dick'' would easily meet that requirement; a tie-in novel for a tabletop RPG probably does not. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 22:08, 29 August 2025 (UTC) == [[Objective Projection: Why the Brain Never Forgets Some Stories]] == Undisclosed AI-generated content. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 02:13, 9 May 2026 (UTC) :<nowiki>'''Keep'''</nowiki> — Comment from page author/subject expert. :I am Levent Bulut, the originator of the <nowiki>''</nowiki>Objective Projection<nowiki>''</nowiki> methodology described in this book (ORCID: 0009-0007-7500-2261, Wikidata: Q138048287). I want to address the AI-generated content concern directly and transparently. :<nowiki>'''</nowiki>On the content itself:<nowiki>'''</nowiki> The methodology, theoretical framework (the six-variable operator E(r) = projS(M, T, V, Δ, Ω, Ng), the Six Golden Rules, the Six-Layer Framework), and all original arguments are my own intellectual work, developed and published independently. This is documented through: :* 26 DOI-registered academic publications on Zenodo (search: "Levent Bulut Objective Projection") :* A peer-reviewed submission currently under review at <nowiki>''</nowiki>Digital Humanities Quarterly<nowiki>''</nowiki> :* Parallel Turkish-language Wikibook and Wikiversity pages on the same methodology :* An open-source SFT dataset on Hugging Face (leventbulut/objective-projection) :<nowiki>'''</nowiki>On AI assistance:<nowiki>'''</nowiki> I used AI tools (Claude) for English translation polish and copy-editing from my Turkish source materials — the same way a non-native English-speaking academic would use a human translator or editor. The <nowiki>''</nowiki>ideas, structure, terminology, citations, and arguments<nowiki>''</nowiki> are entirely my own and pre-date the Wikibooks version, traceable through Zenodo DOI timestamps starting in 2025. :<nowiki>'''</nowiki>Proposed remedy instead of deletion:<nowiki>'''</nowiki> I am happy to: :# Add a clear AI-assistance disclosure to the book's preface, per Wikibooks transparency norms :# Add inline citations to the underlying DOI-registered publications for every major claim :# Link to the parallel Turkish version and academic record :This would address the <nowiki>''</nowiki>undisclosed<nowiki>''</nowiki> part of the concern (which is the actionable policy issue) while preserving content that is original academic work by an identifiable author with a published track record. Deletion of original scholarship because translation assistance was used would set a concerning precedent for non-native English contributors. :<nowiki>I request a few days to add the disclosure and citations before any deletion action. ~~~~</nowiki> [[Special:Contributions/&#126;2026-28847-60|&#126;2026-28847-60]] ([[User talk:&#126;2026-28847-60|talk]]) 18:46, 13 May 2026 (UTC) ::Administrative assistance needed: Automated filters blocking structural improvements and disclosures ::'''Request for Help''' — I am Levent Bulut, the author of this book. I have already provided my AI disclosure and academic credentials (ORCID, DOI list) here in this discussion. ::I am trying to update the book to comply with Wikibooks standards by: ::Adding a formal '''AI assistance disclosure''' at the top of the page. ::Restructuring the content into an '''instructional textbook format''' (adding Learning Objectives). ::Converting plain text formulas into '''LaTeX''' ( format). ::Updating references to include full academic '''DOI''' records. ::However, the automated filter is blocking all my attempts: ::If I try to replace the content with the improved version, it triggers the '''"large amount of content removal"''' filter. ::If I try to add specific academic links, it triggers the '''"automated link/spam"''' filter. ::I am essentially trapped by the filters while trying to improve the book and follow transparency norms. Could an administrator please either whitelist my account or manually apply the improved version of the text? I am ready to provide the full MediaWiki code here if requested. My intent is purely constructive and academic. [[Special:Contributions/&#126;2026-28847-60|&#126;2026-28847-60]] ([[User talk:&#126;2026-28847-60|talk]]) 19:15, 13 May 2026 (UTC) ::: Hi, @[[User:~2026-28847-60|~2026-28847-60]]. Your account was incorrectly locked by a steward. It is now currently unlocked. [[User:Codename Noreste|<span style="color:#0024FF">Codename Noreste</span>]] ([[User talk:Codename Noreste|discuss]] • [[Special:Contributions/Codename Noreste|contribs]]) 17:44, 15 May 2026 (UTC) :::: Pinging @[[User:Projection Architect|Projection Architect]], who was previously LeventBulut. [[User:Codename Noreste|<span style="color:#0024FF">Codename Noreste</span>]] ([[User talk:Codename Noreste|discuss]] • [[Special:Contributions/Codename Noreste|contribs]]) 15:51, 4 July 2026 (UTC) ::Please review [[Wikibooks:Artificial intelligence]]. It states unequivocally that {{tq|LLMs may not be used to generate or summarize material and ideas at Wikibooks}}, and that {{tq|translations made by LLMs are not allowed on Wikibooks}}. The fact that you did not disclose your usage of AI is part of the problem, but disclosing it does not make it allowable either. ::More broadly, based on what you've said above, the content of this book is a reflection of your personal theories on writing. This is essentially [[Wikibooks:Original research]] and is not permitted. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 22:36, 13 May 2026 (UTC) == [[Suicide]] == I realize this book has been nominated for deletion before ([[Wikibooks:Requests for deletion/Suicide|1]], [[Wikibooks:Requests for deletion/Suicide (2)|2]], [[Wikibooks:Requests for deletion/Suicide/Suffocation|3]]), but it's been over ten years since the last nomination. The project's position on what material is in its educational scope has shifted, as have some of the facts on the ground. * The chartered purpose of Wikibooks is to produce "open-content textbooks" (cf. [[Wikibooks:What is Wikibooks?]]) which are suitable for use in an instructional environment. Providing educational information about suicide in the context of psychiatry could certainly be in scope, as psychiatry is an educational topic; however, instructional material on how to commit suicide is not an educational topic, and should not be considered in scope. * This book is, and has always been, primarily intended as an instructional work guiding users on how to commit suicide. It provides effectively no meaningful analytical content ''about'' suicide as a topic. Most of the original content in the book was imported from an early-2000s wiki associated with the <code>alt.suicide.holiday</code> Usenet group, the "ASH wiki", which was specifically and unequivocally dedicated to describing and recommending methods by which readers could commit suicide, and this has carried through to the current version of the book. * Most of the content in the book was removed in 2020 (by redirecting it to the book's main page, e.g. [[Special:Diff/3660495]]) over concerns that it was created by a WMF-banned user ([[User:Leucosticte]]), and because it was likely in violation of the ASH wiki's (unclear) copyright. These changes removed most of the content of the book; much of what remains is image gallery pages like [[Suicide/Blades]] which have no educational value. Suicide is a sensitive topic; if it is covered by a textbook, it should be covered tastefully and with an aim to educate. This book is largely the opposite of that. Having it here is doing more harm than good. If this book is deleted, the following related pages should be deleted as well: * [[Template:Suicide methods]] * [[Template:Infobox suicide method]] (currently unused) * [[User:Leucosticte/About ASH]] - from the ASH wiki, as mentioned above * [[User:Leucosticte/Frequently Asked Questions]] - also from the ASH wiki [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 22:41, 21 July 2026 (UTC) : {{keep|weak keep}} a)&nbsp;Age is no argument. There are many stale underdeveloped books I would rather delete than keeping around. b)&nbsp;The book’s topic is exceptionally difficult to write about. ''This'' impedes collaborative authoring. c)&nbsp;The book does not really explain ''how'' to commit suicide (like a step‐by‐step guide), neither is it the book’s learning objective. d)&nbsp;Even if ''you construed'' the chapter summarizing various suicide methods ''as instructions'', instructional material on how to commit suicide ''is'' an educational topic. In most ''present‐day societies'' it is not ''ethical'' to teach students how to commit suicide, though. e)&nbsp;Therefore the correct path is to first alter the [[WB:WIW#Wikibooks includes instructional texts|project scope]] to censor books on ethical grounds ''and then'' nominate the book for censorship. ‑‑[[User:Kai Burghardt|Kai Burghardt]] ([[User talk:Kai Burghardt|discuss]] • [[Special:Contributions/Kai Burghardt|contribs]]) 04:50, 28 July 2026 (UTC) ::Re. c: most of the explicit directions were edited out in 2020, as noted in my nomination, but are still visible in page history. For a couple of explicit examples, see e.g. [[Special:Permalink/3318613]] or [[Special:Permalink/3654645]]. Providing specific instructions was the original intent of this book, and it has never escaped that legacy. If someone were interested in writing a book ''about'' the phenomenon of suicide, they would be better off starting afresh. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 05:26, 28 July 2026 (UTC) *'''Delete all'''. ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 16:17, 28 July 2026 (UTC) * '''Delete all''' per the nomination above. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] ([[User talk:Codename Noreste|discuss]] • [[Special:Contributions/Codename Noreste|contribs]]) 02:17, 30 July 2026 (UTC) * '''Keep''' with caution. Rename to "suicide prevention"?--[[User:TunnelESON|TunnelESON]] ([[User talk:TunnelESON|discuss]] • [[Special:Contributions/TunnelESON|contribs]]) 04:03, 2 September 2026 (UTC) *:Re. the rename: absolutely not. There is no content in the book about suicide prevention. If you are interested in writing a book on that topic, please start a new one. [[User:Omphalographer|Omphalographer]] ([[User talk:Omphalographer|discuss]] • [[Special:Contributions/Omphalographer|contribs]]) 18:48, 5 September 2026 (UTC) == [[User:PETER A. SAUL/You Become What You Think: Transform Your Life]] == Overall reads like a violation of [[WB:SOAP]]. Mass addition of pages. Bold claims with no reputable sources/support. See e.g. [[Peter A. Saul: Personal Development and Mindset Anthology/You Become What You Think/Chapter 9|here]]. Markdown errors that suggest LLM use (e.g. [[Peter A. Saul: Personal Development and Mindset Anthology/You Become What You Think/Chapter 16|here]], [[Peter A. Saul: Personal Development and Mindset Anthology/You Become What You Think/Chapter 17|here]], etc. —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 14:21, 5 August 2026 (UTC) :I'll also note a significant amount of self-promo. —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 14:32, 5 August 2026 (UTC) :'''Speedy delete''' Obviously inappropriate. ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 17:17, 5 August 2026 (UTC) ::{{done}}. I was on the fence for speedy, but since another admin agrees, I went ahead and deleted. —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 18:38, 5 August 2026 (UTC) == [[User:PETER A. SAUL/Why 95 Percent of Your Life Is a Lie: How to Control Your Mind]] == Same reasons as RFD for other pages by this editor. Violation of [[WB:SOAP]], no support for extreme claims, potential LLM use, self-promo. —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 14:28, 5 August 2026 (UTC) :'''Speedy delete''' Obviously inappropriate. ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 17:17, 5 August 2026 (UTC) ::{{done}}. As with other contributions. —[[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 18:38, 5 August 2026 (UTC) hl21ps2214xeiiep5yjxru3yc6reixs World History/World Religions 0 497 4669092 4445174 2026-09-06T10:23:53Z WereSpielChequers 248949 typo 4669092 wikitext text/x-wiki {{WHP - page top 1}} '''''<u>This page is for an elementary explanation of the origins and nature of the religions. It is not meant to be an in depth study by any means.</u>''''' ==Animism== Animism (from Latin animus, -i "soul, life") is the worldview that non-human entities (animals, plants, and inanimate objects or phenomena), possess a spiritual essence. ==Baha'i Faith== [[File:Bahai star.svg|thumb|The nine pointed star]] The ''Bahá'í Faith'' is the youngest of the world's independent religions. Its founder, [[w:Baha'u'llah|Bahá'u'lláh]] (1817–1892), is regarded by Bahá'ís as the most recent in the line of [[w:Manifestations of God|Messengers of God]] that stretches back beyond recorded time and that includes Abraham, Moses, Buddha, Zoroaster, Christ and Muhammad. The central theme of Bahá'u'lláh's message is that humanity is one single race and that the day has come for its unification in one global society. God, Bahá'u'lláh said, has set in motion historical forces that are breaking down traditional barriers of race, class, creed, and nation and that will, in time, give birth to a universal civilization. The principal challenge facing the peoples of the earth is to accept the fact of their oneness and to assist the processes of unification. [http://www.bahai.org/faq/facts/bahai_faith] Wikipedia article: [[w:Baha'i Faith|Bahá'í Faith]] ==Buddhism== [[File:Dharma Wheel (2).svg|thumb|Dharmachakra, a significant symbol in many religions, including Buddhism.]] Buddhism is a religion based largely around the teachings of the Siddhārtha Gautama (although his exact status is still controversial and changes by sect) and is now the central religion of most of Southeast Asia, Mongolia, Sri Lanka, and parts of China, Nepal, India, and a small part of Russia. It is also a major religion in Korea and Japan and has a growing influence in the west. [[File:Four Scenes from the Life of the Buddha - Enlightenment - Kushan dynasty, late 2nd to early 3rd century AD, Gandhara, schist - Freer Gallery of Art - DSC05124.JPG|thumb|A depiction of scenes from the Life of Buddha.]] Gautama was born in ancient Nepal around the 6th century BC, son of a King and relieved of all tasks. One day, while being brought around by his charioteer, he saw the four passing sights (an old man, a sickly man, a decaying corpse, and a holy man), which brought him to the realization that birth, old age, sickness, and death happen to all people over countless lives. He left his wife, children, rank, and his entire life to solve that problem. Gautama tried everything to achieve inner peace (he nearly killed himself numerous times) but found nothing that worked. He then tried sitting peacefully under a Bohdi tree and meditating. This proved very successful, and he soon achieved the inner peace he wanted. He then traveled the lands, preaching his new faith. (Postscript-Buddhism is largely based on Jainism, and shares many beliefs with Jainism.) Within the context of postclassical China, dominations such as pure land and Zen Buddhism appealed to both aristocratic elites and the mass peasantry. A commonality of religion in the global context: the induction of fervent belief system in the presence of societal corruption and lack of intellectual synthesis. Modern Buddhism still follows the ideals of Gautama-peace, kindness to man, and love of nature (including vegetarianism). There are three modern sects of Buddhism - Theravada, Mahāyāna, and Vajrayāna (practiced in southeast Asia, East Asia, and scattered parts of Asia, respectively). For information on the sects of Buddhism, or some tenets of Buddhism, go to the Wikipedia articles on: [[w:Buddhism|Buddhism]] [[w:Theravada|Theravada]] [[w:Mahayana|Mahayana]] [[w:Vajrayana|Vajrayana]] ==Christianity== [[File:Christian cross.svg|thumb|100px|A cross, the symbol of Christianity.]] {{Clear}}The story of Jesus and the Gospel of salvation is central to the Christian faith. It begins with the life and teachings of Jesus Christ, who is believed by Christians to be the Son of God and the Savior of humanity. === 1. The Birth of Jesus === Jesus was born in Bethlehem around 2,000 years ago to Mary and Joseph. His birth is considered a miraculous event, as Christians believe Mary was a virgin when she conceived Jesus through the Holy Spirit. His birth is seen as the fulfillment of ancient prophecies that a Messiah (Savior) would come to deliver the people. === 2. The Life and Ministry of Jesus === Jesus grew up in Nazareth and began his public ministry around the age of 30. He taught about love, forgiveness, repentance, and the coming of the Kingdom of God. He performed many miracles, such as healing the sick, raising the dead, and feeding the hungry, all of which demonstrated his divine authority. His teachings emphasized love for God and neighbor, and he often challenged the religious leaders of his time, calling for a deeper, more sincere relationship with God. === 3. The Crucifixion and Atonement === Jesus' teachings and actions eventually led to conflict with the religious authorities and the Roman authorities, who saw him as a threat. He was arrested, tried, and sentenced to death by crucifixion. Christians believe that Jesus' death on the cross was not just a tragic event but a sacrifice for the sins of humanity. This is known as the "atonement," where Jesus, who lived a sinless life, took upon himself the punishment for the sins of the world. Through his death, Christians believe that Jesus reconciled humanity with God, offering forgiveness for sins and the opportunity for eternal life. His crucifixion is seen as a fulfillment of Old Testament prophecies that a Savior would suffer for the sins of the people. === 4. The Resurrection === Three days after Jesus' death, Christians believe that he rose from the dead—an event known as the Resurrection. This miraculous event is seen as proof of his divine nature and the power of God over death. The Resurrection also signifies the hope of eternal life for all who believe in him. === 5. The Ascension and the Gospel of Salvation === After appearing to his disciples for forty days following his Resurrection, Jesus ascended into heaven, promising to send the Holy Spirit to guide and empower his followers. His final words to his disciples were to go and make disciples of all nations, baptizing them and teaching them to obey his commandments (Matthew 28:18-20). The '''Gospel of salvation''' refers to the "good news" that through Jesus’ life, death, and resurrection, salvation is available to all people. Salvation means being forgiven for sins and being reconciled to God, which is a free gift offered to everyone, regardless of background or past mistakes. Christians believe that faith in Jesus Christ as Lord and Savior is the way to receive this salvation (John 14:6, Ephesians 2:8-9). === 6. The Promise of Eternal Life === Christians believe that by trusting in Jesus and accepting his sacrifice, they can receive eternal life with God. This hope is rooted in the belief that Jesus will return one day to judge the living and the dead, and that those who have faith in him will live with God forever in a restored, perfect world. In summary, the story of Jesus and the Gospel of salvation is about God's love for humanity, demonstrated through the life, death, and resurrection of Jesus Christ. It is the message that salvation—freedom from sin and eternal life—is available to all through faith in Jesus Christ. ==Confucianism== [[File:木鐸 --- Confucian wooden-clapper bell.svg|thumb|100px|Symbol of a wooden clapper bell, associated with Confucianism.]] Wikipedia article on [[w:Confucianism|Confucianism]] {{Clear}} ==Hinduism== [[File:Aum Om navy blue circle coral.svg|thumb|''Om'', a symbol of Hinduism]] ''Hinduism'' is a term coined to designate the traditional socio-religious systems of the people of India. This term does not appear in any of the sacred literature of India. Hindus refer to their religion as ''Sanatana Dharma'' which loosely translated means “The Eternal Path”. ''Sanatana'' means ''eternal'', ''perpetual'' or ''sustained''. ''Dharma'' means any method by which one sees reality for what it is, and that by which one is drawn closer to the Absolute Truth and Ultimate Reality — it is the ''Philosophia Perenis''. In a context of world history, the Hindu emphasis placed upon social divisions as ample means for a productive society led to the highly stratified caste system in which birth and socio-economic position determined semi-permanent placement. There are two world religions which have formed the cultural and ethical basis of the world as we know it. Both have an unbroken history going back thousands of years. Judaism with a 5000 year old tradition is the mother of the western civilization through its offshoot Christianity. Hinduism is the older of the two with a literature going back to the beginning of recorded history. Hindu civilisation originated in the Gangetic and Indus valleys and from there spread out over the entire region of southeast Asia. Its offshoot — Buddhism, shaped and molded the civilizations of Japan, China, Tibet and the rest of Asia. There is evidence to suggest that the Ancient pre-Biblical kingdom of the Mittani in Asia minor was ruled by Kings with Hindu/Sanskrit names. The Hittites were an Indo-European people and according to some sources are said to have originated in the Gangetic Basin of India. Hindu philosophy/theology influenced the ancient Greeks since the time Alexander the Great conquered parts of north India. A remarkable similarity has also been demonstrated between the religion and mythology of the ancient Scandinavian people and that of the people of India. The ancient civilizations such as the Roman, Greek, Egyptian, Sumerian, Babylonian, Mayan, Aztec, and Inca have all passed away. Even the Jewish culture has undergone many radical changes since its inception 5000 years ago – yet the Hindu civilisation continues as a vibrant and living vector, and has remained virtually unchanged for over 6000 years. Today, Hindu communities are to be found in almost every country on earth. [[w:Hinduism|Hinduism]] ==Islam== [http://en.wikipedia.org/wiki/Islam Islam] ==Jainism== [http://en.wikipedia.org/wiki/Jainism Jainism] ==Judaism== [http://en.wikipedia.org/wiki/Judaism Judaism] ==Sikhism== [http://en.wikipedia.org/wiki/Sikhism Sikhism] ==Shinto== [http://en.wikipedia.org/wiki/Shinto Shinto] ==Taoism== [http://en.wikipedia.org/wiki/Taoism Taoism/Daoism] ==Marxism-Leninism== [http://en.wikipedia.org/wiki/Marxism] ==Legalism== ==Other notable religions== ==New Age Alternative Religions== {{BookCat}} tjk90f1z27sarh1vvcj96j494l3xnkk Aros/Developer/Docs 0 13107 4668959 4666501 2026-09-05T17:26:35Z Jeff1138 301139 4668959 wikitext text/x-wiki {{ArosNav}} ==A technical overview of AROS== Google translation [http://translate.google.com/translate?hl=en&sl=auto&tl=de&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs German], [http://translate.google.com/translate?hl=en&sl=auto&tl=fr&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs French], [http://translate.google.com/translate?hl=en&sl=auto&tl=it&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Italian], [http://translate.google.com/translate?hl=en&sl=auto&tl=es&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Spanish], [http://translate.google.com/translate?hl=en&sl=auto&tl=hi&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Hindi], [http://translate.google.com/translate?hl=en&sl=auto&tl=zh-CN&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Chinese], [http://translate.google.com/translate?hl=en&sl=auto&tl=ru&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Russian], [http://translate.google.com/translate?hl=en&sl=auto&tl=pl&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Polish], [http://translate.google.com/translate?hl=en&sl=auto&tl=pt&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Portuguese] {{Uncited}} AROS,<ref>[http://aros.sourceforge.net/download.php References and sources]</ref> like AmigaOS (TM), is a [[w:Message passing|message-passing]], [[w:Preemption (computing)|preemptive]] [[w:Multitasking|multitasking]] [[w:Operating system|OS]]. It uses [[w:Reentrant (subroutine)|re-entrant]] shared libraries to save memory space. AROS is based around an executive library kernel (Exec) and two other libraries: * Exec (the "kernel", which is not a kernel in the modern sense), * Intuition (graphics and GUI, integrated into the system) and * AmigaDOS (Disk Operating System, the Metacomco's Tripos modified to work with Exec). The design philosophies of AmigaDOS and Intuition are rather different, the former adopting a C-like API and the latter creating an [http://www.basden.demon.co.uk/amiga/amiga.oo.html object-oriented], message passing aware environment for the programmer. The system base is the only absolute address in AmigaOS (located at 0x00000004) this does differ with AROS as AROS SysBase is automatically provided (no $4) but everything else is dynamically loaded. The OS is well known for delivering high performance due to its close connections with the hardware, while simultaneously having the flexibility to support re-targetable graphics (Cybergraphics) and retargetable audio subsystems (AHI). : Diagram showing relationships of libraries to system needed Remember, AROS is a [http://en.wikibooks.org/wiki/Aros/Developer/ABIv1 research] operating system, and while all contributions to the base AROS code are welcome, please contact the dev list first for any core changes. Writing applications for AROS does not have this requirement. While AROS appears and feels almost feature complete, it is still [[Aros/Developer/IncompleteAPIs|missing a small number of functions]] from the Amiga API. [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1201 This thread provides] information for setup, [http://www.aros.org/documentation/developers/index.php documentation] and whether you are interested in core OS changes and/or writing/porting software apps *you compile directly under AROS, which can be running on either real hardware, virtual hardware *in hosted mode under linux/window, cross-compile from that host OS (save your files as ISO-8859-15 encoding instead of UTF-8) [https://github.com/BlitterStudio/aros-compiler-docker Docker images] '''The repository''' for 64bit and 32bit ABIv1 all hardware platforms is [https://github.com/aros-development-team/AROS current development version]. There are many forks of this so that developers can work on their own and forward changes at a later date as discussed on the dev forum 64bit PC is one of two hardware platform with another fork called [https://github.com/deadwood2/AROS abiv11] which is used for Aros One x64 PC 32bit PC is the other fork [https://github.com/deadw00d/AROS/tree/alt-abiv0 repository for current stable PC version ABIv0 with backported ABIv1 features is located which is used on AROS One and Icaros x86 32bit based distros] this is for historic reasons Any [https://github.com/aros-development-team/AROS/issues bugs / issues can be added for ABIv1 issues]. The two individual PC forks have their own issues tab on their github webpages We have a [https://arosdevteam.slack.com/archives/CUFV48U3H slack here], discord on [https://discord.gg/UKp9qdEBuQ Discord@AmigaDev], ==Software Development for AROS== ===Programming languages=== ====Common to all==== 'The Developer Environment', which primarily supports C/C++ code, there are other programming languages available for AROS: '''Scripting''' :[[Aros/User/DOS|DOS]] :[[Aros/Developer/Docs/LUA|LUA]] :REXX [[Aros/Developer/Docs/Rexx|Regina (AROS' ARexx)]] ====Needs to be compiled/ported==== ::[[Aros/Developer/Docs/LLVM|LLVM]] ::Python [ Info], [], ::[https://ae.arosworld.org/index.php?board=11.0 FreePascal FPC Aros-Exec thread], [https://archives.arosworld.org/index.php?function=browse&cat=development/language fpc arm here is very old and will not work], FreePascal for AROS has its own [http://fpcaroswiki.alb42.de/ Wikibook], ::[http://sourceforge.net/projects/xamos/ X-Amos Basic] ::[http://sdlbasic.sourceforge.net/ SDLBasic] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[[Aros/Developer/Basic/Basic4SDL|Basic4SDL]] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[http://alvyn.sourceforge.net/ Alvyn] ([http://www.dusabledanslherbe.eu/AROSPage/MISC.14.html download]) ::[http://www.airsoftsoftwair.com/ Hollywood when enough users warrant a port - paid one time fee language] ::[[Aros/Developer/Docs/E|AmigaE Portable E]] ====Hardware Restricted==== '''Basic''' :[http://amos.pspuae.com/AmosProManual/contents/c1.html '''Amos Pro'''] [http://amos.pspuae.com/index.php?action=forum#1 compatible] [http://www.amigacoding.com/index.php/Main_Page commands] (all incomplete) :'''Blitz Basic''' [http://aros-exec.org/modules/newbb/viewtopic.php?post_id=46537#forumpost46537 none on AROS] :: [http://www.amiforce.de/main.php Amiblitz] on amiga(TM) emulator :'''Amiga Basic''' :: [ ACEBasic] '''Misc''' :Ruby [http://www.ruby-lang.org/en Info]/[https://archives.arosworld.org/index.php?function=browse&cat=development/language Ruby 32bit PC], ===Where to get the C/C++ Environment=== If you want to develop for AROS, its generally easier to be running linux hosted AROS development environment especially for C++, cross compiling the code. That's how most developers now are doing it. g++ is used to compile owb web browser as well as some other AROS software. If you were hoping for a rich set of C++ libraries or classes defined for the OS feature set, you might be disappointed. AROS Native compiling is possible, but you're much more likely to run into the odd bug(s) in the dev environment since it gets little testing and fixing by other developers. Is there a sftp software or scp over ssh available? Maybe. At least the security part would be handled by [https://github.com/jens-maus/amissl amissl] [https://archives.arosworld.org/index.php?function=browse&cat=network/misc port]. [https://github.com/BlitterStudio/dopus5 DOpus5] has recently added sftp support. See here for a [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1974&highlight=ssh&pid=12073#post_12073 ssh scp client] [https://arosdevteam.slack.com/join/shared_invite/enQtOTc4Mzg0NDIzNzQ0LWQ2NWZmNmMwNGIwNGEyNTgxNzU3MGFjMTk3ZThmOTQ1MTVjMzhmNTllYWQ0ZTUxMjBjMGE0Y2VjMDJmNTc5MzI#/shared-invite/email Slack Dev Forum] ====Cross compilers from Windows or Linux==== *Windows WSL2 walkthrough can be [https://arosnews.github.io/how-to-cross-compile-aros-hosted-wsl/ found here] you want to build AROS. No problem. Here are instructions for PC 64-bit: https://github.com/deadw00d/AROS/blob/master/INSTALL.md Here are instructions for PC 32-bit: https://github.com/deadw00d/AROS/blob/alt-abiv0/INSTALL.md And as always has been the case you can use the contrib archive to 'obtain' the development directory which contains the /native/ AROS gcc compiler and tools. That compiler is used to build AROS itself but can be used outside the AROS build process by providing --sysroot with indicated directory to cross compile for AROS. =====Older guides for Linux hosted compiler===== Please install these packages before moving to next step. Below is a reference list for Debian-based distributions. Reference build system was Ubuntu 18.04/20.04 amd64. subversion git-core gcc g++ make gawk bison flex bzip2 netpbm autoconf automake libx11-dev libxext-dev libc6-dev liblzo2-dev libxxf86vm-dev libpng-dev gcc-multilib libsdl1.2-dev byacc python-mako libxcursor-dev cmake zsh mingw64 Do all of these operations under home directory of your user or another directory where your user has write permissions. Specifically, in a section "Linux-i386", be sure first to build the cross-compiler (toolchain-alt-abiv0-i386) and only then AROS itself (alt-abiv0-linux-i386). Clone & build <pre> $ mkdir myrepo $ cd myrepo $ git clone https://github.com/deadw00d/AROS.git AROS $ cd AROS $ git checkout alt-abiv0 $ cd .. $ cp ./AROS/scripts/rebuild.sh . $ ./rebuild.sh </pre> Now to the build selection below - Linux-i386 Select toolchain-alt-abiv0-i386 - Select alt-abiv0-linux-i386 (DEBUG) Start AROS by: <pre> $ cd alt-abiv0-linux-i386/bin/linux-i386/AROS $ ./Arch/linux/AROSBootstrap </pre> Pc-i386 Select toolchain-alt-abiv0-i386 (if not built yet) - Select alt-abiv0-pc-i386 ISO image available in alt-abiv0-pc-i386/distfiles Now that we have linux-hosted build, we can resume native (option 2). Run ./rebuild.sh and selection option 2. Wait until it finished, then: <pre> $ cd alt-abiv0-pc-i386 $ make </pre> Now <pre> $ make bootiso </pre> Now, your compiler is located in toolchain-alt-abiv0-i386 directory and named i386-aros-gcc. Includes are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/include and libraries are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development.lib. This is how then can be passed to the compiler: /home/xxx/toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot /home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development -L/home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/lib ../toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot bin/linux-i386/AROS/Development local/helloworld/helloworld.c -o local/helloworld/helloworld Another method was using Debian like distros and download the gimmearos.sh script (on [http://archives.aros-exec.org/index.php?function=browse&cat=development/cross aros-archives]) to setup the developer environment by downloading necessary packages ... The gimmearos script is a good start in that direction, building the cross compilers and hosted AROS environment, but gimmearos.sh might be out of date or not be completely compatible with any given linux distro. In order to do that, you have to compile AROS yourself. Download AROS source archive not contrib. Compile AROS by entering the main directory ./configure make ([http://aros.sourceforge.net/documentation/developers/compiling.php More on compiling AROS]). The result will be a basic AROS system without development tools. To compile C++ on Linux, type 'make gnu-contrib-crosstools', creating the cross-compilers in ./bin/linux-i386/tools/, named i386-aros-gcc, etc. '''Note''': Currently, to make the cross compilers usable copy 'collect-aros' from tools/ to tools/i386-aros/bin/. At the moment the cross compilers if used from the Linux command line will only find it when it's there. If you want to compile native compilers (the Developer Environment), type 'make contrib-gnu-gcc', creating native compilers in AROS' System:Development/bin directory. When the output needs to be stripped <code>--strip-unneeded --remove-section .comment</code> The Obj-C backend should build out of the box. Open contrib/gnu/gcc/mmakefile.src and search for the line which contains "--enable-languages" and add "objc" to the list of languages that follows it. --enable-languages=c,c++,objc Better make it—enable-languages=c,c++,objc,obj-c++ ObjC++ is broken as soon as you try to use exceptions, but that might change in future GCC versions and it does not hurt having it there already. Do you need a cross-compiler or a real compiler? In the first case you can get away with just downloading the proper gcc archive, apply the patch and proceed with the normal gcc build. In the case of a real cross-compiler then when downloading the contrib sources, also need to download the normal sources, place the contrib sources into a directory called contrib, need to install autoconf+automake+perl+python, call ./configure, cd into the subdirectory and type make. to rebuild GCC with host == build == target == i386-pc-aros. So just get the vanilla sources and apply the patches without bothering about the build system? [https://vmwaros.blogspot.com/2019/10/a-pre-configured-development-machine.html pre-configured VM environment vmware virtual machine to develop AROS and AROS software] '''64 bit''' '''32 bit''' A good option for multiple OS is [https://axrt.org/index.php?tab=download-aros AxRuntime lets developers compile their Amiga API-based applications as Linux binaries being able to utilize modern development tools available on Linux, like IDEs, debuggers, profilers, etc] ====Native compilers for AROS==== Namely gcc for C or g++ for C++ are supplied with the [[Aros/Developer/Docs#The Developer Environment|Developer Environment]], which is already '''setup''' and part of any current AROS distribution like AROS One or the nightlies * Current GCC 6.5 (32bit) though moving to 10.5 and 15.1 (64bit) * Older software components. GNU GCC 4.x GNU BinUtils, GNU Fileutils 4.x, GNU Textutils and others usually deprecated On single partition systems and the Boot ISO, the AROS Developer environment is installed under "SYS:Development/". Systems with multiple partitions - such as a Work: partition - tend to install it to there instead, however it can be installed manually to any location. Please remember, if moving, that you will need to correct the Development packages 'install location' env variable to point to the new locations root - look in SYS:S/startup-sequence. <pre> Assign Development: SYS:Development Assign C: Development:bin ADD </pre> In the aros build instructions. you need to check out contrib and/or ports into your AROS source directory, as subdirs. then, assuming you are building in an external build dir, as you should, you simply configure and "make contrib" for instance or whatever submodule you might want to build. ===Beginners Tutorials in C C++=== As AROS is [http://eab.abime.net/showthread.php?t=29856 C based] API compatible to AmigaOS 3.x, so most of the information on programming C on the Amiga applies to AROS as well. Please note that there is a lot of AmigaOS 1.3 (1985-1989) and [https://www.markround.com/amigaguide AmigaOS AOS 2.x (1990-1992)] information around but OS3.1 is recommended but limited in amount. Brief overview of what is required to write AROS Applications # Using [[Aros/Developer/Docs/Libraries/Intuition|Intuition]] for basic screens/windows # Using graphics within windows via 8bit [[Aros/Developer/Docs/Libraries/Graphics|graphics]] and so onto 15-16-24bit [[Aros/Developer/Docs/Libraries/CGFX|cybergraphx]] # Load and save work to [[Aros/Developer/Docs/Libraries/DOS|dos]] disk drives # Using the [[Aros/Developer/Zune|ZUNE GUI Environment]] Writing native games require this extra information # Using [[Aros/Developer/AHIDrivers|AHI audio hardware independent API]] # Using USB joystick/joypad with the Poseidon USB stack through [[Aros/Developer/Docs/Libraries/LowLevel|LowLevel]] library Additional features that could be added later # Adding additional [[Aros/Developer/Docs/Libraries/Locale|Locale]] language translations to your program # Adding a [[Aros/Developer/Docs/Rexx|AREXX/Regina]] port to your application # Executing Amiga(TM) [[Aros/User/DOS|DOS]] commands from your application # Using [[Aros/Developer/Docs/Libraries/Icon|icons]] (.info files) and icon tooltypes (stack, version, and program startup options) # Local couch or IP based SANA2 networking co-op multi player gaming support Most AmigaOS programming books are nowadays very much out of date as most are from the late 1980s and do not cover later amigaOS releases like 3.1 for example, Rob Peck's book "Programmer's Guide to the Amiga". The Amiga ROM Kernel manuals aka RKMs like Libraries (3rd edition), Devices (), the AmigaDOS manual (3rd edition) and the Style Guide may have their uses. There are some reference examples from AmigaMail and Devcon notes (available again on an Amiga developers CD 2.1). For Arexx then "The Amiga Programmer's Guide to ARexx" by Eric Giguere, which was published by Commodore is useful as well as an "Arexx Cookbook". Curly brackets missing - try SHIFT + ALT + 7 or 0. * Beginners C Guide [http://www.iu.hio.no/~mark/CTutorial/CTutorial.html C Tutorial], * [http://thecguru.com/ C for beginners], * [http://fresh2refresh.com/c/c-basic-program/ C programming basics] for students, * [https://www.edx.org/courses Free Online course] from American Universities * Reference Amiga [http://amigadev.elowar.com/ API reference]. * AROS based c source can be found [[Aros/Developer/Docs/Examples|here]] and lots of example code can be found inside [https://github.com/aros-development-team AROS sources] themselves and from the contrib section of the archives from [https://github.com/aros-development-team/contrib Aros site], and study the AROS applications source code, e.g. the test programs from the Tests drawer (folder/directory). Take a look at the code of some smaller AROS programs might be a better and more up to date When you upload your builds, please write the architecture (like i386-aros, x86_64-aros, armPi-64 etc.) in the archive name and it is also advisable to write in the field "Requirements" what ABI (ABIv1 or for PC forks ABIv11 or ABIv0) ===Compiling C/C++ Code=== Native, although we have a IDE Integrated Development Environment (Murks), it does lack a debugger. Whilst others use a combination of a text editor and shell to edit code. Most though use an AROS hosted on Linux to take advantage of the better GCC tools like GDB and various IDEs. Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w (or F12 and w) within the directory with the source code. Type in sh to change the amiga shell into a unix shell. You can then type in ls (unix equivalent to amiga dir). Take a look [http://en.wikibooks.org/wiki/Linux_commands here] for more commands. For a single file program-name.c or program-name.cpp gcc -o program-name program-name.c or g++ -o program-name program-name.cpp or g++ -o test -Wall -g main.cc texturelib.cpp xmodelib.cc -lsdl -lgl To close the shell, click on the top left-hand corner to close (twice). Once to get back the aros shell and then again to close finally. Use [http://freshmeat.net/projects/cksfv/ cksfv] as a test. Some source code requires the addition of Amiga API libraries, like dos, which you can flag at the compile time as gcc -o julia.exe julia.c -ldos For DOS use -ldos as example and if you are compiling mui codes it will be -lmui or intuition -lintuition. Other missing symbols are due to linker libraries being necessary for linking in functions that aren't in the standard C libraries. For example some source code would need added -lz or -lm or -lpng or -larosc etc. use this in unix line command mode to search for 'search-item' in many .c files (*.cpp for c++, etc.) grep -l 'search-item' *.c If the program is not executable, try using parameter fno-common "Delete #?.o"? Or if you are using abcshell then "rm *.o" :''More information: [[Aros/Developer/Porting software]]'' === How to make Apps have AROS 64-bit specific support code === [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] AROS64 already uses 64bit addressing, it just doesn't setup the MMU for more than 4GB physical memory currently. When porting software to AROS64 it is "mostly" a case of converting ULONG's that are used to store pointers, into IPTR's instead, etc. Another quirk, is making sure items on the stack are the correct size by using the STACKED attribute for them. * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. compiling mui stuff for aros setting -std=gnu99 is necessary, had -std=c99 usually A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. crash which suggest memory corruption. From my experience porting from 32-bit to 64-bit these kinds of errors can happen if a pointer is passed somewhere via ULONG variable. Then half of the pointer is cut. To generate this error, please run AROSBootstrap with -m 1024. This will allocate heap to 64-bit address space which will make these errors immediatelly visible. These types of crashes are hard to debug. Disabled as little code as possible to stop corruption from occurring and then try to read from the code where it can be broken Crashing in tslf_freevec is another symptom of memory corruption and these memory corruptions will manifest differently on different setups. ==Coding conventions== As the AROS core source is a shared developer experience, there are rules regarding structure and style. When it comes to your creating your own app and coding, the structure and style should be your own, i.e. you should enjoy what you do and do it so that you can understand what is going on. ===Layout=== <syntaxhighlight lang="c"> static void 1st_function() { program exit(0); } int main(void) { 1st_function(); 2nd_function(); 3rd_function(); return 0; } </syntaxhighlight> <syntaxhighlight lang="c"> struct Screen * openscreen(void); struct Window *openwindow(struct Screen *screen, const char *title, LONG x, LONG y, LONG w, LONG h); VOID 1st_function(); VOID 2nd_function(); int main(int argc, char **argv) { program return 0; } /* main */ VOID 1st_function() { } VOID 2nd_function() { } </syntaxhighlight> ===General style=== This code is used by many people and therefore you should keep some things in mind when you submit source code: * Keep things simple * Keep the source clean * Always know what you are doing, if not flag it and describe what needs to be done... * Explain clearly/simply what you are doing * Remember that you write code once but that it is read many times by many people ===Comments=== AROS uses some of the comments in the source to generate the documentation. Therefore it's necessary to keep a certain format so the tools can find their information. Other comments are ignored but they should explain what you thought when you wrote the code. If you really can't think of an explanation, then don't write the code a second time like this: <pre> /* This adds 1 to t */ t ++; </pre> What we think of is this: <pre> /* Go on with next element */ t ++; </pre> ===Formatting=== This is only '''IMPORTANT''' if you are going to work on the core AROS code or contrib but not applications which may reside outside like on AROS Archives or other websites. <syntaxhighlight lang="c"> { /* a */ struct RastPort * rp; int a; /* b */ rp = NULL; a = 1; /* c */ if (a == 1) printf ("Init worked\n"); /* d */ if ( !(rp = Get_a_pointer_to_the_RastPort ( some , long , arguments ) ) || a <= 0 ) { printf ("Something failed\n"); return FAIL; } /* e */ a = printf ("My RastPort is %p, a=%d\n" , rp , a ); return OK; } </syntaxhighlight> Looks ugly, eh ? :-) Ok, here are the rules: <pre> If several lines contain similar code, put similar things below each other (see a and b); Put spaces between operands and operators Put braces {}, brackets [] and parentheses () below each other (d) if there is much code between. Brackets and parentheses may be in one line if the code between is small (c) Indent by 4 Spaces. Two indent levels may be abbreviated by one tab. </pre> '''Before committing please normalize the indentation - if you have a mixture of tabs and spaced - please always use spaces, 1 tab = 4 spaces.''' The reasons for this are: # While some editors can use an arbitrary sizes for tabs, it's a bit complicated to tell another editor which tab size was used by the one used to write the code. # Most code in AROS was written this way and your code should look like the rest. # You can print this code on any printer without special tools to "fix" the tabs. # Most editors have smart tabs which do exactly this. If your editor doesn't, write a bug report. If you have a function with many arguments (d, e) you should put the parentheses in lines of their own and each argument in one line (d) or put the first argument behind the opening parentheses (e) and each following argument in a line of its own with the comma in front. The closing parentheses is in a line of its own and aligned with the beginning of the expression (i.e. the a and not the opening parentheses or the printf()). Use a single blank line to separate logical blocks. Large comments should have a blank line before and after them, small comments should be put before the code they explain with only one blank line before them. If you see any TABS in AROS core sources then the suggestion is to "detab the file and commit that separately" either before or afterwards from making functionality changes. Make two commits instead of one. This makes it easier for others to see the real changes instead of having to dig through multiple lines of irrelevant diffs. ===Eliminating Global Variables=== i.e. pass variables to functions (local scope) or classes making it easier to track and debug your code. Any time you find that you need a particular thing in 'a lot of different places', chances are that all those places are conceptually related, and so you can create a class, a namespace, a function, or some other higher-level organizational unit to represent that relationship. This makes the program easier to understand. Bad Designs * All variables are global. * There are no standalone functions, only sub-procedures which act on the global variables. * Every sub-procedure is at least 500 lines to several thousand * Every sub-procedure has more than one task to perform * Copy-paste is preferred to writing methods, AND subtle changes are made in the middle of the code Good Designs * structure program into functions (C or basic) - top-down procedural approach * put in class(es) (freepascal or C++) - the object is fixed and you use methods to access the object <pre>  class String_List  {  private:  list<string> m_List;  // member  public:  void read_strings() { /* read strings into m_List */ }  void print_strings() { /* write contents of m_List to stdout */ }  void sort_strings() { /* sort contents of m_List */ }  void sort_strings_reverse() { /* reverse-sort contents of m_List */ }  void unique_strings() { /* remove duplicate strings */ }  };  int main()  {  String_List myList;  // local  myList.read_strings();  myList.sort_strings();  myList.print_strings();  myList.sort_strings_reverse();  myList.print_strings();  myList.unique_strings();  myList.print_strings();  return 0;  } </pre> This way it is very easy to replace the list with new list for debugging purposes, or replacing the methods without replacing the list, when you want different results. You only have to replace the content of the local variables. So create the structure that matches your data (linked lists, trees, arrays, etc.) and what to do with them (sorting, searching, etc.) <pre> .h usually contain #define #include typedef enum struct extern screen and window definitions (data structures) .c should contains functions and algorithms </pre> One way to look at it is that menu headings act as the .c file and sub-menu headings as functions. When you start a project, you place a couple of declarations in the include file. As the project continues, you place more and more declarations in the include file, some of which refer to or contain previous declarations. Before you know it, you have a real mess on your hands. The majority of your source files have knowledge of the data structures and directly reference elements from the structures. Making changes in an environment where many data structures directly refer to other data structures becomes, at best, a headache. Consider what happens when you change a data structure. Use good variables names to help clarify code and only comment when you need to explain why a certain programming approach was made. You're Refactoring Legacy Code, you see a global, you want to get rid of it. How do you do this? Exactly what to do depends on how the global is used. The first step is to find all uses of the global throughout the code, and get a feel for what the significance of the variable is and how it relates to the rest of the program. Pay particular attention to the "lifetime" of the variable (when it gets initialized, when it is first used, when it is last used, how it gets cleaned up). Then, you will probably make the global a data member of a class (for OO languages), or you will write some get/set functions. Converting to the Singleton Pattern is common, but you may discover that it makes more sense for the data element to be a member of an existing singleton, or maybe even an instance variable. # Create a basic read method, either as a class or a global function. Replace all reads with the access method, but leave the variable defined as a global. # Review each of the writes to the method and extract action functions one at a time. Unless two operations are coded identically in the original code, extract each write access separately. # Change the variable scope from global to local. # Analyze similar action functions to determine if any can be merged, i.e., there are no functional differences in the results of the function, just differences in the implementation details. # Review the calls to the read method and see if a more complex functionality should be applied. Follow the approach for writes and unless implementations are identical, create separate access functions. # Analyze the access functions for duplication. As returning variables by "passing by value" are forgotten, so "passing by reference" is often used instead. The reference is a pointer to the variable so the value is remembered when returned. Alternatives * Hidden Globals * Singleton Pattern * Database or TupleSpace * Context Object * Dependency Injection * Stateful Procedures ==AROS/AmigaOS APIs and Docs== <pre> Library: - Private data structure - Many public access methods Device: - Private data structure - Two (BeginIO/AbortIO) access methods Resource: - Public data structure - *NO* access methods </pre> And, being Amiga OS-compatible, there are exceptions to all of these. ===System Libraries=== The [http://developers.aros.org/ AROS Guide To Libraries] can be used as a guide to individual commands and old Dev Docs are used in application programming. Amiga/Aros styles libraries are very different from windows and linux libs. Typical .so/dll libraries are foreign to most Amiga-like OS *[[Aros/Developer/Docs/Libraries/AROSC|arosc.library]] *[[Aros/Developer/Docs/Libraries/AmigaGuide|amigaguide.library]] *[[Aros/Developer/Docs/Libraries/ASL|asl.library]] *[[Aros/Developer/Docs/Libraries/Bullet|bullet.library]] *[[Aros/Developer/Docs/Libraries/BSDsocket|bsdsocket.library]] *[[Aros/Developer/Docs/Libraries/CAMD|camd.library]] *[[Aros/Developer/Docs/Libraries/Codesets|codesets.library]] *[[Aros/Developer/Docs/Libraries/CGFX|cybergraphics.library]] *[[Aros/Developer/Docs/Libraries/CGXVIDEO|cgxvideo.library]] *[[Aros/Developer/Docs/Libraries/Commodities|commodities.library]] *[[Aros/Developer/Docs/Libraries/DataTypes|datatypes.library]] *[[Aros/Developer/Docs/Libraries/DiskFont|diskfont.library]] *[[Aros/Developer/Docs/Libraries/DOS|dos.library]] *[[Aros/Developer/Docs/Libraries/Exec|exec.library]] *[[Aros/Developer/Docs/Libraries/Expansion|expansion.library]] *[[Aros/Developer/Docs/Libraries/FreeType2|freetype.library]] *[[Aros/Developer/Docs/Libraries/GadTools|gadtools.library]] *[[Aros/Developer/Docs/Libraries/Graphics|graphics.library]] *[[Aros/Developer/Docs/Libraries/Icon|icon.library]] *[[Aros/Developer/Docs/Libraries/Identify|identify.library]] *[[Aros/Developer/Docs/Libraries/IFFParse|iffparse.library]] *[[Aros/Developer/Docs/Libraries/Intuition|intuition.library]] *[[Aros/Developer/Docs/Libraries/Keymap|keymap.library]] *[[Aros/Developer/Docs/Libraries/Layers|layers.library]] *[[Aros/Developer/Docs/Libraries/Locale|locale.library]] *[[Aros/Developer/Docs/Libraries/LowLevel|lowlevel.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingBas|mathieeesingbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubBas|mathieeedoubbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingTrans|mathieeesingtrans.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubTrans|mathieeedoubtrans.library]] *[[Aros/Developer/Docs/Libraries/Mathtrans|mathtrans.library]] *[[Aros/Developer/Docs/Libraries/MUIMaster|muimaster.library]] *[[Aros/Developer/Docs/Libraries/Partition|partition.library]] *[[Aros/Developer/Docs/Libraries/PopUpMenu|popupmenu.library]] *[[Aros/Developer/Docs/Libraries/OOP|oop.library]] *[[Aros/Developer/Docs/Libraries/Regina|regina.library]] *[[Aros/Developer/Docs/Libraries/Reqtools|reqtools.library]] *[[Aros/Developer/Docs/Libraries/RexxSysLib|rexxsyslib.library]] *[[Aros/Developer/Docs/Libraries/ScreenNotify|screennotify.library]] *[[Aros/Developer/Docs/Libraries/TTEngine|ttengine.library]] *[[Aros/Developer/Docs/Libraries/Thread|thread.library]] *[[Aros/Developer/Docs/Libraries/Utility|utility.library]] *[[Aros/Developer/Docs/Libraries/Xadmaster|xadmaster.library]] *[[Aros/Developer/Docs/Libraries/Workbench|workbench.library]] *[https://github.com/aros-development-team/AROS/commit/c82e86b8480277998014cc327b56c7664023a52f ClassAct Reaction boopsi class] ===AROS Subsystems=== # [[Aros/Developer/Zune|Zune MUI compatible GUI]] # [[Aros/Developer/AROSAppPackages|AROS Application Packages]] # AHI Audio Drivers - [[Aros/Developer/AHIDrivers|Usage]]/[[Aros/Developer/AHIDriversDev|Development]] # AROSTCP Sana2 Network Interface Drivers - [[Aros/Developer/NICDrivers|Usage]]/[[Aros/Developer/NICDriversDev|Development]] # [[Aros/Developer/AmiSSL|AmiSSL]] # gfx.hidd/cybergraphics Video Drivers - [[Aros/Developer/GfxDrivers|Usage]]/[[Aros/Developer/GfxDriversDev|Development]] # IO Device Drivers - [[Aros/Developer/IODeviceDrivers|Usage]]/[[Aros/Developer/IODeviceDriversDev|Development]] # USB Device Drivers - [[Aros/Developer/USBDrivers|Usage]]/[[Aros/Developer/USBDriversDev|Development]] # PCI Device Drivers - [[Aros/Developer/PCIDrivers|Usage]]/[[Aros/Developer/PCIDriversDev|Development]] # [http://www.libsdl.org/ SDL] [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2013&pid=13333#post_13333 SDL2 coding usage], [https://github.com/search?q=repo%3Aaros-development-team%2Fcontrib%20SDL2&type=code SDL2 commits], [https://github.com/aros-development-team/contrib/commit/c62c3c425c35bac19dadc23be092b0b13a66c76c SDL3 initial commit], [] # [[w:Gallium3D|Gallium 3D]] [http://www.mesa3d.org/ openGL aka Mesa] - [[Aros/Developer/OpenGL|Usage]]/[[Aros/Developer/OpenGLDev|Development]] [http://www.swiftless.com/opengltuts.html Swfitless] # A small subset of GTK2 through [http://sourceforge.net/projects/gtk-mui/ MUI-GTK] # Cairo 2D Engine - [[Aros/Developer/Cairo|Usage]]/[[Aros/Developer/Cairo|Development]] # [[Aros/Developer/Scalos|Scalos desktop API and plugin modules]] # [[Aros/Developer/VHI|VHI video driver]] ====HIDDs==== *[[Aros/Developer/Docs/HIDD/HIDDClass|hiddclass.hidd]] *[[Aros/Developer/Docs/HIDD/Graphics|graphics.hidd]] *[[Aros/Developer/Docs/HIDD/VesaGfx|vesagfx.hidd]] *[[Aros/Developer/Docs/HIDD/ATI|radeon.hidd]] *[[Aros/Developer/Docs/HIDD/NVidia|nvidia.hidd]] *[[Aros/Developer/Docs/HIDD/Nouveau|nouveau.hidd]] *[[Aros/Developer/Docs/HIDD/Kbd|kbd.hidd]] *[[Aros/Developer/Docs/HIDD/Mouse|mouse.hidd]] *[[Aros/Developer/Docs/HIDD/i2c|i2c.hidd]] *[[Aros/Developer/Docs/HIDD/IRQ|irq.hidd (deprecated)]] *[[Aros/Developer/Docs/HIDD/PCI|pci.hidd]] *[[Aros/Developer/Docs/HIDD/PCIPC|pcipc.hidd]] *[[Aros/Developer/Docs/HIDD/Serial|serial.hidd]] *[[Aros/Developer/Docs/HIDD/Thunderbolt|thunderbolt.hidd]] https://github.com/aros-development-team/AROS/commit/4f02ea691799aff3a01f60cfa5f9182c82fc57a8 HIDD are used for device/peripheral low level hardware support drivers. The HIDD system is split up into a collection of classes with a strict inheritance hierarchy. A HIDD class implements a device driver for a single device or in rare cases a group of devices and provides an interface for other programs and devices to access. In order to maintain portability of interfaces across a wide range of hardware this interface will in general not present the raw interface to the underlying hardware. Instead it will present a generic interface that describes many different hardware implementations. This allows for the best reuse of both interfaces and code. HIDD API is heavyweight though. You need to open a HIDD library, open oop.library, instantiate an object (even if there's no object); and object calls are more costly compared to plain library calls. Basically your task is to implement a subclass of hidd.ata.bus for your hardware. just implementing the XXXATA__Hidd_ATABus__xxxxxx methods for the Amiga chipset - and appropriate versions of the interface_xxx.c file(s). pretty much everything in probe.c could be ignored - just write a replacement scan for relevant amiga devices and store whatever info you need in the bus data? only the "SUPPORT_LEGACY" blocks might be related. You do not need to depend on PCI API. PCI is just a way to discover the hardware on PCs, etc. <hidd/pci.h> includes (at some depth) <interface/HW.h>, which defines IID_HW. This comes from the 'generic' HIDD class in: rom/hidds/hidd/hiddclass.conf did not split up HIDD and HW because they are always used in pair. It's the same as hidd/pci.h bringing definition for: PCI, PCIDriver and PCIDevice. PCI is actually PCIHW, just the name was not changed for backwards compatibility reasons. HW is a 'hub' where HIDD instances plug in. ATA HIDD aoHidd_ATABus_Use32Bit value is completely ignored unless ata.device first detects correct command line parameter. Yes. Unfortunately I was unable to find any comment in code or svn history with explanations. Looked at Linux source, there 32-bit PIO is also controller driver's property. Some of them enable it, some don't. Actually, switching the default to ON should be safe. ata.device is fail-safe at this because during IDENTIFY command it validates upper 16 bits, and if they appear to be zeroes in all 128 longwords, then 32-bit mode is switched off. But, nevertheless, I know how tricky hardware can be, so I decided not to change original behavior. If you think it's wrong in some cases, then it's possible to add one more attribute like aHidd_ATABus_Default32Bit. If set to YES, then this means that 32-bit PIO is safe to use by default. ====Devices==== *[[Aros/Developer/Docs/Devices/ATA|ata.device]] *[[Aros/Developer/Docs/Devices/Console|console.device]] *[[Aros/Developer/Docs/Devices/Narrator|narrator.device]] *[[Aros/Developer/Docs/Devices/Printer|printer.device]] *[[Aros/Developer/Docs/Devices/Trackdisk|trackdisk.device]] *[[Aros/Developer/Docs/Devices/AmberRAM|amberram.device]] *[[Aros/Developer/Docs/Devices/Timer|timer.device]] *[[Aros/Developer/Docs/Devices/|.device]] The Amiga used [[Aros/Developer/Docs/Devices|Devices]] to communicate with [http://aros-exec.org/modules/newbb/viewtopic.php?start=0&topic_id=3475&viewmode=flat&order=ASC additional hardware]. AROS has replaced these hardware devices with hidd equivalents but some are still retained for backwards compatibility. Local libraries/devices/handlers,etc. are supposed to override the ones in ROM if their version is higher than the one in ROM. Here is the list of commands exec default: {| class="wikitable" | CMD_CLEAR | Purge the buffer of the device |---- | CMD_READ | Playback Control |---- | CMD_STOP | Stopped the activity of the device |---- | CMD_FLUSH | Empty the queue of commands |---- | CMD_RESET | Reset a device |---- | CMD_WRITE | Playback Control |---- | CMD_INVALID | Create an error |---- | CMD_UPDATE | Gets updated device |---- | CMD_START | Will restart the device |---- |} While most other "stuff you communicate with" in AmigaOS are devices <ref>AMIGA ROM Kernel Reference Manual: Devices, 3rd Edition. Commodore-Amiga, Inc. Addison-Wesley, 1991. {{ISBN|0-201-56775-X}}</ref> that share a [http://gega.homelinux.net/AmigaDevDocs/ common base interface]. [[Aros/Developer/Docs/Devices1.3|OS 1.3 Device Drivers]]. ====Handlers==== :[[Aros/Developer/Docs/Handlers/Pipe|pipe.handler]] :[[Aros/Developer/Docs/Handlers/Port|port.handler]] :[[Aros/Developer/Docs/Handlers/SFS|sfs.handler]] :[[Aros/Developer/Docs/Handlers/FAT|fat.handler]] :[[Aros/Developer/Docs/Handlers/PFS|pfs.handler]] :[[Aros/Developer/Docs/Handlers/NTFS|fuse.handler]] :[[Aros/Developer/Docs/Handlers/FFS|ffs.handler]] filesystem handlers have their own separate system consisting of completely differently structured messages that dos.library use to pass requests (for things like reading, writing, getting directory contents etc.) to them. AROS originally went with implementing filesystem handlers as devices, which might arguably be more consistent with the rest of the AmigaOS API but which is quite incompatible with AmigaOS itself. However, it made it far harder to port filesystems and the gains were comparatively small, and so there's been a long standing goal of fixing this incompatibility. It has now, June 2011, been reintroduced to all AROS flavors. are argstr and argsize valid for the handler startup environment? DOS/RunHandler() calls DOS/CreateNewProcTags(), and then CallEntry() (in rom/dos/exit.c) to start the handler, so yes, argstr and argsize are *present* in the call signature of the handler. Granted, argstr will be NULL and argsize 0, but those values *are* passed to the handler function using: <pre> AROS_UFC3(ULONG, entry, AROS_UFCA(STRPTR, argptr, A0), AROS_UFCA(ULONG, argsize, D0), AROS_UFCA(struct ExecBase *, SysBase, A6)); </pre> Creating your own [without the whole build tree http://pagesperso-orange.fr/franck.charlet/temp/radeon.zip] and then <pre> make stub make make install </pre> SFS has two Root blocks, one at the start and one at the end of the disk. The Root blocks both contain the same information. They hold various information about the disk structure and have the locations of some important blocks used by the filesystem. The Root ObjectContainer contains the Root directory Object. The name of this Object is the name of the volume. It is identical to a normal directory Object. The Bitmap is used to keep track of free space. Each bit in a bitmap represents a single block. A set bit indicates a free block and a cleared bit a used block. AdminSpaceContainers are used to keep track of space which has been reserved for storing administration blocks. Only the Bitmap, the Root blocks and the actual data stored in files aren't stored in administration space. Administration space is allocated in chunks of 32 blocks at a time. A single AdminSpaceContainer can hold information about a large number of such areas each of which has its own little bitmap of 32 bits. Extents are stored in a B-Tree. The Root block holds a pointer to the root of the Extent B-Tree. Extents keep track of space in use by a specific file. Each fragment a file consists of has its own Extent. Extents are in a double linked list. The list can be used to locate the next or previous fragment of a file. Below is the standard block header. This header is found before EVERY type of block used in the filesystem, except data blocks. The id field is used to check if the block is of the correct type when it is being referred to using a BLCK pointer. The checksum field is the SUM of all LONGs in a block plus one, and then negated. When applying a checksum the checksum field itself should be set to zero. The checking a checksum the checksum is okay if the result of the checksum equals zero. The ownblock BLCK pointer points to the block itself. This field is an extra safety check to ensure we are using a valid block. Field Type Description id ULONG The id field is used to identify the type of block we are dealing with. It is used to make sure that when referencing a block we got a block of the correct type. The id consist of 4 bytes and each blocktype has its own unique foure letter code. checksum ULONG This field contains the sum of all longs in this block, plus one and then negated. The checksum can be used to check if the block hasn't been corrupted in any way. ownblock BLCK Points to itself, or in other words, this field contains the block number of this block. This is yet another way to check whether or not a block is valid. <pre> struct fsBlockHeader { ULONG id; ULONG checksum; BLCK ownblock; }; </pre> The algorithm to calculate the checksum of a block: <pre> ULONG calcchecksum(struct fsBlockHeader *block, LONG blocksize} { ULONG *data=(ULONG *)block; ULONG checksum=1; block->checksum=0; while(blocksize>0) { checksum+=*data++; blocksize-=4; } return(-checksum); } </pre> A Root block contains very important information about the structure of a SFS disk. It has information on the location and size of the disk, the blocksize used, locations of various important blocks, version information and some filesystem specific settings. A SFS disk has two Root blocks; one located at the start of the partition and one at the end. On startup the filesystem will check both Roots to see if it is a valid SFS disk. If either one is missing SFS can still continue (although at the moment it won't). A Root block could be missing on purpose. For example, if you extend the partition at the end (adding a few MB's) then SFS can detect this with the information stored in the Root block located at the beginning (since only the end-offset has changed). Same goes for the other way around, as long as you don't change start and end point at the same time. When a Root block is missing because the partition has been made a bit larger, then SFS will in the future be able to resize itself without re-formatting the disk. Field Type Description bheader struct fsBlockHeader Standard block header. version UWORD The version of the filesystem block structure. You can check this field to identify what version of the filesystem your dealing with it and to see if you can handle this structure correctly. Don't try to interpret the disk's structure when this field contains an unknown version number! sequencenumber UWORD Used to identify which Root block was written last in case the sequencenumber on both Root blocks don't match. datecreated ULONG Creation date of this volume. This is the date when the disk was last formatted and will never be changed. bits UBYTE Various settings, see below. <pre> pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. reserved1 ULONG[2] Reserved, leave zero. firstbyteh ULONG High 32-bits of a 64-bit number. This is the first byte of our partition relative to the start of the disk. firstbyte ULONG Low 32-bits of a 64-bit number. lastbyteh ULONG High 32-bits of a 64-bit number. This is the last byte (exclusive) of our partition relative to the start of the disk. lastbyte ULONG Low 32-bits of a 64-bit number. totalblocks ULONG The total number of blocks this partition consists of. blocksize ULONG The size of a block of this partition. reserved2 ULONG[2] Reserved, leave zero. reserved3 ULONG[8] Reserved, leave zero. bitmapbase BLCK Block number of the start of the Bitmap. adminspacecontainer BLCK Block number of the first AdminSpaceContainer. rootobjectcontainer BLCK Block number of the ObjectContainer which contains the root of the disk (this is where the volume name is stored). extentbnoderoot BLCK Block number of the root of the Extent B-Tree. reserved4 ULONG[4] Reserved, leave zero. </pre> <pre> struct fsRootBlock { struct fsBlockHeader bheader; UWORD version; UWORD sequencenumber; ULONG datecreated; UBYTE bits; UBYTE pad1; UWORD pad2; ULONG reserved1[2]; ULONG firstbyteh; ULONG firstbyte; ULONG lastbyteh; ULONG lastbyte; BLCK totalblocks; ULONG blocksize; ULONG reserved2[2]; ULONG reserved3[8]; BLCK bitmapbase; BLCK adminspacecontainer; BLCK rootobjectcontainer; BLCK extentbnoderoot; ULONG reserved4[4]; }; </pre> AdminSpaceContainers are used to store the location and bitmap of each administration space. The AdminSpaceContainers are located in a double linked list and they contain an array of fsAdminSpace structures. There is one fsAdminSpace structure for every administration space on disk. Field Type Description bheader struct fsBlockHeader Standard block header. next BLCK The next AdminSpaceContainer, or zero if it is the last in the chain. previous BLCK The previous AdminSpaceContainer, or zero if it is the first AdminSpaceContainer. bits UBYTE The number of bits in each in the bits ULONG in the fsAdminSpace structure. pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. adminspace struct fsAdminSpace An array of fsAdminSpace structures. The size of the array is determined by the current blocksize. <pre> struct fsAdminSpaceContainer { struct fsBlockHeader bheader; BLCK next; BLCK previous; UBYTE bits; UBYTE pad1; UWORD pad2; struct fsAdminSpace adminspace[0]; }; </pre> Field Type Description space BLCK The first block of an administration space. bits ULONG A small bitmap which is used to determine which blocks in an administration space are already in use. The number of bits in this bitmap is determined by the bits field in the AdminSpaceContainer. <pre> struct fsAdminSpace { BLCK space; ULONG bits; }; </pre> The fsBitmap structure is used for Bitmap blocks. A bitmap block is used to keep track of which space is in use and which isn't for a particular area of a disk. All bitmap blocks together keep track of the free space for an entire disk. The location of the first bitmap block is known and all other bitmap blocks are stored in order after the first one. Field Type Description bheader struct fsBlockHeader Standard block header. bitmap ULONG An array of ULONG's. These hold the actual information on which blocks are in use and which aren't. <pre> struct fsBitmap { struct fsBlockHeader bheader; ULONG bitmap[0]; }; </pre> Each bit in a bitmap block (except for the block header) represents a single block. If the bit is set than the block is free, and if the bit is clear then it is full. The first ULONG in the bitmap area of the first bitmap block represents blocks 0 through 31 on the disk. Bit 31 of this ULONG is block 0, 30 is block 1, and so on. Bit 0 of the first ULONG represents block 31. Below is a table to clarify how bitmaps work even further. The first column is the bitmap block number, the second column is the number of the ULONG in the bitmap array. The third column is the bit number in this ULONG, and the last column is the block which this specific bit, in this specific bitmap block represents. We'll assume here that a bitmap block has room for 120 ULONG's (meaning there is room for storing 32 * 120 bits). <pre> Bitmap block ULONG number Bit number Block represented 1 (first) 0 31 0 1 0 30 1 ... ... ... ... 1 0 1 30 1 0 0 31 1 1 31 32 ... ... ... ... 1 2 31 64 1 2 30 65 ... ... ... ... 1 119 0 3839 2 0 31 3840 2 0 30 3841 ... ... ... ... </pre> The last bitmap block doesn't need to be completely used. The unused bits (which belong to blocks which do not exist) all have to be clear, to indicate that these blocks are in use. The fsObjectContainer structure is used to hold a variable number of fsObjects structures (Objects) which have the same parent directory. Each ObjectContainer must contain at least one Object. If there is space in the ObjectContainer not used by the variable number of Objects then that space is zero filled. Objects always start at 2-byte boundaries, which means sometimes a padding byte is inserted between two Objects. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the parent Object, or 0 if this object has no parent (which is only the case for the Root directory). next BLCK The next ObjectContainer belonging to this directory, or zero if it is the last in the chain. previous BLCK The previous ObjectContainer belonging to this directory, or zero if it is the first ObjectContainer in this directory. object struct fsObject A variable number of fsObject structures. The number of structures depends on the individual sizes of each fsObject structure and the blocksize. These structures are located directly after each other with at most 1 byte of padding between them to get the structures aligned on a 2 byte boundary. <pre> struct fsObjectContainer { struct fsBlockHeader bheader; NODE parent; BLCK next; BLCK previous; struct fsObject object[0]; }; </pre> fsHashTable is the structure of a HashTable block. It functions much like the hash table found in FFS user directory blocks, except that it is stored in a separate block. This block contains a number of hash-chains (about 120 for a 512 byte block). Each hash-chain is a chain of Nodes. Each Node has a pointer to an Object and a pointer to the next entry in the hash-chain. Using such a hash-chain you can locate an object quickly by only knowing its name. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the directory Object this HashTable block belongs to. hashentry NODE An array of Nodes. Each Node represents the start of a hash-chain (singly linked). A hash-value is calculated using the name of a file or directory, and this value determines in which chain the Object is linked. If there are no entries in a hash-chain then the hashentry value is zero. <pre> struct fsHashTable { struct fsBlockHeader bheader; NODE parent; NODE hashentry[0]; }; </pre> To calculate the hash-value using a name of an Object as input use these routines: <pre> UWORD calchash(UBYTE *name) { UWORD hash=0; /* Calculates a hash value over the passed in string. The end of the string can be either a NUL byte or a slash. The hash function is the same as the one used in FastFileSystem set to international mode. */ while(name[hash]!=0 && name[hash]!='/') { hash++; } while(*name!=0 && *name!='/') { hash=hash*13+upperchar(*name++); } return((UWORD)(hash % (UWORD)((blocksize-sizeof(struct fsHashTable))>>2))); } UBYTE upperchar(UBYTE c) { if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z')) { c-=32; } return(c); } </pre> The BNodeContainer is used to store B-Trees. Currently only one B-Tree is in use by this filesystem and it is used to store the location of file data. The fsBNodeContainer structure contains two other structures. The fsBlockHeader structure and the BTreeContainer structure. Field Type Description bheader struct fsBlockHeader Standard block header. btc struct BTreeContainer Contains information about the B-Tree and its nodes contained in this block. <pre> struct fsBNodeContainer { struct fsBlockHeader bheader; struct BTreeContainer btc; }; </pre> First try and locate the Root block. It should start with "ROOT". SFS has two of these, one at the start of the partition and one at the end. One of the fields contains the block size, which will be the size of all important SFS blocks. The root block has the root object container, which contains information about files and directories in the root directory. The object containers basically hold one or more smaller structures that represent files and directories. Scanning them all should give you a list of files and directories. The root block also has the root of the Extent B-Tree. This is a standard B-Tree structure (not a binary tree) that is used commonly in all kinds of system, you can read about how they work on Wikipedia if needed. The B-Tree holds the information about *where* all the data is located for your files. To recover your files, I'd do this: * Find one of the root blocks, if not present, then figure out the block size your disk was using, and scan every block in turn to see if it looks like an ObjectContainer (check the fsBlockHeader's ID, check if the ownblock number is equal to the block you are currently scanning, and check its checksum). So if you currently have block 12, and you see a block with the correct id, and ownblock = 12 and its checksum is good, then that's probably a valid ObjectContainer. * With all the ObjectContainers found, you can extract filenames and directory names from these, but also the number of their first data block (in the field data) and the file size. For small files (less than blocksize) this data block will be enough to recover the data. For larger files, you might be lucky and all the remaining blocks are found after the first one (if the file was defragmented). You can't be sure of that though so... * For larger files, you need to find all the BNodeContainers. You could scan these in the same way you found all the ObjectContainers (look for blocks with the correct id, ownblock number and checksum). * With all the BNodeContainers found, you can try looking up the first data block of a file in the B-Tree structure. This is a bit complicated -- the B-Tree consists of non-leaf nodes (blocks that only contain pointers to other B-Tree blocks), the isLeaf flag indicates this. Or it can be a B-Tree leaf block. The leaf blocks contain extra information per entry (see https://hjohn.home.xs4all.nl/SFS/extents.htm) <pre> struct fsExtentBNode { ULONG key; ULONG next; ULONG prev; UWORD blocks; }; </pre> The key should be a block of a file (the first of a range), that is 1 to 65535 block long (depending the "blocks" field). If the file is split up into more parts, then "next" will contain block number of the next range of blocks. You need to look this up again in the B-Tree structure to find out how large it is. You can for the most part ignore the other structures (bitmap, admin containers). The fsObjects and B-tree containers is what you'll need to recover the data. ====Resources==== <pre> rom/storage/mmakefile.src rom/storage/storage.conf rom/storage/storage_device.c rom/storage/storage_ids.c rom/storage/storage_init.c rom/storage/storage_intern.h rom/storage/storage_mount.c rom/storage/storage_unit.c </pre> <pre> rom/storage/includes/device.h rom/storage/includes/unit.h rom/storage/includes/volume.h rom/storage/storage_intern.h </pre> <pre> </pre> *[[Aros/Developer/Docs/Resources/ACPI|acpi.resource]] *[[Aros/Developer/Docs/Resources/Battclock|battclock.resource]] *[[Aros/Developer/Docs/Resources/Bootloader|bootloader.resource]] *[[Aros/Developer/Docs/Resources/Cia|cia.resource]] *[[Aros/Developer/Docs/Resources/Filesystem|FileSystem.resource]] *[[Aros/Developer/Docs/Resources/Hostlib|hostlib.resource]] *[[Aros/Developer/Docs/Resources/Kernel|kernel.resource]] *[[Aros/Developer/Docs/Resources/Misc|misc.resource]] *[[Aros/Developer/Docs/Resources/Processor|processor.resource]] ==Debugging Code== Please use the [http://sourceforge.net/tracker/?group_id=43586&atid=439463 AROS Bug Tracker] if any issues are found. GRUB Command line list <pre> sysdebug usbdebug - allows to see Poseidon's log in debug output </pre> How do I get debugging out of InitResident ? If running i386 hosted on linux sysdebug=initresident on command line. This way you can enable any of listed flags. sysdebug=all stands for "everything" Have an executable (crosscompiled C++ code) which has 6 MB size on disk, but after loading it in memory, 250 MB RAM is taken. Any software that would split AROS executable into ELF part which would show actual size values? readelf -S executable it will show you all sections in elf file, including sizes and requested alignment. objdump -h filename That's will give you a quick overview of the sections and sizes. Ignore all the .debug.* sections. Would hazard a guess that you have a large .bss section. That's pretty common in C++. Next step: nm—size-sort filename | grep ' [bB] ' The last few will be your biggest consumers. Would suggest -C to demangle the symbols... ;) Suggest profiling the program (just use some printf's in the main loop for time spent in each part), it usually is quite easy to spot slow parts in games or apps. If someone has '#define IPTR ULONG' somewhere. To see where that define is, redefine IPTR in the source code that fails, just above the line that fails, and the preprocessor will tell you where it was defined first. ===How to setup gdb with AROS/hosted=== Download AROS sources (AROS-xxxxxxxx-source.tar.bz2, where xxxxxxxx is the current date) and AROS contrib sources (AROS-xxxxxxxx-contrib-source) from Untar-bzip2 and cd to the unpacked archive directory. > tar -xvjf AROS-xxxxxxxx-source.tar.bz2 > cd AROS-xxxxxxxx-source Check the link to "contrib" (contrib-source) inside directory, e.g. correct like this: > rm contrib > ln -s ../AROS-xxxxxxxx-contrib-source.tar.bz2 contrib Make sure you have the correct locale setting, otherwise compilation will fail at some point. See [http://aros.sourceforge.net/documentation/developers/compiling.php#setting-the-locale-to-iso8859 here] (or link below) for more on that. You might have to enter this: > export LANG="en_US.ISO-8859-1" Now configure for a debug build - see "./configure --help" for more - here are two examples: > ./configure—enable-debug=stack,modules,symbols > ./configure—enable-debug=all You may "make" now, or choose a separate directory for your build (e.g. for easy removal), for example if compiling for i386 architecture you could create a directory like this: > mkdir linux-i386 > cd linux-i386 > ../AROS/configure—enable-debug=stack,symbols,modules When done configuring you're ready to go: > make Building AROS takes some time - minutes on fast machines (e.g. 2.5&nbsp;GHz quadcore), up to hours on slower machines. The result will be AROS Linux hosted with gdb debugging enabled. See aros.org documentation for more on compiling AROS, including more [http://aros.sourceforge.net/documentation/developers/compiling.php --enable-debug] options. When finished, enter bin/linux-i386/AROS directory (replace "linux-i386" with your compilation target platform, e.g. linux-x86_64, etc.) inside the unpacked archive directory. This directory contains the required .gdbinit file for properly running AROS inside gdb. > cd bin/linux-i386/AROS Run AROS (here: with 128MB of memory) from gdb: > gdb—args boot/aros-unix -m 128 or > gdb—args boot/arosboot -m 128 (gdb) r Watch the shell output - in case AROS complains about "LoadKeyCode2RawKeyTable: Loading "DEVS:Keymaps/X11/keycode2rawkey.table" failed!" you should also see some instructions on how to create a keymap table. (see link above "more on compiling", too.) Quit gdb, and try default keymap table: (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y > cd ../../.. > make default-x11keymaptable Re-run AROS, as described above. Try e.g. RAros (= right windows key) + W to open a shell. If this doesn't work you have to create a keymap table yourself, quit gdb again, and make a new keytable: > make change-x11keymaptable A window will open. Watch the window's title bar, and follow the instructions. When done, re-run AROS. RAros + W should now open a shell. Next, compile your program with gdb support. When you start GDB is there a warning which says warning: File "<whatever>/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to ... If so start gdb with "-ix .gdbinit" <pre> Summary - In short: * build AROS with debugging support (i.e. ./configure --enable-debug=all) * build your application with debugging support (i.e. option -g) * run AROS in the GNU debugger (you may use the GUI frontend "ddd" which simplifies usage a bit) * start your application * use the commands "findaddr" and "add-symbol-file" as written in the debugging manual * if the debugger doesn't find the source code of your application use the "dir" command of the debugger. </pre> ===How to use gdb=== In AROS open a shell, then (in host shell) use CTRL-Z to go into gdb. Use "b Exec_CreatePool" (one of the functions used early on by startup code in programs) to add a breakpoint, then "cont" and gdb will interrupt somewhere early during startup of "program". Use "bt" to show backtrace and "loadseg" for "??" entries. One of them will be for "program". After that you can use "disassemble program". One thing you need to make sure is that .gdbinit you have in your build directory is the same as in source tree. It has been modified some time ago, but the build system does not refresh it - you need to copy it manually To recap, please read our debugging [http://aros.sourceforge.net/documentation/developers/debugging.php manual]: To detect segfaulting when loading, try... ./configure—enable-debug—with-optimization="-O2" Because crash or no crash may depend on optimization. For newer compilers maybe this helps... --with-optimization=-"-O2 -fno-strict-aliasing" One way to make crashes less random (more easily reproducible) is to activate the munging of free memory in rom/exec/freemem.c which is normally commented out: <pre> Index: freemem.c =================================================================== --- freemem.c (revision 34289) +++ freemem.c (working copy) @@ -154,11 +154,12 @@ * created with their TCB placed in the tc_MemEntry list. The workaround * is to avoid munging when FreeMem() is called with task switching disabled. */ + /* DOH! it doesn't work even this way. What's wrong??? - * - * if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) - * MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); */ + + if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) + MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); } </pre> Mungwall can be turned on at runtime. Currently this works in all hosted versions. Just specify "mungwall" on kernel command line and it works. It can work on native too. In order to enable it you need to parse kernel command line, and if "mungwall" is present, set EXECF_MungWall bit in IntExecBase.IntFlags. This needs to be done before the first AllocMem() for obvious reasons. And never reset back this flag! If you change it on a working system, you are doomed. Hosted ports do the processing in rom/exec/prepareexecbase.c --enable-debug=mungwall option in configure still works but is going obsolete. A kludge in rom/exec/allocmem.c is responsible for this and it needs to be removed when the transition is done. BTW, on i386-pc port it can be activated by "mungwall" argument on command line, you don't need to rebuild AROS. New mungwall affects not only AllocMem()/FreeMem(), but also pools. I also tested it with AllocAbs(), seems to work correctly. Runtime mungwall works on: * pc-i386 * pc-x86_64 * linux-i386 * linux-x86_64 * darwin-x86 * linux-ppc Works on all hosted ports, if the port itself is working. * amiga-m68k * Not on sam440-ppc and efika-chrp-ppc, even if they would be able to be built at moment. Does not work on (for now, need NVRAM support) When starting my freshly rebuilt i386-linux-aros which was compiled with full debugging support I get sometimes the error "Program exited with code 0377". Add the following to your .gdbinit: set follow-fork-mode child Here are some of the custom AROS gdb functions (defined in ".gdbinit" file) to resolve "in ?? ()" entries in backtrace: <pre> #0 0xb7ffd424 in __kernel_vsyscall () #1 0xb7e2a657 in sigsuspend () from /lib/libc.so.6 #2 0xb7c63900 in ?? () #3 0xb7c640e3 in ?? () #4 0xb7c641e0 in ?? () </pre> You can use loadseg 0xb7c63900 loadframe 2 or loadbt and some others. Use "help " for a little help text. If the commands do not work try "loadkick" first. Use "thistask", "taskready", "taskwait" to get list of AROS tasks. "bttask " shows backtrace of a task which is in ready or in wait queue and "loadseg" to resolve "??" entries in it's backtrace ("loadframe" would not work as it assume current running task). ===Native debugging tools for AROS=== to enable debugging at boot time entering the GRUB menu editing line (E key) and adding "debug=memory" to your boot line, then press Ctrl+X to complete booting. SYS:Tools/Debug/'''Bifteck''' Open a shell and enter the line below to run Biftek and grab the debug messages collected in RAM into a text file. tools/debug/bifteck > ram:debug.txt and certainly does not open a window. It is a shell tool and only dumps data located from the debug location. It is therefore important to 'catch' that debug data as soon as possible (before it gets overridden). You should invoke bifteck at the first opportunity before doing anything else. You can use the TO option to store bifteck output to a file or you can pipe it manually to a file. SYS:Tools/Debug/'''Sashimi''' - displays error messages One suggestion is to do a bug() debugging. Each time bug() is executed it will be output on sashimi. You include <aros/debug.h> and place bug("something\n"); in your source code at location though which control passes. To get the output - open an aros shell SYS:Tools/Debug/sashimi > RAM:out.txt '''Ctrl C''' to end the output to the RAM Disk. # open shell, and type # ram: (to switch to ram drive) # System:Tools/Debug/Sashimi > mylogfile.txt # open AHI prefs using wanderer (or use another opened shell) # play test sound # close AHI prefs # shell still open with Sashimi running: press ctrl-c to break Sashimi and return to prompt. # in shell: copy mylogfile.txt System: (or to your required location) SYS:Utilities/'''Snoopy''' - monitors OS function calls, run "Sashimi" to see Snoopy's output SYS:Tools/'''WiMP''' - the Window (and Screens) Manipulation Program You can use the -E option of gcc to find out how preprocessor macros are expanded. ===Errors=== crash in strcasecmp usually means that one of its arguments is NULL. empty space between these two names, prossibly some invisible character Old Amiga [http://www.amigacoding.com/index.php?title=Guru_codes&redirect=no Guru Codes] If the crash is in intuition. Sometimes, if it relates to text, a null pointer sets it off. an uninitialised pointer can have any address (this is a common fault). Compiling on 64bit, Many old code would not properly typecast when doing pointer-integer conversions and thus at least throw a warning. This can easily be located and fixed. [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. * Fix (change IPTR/SIPTR back to ULONG/LONG) the few places which really rely on ULONG/LONG being exactly 32 bit. That's for things like pixel (ARGB) buffers, structs written/read to disk, colormaps, but probably not much else. Then again, many current compilers also throw a warning when you try to assign a pointer value to an integer and the integer is possibly too small. This happens under .NET for example when a 64 bit pointer is assigned to something like an ULONG - so exactly the case which you described. === AI === Multimodal Context Prompt <--- Model <---> Agent ---> End user engine Gemini LMStudio Qwen Comfyui etc Recent, self hosting locally on laptops, mini pcs or desktops with '''quantization''' 4bit has reduced memory requirements but still require 16Gb+ and no high end gpu for text based *[https://lmstudio.ai/download LMstudio single gpu], Google Gemma 4 Model *[ 12B QAT] Alibaba Cloud's [https://huggingface.co/ Qwen] team series of large language models LLMs *[https://huggingface.co/models?other=qwen3 Qwen 3], [], *[https://huggingface.co/models?other=qwen2 Qwen 2], [https://huggingface.co/Qwen/Qwen2.5-Coder-32B qwen 2.5 Coder], Small models *[ glm-ocr] *[ medGemma] *[ qwen 3.5-4b] *[https://github.com/sipeed/picoclaw picoclaw claude] Bigger LLMs but with settings *[https://ollama.com/download Ollama single gpu] *[https://github.com/ggml-org/llama.cpp/releases llama.CPP multi gpus], *[ VLM multiple gpus], Multimedia *[ Kimi K3], For the full experience #Training learning using 1+ high end GPUs at least 16GB VRAM per GPU card or 64Gb+ of unified, 16Core CPU with at least 64Gb of RAM system memory, though training can take weeks #Inference with custom asics or GPUs *[ MiniMax H3] for audio and video but gpu 8Gb+ *[https://github.com/jamiepine/voicebox voicebox] *[https://github.com/ideogram-oss/ideogram4 ideogram4] *[https://github.com/calesthio/OpenMontage OpenMontage] <pre> Text to Audio --\ Text to Video --/ Reference Video --> Video and Audio output </pre> === Linux === <syntaxhighlight lang="c"> /* 1. Header for your name,date,purpose of program. 2. Pre-processor directives. This will include the #includes for files you want to add. 3. Includes for function prototypes if necessary. 4. Main() Create Pointers for Libraries and any Window you want to open. 5. Open necessary libraries. 6. Check if open exit program if fail. 7. Open a window exit program if fail. 8. Add your program 9. Close Window 10 Close Libraries. 11 End Program. */ /* standard os included headers <.h> */ #include <dos/dos.h> #include <dos/dosasl.h> #include <dos/dosextens.h> #include <dos/exall.h> #include <dos/rdargs.h> #include <exec/memory.h> #include <exec/types.h> #include <utility/utility.h> #include <intuition/intuition.h> /* define as unresolved external references (proto/xxx.h) and compiler will link to auto(matically) open library */ #include <proto/arossupport.h> #include <proto/dos.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/graphics.h> #include <proto/cybergraphics.h> #include <proto/datatypes.h> #include <proto/icon.h> #include <workbench/workbench.h> #include <workbench/icon.h> #include <datatypes/pictureclass.h> #include <proto/muimaster.h> #include <libraries/mui.h> #include proto/bsdsocket.h #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* my own headers ".h" */ #define CTRL_C (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) #define isDir(fib) ((fib)->fib_DirEntryType >= 0) #define ARG_TEMPLATE "FILE/A,ALL/S,QUIET/S,W=WIDTH/N,H=HEIGHT/N,M=METHOD,DEFTOOL" int main(void) { return retval; } /* main */ </syntaxhighlight> If you used c++, there is not yet c++ support in our shared library system. The easiest way to create / compile a shared library would be to use the AROS build system but the libraries can be created manually. You have to create a ROMTAG structure and some header files. A shared library is built with the %build_module macro with a line like this: %build_module mmake=MetaTarget modname=mylib modtype=library files=SourceFiles This macro can build different AROS module types, like devices, Zune classes, HIDDs, etc. <pre> ##begin config version 1.0 ##end config ##begin functionlist void func1(LONG a, LONG b) int func2(char *s, ULONG a) ##end functionlist </pre> There is more [http://aros.sourceforge.net/documentation/developers/sys-dev/libraries.php here] Alternatively, <pre> #ifndef LIB_H #define LIB_H #define __NOLIBBASE__ #include <exec/libraries.h> #include <exec/semaphores.h> #include <dos/dos.h> #ifdef __AROS__ //#include <aros/debug.h> #define reg(x) #define __saveds #endif #define USESYSBASE struct ExecBase *SysBase = Base->My_SysBase; struct MyTestBase { struct Library My_Test_Lib; struct ExecBase *My_SysBase; APTR My_SegList; int testint; }; #endif </pre> <pre> /*--------------------------------------------------------------------------*/ /* Resident header written for mytest.library */ /*--------------------------------------------------------------------------*/ #define __NOLIBBASE__ #define VERSION 1 #define REVISION 0 #define LIBHEADNAME mytest #define LIBHEADNAMESTR "mytest" #define COMPDATE "04.10.2015" #define VERS "1.0" #define LIBBASETYPE struct MyTestBase #define LIBBASETYPEPTR LIBBASETYPE * #include <aros/debug.h> #include <exec/exec.h> #include <proto/exec.h> #include <exec/resident.h> #include <exec/nodes.h> #include <exec/libraries.h> #include <aros/symbolsets.h> #include "lib.h" const UBYTE lib_name[] = LIBHEADNAMESTR ".library"; const UBYTE lib_id[] = "$VER: " LIBHEADNAMESTR ".library " VERS " (" COMPDATE ") by ALB42\n"; extern const APTR FuncTable[]; AROS_UFP3 (LIBBASETYPEPTR, InitLib, AROS_UFPA(LIBBASETYPEPTR, Base, D0), AROS_UFPA(BPTR, seglist, A0), AROS_UFPA(struct ExecBase *, sysbase, A6) ); static struct LibInitStruct { IPTR LibSize; const APTR *FuncTable; const struct DataTable *DataTable; APTR InitFunc; } const LibInitStruct = { sizeof(LIBBASETYPE), FuncTable, NULL, (APTR)InitLib }; const struct Resident romtag = { RTC_MATCHWORD, /* match word */ (APTR)&romtag, /* back pointer */ (APTR)(&romtag + 1), /* skip pointer */ RTF_AUTOINIT | RTF_EXTENDED,/* flags */ VERSION, /* version */ NT_LIBRARY, /* type of module */ 0, /* init priority */ (STRPTR)lib_name, /* module name */ (STRPTR)lib_id + 6, (APTR)&LibInitStruct, REVISION, NULL }; AROS_UFH3 (LIBBASETYPEPTR, InitLib, AROS_UFHA(LIBBASETYPEPTR, Base, D0), AROS_UFHA(BPTR, seglist, A0), AROS_UFHA(struct ExecBase *, sysbase, A6) ) { AROS_USERFUNC_INIT Base->My_SegList = seglist; Base->My_SysBase = (APTR)sysbase; Base->testint = 0; USESYSBASE bug("InitLib\n"); if (!set_open_libraries()) { set_close_libraries(); return NULL; } return Base; AROS_USERFUNC_EXIT } AROS_LH1(LIBBASETYPEPTR, LibOpen, AROS_LHA (ULONG, version, D0), LIBBASETYPEPTR, Base, 1, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibOpen\n"); (void)version; Base->My_Test_Lib.lib_OpenCnt++; return Base; AROS_LIBFUNC_EXIT } __saveds APTR LibExpungeInternal(LIBBASETYPE *Base reg(a6)) { USESYSBASE APTR seglist; bug("LibExpungeInternal\n"); if (Base->My_Test_Lib.lib_OpenCnt) { return 0; } seglist = Base->My_SegList; Forbid(); Remove((struct Node*)Base); Permit(); FreeMem((APTR)Base - Base->My_Test_Lib.lib_NegSize, (LONG)Base->My_Test_Lib.lib_PosSize + (LONG)Base->My_Test_Lib.lib_NegSize); set_close_libraries(); return seglist; } AROS_LH0(BPTR, LibClose, LIBBASETYPEPTR, Base, 2, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibClose\n"); if (!(--Base->My_Test_Lib.lib_OpenCnt)) { return LibExpungeInternal(Base); } return 0; AROS_LIBFUNC_EXIT } AROS_LH1(BPTR, LibExpunge, AROS_LHA(LIBBASETYPEPTR, Base, D0), struct ExecBase *, sysBase, 3, LIBHEADNAME ) { AROS_LIBFUNC_INIT (void)sysBase; USESYSBASE bug("LibExpunge\n"); return LibExpungeInternal(Base); AROS_LIBFUNC_EXIT } AROS_LH0(LIBBASETYPEPTR, LibReserved, LIBBASETYPEPTR, Base, 4, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibReserved\n"); return 0; //return (APTR)LibReserved(); AROS_LIBFUNC_EXIT } // Space for your own functions // do not forget to update the FuncTable as well AROS_LH1(int, TestFunction, AROS_LHA(int, TestValue, D0), LIBBASETYPEPTR, Base, 5, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("TestFunction\n"); Base->testint = TestValue + Base->testint; return Base->testint; AROS_LIBFUNC_EXIT } // Functable -> Table of all functions in the Library, in right order - important! const APTR FuncTable[] = { &AROS_SLIB_ENTRY(LibOpen,LIBHEADNAME,1), &AROS_SLIB_ENTRY(LibClose,LIBHEADNAME,2), &AROS_SLIB_ENTRY(LibExpunge,LIBHEADNAME,3), &AROS_SLIB_ENTRY(LibReserved,LIBHEADNAME,4), &AROS_SLIB_ENTRY(TestFunction,LIBHEADNAME,5), (void *)-1 }; // AutoInit stuff void *__PROGRAM_ENTRIES__symbol_set_handler_missing; void *__LIBS__symbol_set_handler_missing; // end of AutoInitStuff </pre> Makefile <pre> VPATH = CFLAGS = -O2 -g -fomit-frame-pointer -W -Wall -Wno-parentheses CC = i386-aros-gcc LD = i386-aros-gcc LDFLAGS = -nostartfiles -Wl,-Map -Xlinker linkermap LIBS = -lautoinit -llibinit STRIP = i386-aros-strip --strip-unneeded --remove-section .comment OBJS = lib_header.o all: mytest.library mytest.library: $(OBJS) $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ lib_header.o: lib_header.c lib.h clean: rm -f *.o *.library *.ppu testlibrary linkermap </pre> Porting UNIX library to AROS - dealing with static variables which would make it easy to port such libraries to AROS, keeping the benefits of sharing them on disk, but losing the benefit of actually sharing them in memory. Our problem arises by the fact we want to share the actual code (the .text section of the library) and constant data, but we need to have per-task .bss and .data sections. If we get rid of our intention to share the .text and .rodata sections, things get quite easy: just load and relocate the library whenever it's open, by whoever it's open. It's like statically linking the library into the executable, except that the final linking is done at runtime. In the V0 branch, in workbench/hidds/hidd.nouveau was committed pcimock.hidd. This is a pci driver that allows mocking real PCI devices under linux-hosted. The main idea is to be able to run the real hardware driver under linux-hosted with as little changes as possible (some changes will always be needed though unless someone wants to write complete device simulator) so that driver's code paths can be executed and debugged using gdb. This was a very helpful capability when porting nouveau. Now it is externalized from nouveau.hidd and can be used by other people porting drivers. The pcimock.hidd can currently mock 4 different nvidia cards, 1 AGP bridge and also mock irq.hidd. What's the difference between this driver and the pcilinux.hidd? I used that one to develop many different HW drivers for aros. As far as I understood the intention of pcilinux.hidd it is supposed to get access to real hardware that is running under linux. The pcimock.hidd goal is to mock the hardware. For example my dev box is a PCIE system, but I still would like to run the AGP codes paths in nouveau under linux-hosted to check if they don't seg fault. The other case would be to run codes paths for hardware that the developer does not have (Fermi cards in my case). In the case of pcimock.hidd, the AROS driver's code paths will execute as long as you add proper mocking (for example fill in PCI config area or values for registers in BARs). This is an advantage for ported drivers - the code should already work (since it worked on another system) but there might have been mistakes made during porting which can be detected easily with gdb. In case you are writing your driver from scratch, pcilinux.hidd hidd will give you more advantage, since you can actually access the real hardware from linux-hosted. == Misc == ===APL, MPL, BSD, GPL and LGPL Licences=== The majority of AROS sources in licensed under AROS Public License ([http://aros.sourceforge.net/license.html APL]) which (to a degree) protects us from someone taking AROS sources and not contributing improvements back (for example MorphOS took some AROS source and then contributed changes back) It is written to allow the use of AROS code in other open source or commercial projects without exception whilst providing a mechanism so that improvements/additions can find their way back to the original source in one form or another. There are "3rd" party applications used by AROS that do not fall under this license, which are an extra "Contrib" download for convenience. Anyone can port GPL-ed network and sound drivers as AROSTCP and AHI are GPLed. Direct using (porting) [http://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs GPL]-ed code in other parts of AROS (gfx, sata, usb) is not possible because AROS license is not compatible with GPL. You need to utilize permissive licensed code like BSD or MIT/X11. BSD and MPL license are the closest to APL. APL however is not so compatible with LGPL/GPL. LGPL case - you cannot statically combine APL code with LGPL. You can, however thank to LGPL being "lesser" restrictive, use LGPL dynamically loaded libraries in APL codes. GPL case - you cannot combine APL code with GPL in any way if there is no explicit clause by GPLed code authors allowing that. If you do combine APL with GPL in "bad" ways described above - you have a problem (you violate GPL). This problem might result in everything in AROS becoming GPL or everything running or AROS becoming GPL (here I'm not sure really). The other scenario is that you are not allowed to legally distribute such code at all. To be honest I have grasped how to violate GPL, but I'm still no exactly sure what happens when you violate it (but I'm sure it's not anything nice) GPL software can run on top of non-GPL "system components" (see system components exception of GPL), but the other way around (non-GPL using GPL) leads to problems. This means applications like scout, or Quake III are ok (in the majority of cases). Theres no reason GPL drivers cannot be ported - but they cant be in AROS's ROM (requires linking APL code with GPL), nor can AROS depend on them (e.g. they must use existing apis). If they are launched (dynamically linked) by a user action that is allowed. It is also allowed to distribute such binaries together for convenience. GPL is not about statical or dynamic linking but is about executing process and function calls. These components - SFS, isapnp, Zune texteditor, AHi, network drivers, freetype, openuirl, BHFormat, Edit and (" dynamically loaded libraries") are LGPL, not GPL. Mesa/Nouveau stuff is MIT. Some user tools are GPL though. '''AROS (system)''' * system components (libraries/classes/devices/etc) cannot be GPL as they would propagate GPL to complete system as well as GPL is not compatible with MPL from which APL is based * system components can be LGPL v2 or a permissive license (MIT/BSD) * system applications can be anything you like (but still I would prefer APL or permissive so the code can be reused if needed) '''Contrib:''' * no rules - contrib does not impact AROS system since nothing in AROS system depends on contrib. About stealing code: The chances of this happening is exactly the same whether we are APL or GPL. If any closed-source option wanted to do it, there is no one that can validate otherwise. MorphOS has used some AROS codes, but contributed changes back. The rationale behind APL is that while it guarantees that the original developer will get the improvements back (to a certain degree - file based), the person who uses the codes does not have to open his original codes. BSD does not guarantee that the original developer gets improvements. GPL requires the person using the codes to open his codes as well. The copyright holders needs to stay - we just need information from them that the codes are available under APL (for example a checked-in file like in case of Poseidon). We don't do transfer of copyrights. ; Ultimately what can and cannot be done is up to the author(s) - not the licence. ===AROS source code tree=== * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-trunk.txt * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt Found this interesting (non-GPL) licensing 'anomaly' - to keep in mind for distributors. Programs that lose their license if sold ("non-profit only" licensed): contrib/aminet/comm/term/TinyTerminal contrib/aminet/dev/basic/bwBASIC contrib/aminet/text/edit/xdme contrib/fish/aroach contrib/fish/lotto contrib/fish/shuffle contrib/fish/touch + cdvdfs. Here is a list of all the GPL/GPLv2/GPLv3 licenses fossology found, what have explicit licenses in their comments. excluded LGPL, BSD/GPL dual licensed and programs (such as Prefs/Edit and BHFormat) <pre> AROS/rom/dbus/include/ AFL_v2.1 ,GPL_v2+ (supposedly AFL < 3 is GPL incompatible) AROS/workbench/classes/zune/betterstring/include/ GPL_v2+ AROS/workbench/classes/zune/texteditor/include/ GPL_v2+ AROS/workbench/classes/datatypes/gemimage/ GPL_v2+ GPL AROS/workbench/classes/datatypes/degas/ GPL_v2+ AROS/workbench/libs/openurl/README: GPL AROS/workbench/network/smbfs/documentation/ GPL_v2 AROS/workbench/network/smbfs/source_code/ GPL_v2+ AROS/workbench/network/stacks/AROSTCP/bsdsocket/kern/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/mmakefile.src conf.h GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/sys/ CMU ,GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/net/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/api/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/conf/conf.h: GPL_v2 AROS/workbench/network/stacks/AROSTCP/netinclude/net/radix.h: CMU ,GPL_v2 AROS/workbench/devs/AHI/AHI/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/COPYING: GPL AROS/workbench/devs/AHI/Docs/texinfo.tex: GPL_v2+ AROS/workbench/devs/AHI/COPYING: GPL AROS/workbench/devs/AHI/Drivers/EMU10kx/ GPL_v2+ AROS/workbench/devs/AHI/AHI-Handler/ GPL_v2+ AROS/workbench/devs/networks/rtl8029/ GPL GPL_v2+ AROS/workbench/devs/networks/pcnet32/ GPL GPL_v2+ AROS/workbench/devs/networks/ppp/LEGAL: GPL AROS/workbench/devs/networks/atheros5000/ GPL_v2+ AROS/workbench/devs/networks/rhine/ GPL_v2+ AROS/workbench/devs/networks/nForce/ GPL_v2+ GPL AROS/workbench/devs/networks/prism2/ GPL GPL_v2+ AROS/workbench/devs/networks/fec/LEGAL: GPL AROS/workbench/devs/networks/rtl8139/ GPL GPL_v2+ AROS/workbench/devs/networks/etherlink3/ GPL GPL_v2+ AROS/workbench/devs/networks/intelpro100/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8169/ GPL GPL_v2+ AROS/workbench/devs/networks/emac/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8168/ GPL GPL_v2+ AROS/workbench/devs/networks/realtek8180/ GPL_v2+ AROS/workbench/devs/networks/via-rhine/via-rhine.c: GPL_v2+ AROS/workbench/devs/networks/via-rhine/ GPL GPL_v2+ AROS/workbench/devs/networks/e1000/ GPL_v2 AROS/workbench/devs/networks/sis900/ GPL GPL_v2+ </pre> AHI: it has special provisions (COPYING.DRIVERS). The library is LGPL, preferences software is GPL and drivers can be anything without breaking GPL/LGPL. Network stack: well, we are long overdue for a new, IPv6 enabled network stack anyway, anyone interested? ;) Seriously though it seems like the glue code is GPL and as all the drivers. However some of the drivers are our own code, so they could be relicensed to LGPL. Same filter as the AROS trunk list. These should all be libraries or plugins - no programs. <pre> contrib/regina/utsname.h: GPL_v2+ contrib/mui/classes/nlist/include/default-align.h: GPL_v2+ contrib/mui/classes/nlist/include/amiga-align.h: GPL_v2+ contrib/mui/classes/BWins/include/MUI/BWin_mcc.h: GPL contrib/mui/classes/BWins/include/BWin_private_mcc.h: GPL contrib/mui/classes/BWins/COPYING: GPL_v2 contrib/mui/classes/BWins/MCC_BWins.readme: GPL_v2 contrib/mui/classes/thebar/include/default-align.h: GPL_v2+ contrib/mui/classes/thebar/include/amiga-align.h: GPL_v2+ contrib/gfx/libs/wazp3d/LEGAL: GPL contrib/gfx/libs/wazp3d/Wazp3D.readme: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.c: GPL contrib/libs/mpega/ GPL_v2+ </pre> http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt ===Types=== On AROS following rules apply: <pre> 1. BYTE/UBYTE is 8bit, WORD/UWORD is 16bit, LONG/ULONG is 32bit, QUAD/UQUAD is 64bit, the types are comparable with stdint types (int8_t, int16_t, int32_t, int64_t) 2. IPTR/SIPTR are integer types large enough to fit pointer, that is sizeof(IPTR) = sizeof(APTR) = 4 on 32bit system, and = 8 on 64bit system 3. ti_Data in TagList is large enough to hold a IPTR/APTR type. 4. never store a pointer in integer of type LONG. It may work (if the pointer has upper 32bits clear), but does not have to. Compiler should warn you about that. 5. If you are unsure about point 4, allocate your memory with MEMF_31BIT flag set. But don't expect that AROS internals will do the same. </pre> point 4 is actually important. * UBYTE/BYTE for 8bit * UWORD/WORD for 16bit * ULONG/LONG for 32bit * UQUAD/QUAD for 64bit <pre> UBYTE Unsigned 8 bit integer variable (byte). BYTE Signed 8 bit integer variable (byte). UWORD Unsigned 16 bit integer variable (word). WORD Signed 16 bit integer variable (word). ULONG Unsigned 32 bit integer variable (longword). LONG Signed 32 bit integer variable (longword). FLOAT 32 bit IEEE floating point variable. UQUAD Unsigned 64 bit integer variable. QUAD Signed 64 bit integer variable. DOUBLE 64bit IEEE floating point variable. BOOL Boolean variable, TRUE and FALSE are also defined in exec/types.h. VOID Void. APTR A generic pointer for multiple purposes - Arrays. STRPTR A pointer to a null-terminated string. IPTR Really important in AROS, the only way to declare a field that can contain both: an integer or a pointer. </pre> if you want to write really portable app, you may be interested in standard datatypes defined in C99: int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, intptr_t, uintptr_t. They are all defined in inttypes.h include file. In exec/types.h the following short-cuts are typedef'd. They are used often in AROS, so you should nearly always include exec/types.h and soon only they will be removed from sys/_types.h include, all types are now defined in include files named aros/types/xxx.h. (Preparation for C library split; sys/xxx.h include will only be available there when compiling with POSIX C library) Compiler specific types, like int and long might change their size. In case of AROS, similar to linux, int remains 32 bit whereas long grows to 64 bits in size. If you use Amiga-like data types, i.e. BYTE/UBYTE, WORD/UWORD, LONG/ULONG and QUAD/UQUAD or the C99 standard types (uint8_t and so on, see stdint.h include) then you should have less issues to solve than by using types without size guarantee. Of course, all pointers grow to 64 bytes using 64bit cpu. Most of the code can be just recompiled and will work. In rare cases, where e.g. pointers are casted to integers, a special care must be taken. Especially in the cases, where pointer is casted to LONG/ULONG (this code will break on 64 bit AROS) e.g. '#define IPTR ULONG'. With compiler delint patches which the majority of them are simple casting issues to make the compiler happy. Notice some of the changes involve introducing double casts. In very recent versions of GCC. Yes, the bulk of the double casts are for converting 32 bit addresses (ie from a 32 bit PCI DMA address register) to a 64 bit pointer. First cast is to IPTR (to expand to 64 bits, and prevent sign extension if the address is above 0x7FFFFFFF), and then to APTR. ULONG != IPTR except on 32bit .. so if you need to store pointers make sure and use IPTR and not ULONG (which some old code does). For this reason things like Taglist elements are 64bit (since the tag data can be a pointer). If your passing items on the stack you should use the STACKED attribute to make sure they are correctly aligned (on 64bit all items on the stack are 64bit..) There is more issues like using "== 0L" causes problems. ===Endian=== *BE *LE Use the macros from <endian.h> instead making a guess based upon architecture defines <pre> #if _BYTE_ORDER == _BIG_ENDIAN #elif _BYTE_ORDER == _LITTLE_ENDIAN #else + #error <whatever.h> - Byte order for this architecture is unsupported! </pre> ===SVN and GIT=== If you want to help develop AROS OS itself, you can * view current GIT/SVN entries [http://aros.sourceforge.net/ Aros Org website] or [https://github.com/aros-development-team/AROS Github], [https://github.com/ezrec older ezrec mirror], [https://github.com/michalsc/AROS/ older mirror], [https://trac.aros.org/trac/timeline TRAC], [], * awaiting update [http://repo.or.cz/w/AROS.git git repo], [http://www.ohloh.net/p/aros/commits ohloh] or [https://svn.aros.org/svn/aros/trunk/ svn repo] and access [Git version git://repo.or.cz/AROS.git here], * deprecated [https://www.gitorious.org/aros/aros/commit/a7fda9e ARIX commits] or [https://gitorious.org/aros/aros GIT old] If you have SVN access (early 2015 introduced a new SVN server, create a new account at trac aros org) and/or have obtained the source [http://aros.sourceforge.net/download.php AROS site] - you can compile the current build tools/environment using: > make development and follow this [http://aros.sourceforge.net/documentation/developers/compiling.php#building procedure] or [https://github.com/apiraino/aros_guide Guide] https://trac.aros.org/trac#Developing If you plan on contributing back changes, please post information about such changes first on this [http://mail.aros.org/mailman/listinfo/aros-dev/ mailing list] for more experience developers can validate whether they are correct. Then there are the nightly build machines. They svn update before the build and run configure as one of the next steps. autoconf might be added to the nightly build scripts. Our build relies on packages downloaded from Internet (SDL for example) - it always worked this way. The minimal requirement (when just building core AROS) is binutils and gcc. If you build contrib as well, you need many more packages to be downloaded. https://gitorious.org/aros/aros/commits/crosstools-II git://gitorious.org/aros/aros.git Branch crosstools-II there is only one commit on top of ABI_V1 <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-x86_64 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-x86_64 </pre> and <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-i386 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-i386 </pre> build OK. :''More information: [[Aros/Developer/Maintainer|AROS Maintainer Docs]]'' ===SDI Calls=== Integrate the 'SDI'-headers to allow easier porting to all amiga-like platforms. <pre> PUTCHARPROTO( PutTheChar, char c, struct SPrintfStream *s ) { // REAL CODE } </pre> have "SDI_compiler.h" and "SDI_hook.h" included its more organized like #include SDI/SDI_hook.h than #include SDI_hook.h option 1 --- i also use when back porting from amiga's.. <pre> #ifdef __AROS__ #include SDI/SDI_hook.h #else #include SDI_hook.h #endif </pre> also you can add the -i include/sdi/ location if you do not want to add or edit any files. Defining HOOKPROTO to IPTR name(struct IClass * cl, Object * obj, Msg msg); solved the problem A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. examine compiler/include/aros/symbolsets.h (AROS_LIBREQ) compiling mui stuff for aros setting -std=gnu99 is necessary (i have had -std=c99 most of the time). ===Locale with Flexcat=== Most languages have a locale, but not every app is localized, the only thing needed is to translate the "catalog" files. It is a case of locating the correct catalog and saving the translated version. For every app that lacks of your language catalog and is localized anyway, you should find (in the sources) files related to locale: * file.cd = catalog descriptor, contains base msg, with internal language (usually english) * language.ct = catalog translation, contains every translated msg, indexed as in the file.cd. Compare with other localized apps... Then, "make my_app-catalogs" should create and install your translated catalogs. ex : for, saying, sys:prefs/wanderer: on root of AROS sources, type: "make workbench-prefs-wanderer-catalogs" then (if you changed the .cd file): "make workbench-prefs-wanderer" For apps not localized, you have to adapt their code to support it, if it is possible... noticed the original .cd file has many (//) strings at the end of any voice, so added them also to the .ct file. That (//) is only for cd files. I'm highly recommending to use FlexCat for updating ct files, e.g. like this: flexcat app.cd deutsch.ct newctfile deutsch.ct You'll get error checking and new entries are marked in the resulting ct file. When editing .ct files, only change those lines containing translation and perhaps version string, nothing else. The rest is up to the relevant tool, flexcat. In order to update your translation, type in the following in your shell: flexcat xyz.cd xyz.ct NEWCTFILE xyz_upd.ct COPYMSGNEW This way you will not only make sure you have correct translation file but flexcat also pre-fills newly added strings with "*** NEW *** text. Even better tool for checking cd/ct/catalog files is catcheck, but this one is sadly only available for AmigaOS/68k... Some languages have variations, like portugues from portugal and portugues from brasil differs... This is the way to go. I will have a look at language files, but basically if those two languages differ you have to do two separated set of translation files, yes. (you could create a brazilian slang language localization too) * At system level localization for one language is a dot language file. (ex: locale:languages/klingon.language) * At app level localization is a dot catalog file (ex: locale:catalogs/klingon/system/libs/dos.catalog) * At sources level, the dot ct file, and "$language" dot cd files and some building framework. (ex: catalogs/my_app.ct catalogs/klingon.cd catalogs/mmakefile.src support.c support.h) Please, use Flexcat to generate CT files: FlexCat wanderer.cd NEWCTFILE=deutsch.ct Then fill the first 2 lines with something useful: <pre> ## version $VER: wanderer.catalog 1.1 (9.2.2006) ## language deutsch </pre> You can even update the CT-File: (This adds the new strings) FlexCat wanderer.cd deutsch.ct NEWCTFILE=deutsch.ct To compile a catalog you only need the .cd file and your translation (.ct file): FlexCat multiview.cd deutsch.ct CATALOG=MultiView.catalog [http://murks-ide.svn.sourceforge.net/viewvc/murks-ide/trunk/src/Catalogs/flexcat_linux?revision=100 Linux version of FlexCat] : [http://aros.sourceforge.net/documentation/developers/app-dev/localization.php#localization-for-non-developers More information] A script which compares the required version (i.e. the version which an application/module etc. tries to open) with the version of the existing CT files. The result is in this table: https://github.com/aros-translation-team/translations/wiki/Progress The following cases are highlighted: n/a i.e. CT misses at all version in existing CT file is lower than the required version It might be a bit difficult to participate if you haven't worked with Git before but alternatively you can send your CT files to our Slack channel. When the ct file has been generated via flexcat (flexcat keyshow.cd NEWCTFILE=spanish.ct) it has the following header: --------------------------------------------------------------------------------------------------------------- ## version $VER: <name>.catalog <ver>.<rev> (04.01.2021) ## language nolanguage ## codeset 0 ; --------------------------------------------------------------------------------------------------------------- Those values <ver>.<rev> are the version and revision of the CT file for the languaje or are the values of the application being localized? The <ver> part must match with version which the application tries to open. You can find the value either in the column "Required Version" in the table which I've linked above, our you can look in the git repository. For keyshow it would be https://github.com/aros-translation-team/keyshow. You can find in the file "catalog_version.h" the right version number. The <rev> part starts for new CT files with 0 and should be increased every time the CT file is updated. Updated several files and created a few more that were missing on the spanish catalog. The catalogs are in Git repositories at https://github.com/aros-translation-team a) You tell me your Github user name. I'll invite you. You can work directly with the Git repositories. b) You create Github forks of the catalog repositories and create pull requests. c) You send the CT files to mrustler gmx de ===C Utils Misc=== The AROS source uses at several places the __DATE__ macro to fill the date entry of a $VER tag. Problem is that c:version doesn't understand that date format (e.g. "May 21, 2011"). As a result the output of e.g. > "version c:shell full" contains "(null)". Is extending the version command to understand the format of __DATE__ the right solution for that problem? AmigaOs compilers should use __AMIGADATE__ macro or similar form, if it isn't implemented it could be emulated in makefile: -D__AMIGADATE__=\"$(shell date "+%d.%m.%Y")\" BTW. I think DD.MM.YYYY is better format than "Month DD YYY" because "Month DD YYY" is not localized in any way. "strnicmp" shouldn't work with NULL pointers The Situation: compiled a linklib using c++ object files (using the c++ cross compiler). compiled a C stub that uses the linklib (using the c++ cross compiler). Try to link them together (using the c++ cross compiler) with C object files (using the normal target c compiler) that need to use -nostartup = cant do because using the c++ files pulls in arosc (for stdio etc.) - so wants to have the autoinit stuff present. What can I do about this?? If it is possible to manually open it then what do I need to do exactly? === ENV === The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. 99% of the time that statement is true (not required) for pretty much every file in ENV: or do people change their default icons - and prefs settings - every boot? There seem to be a bad habit of late with developers changing things to reflect their own personal preference when the change isn't actually necessary - It would be nice if people could refrain from doing that in the tree without at least discussing it on the dev-list first (and with good reasoning unless they committed said work in the first place..) We're not keen on the pollution of the "S:" dir: it's meant to be for scripts. What's wrong with "ENV:"? Only the fact that it takes up RAM. I understand that for PCs with several gigabytes of RAM this is irrelevant. But let's remember about other machines. The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. How about implementing in the style of HappyENV then? RAM-disk handler that falls through to reading from ENVARC: if there is no such file stored in it already. Removes RAM usage for unchanged files, removes the need to copy ENVARC to ENV in startup-sequence. Shouldn't be too hard to make from AmberRAM, or even just extend AmberRAM to provide this service. Is it feasable to build a special version of AmberRAM handling ENV: that will try and copy the requested file from ENVARC: if it isnt found in ENV: ? Additionaly it could mark closed "files" as untouched - and expunge them from ENV: after a period of time to free up additional RAM:, or when the system is running low on free memory? Silenty disappearing files may not be a good plan. Would be nice if the following would work: ASSIGN :ENV SYS:Prefs/Env-Arc ADD ASSIGN :ENV RAM:ENV ADD Where new files put in ENV: end up in RAM:ENV, and opening files looks in RAM:ENV first, then SYS:Prefs/Env-Arc Well - that's essentially what im proposing but without the assigns - or need for a RAM:ENV directory. Adding it as a feature of AmberRAM sounds like the most memory efficient way (one handler to load in RAM) but that's only if it is possible to make it handle ENV: additionally to RAM:, and if it is even possible to add the proposed functionality (...and how to make it enable it when accessing ENV:). ===(AS)MP support=== If one has to recompile software for SMP multi core, is there any thing special one has to do to get software to run? Use task.resource if you need to query information about what tasks are running, and clear msgports completely when they are allocated. Most code should not need Forbid. Use Semaphores, Messages etc. to sync your own code. Accessing system structures is a different thing. Use the proper API whenever possible. How single structures will be protected in the future is still a moving target, at least it is not documented. And you should never use undocumented stuff Ideas on for SMP multi-core Another suggestion is ... Forbid/Permit function calls are meant to halt multitasking so as no other task could intervene with what ever the calling task is doing, e.g. setting semaphores. Disable/Enable calls are meant to halt interrupts and as a side effect they also halt task switching. One option is to make it compulsory to protect shared resources with semaphores and forbid the use of simple Forbid() calls as to protect something. Setting semaphore should be done if possible with atomic instructions (check and alter in one instruction). Or make the second concurrent ObtainSemaphore call halt the second calling task and force if possible a task switch which ever gives better results. Semaphores could store the owning tasks task pointer instead of boolean to make things easier. As long as the CPU initiates the DMA transfers through the OS, and the OS ensures that the transferred memory is within the region accessible to the user initiating the transfer, everything is fine. The CPU is the conductor, and the CPU by that has the control of which DMA transfer is initiated and which is not. All you need to do is to write device drivers reasonable. Hint: CachePreDMA and CachePostDMA exist. All the Os has to do is to verify that the memory regions to be transferred are valid, and prohibit direct access to the DMA control registers from user space. None of these algorithms imply huge costs. The current OS design doesn't really allow virtual memory in first place, Forbid() is again the problem. [http://www.tbs-software.com/guide/index.php?guide=autodocs.doc%2Fmemory.doc&node=1 memory.library API] seem to low level. IMHO the programs should not know how the swapping is implemented. I would just go for one new memory flag MEMF_SWAPPABLE that indicates that a certain memory region or a whole memory pool won't be accessed during Forbid()/Permit() etc. It only solves part of the problem, it only implements virtual memory and not memory protection. For the latter you need to be able make certain memory inaccessible by other programs, some memory read-only for one task and read-write for other tasks, etc. And I think this should be done in the same Address Space in order to avoid you constantly need to swap between different address spaces. So to summarize, if there are programs using this API we may provide a wrapper layer to get them working but I am not convinced this API should be the reference API with whom to provide VM to AROS programs. === Variadic === variadic functions (i.e. functions with an arbitrary amount of arguments). <pre> #include <stdarg.h> [...] char * STDARGS GetKeyWord(int value, char *def, ...) { [...] va_list va; [...] va_start(va, def); [...] va_end (args); </pre> Please keep with using stdarg rather than having va casted to a LONG * type and varargs handled manually. Doing so, prevents tons of casting, where a simple va_arg can be used. So, string = *((char **) args) instead of string=va_arg(va, char *). <pre> #include <stdio.h> #include <stdarg.h> int printf (const char * format, ...) { int retval; va_list args; va_start (args, format); retval = vfprintf (stdout, format, args); va_end (args); fflush (stdout); return retval; } /* printf */ </pre> Couldn't find varargs.h or stdarg.h. and have no use for AROS_SLOWSTACKHOOKS or AROS_SLOWSTACKTAGS. GCC looks for stdarg.h in a different place: /bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/include/stdarg.h Here is a path for a "normal" header: bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/../../../../i386-aros/sys-include/aros/system.h The use of vararg.h isn't supported by newer gcc versions. If you want your code to run on architectures that pass part of variadic arguments in a number of registers you need to use AROS_SLOWSTACK macros. Otherwise your program will not work on powerpc and x86_64 ports. Of course the SLOWSTACK stuff is not needed in a function that can use va_list, va_start, va_arg and va_end. It's only needed if you want to write functions like DoMethod or similar. #include <stdarg.h> should be enough no matter if you do cross or native compiling. If it does not work, something is wrong and should be corrected. Stdarg.h is here, Development:lib/gcc/i386-aros/4.2.2/include/ ...which is part of the compiler's default include paths. In other words, #include <stdarg.h> works out of the box, indeed. (sorry, I should have just tried it before invoking "search" or "find"...) furthermore, myprintf() as shown above won't work, because... printf(format, args); ...is wrong - the second argument does not match printf() prototype, it expects a argument list, but args is of type va_list (obviously) - so one has to use... vfprintf(stdout, format, args); ...instead, just like in the original printf(), and add fflush(stdout). additionally, one could use... int myarg = va_arg(args, int); ...between va_start() and va_end() to access individual arguments, where each call to va_arg() returns an argument casted to the desired type (here: "int") from the list given (here: "args") and advances to the next one. wrapping up vfprintf() and modifying the format string now is a major speedup! no more backslash-n typing! this has been haunting me for years! On MOS and AmigaOS, the NewObject variadic function is kept in the static library. It takes most of the parameters on the stack - thanks to that the implementation of NewObject calls the NewObjectA function. Everything works perfect, and the typical MUI macros may be easily used. This, however, is not the case when you compile for AROS. Here, NewObject is a variadic macro, not a function. Thanks such approach we do not need any custom compiler in case of systems, where the arguments of variadic functions are passed partially through registers and partially through the stack (This is the case of PPC and x86_64, this is also the reason why both OS4 and MOS require specially patched compilers). Since NewObject is a macro, the gcc's preprocessor expects the list of macros arguments enclosed within parentheses. In MUI macros it is not the case. Imagine the following test code: <pre> #define foo(a,b) ((a)+(b)) int loosy_function(int a, int b) { return foo(a,b); } </pre> This will compile and work, but the following piece of code: <pre> #define foo(a,b) ((a)+(b)) #define END ) int loosy_function(int a, int b) { return foo(a,b END; } </pre> will fail with the error: unterminated argument list invoking macro "foo" There are two ways of fixing your issue. Either create your new objects outside this huge MUI constructions, and in there use just a pointer, or get rid of the "End" macro and exchange it with "TAG_DONE)". Badly written software is, for example, casting va_list to an APTR or even doing so as if va_list were a plain table of function arguments. Such code needs to be fixed because it has very few chances to work anywhere but on author's machine ;) The problem is nOt that they assume sizeof(APTR) == 4, its that they often do not use APTR, and use ULONG to store pointers exclusively. If the code used APTR/IPTR as it should - most of the "problems" wouldn't exist. It would also help if people would start using variadic arguments properly. Many coders do assumptions which shall never be made. Instead, they should consider using stdarg.h file and all the va_* functions :) ===ABI=== In the head of our SVN repository there are now only 3 directories: <pre> admin/ branches/ trunk/ </pre> We have added two extra dirs there: tags and imports As discussed when we branch ABI V0 and [[Aros/Developer/ABIv1|ABI V1]] it would also be good to introduce tags. Normally this is done in a directory in the repository called tags. Currently we don't have this directory there. (We do have branches/tags that is a hack I have done because one doesn't have write access in the top directory. I think this directory is not clean and should be removed). The second directory I would introduce is an imports directory for implementing vendor branches as discussed in the svn [http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html book]. Currently we use code from several different projects and that code is stored inside the AROS tree; we seem to have problems with keeping this code up to date and merge our changes upstream. Maintainers of up stream projects like the MUI classes etc. have complained about this (to put it lightly). Introducing these vendor branches would make it easier to see what changes we have made and make patches to be sent upstream and make it easier to import newer upstream versions of their code. Although can't "copy" the vendor branch into the main branch because it's already there, so start with a "merge". Yes, the first step to make the code already in the repository compatible with the vendor branches will be the most difficult. The best way to do it the following way: * first import the version on which the current AROS code is based into the vendor branch * then import the new version over it in the vendor branch * finally merge the difference between these two version in the AROS code present in the repository. For example, place NList directly under vendor and not in a subdirectory like "contrib/zune/classes". Actually after we have a stable [http://aros.sourceforge.net/documentation/developers/specifications/drafts/abiv1.php ABIv1 (2012 or later)]. We need to move away as much as possible from the contrib directory to some other repositories. The reasons are ... * The AROS repository should be for the core AROS code. * other contrib projects should be tried to be compiled for all Amiga-like OSes. * The release scheme for AROS and the other programs should not have to be aligned. * Binary versions should be provided on aros-archives and on aminet and/or OS4Depot to install them. (Some clever programs should maybe be provided to make the life of distribution developers easier). * avoid parallel forks of programs for AROS and the other amiga OSes. If there is really a need for a place for hosting AROS projects we may investigate setting up such a server but then including bug tracking, governance, maillist, etc. for each project separately. I personally think there are already enough places like sourceforge, google code, savannah, etc. where people can go for hosting such projects. ==Links== * http://amigadocs.hokstad.com * http://amigadocs.hokstad.com/doku.php?id=dev-links * http://www.liquido2.com/tutorial/index.html * Amiga(TM) OS4 has a [http://www.ast-workshops.co.uk/os4pg/ workshop] page and hope to produce a [http://amigaworld.net/modules/newbb/viewtopic.php?topic_id=31117&forum=42#549091 book] soon. [http://www.solie.ca/articles/map/map.html Brief Guide]. In the future...? *AROS 64bit - SMP, Vulkan with OpenGL compability layer *AROS 32bit - keep for historic reasons What would you like to see implemented in AROS? ABIv1 completed, SMP (x86_64), SendMsg()/GetMsg() to support memory protection between target and destination, in that order. Michal Schulz and Jason McMullan have been toying with the question "What are the minimal changes needed to the AmigaOS 3.1 API to support SMP"? The answer so far seems to be "few, but subtle". For example, SysBase->ThisTask is no longer meaningful on SMP, but FindTask(NULL) is. Disable() and Forbid() are shockingly bad on performance, but adding a spinlock semaphore mode to SignalSemaphore will help new code on SMP. Leveraging a 'common' OS with a lot of machine support (Linux, MacOS, Windows, QNX, etc.) is something that AROS has been doing for quite a long time, and it is the biggest strength of AROS. This AROS experience and programming model, in the same way the Google's Android layers on top of Linux, or MacOS X layers on top of the Darwin/BSD kernel, as a first step * The graphics + layers subsystem could be implemented as a shim on top of a OpenGL ES implementation (ie on any modern Linux system, or the RaspberryPI's hardware, MacOS X, etc). - This also allows every window to be on its own 3D surface with backing store, allowing Wanderer (or a Commodity) rearrange/zoom/animate app windows without having to send a pile or refreshes to them * Use OpenAL as the sound backend * AROSTCP would be a thin layer over the native OS's TCP/IP stack * dos.library, poseidon.library, and input.device would be slim shims over the native APIs * If we move to loading all libraries' into the application's task space, instead of a single global instance of the library, this will allow SMP and MMU more easily. - Yes, it will require a lot of work in the libraries to make this transition - Yes, I do think it will be worth it in the end. * A 'fat binary' install format (or, maybe LLVM bytecode) that can be 'flattend' to the target architecture on installation. So, what would this 'AROS of the future' look like? * AmigaOS 3.x style API, with certain 'fundamental changes' to message passing * Uses the underlying OS' device drivers, so more AROS developer effort can go to user-visible features and bugfixes * Allows AROS applications to run side-by-side with the OS's native apps And why would anyone want to program on such a system? * AROS applications would run on any system that has the AROS Framework installed * AROS applications are pixel-for-pixel the same on all platforms. * Develop with the knowledge that you are guaranteed OpenGL and OpenAL, and the rest of the AROS Framework an option for mmake to dump its dependency of metatarget in a graphviz[*] input file. This should make it possible to visualize the dependencies and hopefully be inspiration for cleaning up some mess, circular or unneeded dependencies and so on. AmigaOS gcc 9 [https://franke.ms/amiga/gcc.wiki Old versions] able to create binaries for AmigaOS and [https://eab.abime.net/showthread.php?t=93813 Upgrading gcc versions] ==References== {{reflist}} {{status|50%}} {{BookCat}} 9qd2mfbp9o8lt8w558ody2lmjzkem4q 4668962 4668959 2026-09-05T17:29:53Z Jeff1138 301139 4668962 wikitext text/x-wiki {{ArosNav}} ==A technical overview of AROS== Google translation [http://translate.google.com/translate?hl=en&sl=auto&tl=de&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs German], [http://translate.google.com/translate?hl=en&sl=auto&tl=fr&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs French], [http://translate.google.com/translate?hl=en&sl=auto&tl=it&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Italian], [http://translate.google.com/translate?hl=en&sl=auto&tl=es&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Spanish], [http://translate.google.com/translate?hl=en&sl=auto&tl=hi&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Hindi], [http://translate.google.com/translate?hl=en&sl=auto&tl=zh-CN&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Chinese], [http://translate.google.com/translate?hl=en&sl=auto&tl=ru&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Russian], [http://translate.google.com/translate?hl=en&sl=auto&tl=pl&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Polish], [http://translate.google.com/translate?hl=en&sl=auto&tl=pt&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Portuguese] {{Uncited}} AROS,<ref>[http://aros.sourceforge.net/download.php References and sources]</ref> like AmigaOS (TM), is a [[w:Message passing|message-passing]], [[w:Preemption (computing)|preemptive]] [[w:Multitasking|multitasking]] [[w:Operating system|OS]]. It uses [[w:Reentrant (subroutine)|re-entrant]] shared libraries to save memory space. AROS is based around an executive library kernel (Exec) and two other libraries: * Exec (the "kernel", which is not a kernel in the modern sense), * Intuition (graphics and GUI, integrated into the system) and * AmigaDOS (Disk Operating System, the Metacomco's Tripos modified to work with Exec). The design philosophies of AmigaDOS and Intuition are rather different, the former adopting a C-like API and the latter creating an [http://www.basden.demon.co.uk/amiga/amiga.oo.html object-oriented], message passing aware environment for the programmer. The system base is the only absolute address in AmigaOS (located at 0x00000004) this does differ with AROS as AROS SysBase is automatically provided (no $4) but everything else is dynamically loaded. The OS is well known for delivering high performance due to its close connections with the hardware, while simultaneously having the flexibility to support re-targetable graphics (Cybergraphics) and retargetable audio subsystems (AHI). : Diagram showing relationships of libraries to system needed Remember, AROS is a [http://en.wikibooks.org/wiki/Aros/Developer/ABIv1 research] operating system, and while all contributions to the base AROS code are welcome, please contact the dev list first for any core changes. Writing applications for AROS does not have this requirement. While AROS appears and feels almost feature complete, it is still [[Aros/Developer/IncompleteAPIs|missing a small number of functions]] from the Amiga API. [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1201 This thread provides] information for setup, [http://www.aros.org/documentation/developers/index.php documentation] and whether you are interested in core OS changes and/or writing/porting software apps *you compile directly under AROS, which can be running on either real hardware, virtual hardware *in hosted mode under linux/window, cross-compile from that host OS (save your files as ISO-8859-15 encoding instead of UTF-8) [https://github.com/BlitterStudio/aros-compiler-docker Docker images] '''The repository''' for 64bit and 32bit ABIv1 all hardware platforms is [https://github.com/aros-development-team/AROS current development version]. There are many forks of this so that developers can work on their own and forward changes at a later date as discussed on the dev forum 64bit PC is one of two hardware platform with another fork called [https://github.com/deadwood2/AROS abiv11] which is used for Aros One x64 PC 32bit PC is the other fork [https://github.com/deadw00d/AROS/tree/alt-abiv0 repository for current stable PC version ABIv0 with backported ABIv1 features is located which is used on AROS One and Icaros x86 32bit based distros] this is for historic reasons Any [https://github.com/aros-development-team/AROS/issues bugs / issues can be added for ABIv1 issues]. The two individual PC forks have their own issues tab on their github webpages We have a [https://arosdevteam.slack.com/archives/CUFV48U3H slack here], discord on [https://discord.gg/UKp9qdEBuQ Discord@AmigaDev], ==Software Development for AROS== ===Programming languages=== ====Common to all==== 'The Developer Environment', which primarily supports C/C++ code, there are other programming languages available for AROS: '''Scripting''' :[[Aros/User/DOS|DOS]] :[[Aros/Developer/Docs/LUA|LUA]] :REXX [[Aros/Developer/Docs/Rexx|Regina (AROS' ARexx)]] ====Needs to be compiled/ported==== ::[[Aros/Developer/Docs/LLVM|LLVM]] ::Python [ Info], [], ::[https://ae.arosworld.org/index.php?board=11.0 FreePascal FPC Aros-Exec thread], [https://archives.arosworld.org/index.php?function=browse&cat=development/language fpc arm here is very old and will not work], FreePascal for AROS has its own [http://fpcaroswiki.alb42.de/ Wikibook], ::[http://sourceforge.net/projects/xamos/ X-Amos Basic] ::[http://sdlbasic.sourceforge.net/ SDLBasic] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[[Aros/Developer/Basic/Basic4SDL|Basic4SDL]] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[http://alvyn.sourceforge.net/ Alvyn] ([http://www.dusabledanslherbe.eu/AROSPage/MISC.14.html download]) ::[http://www.airsoftsoftwair.com/ Hollywood when enough users warrant a port - paid one time fee language] ::[[Aros/Developer/Docs/E|AmigaE Portable E]] ====Hardware Restricted==== '''Basic''' :[http://amos.pspuae.com/AmosProManual/contents/c1.html '''Amos Pro'''] [http://amos.pspuae.com/index.php?action=forum#1 compatible] [http://www.amigacoding.com/index.php/Main_Page commands] (all incomplete) :'''Blitz Basic''' [http://aros-exec.org/modules/newbb/viewtopic.php?post_id=46537#forumpost46537 none on AROS] :: [http://www.amiforce.de/main.php Amiblitz] on amiga(TM) emulator :'''Amiga Basic''' :: [ ACEBasic] '''Misc''' :Ruby [http://www.ruby-lang.org/en Info]/[https://archives.arosworld.org/index.php?function=browse&cat=development/language Ruby 32bit PC], ===Where to get the C/C++ Environment=== If you want to develop for AROS, its generally easier to be running linux hosted AROS development environment especially for C++, cross compiling the code. That's how most developers now are doing it. g++ is used to compile owb web browser as well as some other AROS software. If you were hoping for a rich set of C++ libraries or classes defined for the OS feature set, you might be disappointed. AROS Native compiling is possible, but you're much more likely to run into the odd bug(s) in the dev environment since it gets little testing and fixing by other developers. Is there a sftp software or scp over ssh available? Maybe. At least the security part would be handled by [https://github.com/jens-maus/amissl amissl] [https://archives.arosworld.org/index.php?function=browse&cat=network/misc port]. [https://github.com/BlitterStudio/dopus5 DOpus5] has recently added sftp support. See here for a [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1974&highlight=ssh&pid=12073#post_12073 ssh scp client] [https://arosdevteam.slack.com/join/shared_invite/enQtOTc4Mzg0NDIzNzQ0LWQ2NWZmNmMwNGIwNGEyNTgxNzU3MGFjMTk3ZThmOTQ1MTVjMzhmNTllYWQ0ZTUxMjBjMGE0Y2VjMDJmNTc5MzI#/shared-invite/email Slack Dev Forum] ====Cross compilers from Windows or Linux==== *Windows WSL2 walkthrough can be [https://arosnews.github.io/how-to-cross-compile-aros-hosted-wsl/ found here] you want to build AROS. No problem. Here are instructions for PC 64-bit: https://github.com/deadw00d/AROS/blob/master/INSTALL.md Here are instructions for PC 32-bit: https://github.com/deadw00d/AROS/blob/alt-abiv0/INSTALL.md And as always has been the case you can use the contrib archive to 'obtain' the development directory which contains the /native/ AROS gcc compiler and tools. That compiler is used to build AROS itself but can be used outside the AROS build process by providing --sysroot with indicated directory to cross compile for AROS. =====Older guides for Linux hosted compiler===== Please install these packages before moving to next step. Below is a reference list for Debian-based distributions. Reference build system was Ubuntu 18.04/20.04 amd64. subversion git-core gcc g++ make gawk bison flex bzip2 netpbm autoconf automake libx11-dev libxext-dev libc6-dev liblzo2-dev libxxf86vm-dev libpng-dev gcc-multilib libsdl1.2-dev byacc python-mako libxcursor-dev cmake zsh mingw64 Do all of these operations under home directory of your user or another directory where your user has write permissions. Specifically, in a section "Linux-i386", be sure first to build the cross-compiler (toolchain-alt-abiv0-i386) and only then AROS itself (alt-abiv0-linux-i386). Clone & build <pre> $ mkdir myrepo $ cd myrepo $ git clone https://github.com/deadw00d/AROS.git AROS $ cd AROS $ git checkout alt-abiv0 $ cd .. $ cp ./AROS/scripts/rebuild.sh . $ ./rebuild.sh </pre> Now to the build selection below - Linux-i386 Select toolchain-alt-abiv0-i386 - Select alt-abiv0-linux-i386 (DEBUG) Start AROS by: <pre> $ cd alt-abiv0-linux-i386/bin/linux-i386/AROS $ ./Arch/linux/AROSBootstrap </pre> Pc-i386 Select toolchain-alt-abiv0-i386 (if not built yet) - Select alt-abiv0-pc-i386 ISO image available in alt-abiv0-pc-i386/distfiles Now that we have linux-hosted build, we can resume native (option 2). Run ./rebuild.sh and selection option 2. Wait until it finished, then: <pre> $ cd alt-abiv0-pc-i386 $ make </pre> Now <pre> $ make bootiso </pre> Now, your compiler is located in toolchain-alt-abiv0-i386 directory and named i386-aros-gcc. Includes are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/include and libraries are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development.lib. This is how then can be passed to the compiler: /home/xxx/toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot /home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development -L/home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/lib ../toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot bin/linux-i386/AROS/Development local/helloworld/helloworld.c -o local/helloworld/helloworld Another method was using Debian like distros and download the gimmearos.sh script (on [http://archives.aros-exec.org/index.php?function=browse&cat=development/cross aros-archives]) to setup the developer environment by downloading necessary packages ... The gimmearos script is a good start in that direction, building the cross compilers and hosted AROS environment, but gimmearos.sh might be out of date or not be completely compatible with any given linux distro. In order to do that, you have to compile AROS yourself. Download AROS source archive not contrib. Compile AROS by entering the main directory ./configure make ([http://aros.sourceforge.net/documentation/developers/compiling.php More on compiling AROS]). The result will be a basic AROS system without development tools. To compile C++ on Linux, type 'make gnu-contrib-crosstools', creating the cross-compilers in ./bin/linux-i386/tools/, named i386-aros-gcc, etc. '''Note''': Currently, to make the cross compilers usable copy 'collect-aros' from tools/ to tools/i386-aros/bin/. At the moment the cross compilers if used from the Linux command line will only find it when it's there. If you want to compile native compilers (the Developer Environment), type 'make contrib-gnu-gcc', creating native compilers in AROS' System:Development/bin directory. When the output needs to be stripped <code>--strip-unneeded --remove-section .comment</code> The Obj-C backend should build out of the box. Open contrib/gnu/gcc/mmakefile.src and search for the line which contains "--enable-languages" and add "objc" to the list of languages that follows it. --enable-languages=c,c++,objc Better make it—enable-languages=c,c++,objc,obj-c++ ObjC++ is broken as soon as you try to use exceptions, but that might change in future GCC versions and it does not hurt having it there already. Do you need a cross-compiler or a real compiler? In the first case you can get away with just downloading the proper gcc archive, apply the patch and proceed with the normal gcc build. In the case of a real cross-compiler then when downloading the contrib sources, also need to download the normal sources, place the contrib sources into a directory called contrib, need to install autoconf+automake+perl+python, call ./configure, cd into the subdirectory and type make. to rebuild GCC with host == build == target == i386-pc-aros. So just get the vanilla sources and apply the patches without bothering about the build system? [https://vmwaros.blogspot.com/2019/10/a-pre-configured-development-machine.html pre-configured VM environment vmware virtual machine to develop AROS and AROS software] '''64 bit''' '''32 bit''' A good option for multiple OS is [https://axrt.org/index.php?tab=download-aros AxRuntime lets developers compile their Amiga API-based applications as Linux binaries being able to utilize modern development tools available on Linux, like IDEs, debuggers, profilers, etc] ====Native compilers for AROS==== Namely gcc for C or g++ for C++ are supplied with the [[Aros/Developer/Docs#The Developer Environment|Developer Environment]], which is already '''setup''' and part of any current AROS distribution like AROS One or the nightlies * Current GCC 6.5 (32bit) though moving to 10.5 and 15.1 (64bit) * Older software components. GNU GCC 4.x GNU BinUtils, GNU Fileutils 4.x, GNU Textutils and others usually deprecated On single partition systems and the Boot ISO, the AROS Developer environment is installed under "SYS:Development/". Systems with multiple partitions - such as a Work: partition - tend to install it to there instead, however it can be installed manually to any location. Please remember, if moving, that you will need to correct the Development packages 'install location' env variable to point to the new locations root - look in SYS:S/startup-sequence. <pre> Assign Development: SYS:Development Assign C: Development:bin ADD </pre> In the aros build instructions. you need to check out contrib and/or ports into your AROS source directory, as subdirs. then, assuming you are building in an external build dir, as you should, you simply configure and "make contrib" for instance or whatever submodule you might want to build. ===Beginners Tutorials in C C++=== As AROS is [http://eab.abime.net/showthread.php?t=29856 C based] API compatible to AmigaOS 3.x, so most of the information on programming C on the Amiga applies to AROS as well. Please note that there is a lot of AmigaOS 1.3 (1985-1989) and [https://www.markround.com/amigaguide AmigaOS AOS 2.x (1990-1992)] information around but OS3.1 is recommended but limited in amount. Brief overview of what is required to write AROS Applications # Using [[Aros/Developer/Docs/Libraries/Intuition|Intuition]] for basic screens/windows # Using graphics within windows via 8bit [[Aros/Developer/Docs/Libraries/Graphics|graphics]] and so onto 15-16-24bit [[Aros/Developer/Docs/Libraries/CGFX|cybergraphx]] # Load and save work to [[Aros/Developer/Docs/Libraries/DOS|dos]] disk drives # Using the [[Aros/Developer/Zune|ZUNE GUI Environment]] Writing native games require this extra information # Using [[Aros/Developer/AHIDrivers|AHI audio hardware independent API]] # Using USB joystick/joypad with the Poseidon USB stack through [[Aros/Developer/Docs/Libraries/LowLevel|LowLevel]] library Additional features that could be added later # Adding additional [[Aros/Developer/Docs/Libraries/Locale|Locale]] language translations to your program # Adding a [[Aros/Developer/Docs/Rexx|AREXX/Regina]] port to your application # Executing Amiga(TM) [[Aros/User/DOS|DOS]] commands from your application # Using [[Aros/Developer/Docs/Libraries/Icon|icons]] (.info files) and icon tooltypes (stack, version, and program startup options) # Local couch or IP based SANA2 networking co-op multi player gaming support Most AmigaOS programming books are nowadays very much out of date as most are from the late 1980s and do not cover later amigaOS releases like 3.1 for example, Rob Peck's book "Programmer's Guide to the Amiga". The Amiga ROM Kernel manuals aka RKMs like Libraries (3rd edition), Devices (), the AmigaDOS manual (3rd edition) and the Style Guide may have their uses. There are some reference examples from AmigaMail and Devcon notes (available again on an Amiga developers CD 2.1). For Arexx then "The Amiga Programmer's Guide to ARexx" by Eric Giguere, which was published by Commodore is useful as well as an "Arexx Cookbook". Curly brackets missing - try SHIFT + ALT + 7 or 0. * Beginners C Guide [http://www.iu.hio.no/~mark/CTutorial/CTutorial.html C Tutorial], * [http://thecguru.com/ C for beginners], * [http://fresh2refresh.com/c/c-basic-program/ C programming basics] for students, * [https://www.edx.org/courses Free Online course] from American Universities * Reference Amiga [http://amigadev.elowar.com/ API reference]. * AROS based c source can be found [[Aros/Developer/Docs/Examples|here]] and lots of example code can be found inside [https://github.com/aros-development-team AROS sources] themselves and from the contrib section of the archives from [https://github.com/aros-development-team/contrib Aros site], and study the AROS applications source code, e.g. the test programs from the Tests drawer (folder/directory). Take a look at the code of some smaller AROS programs might be a better and more up to date When you upload your builds, please write the architecture (like i386-aros, x86_64-aros, armPi-64 etc.) in the archive name and it is also advisable to write in the field "Requirements" what ABI (ABIv1 or for PC forks ABIv11 or ABIv0) ===Compiling C/C++ Code=== Native, although we have a IDE Integrated Development Environment (Murks), it does lack a debugger. Whilst others use a combination of a text editor and shell to edit code. Most though use an AROS hosted on Linux to take advantage of the better GCC tools like GDB and various IDEs. Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w (or F12 and w) within the directory with the source code. Type in sh to change the amiga shell into a unix shell. You can then type in ls (unix equivalent to amiga dir). Take a look [http://en.wikibooks.org/wiki/Linux_commands here] for more commands. For a single file program-name.c or program-name.cpp gcc -o program-name program-name.c or g++ -o program-name program-name.cpp or g++ -o test -Wall -g main.cc texturelib.cpp xmodelib.cc -lsdl -lgl To close the shell, click on the top left-hand corner to close (twice). Once to get back the aros shell and then again to close finally. Use [http://freshmeat.net/projects/cksfv/ cksfv] as a test. Some source code requires the addition of Amiga API libraries, like dos, which you can flag at the compile time as gcc -o julia.exe julia.c -ldos For DOS use -ldos as example and if you are compiling mui codes it will be -lmui or intuition -lintuition. Other missing symbols are due to linker libraries being necessary for linking in functions that aren't in the standard C libraries. For example some source code would need added -lz or -lm or -lpng or -larosc etc. use this in unix line command mode to search for 'search-item' in many .c files (*.cpp for c++, etc.) grep -l 'search-item' *.c If the program is not executable, try using parameter fno-common "Delete #?.o"? Or if you are using abcshell then "rm *.o" :''More information: [[Aros/Developer/Porting software]]'' === How to make Apps have AROS 64-bit specific support code === [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] AROS64 already uses 64bit addressing, it just doesn't setup the MMU for more than 4GB physical memory currently. When porting software to AROS64 it is "mostly" a case of converting ULONG's that are used to store pointers, into IPTR's instead, etc. Another quirk, is making sure items on the stack are the correct size by using the STACKED attribute for them. * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. compiling mui stuff for aros setting -std=gnu99 is necessary, had -std=c99 usually A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. crash which suggest memory corruption. From my experience porting from 32-bit to 64-bit these kinds of errors can happen if a pointer is passed somewhere via ULONG variable. Then half of the pointer is cut. To generate this error, please run AROSBootstrap with -m 1024. This will allocate heap to 64-bit address space which will make these errors immediatelly visible. These types of crashes are hard to debug. Disabled as little code as possible to stop corruption from occurring and then try to read from the code where it can be broken Crashing in tslf_freevec is another symptom of memory corruption and these memory corruptions will manifest differently on different setups. ==Coding conventions== As the AROS core source is a shared developer experience, there are rules regarding structure and style. When it comes to your creating your own app and coding, the structure and style should be your own, i.e. you should enjoy what you do and do it so that you can understand what is going on. ===Layout=== <syntaxhighlight lang="c"> static void 1st_function() { program exit(0); } int main(void) { 1st_function(); 2nd_function(); 3rd_function(); return 0; } </syntaxhighlight> <syntaxhighlight lang="c"> struct Screen * openscreen(void); struct Window *openwindow(struct Screen *screen, const char *title, LONG x, LONG y, LONG w, LONG h); VOID 1st_function(); VOID 2nd_function(); int main(int argc, char **argv) { program return 0; } /* main */ VOID 1st_function() { } VOID 2nd_function() { } </syntaxhighlight> ===General style=== This code is used by many people and therefore you should keep some things in mind when you submit source code: * Keep things simple * Keep the source clean * Always know what you are doing, if not flag it and describe what needs to be done... * Explain clearly/simply what you are doing * Remember that you write code once but that it is read many times by many people ===Comments=== AROS uses some of the comments in the source to generate the documentation. Therefore it's necessary to keep a certain format so the tools can find their information. Other comments are ignored but they should explain what you thought when you wrote the code. If you really can't think of an explanation, then don't write the code a second time like this: <pre> /* This adds 1 to t */ t ++; </pre> What we think of is this: <pre> /* Go on with next element */ t ++; </pre> ===Formatting=== This is only '''IMPORTANT''' if you are going to work on the core AROS code or contrib but not applications which may reside outside like on AROS Archives or other websites. <syntaxhighlight lang="c"> { /* a */ struct RastPort * rp; int a; /* b */ rp = NULL; a = 1; /* c */ if (a == 1) printf ("Init worked\n"); /* d */ if ( !(rp = Get_a_pointer_to_the_RastPort ( some , long , arguments ) ) || a <= 0 ) { printf ("Something failed\n"); return FAIL; } /* e */ a = printf ("My RastPort is %p, a=%d\n" , rp , a ); return OK; } </syntaxhighlight> Looks ugly, eh ? :-) Ok, here are the rules: <pre> If several lines contain similar code, put similar things below each other (see a and b); Put spaces between operands and operators Put braces {}, brackets [] and parentheses () below each other (d) if there is much code between. Brackets and parentheses may be in one line if the code between is small (c) Indent by 4 Spaces. Two indent levels may be abbreviated by one tab. </pre> '''Before committing please normalize the indentation - if you have a mixture of tabs and spaced - please always use spaces, 1 tab = 4 spaces.''' The reasons for this are: # While some editors can use an arbitrary sizes for tabs, it's a bit complicated to tell another editor which tab size was used by the one used to write the code. # Most code in AROS was written this way and your code should look like the rest. # You can print this code on any printer without special tools to "fix" the tabs. # Most editors have smart tabs which do exactly this. If your editor doesn't, write a bug report. If you have a function with many arguments (d, e) you should put the parentheses in lines of their own and each argument in one line (d) or put the first argument behind the opening parentheses (e) and each following argument in a line of its own with the comma in front. The closing parentheses is in a line of its own and aligned with the beginning of the expression (i.e. the a and not the opening parentheses or the printf()). Use a single blank line to separate logical blocks. Large comments should have a blank line before and after them, small comments should be put before the code they explain with only one blank line before them. If you see any TABS in AROS core sources then the suggestion is to "detab the file and commit that separately" either before or afterwards from making functionality changes. Make two commits instead of one. This makes it easier for others to see the real changes instead of having to dig through multiple lines of irrelevant diffs. ===Eliminating Global Variables=== i.e. pass variables to functions (local scope) or classes making it easier to track and debug your code. Any time you find that you need a particular thing in 'a lot of different places', chances are that all those places are conceptually related, and so you can create a class, a namespace, a function, or some other higher-level organizational unit to represent that relationship. This makes the program easier to understand. Bad Designs * All variables are global. * There are no standalone functions, only sub-procedures which act on the global variables. * Every sub-procedure is at least 500 lines to several thousand * Every sub-procedure has more than one task to perform * Copy-paste is preferred to writing methods, AND subtle changes are made in the middle of the code Good Designs * structure program into functions (C or basic) - top-down procedural approach * put in class(es) (freepascal or C++) - the object is fixed and you use methods to access the object <pre>  class String_List  {  private:  list<string> m_List;  // member  public:  void read_strings() { /* read strings into m_List */ }  void print_strings() { /* write contents of m_List to stdout */ }  void sort_strings() { /* sort contents of m_List */ }  void sort_strings_reverse() { /* reverse-sort contents of m_List */ }  void unique_strings() { /* remove duplicate strings */ }  };  int main()  {  String_List myList;  // local  myList.read_strings();  myList.sort_strings();  myList.print_strings();  myList.sort_strings_reverse();  myList.print_strings();  myList.unique_strings();  myList.print_strings();  return 0;  } </pre> This way it is very easy to replace the list with new list for debugging purposes, or replacing the methods without replacing the list, when you want different results. You only have to replace the content of the local variables. So create the structure that matches your data (linked lists, trees, arrays, etc.) and what to do with them (sorting, searching, etc.) <pre> .h usually contain #define #include typedef enum struct extern screen and window definitions (data structures) .c should contains functions and algorithms </pre> One way to look at it is that menu headings act as the .c file and sub-menu headings as functions. When you start a project, you place a couple of declarations in the include file. As the project continues, you place more and more declarations in the include file, some of which refer to or contain previous declarations. Before you know it, you have a real mess on your hands. The majority of your source files have knowledge of the data structures and directly reference elements from the structures. Making changes in an environment where many data structures directly refer to other data structures becomes, at best, a headache. Consider what happens when you change a data structure. Use good variables names to help clarify code and only comment when you need to explain why a certain programming approach was made. You're Refactoring Legacy Code, you see a global, you want to get rid of it. How do you do this? Exactly what to do depends on how the global is used. The first step is to find all uses of the global throughout the code, and get a feel for what the significance of the variable is and how it relates to the rest of the program. Pay particular attention to the "lifetime" of the variable (when it gets initialized, when it is first used, when it is last used, how it gets cleaned up). Then, you will probably make the global a data member of a class (for OO languages), or you will write some get/set functions. Converting to the Singleton Pattern is common, but you may discover that it makes more sense for the data element to be a member of an existing singleton, or maybe even an instance variable. # Create a basic read method, either as a class or a global function. Replace all reads with the access method, but leave the variable defined as a global. # Review each of the writes to the method and extract action functions one at a time. Unless two operations are coded identically in the original code, extract each write access separately. # Change the variable scope from global to local. # Analyze similar action functions to determine if any can be merged, i.e., there are no functional differences in the results of the function, just differences in the implementation details. # Review the calls to the read method and see if a more complex functionality should be applied. Follow the approach for writes and unless implementations are identical, create separate access functions. # Analyze the access functions for duplication. As returning variables by "passing by value" are forgotten, so "passing by reference" is often used instead. The reference is a pointer to the variable so the value is remembered when returned. Alternatives * Hidden Globals * Singleton Pattern * Database or TupleSpace * Context Object * Dependency Injection * Stateful Procedures ==AROS/AmigaOS APIs and Docs== <pre> Library: - Private data structure - Many public access methods Device: - Private data structure - Two (BeginIO/AbortIO) access methods Resource: - Public data structure - *NO* access methods </pre> And, being Amiga OS-compatible, there are exceptions to all of these. ===System Libraries=== The [http://developers.aros.org/ AROS Guide To Libraries] can be used as a guide to individual commands and old Dev Docs are used in application programming. Amiga/Aros styles libraries are very different from windows and linux libs. Typical .so/dll libraries are foreign to most Amiga-like OS *[[Aros/Developer/Docs/Libraries/AROSC|arosc.library]] *[[Aros/Developer/Docs/Libraries/AmigaGuide|amigaguide.library]] *[[Aros/Developer/Docs/Libraries/ASL|asl.library]] *[[Aros/Developer/Docs/Libraries/Bullet|bullet.library]] *[[Aros/Developer/Docs/Libraries/BSDsocket|bsdsocket.library]] *[[Aros/Developer/Docs/Libraries/CAMD|camd.library]] *[[Aros/Developer/Docs/Libraries/Codesets|codesets.library]] *[[Aros/Developer/Docs/Libraries/CGFX|cybergraphics.library]] *[[Aros/Developer/Docs/Libraries/CGXVIDEO|cgxvideo.library]] *[[Aros/Developer/Docs/Libraries/Commodities|commodities.library]] *[[Aros/Developer/Docs/Libraries/DataTypes|datatypes.library]] *[[Aros/Developer/Docs/Libraries/DiskFont|diskfont.library]] *[[Aros/Developer/Docs/Libraries/DOS|dos.library]] *[[Aros/Developer/Docs/Libraries/Exec|exec.library]] *[[Aros/Developer/Docs/Libraries/Expansion|expansion.library]] *[[Aros/Developer/Docs/Libraries/FreeType2|freetype.library]] *[[Aros/Developer/Docs/Libraries/GadTools|gadtools.library]] *[[Aros/Developer/Docs/Libraries/Graphics|graphics.library]] *[[Aros/Developer/Docs/Libraries/Icon|icon.library]] *[[Aros/Developer/Docs/Libraries/Identify|identify.library]] *[[Aros/Developer/Docs/Libraries/IFFParse|iffparse.library]] *[[Aros/Developer/Docs/Libraries/Intuition|intuition.library]] *[[Aros/Developer/Docs/Libraries/Keymap|keymap.library]] *[[Aros/Developer/Docs/Libraries/Layers|layers.library]] *[[Aros/Developer/Docs/Libraries/Locale|locale.library]] *[[Aros/Developer/Docs/Libraries/LowLevel|lowlevel.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingBas|mathieeesingbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubBas|mathieeedoubbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingTrans|mathieeesingtrans.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubTrans|mathieeedoubtrans.library]] *[[Aros/Developer/Docs/Libraries/Mathtrans|mathtrans.library]] *[[Aros/Developer/Docs/Libraries/MUIMaster|muimaster.library]] *[[Aros/Developer/Docs/Libraries/Partition|partition.library]] *[[Aros/Developer/Docs/Libraries/PopUpMenu|popupmenu.library]] *[[Aros/Developer/Docs/Libraries/OOP|oop.library]] *[[Aros/Developer/Docs/Libraries/Regina|regina.library]] *[[Aros/Developer/Docs/Libraries/Reqtools|reqtools.library]] *[[Aros/Developer/Docs/Libraries/RexxSysLib|rexxsyslib.library]] *[[Aros/Developer/Docs/Libraries/ScreenNotify|screennotify.library]] *[[Aros/Developer/Docs/Libraries/TTEngine|ttengine.library]] *[[Aros/Developer/Docs/Libraries/Thread|thread.library]] *[[Aros/Developer/Docs/Libraries/Utility|utility.library]] *[[Aros/Developer/Docs/Libraries/Xadmaster|xadmaster.library]] *[[Aros/Developer/Docs/Libraries/Workbench|workbench.library]] *[https://github.com/aros-development-team/AROS/commit/c82e86b8480277998014cc327b56c7664023a52f ClassAct Reaction boopsi class] ===AROS Subsystems=== # [[Aros/Developer/Zune|Zune MUI compatible GUI]] # [[Aros/Developer/AROSAppPackages|AROS Application Packages]] # AHI Audio Drivers - [[Aros/Developer/AHIDrivers|Usage]]/[[Aros/Developer/AHIDriversDev|Development]] # AROSTCP Sana2 Network Interface Drivers - [[Aros/Developer/NICDrivers|Usage]]/[[Aros/Developer/NICDriversDev|Development]] # [[Aros/Developer/AmiSSL|AmiSSL]] # gfx.hidd/cybergraphics Video Drivers - [[Aros/Developer/GfxDrivers|Usage]]/[[Aros/Developer/GfxDriversDev|Development]] # IO Device Drivers - [[Aros/Developer/IODeviceDrivers|Usage]]/[[Aros/Developer/IODeviceDriversDev|Development]] # USB Device Drivers - [[Aros/Developer/USBDrivers|Usage]]/[[Aros/Developer/USBDriversDev|Development]] # PCI Device Drivers - [[Aros/Developer/PCIDrivers|Usage]]/[[Aros/Developer/PCIDriversDev|Development]] # [http://www.libsdl.org/ SDL] [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2013&pid=13333#post_13333 SDL2 coding usage], [https://github.com/search?q=repo%3Aaros-development-team%2Fcontrib%20SDL2&type=code SDL2 commits], [https://github.com/aros-development-team/contrib/commit/c62c3c425c35bac19dadc23be092b0b13a66c76c SDL3 initial commit], [] # [[w:Gallium3D|Gallium 3D]] [http://www.mesa3d.org/ openGL aka Mesa] - [[Aros/Developer/OpenGL|Usage]]/[[Aros/Developer/OpenGLDev|Development]] [http://www.swiftless.com/opengltuts.html Swfitless] # A small subset of GTK2 through [http://sourceforge.net/projects/gtk-mui/ MUI-GTK] # Cairo 2D Engine - [[Aros/Developer/Cairo|Usage]]/[[Aros/Developer/Cairo|Development]] # [[Aros/Developer/Scalos|Scalos desktop API and plugin modules]] # [[Aros/Developer/VHI|VHI video driver]] ====HIDDs==== *[[Aros/Developer/Docs/HIDD/HIDDClass|hiddclass.hidd]] *[[Aros/Developer/Docs/HIDD/Graphics|graphics.hidd]] *[[Aros/Developer/Docs/HIDD/VesaGfx|vesagfx.hidd]] *[[Aros/Developer/Docs/HIDD/ATI|radeon.hidd]] *[[Aros/Developer/Docs/HIDD/NVidia|nvidia.hidd]] *[[Aros/Developer/Docs/HIDD/Nouveau|nouveau.hidd]] *[[Aros/Developer/Docs/HIDD/Kbd|kbd.hidd]] *[[Aros/Developer/Docs/HIDD/Mouse|mouse.hidd]] *[[Aros/Developer/Docs/HIDD/i2c|i2c.hidd]] *[[Aros/Developer/Docs/HIDD/IRQ|irq.hidd (deprecated)]] *[[Aros/Developer/Docs/HIDD/PCI|pci.hidd]] *[[Aros/Developer/Docs/HIDD/PCIPC|pcipc.hidd]] *[[Aros/Developer/Docs/HIDD/Serial|serial.hidd]] *[[Aros/Developer/Docs/HIDD/Thunderbolt|thunderbolt.hidd]] https://github.com/aros-development-team/AROS/commit/4f02ea691799aff3a01f60cfa5f9182c82fc57a8 HIDD are used for device/peripheral low level hardware support drivers. The HIDD system is split up into a collection of classes with a strict inheritance hierarchy. A HIDD class implements a device driver for a single device or in rare cases a group of devices and provides an interface for other programs and devices to access. In order to maintain portability of interfaces across a wide range of hardware this interface will in general not present the raw interface to the underlying hardware. Instead it will present a generic interface that describes many different hardware implementations. This allows for the best reuse of both interfaces and code. HIDD API is heavyweight though. You need to open a HIDD library, open oop.library, instantiate an object (even if there's no object); and object calls are more costly compared to plain library calls. Basically your task is to implement a subclass of hidd.ata.bus for your hardware. just implementing the XXXATA__Hidd_ATABus__xxxxxx methods for the Amiga chipset - and appropriate versions of the interface_xxx.c file(s). pretty much everything in probe.c could be ignored - just write a replacement scan for relevant amiga devices and store whatever info you need in the bus data? only the "SUPPORT_LEGACY" blocks might be related. You do not need to depend on PCI API. PCI is just a way to discover the hardware on PCs, etc. <hidd/pci.h> includes (at some depth) <interface/HW.h>, which defines IID_HW. This comes from the 'generic' HIDD class in: rom/hidds/hidd/hiddclass.conf did not split up HIDD and HW because they are always used in pair. It's the same as hidd/pci.h bringing definition for: PCI, PCIDriver and PCIDevice. PCI is actually PCIHW, just the name was not changed for backwards compatibility reasons. HW is a 'hub' where HIDD instances plug in. ATA HIDD aoHidd_ATABus_Use32Bit value is completely ignored unless ata.device first detects correct command line parameter. Yes. Unfortunately I was unable to find any comment in code or svn history with explanations. Looked at Linux source, there 32-bit PIO is also controller driver's property. Some of them enable it, some don't. Actually, switching the default to ON should be safe. ata.device is fail-safe at this because during IDENTIFY command it validates upper 16 bits, and if they appear to be zeroes in all 128 longwords, then 32-bit mode is switched off. But, nevertheless, I know how tricky hardware can be, so I decided not to change original behavior. If you think it's wrong in some cases, then it's possible to add one more attribute like aHidd_ATABus_Default32Bit. If set to YES, then this means that 32-bit PIO is safe to use by default. ====Devices==== *[[Aros/Developer/Docs/Devices/ATA|ata.device]] *[[Aros/Developer/Docs/Devices/Console|console.device]] *[[Aros/Developer/Docs/Devices/Narrator|narrator.device]] *[[Aros/Developer/Docs/Devices/Printer|printer.device]] *[[Aros/Developer/Docs/Devices/Trackdisk|trackdisk.device]] *[[Aros/Developer/Docs/Devices/AmberRAM|amberram.device]] *[[Aros/Developer/Docs/Devices/Timer|timer.device]] *[[Aros/Developer/Docs/Devices/|.device]] The Amiga used [[Aros/Developer/Docs/Devices|Devices]] to communicate with [http://aros-exec.org/modules/newbb/viewtopic.php?start=0&topic_id=3475&viewmode=flat&order=ASC additional hardware]. AROS has replaced these hardware devices with hidd equivalents but some are still retained for backwards compatibility. Local libraries/devices/handlers,etc. are supposed to override the ones in ROM if their version is higher than the one in ROM. Here is the list of commands exec default: {| class="wikitable" | CMD_CLEAR | Purge the buffer of the device |---- | CMD_READ | Playback Control |---- | CMD_STOP | Stopped the activity of the device |---- | CMD_FLUSH | Empty the queue of commands |---- | CMD_RESET | Reset a device |---- | CMD_WRITE | Playback Control |---- | CMD_INVALID | Create an error |---- | CMD_UPDATE | Gets updated device |---- | CMD_START | Will restart the device |---- |} While most other "stuff you communicate with" in AmigaOS are devices <ref>AMIGA ROM Kernel Reference Manual: Devices, 3rd Edition. Commodore-Amiga, Inc. Addison-Wesley, 1991. {{ISBN|0-201-56775-X}}</ref> that share a [http://gega.homelinux.net/AmigaDevDocs/ common base interface]. [[Aros/Developer/Docs/Devices1.3|OS 1.3 Device Drivers]]. ====Handlers==== :[[Aros/Developer/Docs/Handlers/Pipe|pipe.handler]] :[[Aros/Developer/Docs/Handlers/Port|port.handler]] :[[Aros/Developer/Docs/Handlers/SFS|sfs.handler]] :[[Aros/Developer/Docs/Handlers/FAT|fat.handler]] :[[Aros/Developer/Docs/Handlers/PFS|pfs.handler]] :[[Aros/Developer/Docs/Handlers/NTFS|fuse.handler]] :[[Aros/Developer/Docs/Handlers/FFS|ffs.handler]] filesystem handlers have their own separate system consisting of completely differently structured messages that dos.library use to pass requests (for things like reading, writing, getting directory contents etc.) to them. AROS originally went with implementing filesystem handlers as devices, which might arguably be more consistent with the rest of the AmigaOS API but which is quite incompatible with AmigaOS itself. However, it made it far harder to port filesystems and the gains were comparatively small, and so there's been a long standing goal of fixing this incompatibility. It has now, June 2011, been reintroduced to all AROS flavors. are argstr and argsize valid for the handler startup environment? DOS/RunHandler() calls DOS/CreateNewProcTags(), and then CallEntry() (in rom/dos/exit.c) to start the handler, so yes, argstr and argsize are *present* in the call signature of the handler. Granted, argstr will be NULL and argsize 0, but those values *are* passed to the handler function using: <pre> AROS_UFC3(ULONG, entry, AROS_UFCA(STRPTR, argptr, A0), AROS_UFCA(ULONG, argsize, D0), AROS_UFCA(struct ExecBase *, SysBase, A6)); </pre> Creating your own [without the whole build tree http://pagesperso-orange.fr/franck.charlet/temp/radeon.zip] and then <pre> make stub make make install </pre> SFS has two Root blocks, one at the start and one at the end of the disk. The Root blocks both contain the same information. They hold various information about the disk structure and have the locations of some important blocks used by the filesystem. The Root ObjectContainer contains the Root directory Object. The name of this Object is the name of the volume. It is identical to a normal directory Object. The Bitmap is used to keep track of free space. Each bit in a bitmap represents a single block. A set bit indicates a free block and a cleared bit a used block. AdminSpaceContainers are used to keep track of space which has been reserved for storing administration blocks. Only the Bitmap, the Root blocks and the actual data stored in files aren't stored in administration space. Administration space is allocated in chunks of 32 blocks at a time. A single AdminSpaceContainer can hold information about a large number of such areas each of which has its own little bitmap of 32 bits. Extents are stored in a B-Tree. The Root block holds a pointer to the root of the Extent B-Tree. Extents keep track of space in use by a specific file. Each fragment a file consists of has its own Extent. Extents are in a double linked list. The list can be used to locate the next or previous fragment of a file. Below is the standard block header. This header is found before EVERY type of block used in the filesystem, except data blocks. The id field is used to check if the block is of the correct type when it is being referred to using a BLCK pointer. The checksum field is the SUM of all LONGs in a block plus one, and then negated. When applying a checksum the checksum field itself should be set to zero. The checking a checksum the checksum is okay if the result of the checksum equals zero. The ownblock BLCK pointer points to the block itself. This field is an extra safety check to ensure we are using a valid block. Field Type Description id ULONG The id field is used to identify the type of block we are dealing with. It is used to make sure that when referencing a block we got a block of the correct type. The id consist of 4 bytes and each blocktype has its own unique foure letter code. checksum ULONG This field contains the sum of all longs in this block, plus one and then negated. The checksum can be used to check if the block hasn't been corrupted in any way. ownblock BLCK Points to itself, or in other words, this field contains the block number of this block. This is yet another way to check whether or not a block is valid. <pre> struct fsBlockHeader { ULONG id; ULONG checksum; BLCK ownblock; }; </pre> The algorithm to calculate the checksum of a block: <pre> ULONG calcchecksum(struct fsBlockHeader *block, LONG blocksize} { ULONG *data=(ULONG *)block; ULONG checksum=1; block->checksum=0; while(blocksize>0) { checksum+=*data++; blocksize-=4; } return(-checksum); } </pre> A Root block contains very important information about the structure of a SFS disk. It has information on the location and size of the disk, the blocksize used, locations of various important blocks, version information and some filesystem specific settings. A SFS disk has two Root blocks; one located at the start of the partition and one at the end. On startup the filesystem will check both Roots to see if it is a valid SFS disk. If either one is missing SFS can still continue (although at the moment it won't). A Root block could be missing on purpose. For example, if you extend the partition at the end (adding a few MB's) then SFS can detect this with the information stored in the Root block located at the beginning (since only the end-offset has changed). Same goes for the other way around, as long as you don't change start and end point at the same time. When a Root block is missing because the partition has been made a bit larger, then SFS will in the future be able to resize itself without re-formatting the disk. Field Type Description bheader struct fsBlockHeader Standard block header. version UWORD The version of the filesystem block structure. You can check this field to identify what version of the filesystem your dealing with it and to see if you can handle this structure correctly. Don't try to interpret the disk's structure when this field contains an unknown version number! sequencenumber UWORD Used to identify which Root block was written last in case the sequencenumber on both Root blocks don't match. datecreated ULONG Creation date of this volume. This is the date when the disk was last formatted and will never be changed. bits UBYTE Various settings, see below. <pre> pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. reserved1 ULONG[2] Reserved, leave zero. firstbyteh ULONG High 32-bits of a 64-bit number. This is the first byte of our partition relative to the start of the disk. firstbyte ULONG Low 32-bits of a 64-bit number. lastbyteh ULONG High 32-bits of a 64-bit number. This is the last byte (exclusive) of our partition relative to the start of the disk. lastbyte ULONG Low 32-bits of a 64-bit number. totalblocks ULONG The total number of blocks this partition consists of. blocksize ULONG The size of a block of this partition. reserved2 ULONG[2] Reserved, leave zero. reserved3 ULONG[8] Reserved, leave zero. bitmapbase BLCK Block number of the start of the Bitmap. adminspacecontainer BLCK Block number of the first AdminSpaceContainer. rootobjectcontainer BLCK Block number of the ObjectContainer which contains the root of the disk (this is where the volume name is stored). extentbnoderoot BLCK Block number of the root of the Extent B-Tree. reserved4 ULONG[4] Reserved, leave zero. </pre> <pre> struct fsRootBlock { struct fsBlockHeader bheader; UWORD version; UWORD sequencenumber; ULONG datecreated; UBYTE bits; UBYTE pad1; UWORD pad2; ULONG reserved1[2]; ULONG firstbyteh; ULONG firstbyte; ULONG lastbyteh; ULONG lastbyte; BLCK totalblocks; ULONG blocksize; ULONG reserved2[2]; ULONG reserved3[8]; BLCK bitmapbase; BLCK adminspacecontainer; BLCK rootobjectcontainer; BLCK extentbnoderoot; ULONG reserved4[4]; }; </pre> AdminSpaceContainers are used to store the location and bitmap of each administration space. The AdminSpaceContainers are located in a double linked list and they contain an array of fsAdminSpace structures. There is one fsAdminSpace structure for every administration space on disk. Field Type Description bheader struct fsBlockHeader Standard block header. next BLCK The next AdminSpaceContainer, or zero if it is the last in the chain. previous BLCK The previous AdminSpaceContainer, or zero if it is the first AdminSpaceContainer. bits UBYTE The number of bits in each in the bits ULONG in the fsAdminSpace structure. pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. adminspace struct fsAdminSpace An array of fsAdminSpace structures. The size of the array is determined by the current blocksize. <pre> struct fsAdminSpaceContainer { struct fsBlockHeader bheader; BLCK next; BLCK previous; UBYTE bits; UBYTE pad1; UWORD pad2; struct fsAdminSpace adminspace[0]; }; </pre> Field Type Description space BLCK The first block of an administration space. bits ULONG A small bitmap which is used to determine which blocks in an administration space are already in use. The number of bits in this bitmap is determined by the bits field in the AdminSpaceContainer. <pre> struct fsAdminSpace { BLCK space; ULONG bits; }; </pre> The fsBitmap structure is used for Bitmap blocks. A bitmap block is used to keep track of which space is in use and which isn't for a particular area of a disk. All bitmap blocks together keep track of the free space for an entire disk. The location of the first bitmap block is known and all other bitmap blocks are stored in order after the first one. Field Type Description bheader struct fsBlockHeader Standard block header. bitmap ULONG An array of ULONG's. These hold the actual information on which blocks are in use and which aren't. <pre> struct fsBitmap { struct fsBlockHeader bheader; ULONG bitmap[0]; }; </pre> Each bit in a bitmap block (except for the block header) represents a single block. If the bit is set than the block is free, and if the bit is clear then it is full. The first ULONG in the bitmap area of the first bitmap block represents blocks 0 through 31 on the disk. Bit 31 of this ULONG is block 0, 30 is block 1, and so on. Bit 0 of the first ULONG represents block 31. Below is a table to clarify how bitmaps work even further. The first column is the bitmap block number, the second column is the number of the ULONG in the bitmap array. The third column is the bit number in this ULONG, and the last column is the block which this specific bit, in this specific bitmap block represents. We'll assume here that a bitmap block has room for 120 ULONG's (meaning there is room for storing 32 * 120 bits). <pre> Bitmap block ULONG number Bit number Block represented 1 (first) 0 31 0 1 0 30 1 ... ... ... ... 1 0 1 30 1 0 0 31 1 1 31 32 ... ... ... ... 1 2 31 64 1 2 30 65 ... ... ... ... 1 119 0 3839 2 0 31 3840 2 0 30 3841 ... ... ... ... </pre> The last bitmap block doesn't need to be completely used. The unused bits (which belong to blocks which do not exist) all have to be clear, to indicate that these blocks are in use. The fsObjectContainer structure is used to hold a variable number of fsObjects structures (Objects) which have the same parent directory. Each ObjectContainer must contain at least one Object. If there is space in the ObjectContainer not used by the variable number of Objects then that space is zero filled. Objects always start at 2-byte boundaries, which means sometimes a padding byte is inserted between two Objects. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the parent Object, or 0 if this object has no parent (which is only the case for the Root directory). next BLCK The next ObjectContainer belonging to this directory, or zero if it is the last in the chain. previous BLCK The previous ObjectContainer belonging to this directory, or zero if it is the first ObjectContainer in this directory. object struct fsObject A variable number of fsObject structures. The number of structures depends on the individual sizes of each fsObject structure and the blocksize. These structures are located directly after each other with at most 1 byte of padding between them to get the structures aligned on a 2 byte boundary. <pre> struct fsObjectContainer { struct fsBlockHeader bheader; NODE parent; BLCK next; BLCK previous; struct fsObject object[0]; }; </pre> fsHashTable is the structure of a HashTable block. It functions much like the hash table found in FFS user directory blocks, except that it is stored in a separate block. This block contains a number of hash-chains (about 120 for a 512 byte block). Each hash-chain is a chain of Nodes. Each Node has a pointer to an Object and a pointer to the next entry in the hash-chain. Using such a hash-chain you can locate an object quickly by only knowing its name. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the directory Object this HashTable block belongs to. hashentry NODE An array of Nodes. Each Node represents the start of a hash-chain (singly linked). A hash-value is calculated using the name of a file or directory, and this value determines in which chain the Object is linked. If there are no entries in a hash-chain then the hashentry value is zero. <pre> struct fsHashTable { struct fsBlockHeader bheader; NODE parent; NODE hashentry[0]; }; </pre> To calculate the hash-value using a name of an Object as input use these routines: <pre> UWORD calchash(UBYTE *name) { UWORD hash=0; /* Calculates a hash value over the passed in string. The end of the string can be either a NUL byte or a slash. The hash function is the same as the one used in FastFileSystem set to international mode. */ while(name[hash]!=0 && name[hash]!='/') { hash++; } while(*name!=0 && *name!='/') { hash=hash*13+upperchar(*name++); } return((UWORD)(hash % (UWORD)((blocksize-sizeof(struct fsHashTable))>>2))); } UBYTE upperchar(UBYTE c) { if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z')) { c-=32; } return(c); } </pre> The BNodeContainer is used to store B-Trees. Currently only one B-Tree is in use by this filesystem and it is used to store the location of file data. The fsBNodeContainer structure contains two other structures. The fsBlockHeader structure and the BTreeContainer structure. Field Type Description bheader struct fsBlockHeader Standard block header. btc struct BTreeContainer Contains information about the B-Tree and its nodes contained in this block. <pre> struct fsBNodeContainer { struct fsBlockHeader bheader; struct BTreeContainer btc; }; </pre> First try and locate the Root block. It should start with "ROOT". SFS has two of these, one at the start of the partition and one at the end. One of the fields contains the block size, which will be the size of all important SFS blocks. The root block has the root object container, which contains information about files and directories in the root directory. The object containers basically hold one or more smaller structures that represent files and directories. Scanning them all should give you a list of files and directories. The root block also has the root of the Extent B-Tree. This is a standard B-Tree structure (not a binary tree) that is used commonly in all kinds of system, you can read about how they work on Wikipedia if needed. The B-Tree holds the information about *where* all the data is located for your files. To recover your files, I'd do this: * Find one of the root blocks, if not present, then figure out the block size your disk was using, and scan every block in turn to see if it looks like an ObjectContainer (check the fsBlockHeader's ID, check if the ownblock number is equal to the block you are currently scanning, and check its checksum). So if you currently have block 12, and you see a block with the correct id, and ownblock = 12 and its checksum is good, then that's probably a valid ObjectContainer. * With all the ObjectContainers found, you can extract filenames and directory names from these, but also the number of their first data block (in the field data) and the file size. For small files (less than blocksize) this data block will be enough to recover the data. For larger files, you might be lucky and all the remaining blocks are found after the first one (if the file was defragmented). You can't be sure of that though so... * For larger files, you need to find all the BNodeContainers. You could scan these in the same way you found all the ObjectContainers (look for blocks with the correct id, ownblock number and checksum). * With all the BNodeContainers found, you can try looking up the first data block of a file in the B-Tree structure. This is a bit complicated -- the B-Tree consists of non-leaf nodes (blocks that only contain pointers to other B-Tree blocks), the isLeaf flag indicates this. Or it can be a B-Tree leaf block. The leaf blocks contain extra information per entry (see https://hjohn.home.xs4all.nl/SFS/extents.htm) <pre> struct fsExtentBNode { ULONG key; ULONG next; ULONG prev; UWORD blocks; }; </pre> The key should be a block of a file (the first of a range), that is 1 to 65535 block long (depending the "blocks" field). If the file is split up into more parts, then "next" will contain block number of the next range of blocks. You need to look this up again in the B-Tree structure to find out how large it is. You can for the most part ignore the other structures (bitmap, admin containers). The fsObjects and B-tree containers is what you'll need to recover the data. ====Resources==== <pre> rom/storage/mmakefile.src rom/storage/storage.conf rom/storage/storage_device.c rom/storage/storage_ids.c rom/storage/storage_init.c rom/storage/storage_intern.h rom/storage/storage_mount.c rom/storage/storage_unit.c </pre> <pre> rom/storage/includes/device.h rom/storage/includes/unit.h rom/storage/includes/volume.h rom/storage/storage_intern.h </pre> <pre> </pre> *[[Aros/Developer/Docs/Resources/ACPI|acpi.resource]] *[[Aros/Developer/Docs/Resources/Battclock|battclock.resource]] *[[Aros/Developer/Docs/Resources/Bootloader|bootloader.resource]] *[[Aros/Developer/Docs/Resources/Cia|cia.resource]] *[[Aros/Developer/Docs/Resources/Filesystem|FileSystem.resource]] *[[Aros/Developer/Docs/Resources/Hostlib|hostlib.resource]] *[[Aros/Developer/Docs/Resources/Kernel|kernel.resource]] *[[Aros/Developer/Docs/Resources/Misc|misc.resource]] *[[Aros/Developer/Docs/Resources/Processor|processor.resource]] ==Debugging Code== Please use the [http://sourceforge.net/tracker/?group_id=43586&atid=439463 AROS Bug Tracker] if any issues are found. GRUB Command line list <pre> sysdebug usbdebug - allows to see Poseidon's log in debug output </pre> How do I get debugging out of InitResident ? If running i386 hosted on linux sysdebug=initresident on command line. This way you can enable any of listed flags. sysdebug=all stands for "everything" Have an executable (crosscompiled C++ code) which has 6 MB size on disk, but after loading it in memory, 250 MB RAM is taken. Any software that would split AROS executable into ELF part which would show actual size values? readelf -S executable it will show you all sections in elf file, including sizes and requested alignment. objdump -h filename That's will give you a quick overview of the sections and sizes. Ignore all the .debug.* sections. Would hazard a guess that you have a large .bss section. That's pretty common in C++. Next step: nm—size-sort filename | grep ' [bB] ' The last few will be your biggest consumers. Would suggest -C to demangle the symbols... ;) Suggest profiling the program (just use some printf's in the main loop for time spent in each part), it usually is quite easy to spot slow parts in games or apps. If someone has '#define IPTR ULONG' somewhere. To see where that define is, redefine IPTR in the source code that fails, just above the line that fails, and the preprocessor will tell you where it was defined first. ===How to setup gdb with AROS/hosted=== Download AROS sources (AROS-xxxxxxxx-source.tar.bz2, where xxxxxxxx is the current date) and AROS contrib sources (AROS-xxxxxxxx-contrib-source) from Untar-bzip2 and cd to the unpacked archive directory. > tar -xvjf AROS-xxxxxxxx-source.tar.bz2 > cd AROS-xxxxxxxx-source Check the link to "contrib" (contrib-source) inside directory, e.g. correct like this: > rm contrib > ln -s ../AROS-xxxxxxxx-contrib-source.tar.bz2 contrib Make sure you have the correct locale setting, otherwise compilation will fail at some point. See [http://aros.sourceforge.net/documentation/developers/compiling.php#setting-the-locale-to-iso8859 here] (or link below) for more on that. You might have to enter this: > export LANG="en_US.ISO-8859-1" Now configure for a debug build - see "./configure --help" for more - here are two examples: > ./configure—enable-debug=stack,modules,symbols > ./configure—enable-debug=all You may "make" now, or choose a separate directory for your build (e.g. for easy removal), for example if compiling for i386 architecture you could create a directory like this: > mkdir linux-i386 > cd linux-i386 > ../AROS/configure—enable-debug=stack,symbols,modules When done configuring you're ready to go: > make Building AROS takes some time - minutes on fast machines (e.g. 2.5&nbsp;GHz quadcore), up to hours on slower machines. The result will be AROS Linux hosted with gdb debugging enabled. See aros.org documentation for more on compiling AROS, including more [http://aros.sourceforge.net/documentation/developers/compiling.php --enable-debug] options. When finished, enter bin/linux-i386/AROS directory (replace "linux-i386" with your compilation target platform, e.g. linux-x86_64, etc.) inside the unpacked archive directory. This directory contains the required .gdbinit file for properly running AROS inside gdb. > cd bin/linux-i386/AROS Run AROS (here: with 128MB of memory) from gdb: > gdb—args boot/aros-unix -m 128 or > gdb—args boot/arosboot -m 128 (gdb) r Watch the shell output - in case AROS complains about "LoadKeyCode2RawKeyTable: Loading "DEVS:Keymaps/X11/keycode2rawkey.table" failed!" you should also see some instructions on how to create a keymap table. (see link above "more on compiling", too.) Quit gdb, and try default keymap table: (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y > cd ../../.. > make default-x11keymaptable Re-run AROS, as described above. Try e.g. RAros (= right windows key) + W to open a shell. If this doesn't work you have to create a keymap table yourself, quit gdb again, and make a new keytable: > make change-x11keymaptable A window will open. Watch the window's title bar, and follow the instructions. When done, re-run AROS. RAros + W should now open a shell. Next, compile your program with gdb support. When you start GDB is there a warning which says warning: File "<whatever>/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to ... If so start gdb with "-ix .gdbinit" <pre> Summary - In short: * build AROS with debugging support (i.e. ./configure --enable-debug=all) * build your application with debugging support (i.e. option -g) * run AROS in the GNU debugger (you may use the GUI frontend "ddd" which simplifies usage a bit) * start your application * use the commands "findaddr" and "add-symbol-file" as written in the debugging manual * if the debugger doesn't find the source code of your application use the "dir" command of the debugger. </pre> ===How to use gdb=== In AROS open a shell, then (in host shell) use CTRL-Z to go into gdb. Use "b Exec_CreatePool" (one of the functions used early on by startup code in programs) to add a breakpoint, then "cont" and gdb will interrupt somewhere early during startup of "program". Use "bt" to show backtrace and "loadseg" for "??" entries. One of them will be for "program". After that you can use "disassemble program". One thing you need to make sure is that .gdbinit you have in your build directory is the same as in source tree. It has been modified some time ago, but the build system does not refresh it - you need to copy it manually To recap, please read our debugging [http://aros.sourceforge.net/documentation/developers/debugging.php manual]: To detect segfaulting when loading, try... ./configure—enable-debug—with-optimization="-O2" Because crash or no crash may depend on optimization. For newer compilers maybe this helps... --with-optimization=-"-O2 -fno-strict-aliasing" One way to make crashes less random (more easily reproducible) is to activate the munging of free memory in rom/exec/freemem.c which is normally commented out: <pre> Index: freemem.c =================================================================== --- freemem.c (revision 34289) +++ freemem.c (working copy) @@ -154,11 +154,12 @@ * created with their TCB placed in the tc_MemEntry list. The workaround * is to avoid munging when FreeMem() is called with task switching disabled. */ + /* DOH! it doesn't work even this way. What's wrong??? - * - * if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) - * MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); */ + + if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) + MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); } </pre> Mungwall can be turned on at runtime. Currently this works in all hosted versions. Just specify "mungwall" on kernel command line and it works. It can work on native too. In order to enable it you need to parse kernel command line, and if "mungwall" is present, set EXECF_MungWall bit in IntExecBase.IntFlags. This needs to be done before the first AllocMem() for obvious reasons. And never reset back this flag! If you change it on a working system, you are doomed. Hosted ports do the processing in rom/exec/prepareexecbase.c --enable-debug=mungwall option in configure still works but is going obsolete. A kludge in rom/exec/allocmem.c is responsible for this and it needs to be removed when the transition is done. BTW, on i386-pc port it can be activated by "mungwall" argument on command line, you don't need to rebuild AROS. New mungwall affects not only AllocMem()/FreeMem(), but also pools. I also tested it with AllocAbs(), seems to work correctly. Runtime mungwall works on: * pc-i386 * pc-x86_64 * linux-i386 * linux-x86_64 * darwin-x86 * linux-ppc Works on all hosted ports, if the port itself is working. * amiga-m68k * Not on sam440-ppc and efika-chrp-ppc, even if they would be able to be built at moment. Does not work on (for now, need NVRAM support) When starting my freshly rebuilt i386-linux-aros which was compiled with full debugging support I get sometimes the error "Program exited with code 0377". Add the following to your .gdbinit: set follow-fork-mode child Here are some of the custom AROS gdb functions (defined in ".gdbinit" file) to resolve "in ?? ()" entries in backtrace: <pre> #0 0xb7ffd424 in __kernel_vsyscall () #1 0xb7e2a657 in sigsuspend () from /lib/libc.so.6 #2 0xb7c63900 in ?? () #3 0xb7c640e3 in ?? () #4 0xb7c641e0 in ?? () </pre> You can use loadseg 0xb7c63900 loadframe 2 or loadbt and some others. Use "help " for a little help text. If the commands do not work try "loadkick" first. Use "thistask", "taskready", "taskwait" to get list of AROS tasks. "bttask " shows backtrace of a task which is in ready or in wait queue and "loadseg" to resolve "??" entries in it's backtrace ("loadframe" would not work as it assume current running task). ===Native debugging tools for AROS=== to enable debugging at boot time entering the GRUB menu editing line (E key) and adding "debug=memory" to your boot line, then press Ctrl+X to complete booting. SYS:Tools/Debug/'''Bifteck''' Open a shell and enter the line below to run Biftek and grab the debug messages collected in RAM into a text file. tools/debug/bifteck > ram:debug.txt and certainly does not open a window. It is a shell tool and only dumps data located from the debug location. It is therefore important to 'catch' that debug data as soon as possible (before it gets overridden). You should invoke bifteck at the first opportunity before doing anything else. You can use the TO option to store bifteck output to a file or you can pipe it manually to a file. SYS:Tools/Debug/'''Sashimi''' - displays error messages One suggestion is to do a bug() debugging. Each time bug() is executed it will be output on sashimi. You include <aros/debug.h> and place bug("something\n"); in your source code at location though which control passes. To get the output - open an aros shell SYS:Tools/Debug/sashimi > RAM:out.txt '''Ctrl C''' to end the output to the RAM Disk. # open shell, and type # ram: (to switch to ram drive) # System:Tools/Debug/Sashimi > mylogfile.txt # open AHI prefs using wanderer (or use another opened shell) # play test sound # close AHI prefs # shell still open with Sashimi running: press ctrl-c to break Sashimi and return to prompt. # in shell: copy mylogfile.txt System: (or to your required location) SYS:Utilities/'''Snoopy''' - monitors OS function calls, run "Sashimi" to see Snoopy's output SYS:Tools/'''WiMP''' - the Window (and Screens) Manipulation Program You can use the -E option of gcc to find out how preprocessor macros are expanded. ===Errors=== crash in strcasecmp usually means that one of its arguments is NULL. empty space between these two names, prossibly some invisible character Old Amiga [http://www.amigacoding.com/index.php?title=Guru_codes&redirect=no Guru Codes] If the crash is in intuition. Sometimes, if it relates to text, a null pointer sets it off. an uninitialised pointer can have any address (this is a common fault). Compiling on 64bit, Many old code would not properly typecast when doing pointer-integer conversions and thus at least throw a warning. This can easily be located and fixed. [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. * Fix (change IPTR/SIPTR back to ULONG/LONG) the few places which really rely on ULONG/LONG being exactly 32 bit. That's for things like pixel (ARGB) buffers, structs written/read to disk, colormaps, but probably not much else. Then again, many current compilers also throw a warning when you try to assign a pointer value to an integer and the integer is possibly too small. This happens under .NET for example when a 64 bit pointer is assigned to something like an ULONG - so exactly the case which you described. === AI === Multimodal Context Prompt <--- Model <---> Agent ---> End user engine Gemini LMStudio Qwen Comfyui etc Recent, self hosting locally on laptops, mini pcs or desktops with '''quantization''' 4bit has reduced memory requirements but still require 16Gb+ and no high end gpu for text based *[https://lmstudio.ai/download LMstudio single gpu], Google Gemma 4 Model *[ 12B QAT] Alibaba Cloud's [https://huggingface.co/ Qwen] team series of large language models LLMs *[https://huggingface.co/models?other=qwen3 Qwen 3], [], *[https://huggingface.co/models?other=qwen2 Qwen 2], [https://huggingface.co/Qwen/Qwen2.5-Coder-32B qwen 2.5 Coder], Small models *[ glm-ocr] *[ medGemma] *[ qwen 3.5-4b] *[https://github.com/sipeed/picoclaw picoclaw claude] Bigger LLMs but with settings *[https://ollama.com/download Ollama single gpu] *[https://github.com/ggml-org/llama.cpp/releases llama.CPP multi gpus], *[ VLM multiple gpus], Multimedia *[ Kimi K3], For the full experience #Training learning using 1+ high end GPUs at least 16GB VRAM per GPU card or 64Gb+ of unified, 16Core CPU with at least 64Gb of RAM system memory, though training can take weeks #Inference with custom asics or GPUs *[ MiniMax H3] for audio and video but gpu 8Gb+ *[https://github.com/jamiepine/voicebox voicebox] *[https://github.com/ideogram-oss/ideogram4 ideogram4] *[https://github.com/calesthio/OpenMontage OpenMontage] <pre> Text to Audio --\ Text to Video --/ Reference Video --> Video and Audio output </pre> === Example === <syntaxhighlight lang="c"> /* 1. Header for your name,date,purpose of program. 2. Pre-processor directives. This will include the #includes for files you want to add. 3. Includes for function prototypes if necessary. 4. Main() Create Pointers for Libraries and any Window you want to open. 5. Open necessary libraries. 6. Check if open exit program if fail. 7. Open a window exit program if fail. 8. Add your program 9. Close Window 10 Close Libraries. 11 End Program. */ /* standard os included headers <.h> */ #include <dos/dos.h> #include <dos/dosasl.h> #include <dos/dosextens.h> #include <dos/exall.h> #include <dos/rdargs.h> #include <exec/memory.h> #include <exec/types.h> #include <utility/utility.h> #include <intuition/intuition.h> /* define as unresolved external references (proto/xxx.h) and compiler will link to auto(matically) open library */ #include <proto/arossupport.h> #include <proto/dos.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/graphics.h> #include <proto/cybergraphics.h> #include <proto/datatypes.h> #include <proto/icon.h> #include <workbench/workbench.h> #include <workbench/icon.h> #include <datatypes/pictureclass.h> #include <proto/muimaster.h> #include <libraries/mui.h> #include proto/bsdsocket.h #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* my own headers ".h" */ #define CTRL_C (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) #define isDir(fib) ((fib)->fib_DirEntryType >= 0) #define ARG_TEMPLATE "FILE/A,ALL/S,QUIET/S,W=WIDTH/N,H=HEIGHT/N,M=METHOD,DEFTOOL" int main(void) { return retval; } /* main */ </syntaxhighlight> If you used c++, there is not yet c++ support in our shared library system. The easiest way to create / compile a shared library would be to use the AROS build system but the libraries can be created manually. You have to create a ROMTAG structure and some header files. A shared library is built with the %build_module macro with a line like this: %build_module mmake=MetaTarget modname=mylib modtype=library files=SourceFiles This macro can build different AROS module types, like devices, Zune classes, HIDDs, etc. <pre> ##begin config version 1.0 ##end config ##begin functionlist void func1(LONG a, LONG b) int func2(char *s, ULONG a) ##end functionlist </pre> Alternatively, <pre> #ifndef LIB_H #define LIB_H #define __NOLIBBASE__ #include <exec/libraries.h> #include <exec/semaphores.h> #include <dos/dos.h> #ifdef __AROS__ //#include <aros/debug.h> #define reg(x) #define __saveds #endif #define USESYSBASE struct ExecBase *SysBase = Base->My_SysBase; struct MyTestBase { struct Library My_Test_Lib; struct ExecBase *My_SysBase; APTR My_SegList; int testint; }; #endif </pre> <pre> /*--------------------------------------------------------------------------*/ /* Resident header written for mytest.library */ /*--------------------------------------------------------------------------*/ #define __NOLIBBASE__ #define VERSION 1 #define REVISION 0 #define LIBHEADNAME mytest #define LIBHEADNAMESTR "mytest" #define COMPDATE "04.10.2015" #define VERS "1.0" #define LIBBASETYPE struct MyTestBase #define LIBBASETYPEPTR LIBBASETYPE * #include <aros/debug.h> #include <exec/exec.h> #include <proto/exec.h> #include <exec/resident.h> #include <exec/nodes.h> #include <exec/libraries.h> #include <aros/symbolsets.h> #include "lib.h" const UBYTE lib_name[] = LIBHEADNAMESTR ".library"; const UBYTE lib_id[] = "$VER: " LIBHEADNAMESTR ".library " VERS " (" COMPDATE ") by ALB42\n"; extern const APTR FuncTable[]; AROS_UFP3 (LIBBASETYPEPTR, InitLib, AROS_UFPA(LIBBASETYPEPTR, Base, D0), AROS_UFPA(BPTR, seglist, A0), AROS_UFPA(struct ExecBase *, sysbase, A6) ); static struct LibInitStruct { IPTR LibSize; const APTR *FuncTable; const struct DataTable *DataTable; APTR InitFunc; } const LibInitStruct = { sizeof(LIBBASETYPE), FuncTable, NULL, (APTR)InitLib }; const struct Resident romtag = { RTC_MATCHWORD, /* match word */ (APTR)&romtag, /* back pointer */ (APTR)(&romtag + 1), /* skip pointer */ RTF_AUTOINIT | RTF_EXTENDED,/* flags */ VERSION, /* version */ NT_LIBRARY, /* type of module */ 0, /* init priority */ (STRPTR)lib_name, /* module name */ (STRPTR)lib_id + 6, (APTR)&LibInitStruct, REVISION, NULL }; AROS_UFH3 (LIBBASETYPEPTR, InitLib, AROS_UFHA(LIBBASETYPEPTR, Base, D0), AROS_UFHA(BPTR, seglist, A0), AROS_UFHA(struct ExecBase *, sysbase, A6) ) { AROS_USERFUNC_INIT Base->My_SegList = seglist; Base->My_SysBase = (APTR)sysbase; Base->testint = 0; USESYSBASE bug("InitLib\n"); if (!set_open_libraries()) { set_close_libraries(); return NULL; } return Base; AROS_USERFUNC_EXIT } AROS_LH1(LIBBASETYPEPTR, LibOpen, AROS_LHA (ULONG, version, D0), LIBBASETYPEPTR, Base, 1, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibOpen\n"); (void)version; Base->My_Test_Lib.lib_OpenCnt++; return Base; AROS_LIBFUNC_EXIT } __saveds APTR LibExpungeInternal(LIBBASETYPE *Base reg(a6)) { USESYSBASE APTR seglist; bug("LibExpungeInternal\n"); if (Base->My_Test_Lib.lib_OpenCnt) { return 0; } seglist = Base->My_SegList; Forbid(); Remove((struct Node*)Base); Permit(); FreeMem((APTR)Base - Base->My_Test_Lib.lib_NegSize, (LONG)Base->My_Test_Lib.lib_PosSize + (LONG)Base->My_Test_Lib.lib_NegSize); set_close_libraries(); return seglist; } AROS_LH0(BPTR, LibClose, LIBBASETYPEPTR, Base, 2, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibClose\n"); if (!(--Base->My_Test_Lib.lib_OpenCnt)) { return LibExpungeInternal(Base); } return 0; AROS_LIBFUNC_EXIT } AROS_LH1(BPTR, LibExpunge, AROS_LHA(LIBBASETYPEPTR, Base, D0), struct ExecBase *, sysBase, 3, LIBHEADNAME ) { AROS_LIBFUNC_INIT (void)sysBase; USESYSBASE bug("LibExpunge\n"); return LibExpungeInternal(Base); AROS_LIBFUNC_EXIT } AROS_LH0(LIBBASETYPEPTR, LibReserved, LIBBASETYPEPTR, Base, 4, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibReserved\n"); return 0; //return (APTR)LibReserved(); AROS_LIBFUNC_EXIT } // Space for your own functions // do not forget to update the FuncTable as well AROS_LH1(int, TestFunction, AROS_LHA(int, TestValue, D0), LIBBASETYPEPTR, Base, 5, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("TestFunction\n"); Base->testint = TestValue + Base->testint; return Base->testint; AROS_LIBFUNC_EXIT } // Functable -> Table of all functions in the Library, in right order - important! const APTR FuncTable[] = { &AROS_SLIB_ENTRY(LibOpen,LIBHEADNAME,1), &AROS_SLIB_ENTRY(LibClose,LIBHEADNAME,2), &AROS_SLIB_ENTRY(LibExpunge,LIBHEADNAME,3), &AROS_SLIB_ENTRY(LibReserved,LIBHEADNAME,4), &AROS_SLIB_ENTRY(TestFunction,LIBHEADNAME,5), (void *)-1 }; // AutoInit stuff void *__PROGRAM_ENTRIES__symbol_set_handler_missing; void *__LIBS__symbol_set_handler_missing; // end of AutoInitStuff </pre> Makefile <pre> VPATH = CFLAGS = -O2 -g -fomit-frame-pointer -W -Wall -Wno-parentheses CC = i386-aros-gcc LD = i386-aros-gcc LDFLAGS = -nostartfiles -Wl,-Map -Xlinker linkermap LIBS = -lautoinit -llibinit STRIP = i386-aros-strip --strip-unneeded --remove-section .comment OBJS = lib_header.o all: mytest.library mytest.library: $(OBJS) $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ lib_header.o: lib_header.c lib.h clean: rm -f *.o *.library *.ppu testlibrary linkermap </pre> Porting UNIX library to AROS - dealing with static variables which would make it easy to port such libraries to AROS, keeping the benefits of sharing them on disk, but losing the benefit of actually sharing them in memory. Our problem arises by the fact we want to share the actual code (the .text section of the library) and constant data, but we need to have per-task .bss and .data sections. If we get rid of our intention to share the .text and .rodata sections, things get quite easy: just load and relocate the library whenever it's open, by whoever it's open. It's like statically linking the library into the executable, except that the final linking is done at runtime. In the V0 branch, in workbench/hidds/hidd.nouveau was committed pcimock.hidd. This is a pci driver that allows mocking real PCI devices under linux-hosted. The main idea is to be able to run the real hardware driver under linux-hosted with as little changes as possible (some changes will always be needed though unless someone wants to write complete device simulator) so that driver's code paths can be executed and debugged using gdb. This was a very helpful capability when porting nouveau. Now it is externalized from nouveau.hidd and can be used by other people porting drivers. The pcimock.hidd can currently mock 4 different nvidia cards, 1 AGP bridge and also mock irq.hidd. What's the difference between this driver and the pcilinux.hidd? I used that one to develop many different HW drivers for aros. As far as I understood the intention of pcilinux.hidd it is supposed to get access to real hardware that is running under linux. The pcimock.hidd goal is to mock the hardware. For example my dev box is a PCIE system, but I still would like to run the AGP codes paths in nouveau under linux-hosted to check if they don't seg fault. The other case would be to run codes paths for hardware that the developer does not have (Fermi cards in my case). In the case of pcimock.hidd, the AROS driver's code paths will execute as long as you add proper mocking (for example fill in PCI config area or values for registers in BARs). This is an advantage for ported drivers - the code should already work (since it worked on another system) but there might have been mistakes made during porting which can be detected easily with gdb. In case you are writing your driver from scratch, pcilinux.hidd hidd will give you more advantage, since you can actually access the real hardware from linux-hosted. == Misc == ===APL, MPL, BSD, GPL and LGPL Licences=== The majority of AROS sources in licensed under AROS Public License ([http://aros.sourceforge.net/license.html APL]) which (to a degree) protects us from someone taking AROS sources and not contributing improvements back (for example MorphOS took some AROS source and then contributed changes back) It is written to allow the use of AROS code in other open source or commercial projects without exception whilst providing a mechanism so that improvements/additions can find their way back to the original source in one form or another. There are "3rd" party applications used by AROS that do not fall under this license, which are an extra "Contrib" download for convenience. Anyone can port GPL-ed network and sound drivers as AROSTCP and AHI are GPLed. Direct using (porting) [http://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs GPL]-ed code in other parts of AROS (gfx, sata, usb) is not possible because AROS license is not compatible with GPL. You need to utilize permissive licensed code like BSD or MIT/X11. BSD and MPL license are the closest to APL. APL however is not so compatible with LGPL/GPL. LGPL case - you cannot statically combine APL code with LGPL. You can, however thank to LGPL being "lesser" restrictive, use LGPL dynamically loaded libraries in APL codes. GPL case - you cannot combine APL code with GPL in any way if there is no explicit clause by GPLed code authors allowing that. If you do combine APL with GPL in "bad" ways described above - you have a problem (you violate GPL). This problem might result in everything in AROS becoming GPL or everything running or AROS becoming GPL (here I'm not sure really). The other scenario is that you are not allowed to legally distribute such code at all. To be honest I have grasped how to violate GPL, but I'm still no exactly sure what happens when you violate it (but I'm sure it's not anything nice) GPL software can run on top of non-GPL "system components" (see system components exception of GPL), but the other way around (non-GPL using GPL) leads to problems. This means applications like scout, or Quake III are ok (in the majority of cases). Theres no reason GPL drivers cannot be ported - but they cant be in AROS's ROM (requires linking APL code with GPL), nor can AROS depend on them (e.g. they must use existing apis). If they are launched (dynamically linked) by a user action that is allowed. It is also allowed to distribute such binaries together for convenience. GPL is not about statical or dynamic linking but is about executing process and function calls. These components - SFS, isapnp, Zune texteditor, AHi, network drivers, freetype, openuirl, BHFormat, Edit and (" dynamically loaded libraries") are LGPL, not GPL. Mesa/Nouveau stuff is MIT. Some user tools are GPL though. '''AROS (system)''' * system components (libraries/classes/devices/etc) cannot be GPL as they would propagate GPL to complete system as well as GPL is not compatible with MPL from which APL is based * system components can be LGPL v2 or a permissive license (MIT/BSD) * system applications can be anything you like (but still I would prefer APL or permissive so the code can be reused if needed) '''Contrib:''' * no rules - contrib does not impact AROS system since nothing in AROS system depends on contrib. About stealing code: The chances of this happening is exactly the same whether we are APL or GPL. If any closed-source option wanted to do it, there is no one that can validate otherwise. MorphOS has used some AROS codes, but contributed changes back. The rationale behind APL is that while it guarantees that the original developer will get the improvements back (to a certain degree - file based), the person who uses the codes does not have to open his original codes. BSD does not guarantee that the original developer gets improvements. GPL requires the person using the codes to open his codes as well. The copyright holders needs to stay - we just need information from them that the codes are available under APL (for example a checked-in file like in case of Poseidon). We don't do transfer of copyrights. ; Ultimately what can and cannot be done is up to the author(s) - not the licence. ===AROS source code tree=== * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-trunk.txt * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt Found this interesting (non-GPL) licensing 'anomaly' - to keep in mind for distributors. Programs that lose their license if sold ("non-profit only" licensed): contrib/aminet/comm/term/TinyTerminal contrib/aminet/dev/basic/bwBASIC contrib/aminet/text/edit/xdme contrib/fish/aroach contrib/fish/lotto contrib/fish/shuffle contrib/fish/touch + cdvdfs. Here is a list of all the GPL/GPLv2/GPLv3 licenses fossology found, what have explicit licenses in their comments. excluded LGPL, BSD/GPL dual licensed and programs (such as Prefs/Edit and BHFormat) <pre> AROS/rom/dbus/include/ AFL_v2.1 ,GPL_v2+ (supposedly AFL < 3 is GPL incompatible) AROS/workbench/classes/zune/betterstring/include/ GPL_v2+ AROS/workbench/classes/zune/texteditor/include/ GPL_v2+ AROS/workbench/classes/datatypes/gemimage/ GPL_v2+ GPL AROS/workbench/classes/datatypes/degas/ GPL_v2+ AROS/workbench/libs/openurl/README: GPL AROS/workbench/network/smbfs/documentation/ GPL_v2 AROS/workbench/network/smbfs/source_code/ GPL_v2+ AROS/workbench/network/stacks/AROSTCP/bsdsocket/kern/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/mmakefile.src conf.h GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/sys/ CMU ,GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/net/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/api/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/conf/conf.h: GPL_v2 AROS/workbench/network/stacks/AROSTCP/netinclude/net/radix.h: CMU ,GPL_v2 AROS/workbench/devs/AHI/AHI/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/COPYING: GPL AROS/workbench/devs/AHI/Docs/texinfo.tex: GPL_v2+ AROS/workbench/devs/AHI/COPYING: GPL AROS/workbench/devs/AHI/Drivers/EMU10kx/ GPL_v2+ AROS/workbench/devs/AHI/AHI-Handler/ GPL_v2+ AROS/workbench/devs/networks/rtl8029/ GPL GPL_v2+ AROS/workbench/devs/networks/pcnet32/ GPL GPL_v2+ AROS/workbench/devs/networks/ppp/LEGAL: GPL AROS/workbench/devs/networks/atheros5000/ GPL_v2+ AROS/workbench/devs/networks/rhine/ GPL_v2+ AROS/workbench/devs/networks/nForce/ GPL_v2+ GPL AROS/workbench/devs/networks/prism2/ GPL GPL_v2+ AROS/workbench/devs/networks/fec/LEGAL: GPL AROS/workbench/devs/networks/rtl8139/ GPL GPL_v2+ AROS/workbench/devs/networks/etherlink3/ GPL GPL_v2+ AROS/workbench/devs/networks/intelpro100/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8169/ GPL GPL_v2+ AROS/workbench/devs/networks/emac/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8168/ GPL GPL_v2+ AROS/workbench/devs/networks/realtek8180/ GPL_v2+ AROS/workbench/devs/networks/via-rhine/via-rhine.c: GPL_v2+ AROS/workbench/devs/networks/via-rhine/ GPL GPL_v2+ AROS/workbench/devs/networks/e1000/ GPL_v2 AROS/workbench/devs/networks/sis900/ GPL GPL_v2+ </pre> AHI: it has special provisions (COPYING.DRIVERS). The library is LGPL, preferences software is GPL and drivers can be anything without breaking GPL/LGPL. Network stack: well, we are long overdue for a new, IPv6 enabled network stack anyway, anyone interested? ;) Seriously though it seems like the glue code is GPL and as all the drivers. However some of the drivers are our own code, so they could be relicensed to LGPL. Same filter as the AROS trunk list. These should all be libraries or plugins - no programs. <pre> contrib/regina/utsname.h: GPL_v2+ contrib/mui/classes/nlist/include/default-align.h: GPL_v2+ contrib/mui/classes/nlist/include/amiga-align.h: GPL_v2+ contrib/mui/classes/BWins/include/MUI/BWin_mcc.h: GPL contrib/mui/classes/BWins/include/BWin_private_mcc.h: GPL contrib/mui/classes/BWins/COPYING: GPL_v2 contrib/mui/classes/BWins/MCC_BWins.readme: GPL_v2 contrib/mui/classes/thebar/include/default-align.h: GPL_v2+ contrib/mui/classes/thebar/include/amiga-align.h: GPL_v2+ contrib/gfx/libs/wazp3d/LEGAL: GPL contrib/gfx/libs/wazp3d/Wazp3D.readme: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.c: GPL contrib/libs/mpega/ GPL_v2+ </pre> http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt ===Types=== On AROS following rules apply: <pre> 1. BYTE/UBYTE is 8bit, WORD/UWORD is 16bit, LONG/ULONG is 32bit, QUAD/UQUAD is 64bit, the types are comparable with stdint types (int8_t, int16_t, int32_t, int64_t) 2. IPTR/SIPTR are integer types large enough to fit pointer, that is sizeof(IPTR) = sizeof(APTR) = 4 on 32bit system, and = 8 on 64bit system 3. ti_Data in TagList is large enough to hold a IPTR/APTR type. 4. never store a pointer in integer of type LONG. It may work (if the pointer has upper 32bits clear), but does not have to. Compiler should warn you about that. 5. If you are unsure about point 4, allocate your memory with MEMF_31BIT flag set. But don't expect that AROS internals will do the same. </pre> point 4 is actually important. * UBYTE/BYTE for 8bit * UWORD/WORD for 16bit * ULONG/LONG for 32bit * UQUAD/QUAD for 64bit <pre> UBYTE Unsigned 8 bit integer variable (byte). BYTE Signed 8 bit integer variable (byte). UWORD Unsigned 16 bit integer variable (word). WORD Signed 16 bit integer variable (word). ULONG Unsigned 32 bit integer variable (longword). LONG Signed 32 bit integer variable (longword). FLOAT 32 bit IEEE floating point variable. UQUAD Unsigned 64 bit integer variable. QUAD Signed 64 bit integer variable. DOUBLE 64bit IEEE floating point variable. BOOL Boolean variable, TRUE and FALSE are also defined in exec/types.h. VOID Void. APTR A generic pointer for multiple purposes - Arrays. STRPTR A pointer to a null-terminated string. IPTR Really important in AROS, the only way to declare a field that can contain both: an integer or a pointer. </pre> if you want to write really portable app, you may be interested in standard datatypes defined in C99: int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, intptr_t, uintptr_t. They are all defined in inttypes.h include file. In exec/types.h the following short-cuts are typedef'd. They are used often in AROS, so you should nearly always include exec/types.h and soon only they will be removed from sys/_types.h include, all types are now defined in include files named aros/types/xxx.h. (Preparation for C library split; sys/xxx.h include will only be available there when compiling with POSIX C library) Compiler specific types, like int and long might change their size. In case of AROS, similar to linux, int remains 32 bit whereas long grows to 64 bits in size. If you use Amiga-like data types, i.e. BYTE/UBYTE, WORD/UWORD, LONG/ULONG and QUAD/UQUAD or the C99 standard types (uint8_t and so on, see stdint.h include) then you should have less issues to solve than by using types without size guarantee. Of course, all pointers grow to 64 bytes using 64bit cpu. Most of the code can be just recompiled and will work. In rare cases, where e.g. pointers are casted to integers, a special care must be taken. Especially in the cases, where pointer is casted to LONG/ULONG (this code will break on 64 bit AROS) e.g. '#define IPTR ULONG'. With compiler delint patches which the majority of them are simple casting issues to make the compiler happy. Notice some of the changes involve introducing double casts. In very recent versions of GCC. Yes, the bulk of the double casts are for converting 32 bit addresses (ie from a 32 bit PCI DMA address register) to a 64 bit pointer. First cast is to IPTR (to expand to 64 bits, and prevent sign extension if the address is above 0x7FFFFFFF), and then to APTR. ULONG != IPTR except on 32bit .. so if you need to store pointers make sure and use IPTR and not ULONG (which some old code does). For this reason things like Taglist elements are 64bit (since the tag data can be a pointer). If your passing items on the stack you should use the STACKED attribute to make sure they are correctly aligned (on 64bit all items on the stack are 64bit..) There is more issues like using "== 0L" causes problems. ===Endian=== *BE *LE Use the macros from <endian.h> instead making a guess based upon architecture defines <pre> #if _BYTE_ORDER == _BIG_ENDIAN #elif _BYTE_ORDER == _LITTLE_ENDIAN #else + #error <whatever.h> - Byte order for this architecture is unsupported! </pre> ===SVN and GIT=== If you want to help develop AROS OS itself, you can * view current GIT/SVN entries [http://aros.sourceforge.net/ Aros Org website] or [https://github.com/aros-development-team/AROS Github], [https://github.com/ezrec older ezrec mirror], [https://github.com/michalsc/AROS/ older mirror], [https://trac.aros.org/trac/timeline TRAC], [], * awaiting update [http://repo.or.cz/w/AROS.git git repo], [http://www.ohloh.net/p/aros/commits ohloh] or [https://svn.aros.org/svn/aros/trunk/ svn repo] and access [Git version git://repo.or.cz/AROS.git here], * deprecated [https://www.gitorious.org/aros/aros/commit/a7fda9e ARIX commits] or [https://gitorious.org/aros/aros GIT old] If you have SVN access (early 2015 introduced a new SVN server, create a new account at trac aros org) and/or have obtained the source [http://aros.sourceforge.net/download.php AROS site] - you can compile the current build tools/environment using: > make development and follow this [http://aros.sourceforge.net/documentation/developers/compiling.php#building procedure] or [https://github.com/apiraino/aros_guide Guide] https://trac.aros.org/trac#Developing If you plan on contributing back changes, please post information about such changes first on this [http://mail.aros.org/mailman/listinfo/aros-dev/ mailing list] for more experience developers can validate whether they are correct. Then there are the nightly build machines. They svn update before the build and run configure as one of the next steps. autoconf might be added to the nightly build scripts. Our build relies on packages downloaded from Internet (SDL for example) - it always worked this way. The minimal requirement (when just building core AROS) is binutils and gcc. If you build contrib as well, you need many more packages to be downloaded. https://gitorious.org/aros/aros/commits/crosstools-II git://gitorious.org/aros/aros.git Branch crosstools-II there is only one commit on top of ABI_V1 <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-x86_64 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-x86_64 </pre> and <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-i386 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-i386 </pre> build OK. :''More information: [[Aros/Developer/Maintainer|AROS Maintainer Docs]]'' ===SDI Calls=== Integrate the 'SDI'-headers to allow easier porting to all amiga-like platforms. <pre> PUTCHARPROTO( PutTheChar, char c, struct SPrintfStream *s ) { // REAL CODE } </pre> have "SDI_compiler.h" and "SDI_hook.h" included its more organized like #include SDI/SDI_hook.h than #include SDI_hook.h option 1 --- i also use when back porting from amiga's.. <pre> #ifdef __AROS__ #include SDI/SDI_hook.h #else #include SDI_hook.h #endif </pre> also you can add the -i include/sdi/ location if you do not want to add or edit any files. Defining HOOKPROTO to IPTR name(struct IClass * cl, Object * obj, Msg msg); solved the problem A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. examine compiler/include/aros/symbolsets.h (AROS_LIBREQ) compiling mui stuff for aros setting -std=gnu99 is necessary (i have had -std=c99 most of the time). ===Locale with Flexcat=== Most languages have a locale, but not every app is localized, the only thing needed is to translate the "catalog" files. It is a case of locating the correct catalog and saving the translated version. For every app that lacks of your language catalog and is localized anyway, you should find (in the sources) files related to locale: * file.cd = catalog descriptor, contains base msg, with internal language (usually english) * language.ct = catalog translation, contains every translated msg, indexed as in the file.cd. Compare with other localized apps... Then, "make my_app-catalogs" should create and install your translated catalogs. ex : for, saying, sys:prefs/wanderer: on root of AROS sources, type: "make workbench-prefs-wanderer-catalogs" then (if you changed the .cd file): "make workbench-prefs-wanderer" For apps not localized, you have to adapt their code to support it, if it is possible... noticed the original .cd file has many (//) strings at the end of any voice, so added them also to the .ct file. That (//) is only for cd files. I'm highly recommending to use FlexCat for updating ct files, e.g. like this: flexcat app.cd deutsch.ct newctfile deutsch.ct You'll get error checking and new entries are marked in the resulting ct file. When editing .ct files, only change those lines containing translation and perhaps version string, nothing else. The rest is up to the relevant tool, flexcat. In order to update your translation, type in the following in your shell: flexcat xyz.cd xyz.ct NEWCTFILE xyz_upd.ct COPYMSGNEW This way you will not only make sure you have correct translation file but flexcat also pre-fills newly added strings with "*** NEW *** text. Even better tool for checking cd/ct/catalog files is catcheck, but this one is sadly only available for AmigaOS/68k... Some languages have variations, like portugues from portugal and portugues from brasil differs... This is the way to go. I will have a look at language files, but basically if those two languages differ you have to do two separated set of translation files, yes. (you could create a brazilian slang language localization too) * At system level localization for one language is a dot language file. (ex: locale:languages/klingon.language) * At app level localization is a dot catalog file (ex: locale:catalogs/klingon/system/libs/dos.catalog) * At sources level, the dot ct file, and "$language" dot cd files and some building framework. (ex: catalogs/my_app.ct catalogs/klingon.cd catalogs/mmakefile.src support.c support.h) Please, use Flexcat to generate CT files: FlexCat wanderer.cd NEWCTFILE=deutsch.ct Then fill the first 2 lines with something useful: <pre> ## version $VER: wanderer.catalog 1.1 (9.2.2006) ## language deutsch </pre> You can even update the CT-File: (This adds the new strings) FlexCat wanderer.cd deutsch.ct NEWCTFILE=deutsch.ct To compile a catalog you only need the .cd file and your translation (.ct file): FlexCat multiview.cd deutsch.ct CATALOG=MultiView.catalog [http://murks-ide.svn.sourceforge.net/viewvc/murks-ide/trunk/src/Catalogs/flexcat_linux?revision=100 Linux version of FlexCat] : [http://aros.sourceforge.net/documentation/developers/app-dev/localization.php#localization-for-non-developers More information] A script which compares the required version (i.e. the version which an application/module etc. tries to open) with the version of the existing CT files. The result is in this table: https://github.com/aros-translation-team/translations/wiki/Progress The following cases are highlighted: n/a i.e. CT misses at all version in existing CT file is lower than the required version It might be a bit difficult to participate if you haven't worked with Git before but alternatively you can send your CT files to our Slack channel. When the ct file has been generated via flexcat (flexcat keyshow.cd NEWCTFILE=spanish.ct) it has the following header: --------------------------------------------------------------------------------------------------------------- ## version $VER: <name>.catalog <ver>.<rev> (04.01.2021) ## language nolanguage ## codeset 0 ; --------------------------------------------------------------------------------------------------------------- Those values <ver>.<rev> are the version and revision of the CT file for the languaje or are the values of the application being localized? The <ver> part must match with version which the application tries to open. You can find the value either in the column "Required Version" in the table which I've linked above, our you can look in the git repository. For keyshow it would be https://github.com/aros-translation-team/keyshow. You can find in the file "catalog_version.h" the right version number. The <rev> part starts for new CT files with 0 and should be increased every time the CT file is updated. Updated several files and created a few more that were missing on the spanish catalog. The catalogs are in Git repositories at https://github.com/aros-translation-team a) You tell me your Github user name. I'll invite you. You can work directly with the Git repositories. b) You create Github forks of the catalog repositories and create pull requests. c) You send the CT files to mrustler gmx de ===C Utils Misc=== The AROS source uses at several places the __DATE__ macro to fill the date entry of a $VER tag. Problem is that c:version doesn't understand that date format (e.g. "May 21, 2011"). As a result the output of e.g. > "version c:shell full" contains "(null)". Is extending the version command to understand the format of __DATE__ the right solution for that problem? AmigaOs compilers should use __AMIGADATE__ macro or similar form, if it isn't implemented it could be emulated in makefile: -D__AMIGADATE__=\"$(shell date "+%d.%m.%Y")\" BTW. I think DD.MM.YYYY is better format than "Month DD YYY" because "Month DD YYY" is not localized in any way. "strnicmp" shouldn't work with NULL pointers The Situation: compiled a linklib using c++ object files (using the c++ cross compiler). compiled a C stub that uses the linklib (using the c++ cross compiler). Try to link them together (using the c++ cross compiler) with C object files (using the normal target c compiler) that need to use -nostartup = cant do because using the c++ files pulls in arosc (for stdio etc.) - so wants to have the autoinit stuff present. What can I do about this?? If it is possible to manually open it then what do I need to do exactly? === ENV === The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. 99% of the time that statement is true (not required) for pretty much every file in ENV: or do people change their default icons - and prefs settings - every boot? There seem to be a bad habit of late with developers changing things to reflect their own personal preference when the change isn't actually necessary - It would be nice if people could refrain from doing that in the tree without at least discussing it on the dev-list first (and with good reasoning unless they committed said work in the first place..) We're not keen on the pollution of the "S:" dir: it's meant to be for scripts. What's wrong with "ENV:"? Only the fact that it takes up RAM. I understand that for PCs with several gigabytes of RAM this is irrelevant. But let's remember about other machines. The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. How about implementing in the style of HappyENV then? RAM-disk handler that falls through to reading from ENVARC: if there is no such file stored in it already. Removes RAM usage for unchanged files, removes the need to copy ENVARC to ENV in startup-sequence. Shouldn't be too hard to make from AmberRAM, or even just extend AmberRAM to provide this service. Is it feasable to build a special version of AmberRAM handling ENV: that will try and copy the requested file from ENVARC: if it isnt found in ENV: ? Additionaly it could mark closed "files" as untouched - and expunge them from ENV: after a period of time to free up additional RAM:, or when the system is running low on free memory? Silenty disappearing files may not be a good plan. Would be nice if the following would work: ASSIGN :ENV SYS:Prefs/Env-Arc ADD ASSIGN :ENV RAM:ENV ADD Where new files put in ENV: end up in RAM:ENV, and opening files looks in RAM:ENV first, then SYS:Prefs/Env-Arc Well - that's essentially what im proposing but without the assigns - or need for a RAM:ENV directory. Adding it as a feature of AmberRAM sounds like the most memory efficient way (one handler to load in RAM) but that's only if it is possible to make it handle ENV: additionally to RAM:, and if it is even possible to add the proposed functionality (...and how to make it enable it when accessing ENV:). ===(AS)MP support=== If one has to recompile software for SMP multi core, is there any thing special one has to do to get software to run? Use task.resource if you need to query information about what tasks are running, and clear msgports completely when they are allocated. Most code should not need Forbid. Use Semaphores, Messages etc. to sync your own code. Accessing system structures is a different thing. Use the proper API whenever possible. How single structures will be protected in the future is still a moving target, at least it is not documented. And you should never use undocumented stuff Ideas on for SMP multi-core Another suggestion is ... Forbid/Permit function calls are meant to halt multitasking so as no other task could intervene with what ever the calling task is doing, e.g. setting semaphores. Disable/Enable calls are meant to halt interrupts and as a side effect they also halt task switching. One option is to make it compulsory to protect shared resources with semaphores and forbid the use of simple Forbid() calls as to protect something. Setting semaphore should be done if possible with atomic instructions (check and alter in one instruction). Or make the second concurrent ObtainSemaphore call halt the second calling task and force if possible a task switch which ever gives better results. Semaphores could store the owning tasks task pointer instead of boolean to make things easier. As long as the CPU initiates the DMA transfers through the OS, and the OS ensures that the transferred memory is within the region accessible to the user initiating the transfer, everything is fine. The CPU is the conductor, and the CPU by that has the control of which DMA transfer is initiated and which is not. All you need to do is to write device drivers reasonable. Hint: CachePreDMA and CachePostDMA exist. All the Os has to do is to verify that the memory regions to be transferred are valid, and prohibit direct access to the DMA control registers from user space. None of these algorithms imply huge costs. The current OS design doesn't really allow virtual memory in first place, Forbid() is again the problem. [http://www.tbs-software.com/guide/index.php?guide=autodocs.doc%2Fmemory.doc&node=1 memory.library API] seem to low level. IMHO the programs should not know how the swapping is implemented. I would just go for one new memory flag MEMF_SWAPPABLE that indicates that a certain memory region or a whole memory pool won't be accessed during Forbid()/Permit() etc. It only solves part of the problem, it only implements virtual memory and not memory protection. For the latter you need to be able make certain memory inaccessible by other programs, some memory read-only for one task and read-write for other tasks, etc. And I think this should be done in the same Address Space in order to avoid you constantly need to swap between different address spaces. So to summarize, if there are programs using this API we may provide a wrapper layer to get them working but I am not convinced this API should be the reference API with whom to provide VM to AROS programs. === Variadic === variadic functions (i.e. functions with an arbitrary amount of arguments). <pre> #include <stdarg.h> [...] char * STDARGS GetKeyWord(int value, char *def, ...) { [...] va_list va; [...] va_start(va, def); [...] va_end (args); </pre> Please keep with using stdarg rather than having va casted to a LONG * type and varargs handled manually. Doing so, prevents tons of casting, where a simple va_arg can be used. So, string = *((char **) args) instead of string=va_arg(va, char *). <pre> #include <stdio.h> #include <stdarg.h> int printf (const char * format, ...) { int retval; va_list args; va_start (args, format); retval = vfprintf (stdout, format, args); va_end (args); fflush (stdout); return retval; } /* printf */ </pre> Couldn't find varargs.h or stdarg.h. and have no use for AROS_SLOWSTACKHOOKS or AROS_SLOWSTACKTAGS. GCC looks for stdarg.h in a different place: /bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/include/stdarg.h Here is a path for a "normal" header: bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/../../../../i386-aros/sys-include/aros/system.h The use of vararg.h isn't supported by newer gcc versions. If you want your code to run on architectures that pass part of variadic arguments in a number of registers you need to use AROS_SLOWSTACK macros. Otherwise your program will not work on powerpc and x86_64 ports. Of course the SLOWSTACK stuff is not needed in a function that can use va_list, va_start, va_arg and va_end. It's only needed if you want to write functions like DoMethod or similar. #include <stdarg.h> should be enough no matter if you do cross or native compiling. If it does not work, something is wrong and should be corrected. Stdarg.h is here, Development:lib/gcc/i386-aros/4.2.2/include/ ...which is part of the compiler's default include paths. In other words, #include <stdarg.h> works out of the box, indeed. (sorry, I should have just tried it before invoking "search" or "find"...) furthermore, myprintf() as shown above won't work, because... printf(format, args); ...is wrong - the second argument does not match printf() prototype, it expects a argument list, but args is of type va_list (obviously) - so one has to use... vfprintf(stdout, format, args); ...instead, just like in the original printf(), and add fflush(stdout). additionally, one could use... int myarg = va_arg(args, int); ...between va_start() and va_end() to access individual arguments, where each call to va_arg() returns an argument casted to the desired type (here: "int") from the list given (here: "args") and advances to the next one. wrapping up vfprintf() and modifying the format string now is a major speedup! no more backslash-n typing! this has been haunting me for years! On MOS and AmigaOS, the NewObject variadic function is kept in the static library. It takes most of the parameters on the stack - thanks to that the implementation of NewObject calls the NewObjectA function. Everything works perfect, and the typical MUI macros may be easily used. This, however, is not the case when you compile for AROS. Here, NewObject is a variadic macro, not a function. Thanks such approach we do not need any custom compiler in case of systems, where the arguments of variadic functions are passed partially through registers and partially through the stack (This is the case of PPC and x86_64, this is also the reason why both OS4 and MOS require specially patched compilers). Since NewObject is a macro, the gcc's preprocessor expects the list of macros arguments enclosed within parentheses. In MUI macros it is not the case. Imagine the following test code: <pre> #define foo(a,b) ((a)+(b)) int loosy_function(int a, int b) { return foo(a,b); } </pre> This will compile and work, but the following piece of code: <pre> #define foo(a,b) ((a)+(b)) #define END ) int loosy_function(int a, int b) { return foo(a,b END; } </pre> will fail with the error: unterminated argument list invoking macro "foo" There are two ways of fixing your issue. Either create your new objects outside this huge MUI constructions, and in there use just a pointer, or get rid of the "End" macro and exchange it with "TAG_DONE)". Badly written software is, for example, casting va_list to an APTR or even doing so as if va_list were a plain table of function arguments. Such code needs to be fixed because it has very few chances to work anywhere but on author's machine ;) The problem is nOt that they assume sizeof(APTR) == 4, its that they often do not use APTR, and use ULONG to store pointers exclusively. If the code used APTR/IPTR as it should - most of the "problems" wouldn't exist. It would also help if people would start using variadic arguments properly. Many coders do assumptions which shall never be made. Instead, they should consider using stdarg.h file and all the va_* functions :) ===ABI=== In the head of our SVN repository there are now only 3 directories: <pre> admin/ branches/ trunk/ </pre> We have added two extra dirs there: tags and imports As discussed when we branch ABI V0 and [[Aros/Developer/ABIv1|ABI V1]] it would also be good to introduce tags. Normally this is done in a directory in the repository called tags. Currently we don't have this directory there. (We do have branches/tags that is a hack I have done because one doesn't have write access in the top directory. I think this directory is not clean and should be removed). The second directory I would introduce is an imports directory for implementing vendor branches as discussed in the svn [http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html book]. Currently we use code from several different projects and that code is stored inside the AROS tree; we seem to have problems with keeping this code up to date and merge our changes upstream. Maintainers of up stream projects like the MUI classes etc. have complained about this (to put it lightly). Introducing these vendor branches would make it easier to see what changes we have made and make patches to be sent upstream and make it easier to import newer upstream versions of their code. Although can't "copy" the vendor branch into the main branch because it's already there, so start with a "merge". Yes, the first step to make the code already in the repository compatible with the vendor branches will be the most difficult. The best way to do it the following way: * first import the version on which the current AROS code is based into the vendor branch * then import the new version over it in the vendor branch * finally merge the difference between these two version in the AROS code present in the repository. For example, place NList directly under vendor and not in a subdirectory like "contrib/zune/classes". Actually after we have a stable [http://aros.sourceforge.net/documentation/developers/specifications/drafts/abiv1.php ABIv1 (2012 or later)]. We need to move away as much as possible from the contrib directory to some other repositories. The reasons are ... * The AROS repository should be for the core AROS code. * other contrib projects should be tried to be compiled for all Amiga-like OSes. * The release scheme for AROS and the other programs should not have to be aligned. * Binary versions should be provided on aros-archives and on aminet and/or OS4Depot to install them. (Some clever programs should maybe be provided to make the life of distribution developers easier). * avoid parallel forks of programs for AROS and the other amiga OSes. If there is really a need for a place for hosting AROS projects we may investigate setting up such a server but then including bug tracking, governance, maillist, etc. for each project separately. I personally think there are already enough places like sourceforge, google code, savannah, etc. where people can go for hosting such projects. ==Links== * http://amigadocs.hokstad.com * http://amigadocs.hokstad.com/doku.php?id=dev-links * http://www.liquido2.com/tutorial/index.html * Amiga(TM) OS4 has a [http://www.ast-workshops.co.uk/os4pg/ workshop] page and hope to produce a [http://amigaworld.net/modules/newbb/viewtopic.php?topic_id=31117&forum=42#549091 book] soon. [http://www.solie.ca/articles/map/map.html Brief Guide]. In the future...? *AROS 64bit - SMP, Vulkan with OpenGL compability layer *AROS 32bit - keep for historic reasons What would you like to see implemented in AROS? ABIv1 completed, SMP (x86_64), SendMsg()/GetMsg() to support memory protection between target and destination, in that order. Michal Schulz and Jason McMullan have been toying with the question "What are the minimal changes needed to the AmigaOS 3.1 API to support SMP"? The answer so far seems to be "few, but subtle". For example, SysBase->ThisTask is no longer meaningful on SMP, but FindTask(NULL) is. Disable() and Forbid() are shockingly bad on performance, but adding a spinlock semaphore mode to SignalSemaphore will help new code on SMP. Leveraging a 'common' OS with a lot of machine support (Linux, MacOS, Windows, QNX, etc.) is something that AROS has been doing for quite a long time, and it is the biggest strength of AROS. This AROS experience and programming model, in the same way the Google's Android layers on top of Linux, or MacOS X layers on top of the Darwin/BSD kernel, as a first step * The graphics + layers subsystem could be implemented as a shim on top of a OpenGL ES implementation (ie on any modern Linux system, or the RaspberryPI's hardware, MacOS X, etc). - This also allows every window to be on its own 3D surface with backing store, allowing Wanderer (or a Commodity) rearrange/zoom/animate app windows without having to send a pile or refreshes to them * Use OpenAL as the sound backend * AROSTCP would be a thin layer over the native OS's TCP/IP stack * dos.library, poseidon.library, and input.device would be slim shims over the native APIs * If we move to loading all libraries' into the application's task space, instead of a single global instance of the library, this will allow SMP and MMU more easily. - Yes, it will require a lot of work in the libraries to make this transition - Yes, I do think it will be worth it in the end. * A 'fat binary' install format (or, maybe LLVM bytecode) that can be 'flattend' to the target architecture on installation. So, what would this 'AROS of the future' look like? * AmigaOS 3.x style API, with certain 'fundamental changes' to message passing * Uses the underlying OS' device drivers, so more AROS developer effort can go to user-visible features and bugfixes * Allows AROS applications to run side-by-side with the OS's native apps And why would anyone want to program on such a system? * AROS applications would run on any system that has the AROS Framework installed * AROS applications are pixel-for-pixel the same on all platforms. * Develop with the knowledge that you are guaranteed OpenGL and OpenAL, and the rest of the AROS Framework an option for mmake to dump its dependency of metatarget in a graphviz[*] input file. This should make it possible to visualize the dependencies and hopefully be inspiration for cleaning up some mess, circular or unneeded dependencies and so on. AmigaOS gcc 9 [https://franke.ms/amiga/gcc.wiki Old versions] able to create binaries for AmigaOS and [https://eab.abime.net/showthread.php?t=93813 Upgrading gcc versions] ==References== {{reflist}} {{status|50%}} {{BookCat}} cns6icscq65bgb30auhv36k881skbgq 4668982 4668962 2026-09-05T18:29:52Z Jeff1138 301139 4668982 wikitext text/x-wiki {{ArosNav}} ==A technical overview of AROS== Google translation [http://translate.google.com/translate?hl=en&sl=auto&tl=de&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs German], [http://translate.google.com/translate?hl=en&sl=auto&tl=fr&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs French], [http://translate.google.com/translate?hl=en&sl=auto&tl=it&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Italian], [http://translate.google.com/translate?hl=en&sl=auto&tl=es&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Spanish], [http://translate.google.com/translate?hl=en&sl=auto&tl=hi&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Hindi], [http://translate.google.com/translate?hl=en&sl=auto&tl=zh-CN&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Chinese], [http://translate.google.com/translate?hl=en&sl=auto&tl=ru&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Russian], [http://translate.google.com/translate?hl=en&sl=auto&tl=pl&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Polish], [http://translate.google.com/translate?hl=en&sl=auto&tl=pt&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Portuguese] {{Uncited}} AROS,<ref>[http://aros.sourceforge.net/download.php References and sources]</ref> like AmigaOS (TM), is a [[w:Message passing|message-passing]], [[w:Preemption (computing)|preemptive]] [[w:Multitasking|multitasking]] [[w:Operating system|OS]]. It uses [[w:Reentrant (subroutine)|re-entrant]] shared libraries to save memory space. AROS is based around an executive library kernel (Exec) and two other libraries: * Exec (the "kernel", which is not a kernel in the modern sense), * Intuition (graphics and GUI, integrated into the system) and * AmigaDOS (Disk Operating System, the Metacomco's Tripos modified to work with Exec). The design philosophies of AmigaDOS and Intuition are rather different, the former adopting a C-like API and the latter creating an [http://www.basden.demon.co.uk/amiga/amiga.oo.html object-oriented], message passing aware environment for the programmer. The system base is the only absolute address in AmigaOS (located at 0x00000004) this does differ with AROS as AROS SysBase is automatically provided (no $4) but everything else is dynamically loaded. The OS is well known for delivering high performance due to its close connections with the hardware, while simultaneously having the flexibility to support re-targetable graphics (Cybergraphics) and retargetable audio subsystems (AHI). : Diagram showing relationships of libraries to system needed Remember, AROS is a [http://en.wikibooks.org/wiki/Aros/Developer/ABIv1 research] operating system, and while all contributions to the base AROS code are welcome, please contact the dev list first for any core changes. Writing applications for AROS does not have this requirement. While AROS appears and feels almost feature complete, it is still [[Aros/Developer/IncompleteAPIs|missing a small number of functions]] from the Amiga API. [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1201 This thread provides] information for setup, [http://www.aros.org/documentation/developers/index.php documentation] and whether you are interested in core OS changes and/or writing/porting software apps *you compile directly under AROS, which can be running on either real hardware, virtual hardware *in hosted mode under linux/window, cross-compile from that host OS (save your files as ISO-8859-15 encoding instead of UTF-8) [https://github.com/BlitterStudio/aros-compiler-docker Docker images] '''The repository''' for 64bit and 32bit ABIv1 all hardware platforms is [https://github.com/aros-development-team/AROS current development version]. There are many forks of this so that developers can work on their own and forward changes at a later date as discussed on the dev forum 64bit PC is one of two hardware platform with another fork called [https://github.com/deadwood2/AROS abiv11] which is used for Aros One x64 PC 32bit PC is the other fork [https://github.com/deadw00d/AROS/tree/alt-abiv0 repository for current stable PC version ABIv0 with backported ABIv1 features is located which is used on AROS One and Icaros x86 32bit based distros] this is for historic reasons Any [https://github.com/aros-development-team/AROS/issues bugs / issues can be added for ABIv1 issues]. The two individual PC forks have their own issues tab on their github webpages We have a [https://arosdevteam.slack.com/archives/CUFV48U3H slack here], discord on [https://discord.gg/UKp9qdEBuQ Discord@AmigaDev], ==Software Development for AROS== ===Programming languages=== ====Common to all==== 'The Developer Environment', which primarily supports C/C++ code, there are other programming languages available for AROS: '''Scripting''' :[[Aros/User/DOS|DOS]] :[[Aros/Developer/Docs/LUA|LUA]] :REXX [[Aros/Developer/Docs/Rexx|Regina (AROS' ARexx)]] ====Needs to be compiled/ported==== ::[[Aros/Developer/Docs/LLVM|LLVM]] ::Python [ Info], [], ::[https://ae.arosworld.org/index.php?board=11.0 FreePascal FPC Aros-Exec thread], [https://archives.arosworld.org/index.php?function=browse&cat=development/language fpc arm here is very old and will not work], FreePascal for AROS has its own [http://fpcaroswiki.alb42.de/ Wikibook], ::[http://sourceforge.net/projects/xamos/ X-Amos Basic] ::[http://sdlbasic.sourceforge.net/ SDLBasic] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[[Aros/Developer/Basic/Basic4SDL|Basic4SDL]] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[http://alvyn.sourceforge.net/ Alvyn] ([http://www.dusabledanslherbe.eu/AROSPage/MISC.14.html download]) ::[http://www.airsoftsoftwair.com/ Hollywood when enough users warrant a port - paid one time fee language] ::[[Aros/Developer/Docs/E|AmigaE Portable E]] ====Hardware Restricted==== '''Basic''' :[http://amos.pspuae.com/AmosProManual/contents/c1.html '''Amos Pro'''] [http://amos.pspuae.com/index.php?action=forum#1 compatible] [http://www.amigacoding.com/index.php/Main_Page commands] (all incomplete) :'''Blitz Basic''' [http://aros-exec.org/modules/newbb/viewtopic.php?post_id=46537#forumpost46537 none on AROS] :: [http://www.amiforce.de/main.php Amiblitz] on amiga(TM) emulator :'''Amiga Basic''' :: [ ACEBasic] '''Misc''' :Ruby [http://www.ruby-lang.org/en Info]/[https://archives.arosworld.org/index.php?function=browse&cat=development/language Ruby 32bit PC], ===Where to get the C/C++ Environment=== If you want to develop for AROS, its generally easier to be running linux hosted AROS development environment especially for C++, cross compiling the code. That's how most developers now are doing it. g++ is used to compile owb web browser as well as some other AROS software. If you were hoping for a rich set of C++ libraries or classes defined for the OS feature set, you might be disappointed. AROS Native compiling is possible, but you're much more likely to run into the odd bug(s) in the dev environment since it gets little testing and fixing by other developers. Is there a sftp software or scp over ssh available? Maybe. At least the security part would be handled by [https://github.com/jens-maus/amissl amissl] [https://archives.arosworld.org/index.php?function=browse&cat=network/misc port]. [https://github.com/BlitterStudio/dopus5 DOpus5] has recently added sftp support. See here for a [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1974&highlight=ssh&pid=12073#post_12073 ssh scp client] [https://arosdevteam.slack.com/join/shared_invite/enQtOTc4Mzg0NDIzNzQ0LWQ2NWZmNmMwNGIwNGEyNTgxNzU3MGFjMTk3ZThmOTQ1MTVjMzhmNTllYWQ0ZTUxMjBjMGE0Y2VjMDJmNTc5MzI#/shared-invite/email Slack Dev Forum] ====Cross compilers from Windows or Linux==== *Windows WSL2 walkthrough can be [https://arosnews.github.io/how-to-cross-compile-aros-hosted-wsl/ found here] you want to build AROS. No problem. Here are instructions for PC 64-bit: https://github.com/deadw00d/AROS/blob/master/INSTALL.md Here are instructions for PC 32-bit: https://github.com/deadw00d/AROS/blob/alt-abiv0/INSTALL.md And as always has been the case you can use the contrib archive to 'obtain' the development directory which contains the /native/ AROS gcc compiler and tools. That compiler is used to build AROS itself but can be used outside the AROS build process by providing --sysroot with indicated directory to cross compile for AROS. =====Older guides for Linux hosted compiler===== Please install these packages before moving to next step. Below is a reference list for Debian-based distributions. Reference build system was Ubuntu 18.04/20.04 amd64. subversion git-core gcc g++ make gawk bison flex bzip2 netpbm autoconf automake libx11-dev libxext-dev libc6-dev liblzo2-dev libxxf86vm-dev libpng-dev gcc-multilib libsdl1.2-dev byacc python-mako libxcursor-dev cmake zsh mingw64 Do all of these operations under home directory of your user or another directory where your user has write permissions. Specifically, in a section "Linux-i386", be sure first to build the cross-compiler (toolchain-alt-abiv0-i386) and only then AROS itself (alt-abiv0-linux-i386). Clone & build <pre> $ mkdir myrepo $ cd myrepo $ git clone https://github.com/deadw00d/AROS.git AROS $ cd AROS $ git checkout alt-abiv0 $ cd .. $ cp ./AROS/scripts/rebuild.sh . $ ./rebuild.sh </pre> Now to the build selection below - Linux-i386 Select toolchain-alt-abiv0-i386 - Select alt-abiv0-linux-i386 (DEBUG) Start AROS by: <pre> $ cd alt-abiv0-linux-i386/bin/linux-i386/AROS $ ./Arch/linux/AROSBootstrap </pre> Pc-i386 Select toolchain-alt-abiv0-i386 (if not built yet) - Select alt-abiv0-pc-i386 ISO image available in alt-abiv0-pc-i386/distfiles Now that we have linux-hosted build, we can resume native (option 2). Run ./rebuild.sh and selection option 2. Wait until it finished, then: <pre> $ cd alt-abiv0-pc-i386 $ make </pre> Now <pre> $ make bootiso </pre> Now, your compiler is located in toolchain-alt-abiv0-i386 directory and named i386-aros-gcc. Includes are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/include and libraries are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development.lib. This is how then can be passed to the compiler: /home/xxx/toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot /home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development -L/home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/lib ../toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot bin/linux-i386/AROS/Development local/helloworld/helloworld.c -o local/helloworld/helloworld Another method was using Debian like distros and download the gimmearos.sh script (on [http://archives.aros-exec.org/index.php?function=browse&cat=development/cross aros-archives]) to setup the developer environment by downloading necessary packages ... The gimmearos script is a good start in that direction, building the cross compilers and hosted AROS environment, but gimmearos.sh might be out of date or not be completely compatible with any given linux distro. In order to do that, you have to compile AROS yourself. Download AROS source archive not contrib. Compile AROS by entering the main directory ./configure make ([http://aros.sourceforge.net/documentation/developers/compiling.php More on compiling AROS]). The result will be a basic AROS system without development tools. To compile C++ on Linux, type 'make gnu-contrib-crosstools', creating the cross-compilers in ./bin/linux-i386/tools/, named i386-aros-gcc, etc. '''Note''': Currently, to make the cross compilers usable copy 'collect-aros' from tools/ to tools/i386-aros/bin/. At the moment the cross compilers if used from the Linux command line will only find it when it's there. If you want to compile native compilers (the Developer Environment), type 'make contrib-gnu-gcc', creating native compilers in AROS' System:Development/bin directory. When the output needs to be stripped <code>--strip-unneeded --remove-section .comment</code> The Obj-C backend should build out of the box. Open contrib/gnu/gcc/mmakefile.src and search for the line which contains "--enable-languages" and add "objc" to the list of languages that follows it. --enable-languages=c,c++,objc Better make it—enable-languages=c,c++,objc,obj-c++ ObjC++ is broken as soon as you try to use exceptions, but that might change in future GCC versions and it does not hurt having it there already. Do you need a cross-compiler or a real compiler? In the first case you can get away with just downloading the proper gcc archive, apply the patch and proceed with the normal gcc build. In the case of a real cross-compiler then when downloading the contrib sources, also need to download the normal sources, place the contrib sources into a directory called contrib, need to install autoconf+automake+perl+python, call ./configure, cd into the subdirectory and type make. to rebuild GCC with host == build == target == i386-pc-aros. So just get the vanilla sources and apply the patches without bothering about the build system? [https://vmwaros.blogspot.com/2019/10/a-pre-configured-development-machine.html pre-configured VM environment vmware virtual machine to develop AROS and AROS software] '''64 bit''' '''32 bit''' A good option for multiple OS is [https://axrt.org/index.php?tab=download-aros AxRuntime lets developers compile their Amiga API-based applications as Linux binaries being able to utilize modern development tools available on Linux, like IDEs, debuggers, profilers, etc] ====Native compilers for AROS==== Namely gcc for C or g++ for C++ are supplied with the [[Aros/Developer/Docs#The Developer Environment|Developer Environment]], which is already '''setup''' and part of any current AROS distribution like AROS One or the nightlies * Current GCC 6.5 (32bit) though moving to 10.5 and 15.1 (64bit) * Older software components. GNU GCC 4.x GNU BinUtils, GNU Fileutils 4.x, GNU Textutils and others usually deprecated On single partition systems and the Boot ISO, the AROS Developer environment is installed under "SYS:Development/". Systems with multiple partitions - such as a Work: partition - tend to install it to there instead, however it can be installed manually to any location. Please remember, if moving, that you will need to correct the Development packages 'install location' env variable to point to the new locations root - look in SYS:S/startup-sequence. <pre> Assign Development: SYS:Development Assign C: Development:bin ADD </pre> In the aros build instructions. you need to check out contrib and/or ports into your AROS source directory, as subdirs. then, assuming you are building in an external build dir, as you should, you simply configure and "make contrib" for instance or whatever submodule you might want to build. ===Beginners Tutorials in C C++=== As AROS is [http://eab.abime.net/showthread.php?t=29856 C based] API compatible to AmigaOS 3.x, so most of the information on programming C on the Amiga applies to AROS as well. Please note that there is a lot of AmigaOS 1.3 (1985-1989) and [https://www.markround.com/amigaguide AmigaOS AOS 2.x (1990-1992)] information around but OS3.1 is recommended but limited in amount. Brief overview of what is required to write AROS Applications # Using [[Aros/Developer/Docs/Libraries/Intuition|Intuition]] for basic screens/windows # Using graphics within windows via 8bit [[Aros/Developer/Docs/Libraries/Graphics|graphics]] and so onto 15-16-24bit [[Aros/Developer/Docs/Libraries/CGFX|cybergraphx]] # Load and save work to [[Aros/Developer/Docs/Libraries/DOS|dos]] disk drives # Using the [[Aros/Developer/Zune|ZUNE GUI Environment]] Writing native games require this extra information # Using [[Aros/Developer/AHIDrivers|AHI audio hardware independent API]] # Using USB joystick/joypad with the Poseidon USB stack through [[Aros/Developer/Docs/Libraries/LowLevel|LowLevel]] library Additional features that could be added later # Adding additional [[Aros/Developer/Docs/Libraries/Locale|Locale]] language translations to your program # Adding a [[Aros/Developer/Docs/Rexx|AREXX/Regina]] port to your application # Executing Amiga(TM) [[Aros/User/DOS|DOS]] commands from your application # Using [[Aros/Developer/Docs/Libraries/Icon|icons]] (.info files) and icon tooltypes (stack, version, and program startup options) # Local couch or IP based SANA2 networking co-op multi player gaming support Most AmigaOS programming books are nowadays very much out of date as most are from the late 1980s and do not cover later amigaOS releases like 3.1 for example, Rob Peck's book "Programmer's Guide to the Amiga". The Amiga ROM Kernel manuals aka RKMs like Libraries (3rd edition), Devices (), the AmigaDOS manual (3rd edition) and the Style Guide may have their uses. There are some reference examples from AmigaMail and Devcon notes (available again on an Amiga developers CD 2.1). For Arexx then "The Amiga Programmer's Guide to ARexx" by Eric Giguere, which was published by Commodore is useful as well as an "Arexx Cookbook". Curly brackets missing - try SHIFT + ALT + 7 or 0. * Beginners C Guide [http://www.iu.hio.no/~mark/CTutorial/CTutorial.html C Tutorial], * [http://thecguru.com/ C for beginners], * [http://fresh2refresh.com/c/c-basic-program/ C programming basics] for students, * [https://www.edx.org/courses Free Online course] from American Universities * Reference Amiga [http://amigadev.elowar.com/ API reference]. * AROS based c source can be found [[Aros/Developer/Docs/Examples|here]] and lots of example code can be found inside [https://github.com/aros-development-team AROS sources] themselves and from the contrib section of the archives from [https://github.com/aros-development-team/contrib Aros site], and study the AROS applications source code, e.g. the test programs from the Tests drawer (folder/directory). Take a look at the code of some smaller AROS programs might be a better and more up to date When you upload your builds, please write the architecture (like i386-aros, x86_64-aros, armPi-64 etc.) in the archive name and it is also advisable to write in the field "Requirements" what ABI (ABIv1 or for PC forks ABIv11 or ABIv0) ===Compiling C/C++ Code=== Native, although we have a IDE Integrated Development Environment (Murks), it does lack a debugger. Whilst others use a combination of a text editor and shell to edit code. Most though use an AROS hosted on Linux to take advantage of the better GCC tools like GDB and various IDEs. Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w (or F12 and w) within the directory with the source code. Type in sh to change the amiga shell into a unix shell. You can then type in ls (unix equivalent to amiga dir). Take a look [http://en.wikibooks.org/wiki/Linux_commands here] for more commands. For a single file program-name.c or program-name.cpp gcc -o program-name program-name.c or g++ -o program-name program-name.cpp or g++ -o test -Wall -g main.cc texturelib.cpp xmodelib.cc -lsdl -lgl To close the shell, click on the top left-hand corner to close (twice). Once to get back the aros shell and then again to close finally. Use [http://freshmeat.net/projects/cksfv/ cksfv] as a test. Some source code requires the addition of Amiga API libraries, like dos, which you can flag at the compile time as gcc -o julia.exe julia.c -ldos For DOS use -ldos as example and if you are compiling mui codes it will be -lmui or intuition -lintuition. Other missing symbols are due to linker libraries being necessary for linking in functions that aren't in the standard C libraries. For example some source code would need added -lz or -lm or -lpng or -larosc etc. use this in unix line command mode to search for 'search-item' in many .c files (*.cpp for c++, etc.) grep -l 'search-item' *.c If the program is not executable, try using parameter fno-common "Delete #?.o"? Or if you are using abcshell then "rm *.o" :''More information: [[Aros/Developer/Porting software]]'' === How to make Apps have AROS 64-bit specific support code === [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] AROS64 already uses 64bit addressing, it just doesn't setup the MMU for more than 4GB physical memory currently. When porting software to AROS64 it is "mostly" a case of converting ULONG's that are used to store pointers, into IPTR's instead, etc. Another quirk, is making sure items on the stack are the correct size by using the STACKED attribute for them. * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. compiling mui stuff for aros setting -std=gnu99 is necessary, had -std=c99 usually A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. crash which suggest memory corruption. From my experience porting from 32-bit to 64-bit these kinds of errors can happen if a pointer is passed somewhere via ULONG variable. Then half of the pointer is cut. To generate this error, please run AROSBootstrap with -m 1024. This will allocate heap to 64-bit address space which will make these errors immediatelly visible. These types of crashes are hard to debug. Disabled as little code as possible to stop corruption from occurring and then try to read from the code where it can be broken Crashing in tslf_freevec is another symptom of memory corruption and these memory corruptions will manifest differently on different setups. ==Coding conventions== As the AROS core source is a shared developer experience, there are rules regarding structure and style. When it comes to your creating your own app and coding, the structure and style should be your own, i.e. you should enjoy what you do and do it so that you can understand what is going on. ===Layout=== <syntaxhighlight lang="c"> static void 1st_function() { program exit(0); } int main(void) { 1st_function(); 2nd_function(); 3rd_function(); return 0; } </syntaxhighlight> <syntaxhighlight lang="c"> struct Screen * openscreen(void); struct Window *openwindow(struct Screen *screen, const char *title, LONG x, LONG y, LONG w, LONG h); VOID 1st_function(); VOID 2nd_function(); int main(int argc, char **argv) { program return 0; } /* main */ VOID 1st_function() { } VOID 2nd_function() { } </syntaxhighlight> ===General style=== This code is used by many people and therefore you should keep some things in mind when you submit source code: * Keep things simple * Keep the source clean * Always know what you are doing, if not flag it and describe what needs to be done... * Explain clearly/simply what you are doing * Remember that you write code once but that it is read many times by many people ===Comments=== AROS uses some of the comments in the source to generate the documentation. Therefore it's necessary to keep a certain format so the tools can find their information. Other comments are ignored but they should explain what you thought when you wrote the code. If you really can't think of an explanation, then don't write the code a second time like this: <pre> /* This adds 1 to t */ t ++; </pre> What we think of is this: <pre> /* Go on with next element */ t ++; </pre> ===Formatting=== This is only '''IMPORTANT''' if you are going to work on the core AROS code or contrib but not applications which may reside outside like on AROS Archives or other websites. <syntaxhighlight lang="c"> { /* a */ struct RastPort * rp; int a; /* b */ rp = NULL; a = 1; /* c */ if (a == 1) printf ("Init worked\n"); /* d */ if ( !(rp = Get_a_pointer_to_the_RastPort ( some , long , arguments ) ) || a <= 0 ) { printf ("Something failed\n"); return FAIL; } /* e */ a = printf ("My RastPort is %p, a=%d\n" , rp , a ); return OK; } </syntaxhighlight> Looks ugly, eh ? :-) Ok, here are the rules: <pre> If several lines contain similar code, put similar things below each other (see a and b); Put spaces between operands and operators Put braces {}, brackets [] and parentheses () below each other (d) if there is much code between. Brackets and parentheses may be in one line if the code between is small (c) Indent by 4 Spaces. Two indent levels may be abbreviated by one tab. </pre> '''Before committing please normalize the indentation - if you have a mixture of tabs and spaced - please always use spaces, 1 tab = 4 spaces.''' The reasons for this are: # While some editors can use an arbitrary sizes for tabs, it's a bit complicated to tell another editor which tab size was used by the one used to write the code. # Most code in AROS was written this way and your code should look like the rest. # You can print this code on any printer without special tools to "fix" the tabs. # Most editors have smart tabs which do exactly this. If your editor doesn't, write a bug report. If you have a function with many arguments (d, e) you should put the parentheses in lines of their own and each argument in one line (d) or put the first argument behind the opening parentheses (e) and each following argument in a line of its own with the comma in front. The closing parentheses is in a line of its own and aligned with the beginning of the expression (i.e. the a and not the opening parentheses or the printf()). Use a single blank line to separate logical blocks. Large comments should have a blank line before and after them, small comments should be put before the code they explain with only one blank line before them. If you see any TABS in AROS core sources then the suggestion is to "detab the file and commit that separately" either before or afterwards from making functionality changes. Make two commits instead of one. This makes it easier for others to see the real changes instead of having to dig through multiple lines of irrelevant diffs. ===Eliminating Global Variables=== i.e. pass variables to functions (local scope) or classes making it easier to track and debug your code. Any time you find that you need a particular thing in 'a lot of different places', chances are that all those places are conceptually related, and so you can create a class, a namespace, a function, or some other higher-level organizational unit to represent that relationship. This makes the program easier to understand. Bad Designs * All variables are global. * There are no standalone functions, only sub-procedures which act on the global variables. * Every sub-procedure is at least 500 lines to several thousand * Every sub-procedure has more than one task to perform * Copy-paste is preferred to writing methods, AND subtle changes are made in the middle of the code Good Designs * structure program into functions (C or basic) - top-down procedural approach * put in class(es) (freepascal or C++) - the object is fixed and you use methods to access the object <pre>  class String_List  {  private:  list<string> m_List;  // member  public:  void read_strings() { /* read strings into m_List */ }  void print_strings() { /* write contents of m_List to stdout */ }  void sort_strings() { /* sort contents of m_List */ }  void sort_strings_reverse() { /* reverse-sort contents of m_List */ }  void unique_strings() { /* remove duplicate strings */ }  };  int main()  {  String_List myList;  // local  myList.read_strings();  myList.sort_strings();  myList.print_strings();  myList.sort_strings_reverse();  myList.print_strings();  myList.unique_strings();  myList.print_strings();  return 0;  } </pre> This way it is very easy to replace the list with new list for debugging purposes, or replacing the methods without replacing the list, when you want different results. You only have to replace the content of the local variables. So create the structure that matches your data (linked lists, trees, arrays, etc.) and what to do with them (sorting, searching, etc.) <pre> .h usually contain #define #include typedef enum struct extern screen and window definitions (data structures) .c should contains functions and algorithms </pre> One way to look at it is that menu headings act as the .c file and sub-menu headings as functions. When you start a project, you place a couple of declarations in the include file. As the project continues, you place more and more declarations in the include file, some of which refer to or contain previous declarations. Before you know it, you have a real mess on your hands. The majority of your source files have knowledge of the data structures and directly reference elements from the structures. Making changes in an environment where many data structures directly refer to other data structures becomes, at best, a headache. Consider what happens when you change a data structure. Use good variables names to help clarify code and only comment when you need to explain why a certain programming approach was made. You're Refactoring Legacy Code, you see a global, you want to get rid of it. How do you do this? Exactly what to do depends on how the global is used. The first step is to find all uses of the global throughout the code, and get a feel for what the significance of the variable is and how it relates to the rest of the program. Pay particular attention to the "lifetime" of the variable (when it gets initialized, when it is first used, when it is last used, how it gets cleaned up). Then, you will probably make the global a data member of a class (for OO languages), or you will write some get/set functions. Converting to the Singleton Pattern is common, but you may discover that it makes more sense for the data element to be a member of an existing singleton, or maybe even an instance variable. # Create a basic read method, either as a class or a global function. Replace all reads with the access method, but leave the variable defined as a global. # Review each of the writes to the method and extract action functions one at a time. Unless two operations are coded identically in the original code, extract each write access separately. # Change the variable scope from global to local. # Analyze similar action functions to determine if any can be merged, i.e., there are no functional differences in the results of the function, just differences in the implementation details. # Review the calls to the read method and see if a more complex functionality should be applied. Follow the approach for writes and unless implementations are identical, create separate access functions. # Analyze the access functions for duplication. As returning variables by "passing by value" are forgotten, so "passing by reference" is often used instead. The reference is a pointer to the variable so the value is remembered when returned. Alternatives * Hidden Globals * Singleton Pattern * Database or TupleSpace * Context Object * Dependency Injection * Stateful Procedures ==AROS/AmigaOS APIs and Docs== <pre> Library: - Private data structure - Many public access methods Device: - Private data structure - Two (BeginIO/AbortIO) access methods Resource: - Public data structure - *NO* access methods </pre> And, being Amiga OS-compatible, there are exceptions to all of these. ===System Libraries=== The [http://developers.aros.org/ AROS Guide To Libraries] can be used as a guide to individual commands and old Dev Docs are used in application programming. Amiga/Aros styles libraries are very different from windows and linux libs. Typical .so/dll libraries are foreign to most Amiga-like OS *[[Aros/Developer/Docs/Libraries/AROSC|arosc.library]] *[[Aros/Developer/Docs/Libraries/AmigaGuide|amigaguide.library]] *[[Aros/Developer/Docs/Libraries/ASL|asl.library]] *[[Aros/Developer/Docs/Libraries/Bullet|bullet.library]] *[[Aros/Developer/Docs/Libraries/BSDsocket|bsdsocket.library]] *[[Aros/Developer/Docs/Libraries/CAMD|camd.library]] *[[Aros/Developer/Docs/Libraries/Codesets|codesets.library]] *[[Aros/Developer/Docs/Libraries/CGFX|cybergraphics.library]] *[[Aros/Developer/Docs/Libraries/CGXVIDEO|cgxvideo.library]] *[[Aros/Developer/Docs/Libraries/Commodities|commodities.library]] *[[Aros/Developer/Docs/Libraries/DataTypes|datatypes.library]] *[[Aros/Developer/Docs/Libraries/DiskFont|diskfont.library]] *[[Aros/Developer/Docs/Libraries/DOS|dos.library]] *[[Aros/Developer/Docs/Libraries/Exec|exec.library]] *[[Aros/Developer/Docs/Libraries/Expansion|expansion.library]] *[[Aros/Developer/Docs/Libraries/FreeType2|freetype.library]] *[[Aros/Developer/Docs/Libraries/GadTools|gadtools.library]] *[[Aros/Developer/Docs/Libraries/Graphics|graphics.library]] *[[Aros/Developer/Docs/Libraries/Icon|icon.library]] *[[Aros/Developer/Docs/Libraries/Identify|identify.library]] *[[Aros/Developer/Docs/Libraries/IFFParse|iffparse.library]] *[[Aros/Developer/Docs/Libraries/Intuition|intuition.library]] *[[Aros/Developer/Docs/Libraries/Keymap|keymap.library]] *[[Aros/Developer/Docs/Libraries/Layers|layers.library]] *[[Aros/Developer/Docs/Libraries/Locale|locale.library]] *[[Aros/Developer/Docs/Libraries/LowLevel|lowlevel.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingBas|mathieeesingbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubBas|mathieeedoubbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingTrans|mathieeesingtrans.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubTrans|mathieeedoubtrans.library]] *[[Aros/Developer/Docs/Libraries/Mathtrans|mathtrans.library]] *[[Aros/Developer/Docs/Libraries/MUIMaster|muimaster.library]] *[[Aros/Developer/Docs/Libraries/Partition|partition.library]] *[[Aros/Developer/Docs/Libraries/PopUpMenu|popupmenu.library]] *[[Aros/Developer/Docs/Libraries/OOP|oop.library]] *[[Aros/Developer/Docs/Libraries/Regina|regina.library]] *[[Aros/Developer/Docs/Libraries/Reqtools|reqtools.library]] *[[Aros/Developer/Docs/Libraries/RexxSysLib|rexxsyslib.library]] *[[Aros/Developer/Docs/Libraries/ScreenNotify|screennotify.library]] *[[Aros/Developer/Docs/Libraries/TTEngine|ttengine.library]] *[[Aros/Developer/Docs/Libraries/Thread|thread.library]] *[[Aros/Developer/Docs/Libraries/Utility|utility.library]] *[[Aros/Developer/Docs/Libraries/Xadmaster|xadmaster.library]] *[[Aros/Developer/Docs/Libraries/Workbench|workbench.library]] *[https://github.com/aros-development-team/AROS/commit/c82e86b8480277998014cc327b56c7664023a52f ClassAct Reaction boopsi class] ===AROS Subsystems=== # [[Aros/Developer/Zune|Zune MUI compatible GUI]] # [[Aros/Developer/AROSAppPackages|AROS Application Packages]] # AHI Audio Drivers - [[Aros/Developer/AHIDrivers|Usage]]/[[Aros/Developer/AHIDriversDev|Development]] # AROSTCP Sana2 Network Interface Drivers - [[Aros/Developer/NICDrivers|Usage]]/[[Aros/Developer/NICDriversDev|Development]] # [[Aros/Developer/AmiSSL|AmiSSL]] # gfx.hidd/cybergraphics Video Drivers - [[Aros/Developer/GfxDrivers|Usage]]/[[Aros/Developer/GfxDriversDev|Development]] # IO Device Drivers - [[Aros/Developer/IODeviceDrivers|Usage]]/[[Aros/Developer/IODeviceDriversDev|Development]] # USB Device Drivers - [[Aros/Developer/USBDrivers|Usage]]/[[Aros/Developer/USBDriversDev|Development]] # PCI Device Drivers - [[Aros/Developer/PCIDrivers|Usage]]/[[Aros/Developer/PCIDriversDev|Development]] # [http://www.libsdl.org/ SDL] [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2013&pid=13333#post_13333 SDL2 coding usage], [https://github.com/search?q=repo%3Aaros-development-team%2Fcontrib%20SDL2&type=code SDL2 commits], [https://github.com/aros-development-team/contrib/commit/c62c3c425c35bac19dadc23be092b0b13a66c76c SDL3 initial commit], [] # [[w:Gallium3D|Gallium 3D]] [http://www.mesa3d.org/ openGL aka Mesa] - [[Aros/Developer/OpenGL|Usage]]/[[Aros/Developer/OpenGLDev|Development]] [http://www.swiftless.com/opengltuts.html Swfitless] # A small subset of GTK2 through [http://sourceforge.net/projects/gtk-mui/ MUI-GTK] # Cairo 2D Engine - [[Aros/Developer/Cairo|Usage]]/[[Aros/Developer/Cairo|Development]] # [[Aros/Developer/Scalos|Scalos desktop API and plugin modules]] # [[Aros/Developer/VHI|VHI video driver]] ====HIDDs==== *[[Aros/Developer/Docs/HIDD/HIDDClass|hiddclass.hidd]] *[[Aros/Developer/Docs/HIDD/Graphics|graphics.hidd]] *[[Aros/Developer/Docs/HIDD/VesaGfx|vesagfx.hidd]] *[[Aros/Developer/Docs/HIDD/ATI|radeon.hidd]] *[[Aros/Developer/Docs/HIDD/NVidia|nvidia.hidd]] *[[Aros/Developer/Docs/HIDD/Nouveau|nouveau.hidd]] *[[Aros/Developer/Docs/HIDD/Kbd|kbd.hidd]] *[[Aros/Developer/Docs/HIDD/Mouse|mouse.hidd]] *[[Aros/Developer/Docs/HIDD/i2c|i2c.hidd]] *[[Aros/Developer/Docs/HIDD/IRQ|irq.hidd (deprecated)]] *[[Aros/Developer/Docs/HIDD/PCI|pci.hidd]] *[[Aros/Developer/Docs/HIDD/PCIPC|pcipc.hidd]] *[[Aros/Developer/Docs/HIDD/Serial|serial.hidd]] *[[Aros/Developer/Docs/HIDD/Thunderbolt|thunderbolt.hidd]] https://github.com/aros-development-team/AROS/commit/4f02ea691799aff3a01f60cfa5f9182c82fc57a8 HIDD are used for device/peripheral low level hardware support drivers. The HIDD system is split up into a collection of classes with a strict inheritance hierarchy. A HIDD class implements a device driver for a single device or in rare cases a group of devices and provides an interface for other programs and devices to access. In order to maintain portability of interfaces across a wide range of hardware this interface will in general not present the raw interface to the underlying hardware. Instead it will present a generic interface that describes many different hardware implementations. This allows for the best reuse of both interfaces and code. HIDD API is heavyweight though. You need to open a HIDD library, open oop.library, instantiate an object (even if there's no object); and object calls are more costly compared to plain library calls. Basically your task is to implement a subclass of hidd.ata.bus for your hardware. just implementing the XXXATA__Hidd_ATABus__xxxxxx methods for the Amiga chipset - and appropriate versions of the interface_xxx.c file(s). pretty much everything in probe.c could be ignored - just write a replacement scan for relevant amiga devices and store whatever info you need in the bus data? only the "SUPPORT_LEGACY" blocks might be related. You do not need to depend on PCI API. PCI is just a way to discover the hardware on PCs, etc. <hidd/pci.h> includes (at some depth) <interface/HW.h>, which defines IID_HW. This comes from the 'generic' HIDD class in: rom/hidds/hidd/hiddclass.conf did not split up HIDD and HW because they are always used in pair. It's the same as hidd/pci.h bringing definition for: PCI, PCIDriver and PCIDevice. PCI is actually PCIHW, just the name was not changed for backwards compatibility reasons. HW is a 'hub' where HIDD instances plug in. ATA HIDD aoHidd_ATABus_Use32Bit value is completely ignored unless ata.device first detects correct command line parameter. Yes. Unfortunately I was unable to find any comment in code or svn history with explanations. Looked at Linux source, there 32-bit PIO is also controller driver's property. Some of them enable it, some don't. Actually, switching the default to ON should be safe. ata.device is fail-safe at this because during IDENTIFY command it validates upper 16 bits, and if they appear to be zeroes in all 128 longwords, then 32-bit mode is switched off. But, nevertheless, I know how tricky hardware can be, so I decided not to change original behavior. If you think it's wrong in some cases, then it's possible to add one more attribute like aHidd_ATABus_Default32Bit. If set to YES, then this means that 32-bit PIO is safe to use by default. ====Devices==== *[[Aros/Developer/Docs/Devices/ATA|ata.device]] *[[Aros/Developer/Docs/Devices/Console|console.device]] *[[Aros/Developer/Docs/Devices/Narrator|narrator.device]] *[[Aros/Developer/Docs/Devices/Printer|printer.device]] *[[Aros/Developer/Docs/Devices/Trackdisk|trackdisk.device]] *[[Aros/Developer/Docs/Devices/AmberRAM|amberram.device]] *[[Aros/Developer/Docs/Devices/Timer|timer.device]] *[[Aros/Developer/Docs/Devices/|.device]] The Amiga used [[Aros/Developer/Docs/Devices|Devices]] to communicate with [http://aros-exec.org/modules/newbb/viewtopic.php?start=0&topic_id=3475&viewmode=flat&order=ASC additional hardware]. AROS has replaced these hardware devices with hidd equivalents but some are still retained for backwards compatibility. Local libraries/devices/handlers,etc. are supposed to override the ones in ROM if their version is higher than the one in ROM. Here is the list of commands exec default: {| class="wikitable" | CMD_CLEAR | Purge the buffer of the device |---- | CMD_READ | Playback Control |---- | CMD_STOP | Stopped the activity of the device |---- | CMD_FLUSH | Empty the queue of commands |---- | CMD_RESET | Reset a device |---- | CMD_WRITE | Playback Control |---- | CMD_INVALID | Create an error |---- | CMD_UPDATE | Gets updated device |---- | CMD_START | Will restart the device |---- |} While most other "stuff you communicate with" in AmigaOS are devices <ref>AMIGA ROM Kernel Reference Manual: Devices, 3rd Edition. Commodore-Amiga, Inc. Addison-Wesley, 1991. {{ISBN|0-201-56775-X}}</ref> that share a [http://gega.homelinux.net/AmigaDevDocs/ common base interface]. [[Aros/Developer/Docs/Devices1.3|OS 1.3 Device Drivers]]. ====Handlers==== :[[Aros/Developer/Docs/Handlers/Pipe|pipe.handler]] :[[Aros/Developer/Docs/Handlers/Port|port.handler]] :[[Aros/Developer/Docs/Handlers/SFS|sfs.handler]] :[[Aros/Developer/Docs/Handlers/FAT|fat.handler]] :[[Aros/Developer/Docs/Handlers/PFS|pfs.handler]] :[[Aros/Developer/Docs/Handlers/NTFS|fuse.handler]] :[[Aros/Developer/Docs/Handlers/FFS|ffs.handler]] filesystem handlers have their own separate system consisting of completely differently structured messages that dos.library use to pass requests (for things like reading, writing, getting directory contents etc.) to them. AROS originally went with implementing filesystem handlers as devices, which might arguably be more consistent with the rest of the AmigaOS API but which is quite incompatible with AmigaOS itself. However, it made it far harder to port filesystems and the gains were comparatively small, and so there's been a long standing goal of fixing this incompatibility. It has now, June 2011, been reintroduced to all AROS flavors. are argstr and argsize valid for the handler startup environment? DOS/RunHandler() calls DOS/CreateNewProcTags(), and then CallEntry() (in rom/dos/exit.c) to start the handler, so yes, argstr and argsize are *present* in the call signature of the handler. Granted, argstr will be NULL and argsize 0, but those values *are* passed to the handler function using: <pre> AROS_UFC3(ULONG, entry, AROS_UFCA(STRPTR, argptr, A0), AROS_UFCA(ULONG, argsize, D0), AROS_UFCA(struct ExecBase *, SysBase, A6)); </pre> Creating your own [without the whole build tree http://pagesperso-orange.fr/franck.charlet/temp/radeon.zip] and then <pre> make stub make make install </pre> SFS has two Root blocks, one at the start and one at the end of the disk. The Root blocks both contain the same information. They hold various information about the disk structure and have the locations of some important blocks used by the filesystem. The Root ObjectContainer contains the Root directory Object. The name of this Object is the name of the volume. It is identical to a normal directory Object. The Bitmap is used to keep track of free space. Each bit in a bitmap represents a single block. A set bit indicates a free block and a cleared bit a used block. AdminSpaceContainers are used to keep track of space which has been reserved for storing administration blocks. Only the Bitmap, the Root blocks and the actual data stored in files aren't stored in administration space. Administration space is allocated in chunks of 32 blocks at a time. A single AdminSpaceContainer can hold information about a large number of such areas each of which has its own little bitmap of 32 bits. Extents are stored in a B-Tree. The Root block holds a pointer to the root of the Extent B-Tree. Extents keep track of space in use by a specific file. Each fragment a file consists of has its own Extent. Extents are in a double linked list. The list can be used to locate the next or previous fragment of a file. Below is the standard block header. This header is found before EVERY type of block used in the filesystem, except data blocks. The id field is used to check if the block is of the correct type when it is being referred to using a BLCK pointer. The checksum field is the SUM of all LONGs in a block plus one, and then negated. When applying a checksum the checksum field itself should be set to zero. The checking a checksum the checksum is okay if the result of the checksum equals zero. The ownblock BLCK pointer points to the block itself. This field is an extra safety check to ensure we are using a valid block. Field Type Description id ULONG The id field is used to identify the type of block we are dealing with. It is used to make sure that when referencing a block we got a block of the correct type. The id consist of 4 bytes and each blocktype has its own unique foure letter code. checksum ULONG This field contains the sum of all longs in this block, plus one and then negated. The checksum can be used to check if the block hasn't been corrupted in any way. ownblock BLCK Points to itself, or in other words, this field contains the block number of this block. This is yet another way to check whether or not a block is valid. <pre> struct fsBlockHeader { ULONG id; ULONG checksum; BLCK ownblock; }; </pre> The algorithm to calculate the checksum of a block: <pre> ULONG calcchecksum(struct fsBlockHeader *block, LONG blocksize} { ULONG *data=(ULONG *)block; ULONG checksum=1; block->checksum=0; while(blocksize>0) { checksum+=*data++; blocksize-=4; } return(-checksum); } </pre> A Root block contains very important information about the structure of a SFS disk. It has information on the location and size of the disk, the blocksize used, locations of various important blocks, version information and some filesystem specific settings. A SFS disk has two Root blocks; one located at the start of the partition and one at the end. On startup the filesystem will check both Roots to see if it is a valid SFS disk. If either one is missing SFS can still continue (although at the moment it won't). A Root block could be missing on purpose. For example, if you extend the partition at the end (adding a few MB's) then SFS can detect this with the information stored in the Root block located at the beginning (since only the end-offset has changed). Same goes for the other way around, as long as you don't change start and end point at the same time. When a Root block is missing because the partition has been made a bit larger, then SFS will in the future be able to resize itself without re-formatting the disk. Field Type Description bheader struct fsBlockHeader Standard block header. version UWORD The version of the filesystem block structure. You can check this field to identify what version of the filesystem your dealing with it and to see if you can handle this structure correctly. Don't try to interpret the disk's structure when this field contains an unknown version number! sequencenumber UWORD Used to identify which Root block was written last in case the sequencenumber on both Root blocks don't match. datecreated ULONG Creation date of this volume. This is the date when the disk was last formatted and will never be changed. bits UBYTE Various settings, see below. <pre> pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. reserved1 ULONG[2] Reserved, leave zero. firstbyteh ULONG High 32-bits of a 64-bit number. This is the first byte of our partition relative to the start of the disk. firstbyte ULONG Low 32-bits of a 64-bit number. lastbyteh ULONG High 32-bits of a 64-bit number. This is the last byte (exclusive) of our partition relative to the start of the disk. lastbyte ULONG Low 32-bits of a 64-bit number. totalblocks ULONG The total number of blocks this partition consists of. blocksize ULONG The size of a block of this partition. reserved2 ULONG[2] Reserved, leave zero. reserved3 ULONG[8] Reserved, leave zero. bitmapbase BLCK Block number of the start of the Bitmap. adminspacecontainer BLCK Block number of the first AdminSpaceContainer. rootobjectcontainer BLCK Block number of the ObjectContainer which contains the root of the disk (this is where the volume name is stored). extentbnoderoot BLCK Block number of the root of the Extent B-Tree. reserved4 ULONG[4] Reserved, leave zero. </pre> <pre> struct fsRootBlock { struct fsBlockHeader bheader; UWORD version; UWORD sequencenumber; ULONG datecreated; UBYTE bits; UBYTE pad1; UWORD pad2; ULONG reserved1[2]; ULONG firstbyteh; ULONG firstbyte; ULONG lastbyteh; ULONG lastbyte; BLCK totalblocks; ULONG blocksize; ULONG reserved2[2]; ULONG reserved3[8]; BLCK bitmapbase; BLCK adminspacecontainer; BLCK rootobjectcontainer; BLCK extentbnoderoot; ULONG reserved4[4]; }; </pre> AdminSpaceContainers are used to store the location and bitmap of each administration space. The AdminSpaceContainers are located in a double linked list and they contain an array of fsAdminSpace structures. There is one fsAdminSpace structure for every administration space on disk. Field Type Description bheader struct fsBlockHeader Standard block header. next BLCK The next AdminSpaceContainer, or zero if it is the last in the chain. previous BLCK The previous AdminSpaceContainer, or zero if it is the first AdminSpaceContainer. bits UBYTE The number of bits in each in the bits ULONG in the fsAdminSpace structure. pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. adminspace struct fsAdminSpace An array of fsAdminSpace structures. The size of the array is determined by the current blocksize. <pre> struct fsAdminSpaceContainer { struct fsBlockHeader bheader; BLCK next; BLCK previous; UBYTE bits; UBYTE pad1; UWORD pad2; struct fsAdminSpace adminspace[0]; }; </pre> Field Type Description space BLCK The first block of an administration space. bits ULONG A small bitmap which is used to determine which blocks in an administration space are already in use. The number of bits in this bitmap is determined by the bits field in the AdminSpaceContainer. <pre> struct fsAdminSpace { BLCK space; ULONG bits; }; </pre> The fsBitmap structure is used for Bitmap blocks. A bitmap block is used to keep track of which space is in use and which isn't for a particular area of a disk. All bitmap blocks together keep track of the free space for an entire disk. The location of the first bitmap block is known and all other bitmap blocks are stored in order after the first one. Field Type Description bheader struct fsBlockHeader Standard block header. bitmap ULONG An array of ULONG's. These hold the actual information on which blocks are in use and which aren't. <pre> struct fsBitmap { struct fsBlockHeader bheader; ULONG bitmap[0]; }; </pre> Each bit in a bitmap block (except for the block header) represents a single block. If the bit is set than the block is free, and if the bit is clear then it is full. The first ULONG in the bitmap area of the first bitmap block represents blocks 0 through 31 on the disk. Bit 31 of this ULONG is block 0, 30 is block 1, and so on. Bit 0 of the first ULONG represents block 31. Below is a table to clarify how bitmaps work even further. The first column is the bitmap block number, the second column is the number of the ULONG in the bitmap array. The third column is the bit number in this ULONG, and the last column is the block which this specific bit, in this specific bitmap block represents. We'll assume here that a bitmap block has room for 120 ULONG's (meaning there is room for storing 32 * 120 bits). <pre> Bitmap block ULONG number Bit number Block represented 1 (first) 0 31 0 1 0 30 1 ... ... ... ... 1 0 1 30 1 0 0 31 1 1 31 32 ... ... ... ... 1 2 31 64 1 2 30 65 ... ... ... ... 1 119 0 3839 2 0 31 3840 2 0 30 3841 ... ... ... ... </pre> The last bitmap block doesn't need to be completely used. The unused bits (which belong to blocks which do not exist) all have to be clear, to indicate that these blocks are in use. The fsObjectContainer structure is used to hold a variable number of fsObjects structures (Objects) which have the same parent directory. Each ObjectContainer must contain at least one Object. If there is space in the ObjectContainer not used by the variable number of Objects then that space is zero filled. Objects always start at 2-byte boundaries, which means sometimes a padding byte is inserted between two Objects. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the parent Object, or 0 if this object has no parent (which is only the case for the Root directory). next BLCK The next ObjectContainer belonging to this directory, or zero if it is the last in the chain. previous BLCK The previous ObjectContainer belonging to this directory, or zero if it is the first ObjectContainer in this directory. object struct fsObject A variable number of fsObject structures. The number of structures depends on the individual sizes of each fsObject structure and the blocksize. These structures are located directly after each other with at most 1 byte of padding between them to get the structures aligned on a 2 byte boundary. <pre> struct fsObjectContainer { struct fsBlockHeader bheader; NODE parent; BLCK next; BLCK previous; struct fsObject object[0]; }; </pre> fsHashTable is the structure of a HashTable block. It functions much like the hash table found in FFS user directory blocks, except that it is stored in a separate block. This block contains a number of hash-chains (about 120 for a 512 byte block). Each hash-chain is a chain of Nodes. Each Node has a pointer to an Object and a pointer to the next entry in the hash-chain. Using such a hash-chain you can locate an object quickly by only knowing its name. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the directory Object this HashTable block belongs to. hashentry NODE An array of Nodes. Each Node represents the start of a hash-chain (singly linked). A hash-value is calculated using the name of a file or directory, and this value determines in which chain the Object is linked. If there are no entries in a hash-chain then the hashentry value is zero. <pre> struct fsHashTable { struct fsBlockHeader bheader; NODE parent; NODE hashentry[0]; }; </pre> To calculate the hash-value using a name of an Object as input use these routines: <pre> UWORD calchash(UBYTE *name) { UWORD hash=0; /* Calculates a hash value over the passed in string. The end of the string can be either a NUL byte or a slash. The hash function is the same as the one used in FastFileSystem set to international mode. */ while(name[hash]!=0 && name[hash]!='/') { hash++; } while(*name!=0 && *name!='/') { hash=hash*13+upperchar(*name++); } return((UWORD)(hash % (UWORD)((blocksize-sizeof(struct fsHashTable))>>2))); } UBYTE upperchar(UBYTE c) { if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z')) { c-=32; } return(c); } </pre> The BNodeContainer is used to store B-Trees. Currently only one B-Tree is in use by this filesystem and it is used to store the location of file data. The fsBNodeContainer structure contains two other structures. The fsBlockHeader structure and the BTreeContainer structure. Field Type Description bheader struct fsBlockHeader Standard block header. btc struct BTreeContainer Contains information about the B-Tree and its nodes contained in this block. <pre> struct fsBNodeContainer { struct fsBlockHeader bheader; struct BTreeContainer btc; }; </pre> First try and locate the Root block. It should start with "ROOT". SFS has two of these, one at the start of the partition and one at the end. One of the fields contains the block size, which will be the size of all important SFS blocks. The root block has the root object container, which contains information about files and directories in the root directory. The object containers basically hold one or more smaller structures that represent files and directories. Scanning them all should give you a list of files and directories. The root block also has the root of the Extent B-Tree. This is a standard B-Tree structure (not a binary tree) that is used commonly in all kinds of system, you can read about how they work on Wikipedia if needed. The B-Tree holds the information about *where* all the data is located for your files. To recover your files, I'd do this: * Find one of the root blocks, if not present, then figure out the block size your disk was using, and scan every block in turn to see if it looks like an ObjectContainer (check the fsBlockHeader's ID, check if the ownblock number is equal to the block you are currently scanning, and check its checksum). So if you currently have block 12, and you see a block with the correct id, and ownblock = 12 and its checksum is good, then that's probably a valid ObjectContainer. * With all the ObjectContainers found, you can extract filenames and directory names from these, but also the number of their first data block (in the field data) and the file size. For small files (less than blocksize) this data block will be enough to recover the data. For larger files, you might be lucky and all the remaining blocks are found after the first one (if the file was defragmented). You can't be sure of that though so... * For larger files, you need to find all the BNodeContainers. You could scan these in the same way you found all the ObjectContainers (look for blocks with the correct id, ownblock number and checksum). * With all the BNodeContainers found, you can try looking up the first data block of a file in the B-Tree structure. This is a bit complicated -- the B-Tree consists of non-leaf nodes (blocks that only contain pointers to other B-Tree blocks), the isLeaf flag indicates this. Or it can be a B-Tree leaf block. The leaf blocks contain extra information per entry (see https://hjohn.home.xs4all.nl/SFS/extents.htm) <pre> struct fsExtentBNode { ULONG key; ULONG next; ULONG prev; UWORD blocks; }; </pre> The key should be a block of a file (the first of a range), that is 1 to 65535 block long (depending the "blocks" field). If the file is split up into more parts, then "next" will contain block number of the next range of blocks. You need to look this up again in the B-Tree structure to find out how large it is. You can for the most part ignore the other structures (bitmap, admin containers). The fsObjects and B-tree containers is what you'll need to recover the data. ====Resources==== <pre> rom/storage/mmakefile.src rom/storage/storage.conf rom/storage/storage_device.c rom/storage/storage_ids.c rom/storage/storage_init.c rom/storage/storage_intern.h rom/storage/storage_mount.c rom/storage/storage_unit.c </pre> <pre> rom/storage/includes/device.h rom/storage/includes/unit.h rom/storage/includes/volume.h rom/storage/storage_intern.h </pre> <pre> </pre> *[[Aros/Developer/Docs/Resources/ACPI|acpi.resource]] *[[Aros/Developer/Docs/Resources/Battclock|battclock.resource]] *[[Aros/Developer/Docs/Resources/Bootloader|bootloader.resource]] *[[Aros/Developer/Docs/Resources/Cia|cia.resource]] *[[Aros/Developer/Docs/Resources/Filesystem|FileSystem.resource]] *[[Aros/Developer/Docs/Resources/Hostlib|hostlib.resource]] *[[Aros/Developer/Docs/Resources/Kernel|kernel.resource]] *[[Aros/Developer/Docs/Resources/Misc|misc.resource]] *[[Aros/Developer/Docs/Resources/Processor|processor.resource]] ==Debugging Code== Please use the [http://sourceforge.net/tracker/?group_id=43586&atid=439463 AROS Bug Tracker] if any issues are found. GRUB Command line list <pre> sysdebug usbdebug - allows to see Poseidon's log in debug output </pre> How do I get debugging out of InitResident ? If running i386 hosted on linux sysdebug=initresident on command line. This way you can enable any of listed flags. sysdebug=all stands for "everything" Have an executable (crosscompiled C++ code) which has 6 MB size on disk, but after loading it in memory, 250 MB RAM is taken. Any software that would split AROS executable into ELF part which would show actual size values? readelf -S executable it will show you all sections in elf file, including sizes and requested alignment. objdump -h filename That's will give you a quick overview of the sections and sizes. Ignore all the .debug.* sections. Would hazard a guess that you have a large .bss section. That's pretty common in C++. Next step: nm—size-sort filename | grep ' [bB] ' The last few will be your biggest consumers. Would suggest -C to demangle the symbols... ;) Suggest profiling the program (just use some printf's in the main loop for time spent in each part), it usually is quite easy to spot slow parts in games or apps. If someone has '#define IPTR ULONG' somewhere. To see where that define is, redefine IPTR in the source code that fails, just above the line that fails, and the preprocessor will tell you where it was defined first. ===How to setup gdb with AROS/hosted=== Download AROS sources (AROS-xxxxxxxx-source.tar.bz2, where xxxxxxxx is the current date) and AROS contrib sources (AROS-xxxxxxxx-contrib-source) from Untar-bzip2 and cd to the unpacked archive directory. > tar -xvjf AROS-xxxxxxxx-source.tar.bz2 > cd AROS-xxxxxxxx-source Check the link to "contrib" (contrib-source) inside directory, e.g. correct like this: > rm contrib > ln -s ../AROS-xxxxxxxx-contrib-source.tar.bz2 contrib Make sure you have the correct locale setting, otherwise compilation will fail at some point. See [http://aros.sourceforge.net/documentation/developers/compiling.php#setting-the-locale-to-iso8859 here] (or link below) for more on that. You might have to enter this: > export LANG="en_US.ISO-8859-1" Now configure for a debug build - see "./configure --help" for more - here are two examples: > ./configure—enable-debug=stack,modules,symbols > ./configure—enable-debug=all You may "make" now, or choose a separate directory for your build (e.g. for easy removal), for example if compiling for i386 architecture you could create a directory like this: > mkdir linux-i386 > cd linux-i386 > ../AROS/configure—enable-debug=stack,symbols,modules When done configuring you're ready to go: > make Building AROS takes some time - minutes on fast machines (e.g. 2.5&nbsp;GHz quadcore), up to hours on slower machines. The result will be AROS Linux hosted with gdb debugging enabled. See aros.org documentation for more on compiling AROS, including more [http://aros.sourceforge.net/documentation/developers/compiling.php --enable-debug] options. When finished, enter bin/linux-i386/AROS directory (replace "linux-i386" with your compilation target platform, e.g. linux-x86_64, etc.) inside the unpacked archive directory. This directory contains the required .gdbinit file for properly running AROS inside gdb. > cd bin/linux-i386/AROS Run AROS (here: with 128MB of memory) from gdb: > gdb—args boot/aros-unix -m 128 or > gdb—args boot/arosboot -m 128 (gdb) r Watch the shell output - in case AROS complains about "LoadKeyCode2RawKeyTable: Loading "DEVS:Keymaps/X11/keycode2rawkey.table" failed!" you should also see some instructions on how to create a keymap table. (see link above "more on compiling", too.) Quit gdb, and try default keymap table: (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y > cd ../../.. > make default-x11keymaptable Re-run AROS, as described above. Try e.g. RAros (= right windows key) + W to open a shell. If this doesn't work you have to create a keymap table yourself, quit gdb again, and make a new keytable: > make change-x11keymaptable A window will open. Watch the window's title bar, and follow the instructions. When done, re-run AROS. RAros + W should now open a shell. Next, compile your program with gdb support. When you start GDB is there a warning which says warning: File "<whatever>/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to ... If so start gdb with "-ix .gdbinit" <pre> Summary - In short: * build AROS with debugging support (i.e. ./configure --enable-debug=all) * build your application with debugging support (i.e. option -g) * run AROS in the GNU debugger (you may use the GUI frontend "ddd" which simplifies usage a bit) * start your application * use the commands "findaddr" and "add-symbol-file" as written in the debugging manual * if the debugger doesn't find the source code of your application use the "dir" command of the debugger. </pre> ===How to use gdb=== In AROS open a shell, then (in host shell) use CTRL-Z to go into gdb. Use "b Exec_CreatePool" (one of the functions used early on by startup code in programs) to add a breakpoint, then "cont" and gdb will interrupt somewhere early during startup of "program". Use "bt" to show backtrace and "loadseg" for "??" entries. One of them will be for "program". After that you can use "disassemble program". One thing you need to make sure is that .gdbinit you have in your build directory is the same as in source tree. It has been modified some time ago, but the build system does not refresh it - you need to copy it manually To recap, please read our debugging [http://aros.sourceforge.net/documentation/developers/debugging.php manual]: To detect segfaulting when loading, try... ./configure—enable-debug—with-optimization="-O2" Because crash or no crash may depend on optimization. For newer compilers maybe this helps... --with-optimization=-"-O2 -fno-strict-aliasing" One way to make crashes less random (more easily reproducible) is to activate the munging of free memory in rom/exec/freemem.c which is normally commented out: <pre> Index: freemem.c =================================================================== --- freemem.c (revision 34289) +++ freemem.c (working copy) @@ -154,11 +154,12 @@ * created with their TCB placed in the tc_MemEntry list. The workaround * is to avoid munging when FreeMem() is called with task switching disabled. */ + /* DOH! it doesn't work even this way. What's wrong??? - * - * if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) - * MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); */ + + if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) + MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); } </pre> Mungwall can be turned on at runtime. Currently this works in all hosted versions. Just specify "mungwall" on kernel command line and it works. It can work on native too. In order to enable it you need to parse kernel command line, and if "mungwall" is present, set EXECF_MungWall bit in IntExecBase.IntFlags. This needs to be done before the first AllocMem() for obvious reasons. And never reset back this flag! If you change it on a working system, you are doomed. Hosted ports do the processing in rom/exec/prepareexecbase.c --enable-debug=mungwall option in configure still works but is going obsolete. A kludge in rom/exec/allocmem.c is responsible for this and it needs to be removed when the transition is done. BTW, on i386-pc port it can be activated by "mungwall" argument on command line, you don't need to rebuild AROS. New mungwall affects not only AllocMem()/FreeMem(), but also pools. I also tested it with AllocAbs(), seems to work correctly. Runtime mungwall works on: * pc-i386 * pc-x86_64 * linux-i386 * linux-x86_64 * darwin-x86 * linux-ppc Works on all hosted ports, if the port itself is working. * amiga-m68k * Not on sam440-ppc and efika-chrp-ppc, even if they would be able to be built at moment. Does not work on (for now, need NVRAM support) When starting my freshly rebuilt i386-linux-aros which was compiled with full debugging support I get sometimes the error "Program exited with code 0377". Add the following to your .gdbinit: set follow-fork-mode child Here are some of the custom AROS gdb functions (defined in ".gdbinit" file) to resolve "in ?? ()" entries in backtrace: <pre> #0 0xb7ffd424 in __kernel_vsyscall () #1 0xb7e2a657 in sigsuspend () from /lib/libc.so.6 #2 0xb7c63900 in ?? () #3 0xb7c640e3 in ?? () #4 0xb7c641e0 in ?? () </pre> You can use loadseg 0xb7c63900 loadframe 2 or loadbt and some others. Use "help " for a little help text. If the commands do not work try "loadkick" first. Use "thistask", "taskready", "taskwait" to get list of AROS tasks. "bttask " shows backtrace of a task which is in ready or in wait queue and "loadseg" to resolve "??" entries in it's backtrace ("loadframe" would not work as it assume current running task). ===Native debugging tools for AROS=== to enable debugging at boot time entering the GRUB menu editing line (E key) and adding "debug=memory" to your boot line, then press Ctrl+X to complete booting. SYS:Tools/Debug/'''Bifteck''' Open a shell and enter the line below to run Biftek and grab the debug messages collected in RAM into a text file. tools/debug/bifteck > ram:debug.txt and certainly does not open a window. It is a shell tool and only dumps data located from the debug location. It is therefore important to 'catch' that debug data as soon as possible (before it gets overridden). You should invoke bifteck at the first opportunity before doing anything else. You can use the TO option to store bifteck output to a file or you can pipe it manually to a file. SYS:Tools/Debug/'''Sashimi''' - displays error messages One suggestion is to do a bug() debugging. Each time bug() is executed it will be output on sashimi. You include <aros/debug.h> and place bug("something\n"); in your source code at location though which control passes. To get the output - open an aros shell SYS:Tools/Debug/sashimi > RAM:out.txt '''Ctrl C''' to end the output to the RAM Disk. # open shell, and type # ram: (to switch to ram drive) # System:Tools/Debug/Sashimi > mylogfile.txt # open AHI prefs using wanderer (or use another opened shell) # play test sound # close AHI prefs # shell still open with Sashimi running: press ctrl-c to break Sashimi and return to prompt. # in shell: copy mylogfile.txt System: (or to your required location) SYS:Utilities/'''Snoopy''' - monitors OS function calls, run "Sashimi" to see Snoopy's output SYS:Tools/'''WiMP''' - the Window (and Screens) Manipulation Program You can use the -E option of gcc to find out how preprocessor macros are expanded. ===Errors=== crash in strcasecmp usually means that one of its arguments is NULL. empty space between these two names, prossibly some invisible character Old Amiga [http://www.amigacoding.com/index.php?title=Guru_codes&redirect=no Guru Codes] If the crash is in intuition. Sometimes, if it relates to text, a null pointer sets it off. an uninitialised pointer can have any address (this is a common fault). Compiling on 64bit, Many old code would not properly typecast when doing pointer-integer conversions and thus at least throw a warning. This can easily be located and fixed. [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. * Fix (change IPTR/SIPTR back to ULONG/LONG) the few places which really rely on ULONG/LONG being exactly 32 bit. That's for things like pixel (ARGB) buffers, structs written/read to disk, colormaps, but probably not much else. Then again, many current compilers also throw a warning when you try to assign a pointer value to an integer and the integer is possibly too small. This happens under .NET for example when a 64 bit pointer is assigned to something like an ULONG - so exactly the case which you described. === AI === Multimodal Context Prompt <--- Model <---> Agent ---> End user engine Gemini LMStudio Qwen Comfyui etc Recent, self hosting locally on laptops, mini pcs or desktops with '''quantization''' 4bit has reduced memory requirements but still require 16Gb+ and no high end gpu for text based *[https://lmstudio.ai/download LMstudio single gpu], Google Gemma 4 Model *[ 12B QAT] Alibaba Cloud's [https://huggingface.co/ Qwen] team series of large language models LLMs *[https://huggingface.co/models?other=qwen3 Qwen 3], [], *[https://huggingface.co/models?other=qwen2 Qwen 2], [https://huggingface.co/Qwen/Qwen2.5-Coder-32B qwen 2.5 Coder], Small models *[ glm-ocr] *[ medGemma] *[ qwen 3.5-4b] *[https://github.com/sipeed/picoclaw picoclaw claude] Bigger LLMs but with settings *[https://ollama.com/download Ollama single gpu] *[https://github.com/ggml-org/llama.cpp/releases llama.CPP multi gpus], *[ VLM multiple gpus], Multimedia *[ Kimi K3], For the full experience #Training learning using 1+ high end GPUs at least 16GB VRAM per GPU card or 64Gb+ of unified, 16Core CPU with at least 64Gb of RAM system memory, though training can take weeks #Inference with custom asics or GPUs *[ MiniMax H3] for audio and video but gpu 8Gb+ *[https://github.com/jamiepine/voicebox voicebox] *[https://github.com/ideogram-oss/ideogram4 ideogram4] *[https://github.com/calesthio/OpenMontage OpenMontage] <pre> Text to Audio --\ Text to Video --/ Reference Video --> Video and Audio output </pre> === Example === <syntaxhighlight lang="c"> /* 1. Header for your name,date,purpose of program. 2. Pre-processor directives. This will include the #includes for files you want to add. 3. Includes for function prototypes if necessary. 4. Main() Create Pointers for Libraries and any Window you want to open. 5. Open necessary libraries. 6. Check if open exit program if fail. 7. Open a window exit program if fail. 8. Add your program 9. Close Window 10 Close Libraries. 11 End Program. */ /* standard os included headers <.h> */ #include <dos/dos.h> #include <dos/dosasl.h> #include <dos/dosextens.h> #include <dos/exall.h> #include <dos/rdargs.h> #include <exec/memory.h> #include <exec/types.h> #include <utility/utility.h> #include <intuition/intuition.h> /* define as unresolved external references (proto/xxx.h) and compiler will link to auto(matically) open library */ #include <proto/arossupport.h> #include <proto/dos.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/graphics.h> #include <proto/cybergraphics.h> #include <proto/datatypes.h> #include <proto/icon.h> #include <workbench/workbench.h> #include <workbench/icon.h> #include <datatypes/pictureclass.h> #include <proto/muimaster.h> #include <libraries/mui.h> #include proto/bsdsocket.h #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* my own headers ".h" */ #define CTRL_C (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) #define isDir(fib) ((fib)->fib_DirEntryType >= 0) #define ARG_TEMPLATE "FILE/A,ALL/S,QUIET/S,W=WIDTH/N,H=HEIGHT/N,M=METHOD,DEFTOOL" int main(void) { return retval; } /* main */ </syntaxhighlight> If you used c++, there is not yet c++ support in our shared library system. The easiest way to create / compile a shared library would be to use the AROS build system but the libraries can be created manually. You have to create a ROMTAG structure and some header files. A shared library is built with the %build_module macro with a line like this: %build_module mmake=MetaTarget modname=mylib modtype=library files=SourceFiles This macro can build different AROS module types, like devices, Zune classes, HIDDs, etc. <pre> ##begin config version 1.0 ##end config ##begin functionlist void func1(LONG a, LONG b) int func2(char *s, ULONG a) ##end functionlist </pre> Alternatively, <pre> #ifndef LIB_H #define LIB_H #define __NOLIBBASE__ #include <exec/libraries.h> #include <exec/semaphores.h> #include <dos/dos.h> #ifdef __AROS__ //#include <aros/debug.h> #define reg(x) #define __saveds #endif #define USESYSBASE struct ExecBase *SysBase = Base->My_SysBase; struct MyTestBase { struct Library My_Test_Lib; struct ExecBase *My_SysBase; APTR My_SegList; int testint; }; #endif </pre> <pre> /*--------------------------------------------------------------------------*/ /* Resident header written for mytest.library */ /*--------------------------------------------------------------------------*/ #define __NOLIBBASE__ #define VERSION 1 #define REVISION 0 #define LIBHEADNAME mytest #define LIBHEADNAMESTR "mytest" #define COMPDATE "04.10.2015" #define VERS "1.0" #define LIBBASETYPE struct MyTestBase #define LIBBASETYPEPTR LIBBASETYPE * #include <aros/debug.h> #include <exec/exec.h> #include <proto/exec.h> #include <exec/resident.h> #include <exec/nodes.h> #include <exec/libraries.h> #include <aros/symbolsets.h> #include "lib.h" const UBYTE lib_name[] = LIBHEADNAMESTR ".library"; const UBYTE lib_id[] = "$VER: " LIBHEADNAMESTR ".library " VERS " (" COMPDATE ") by ALB42\n"; extern const APTR FuncTable[]; AROS_UFP3 (LIBBASETYPEPTR, InitLib, AROS_UFPA(LIBBASETYPEPTR, Base, D0), AROS_UFPA(BPTR, seglist, A0), AROS_UFPA(struct ExecBase *, sysbase, A6) ); static struct LibInitStruct { IPTR LibSize; const APTR *FuncTable; const struct DataTable *DataTable; APTR InitFunc; } const LibInitStruct = { sizeof(LIBBASETYPE), FuncTable, NULL, (APTR)InitLib }; const struct Resident romtag = { RTC_MATCHWORD, /* match word */ (APTR)&romtag, /* back pointer */ (APTR)(&romtag + 1), /* skip pointer */ RTF_AUTOINIT | RTF_EXTENDED,/* flags */ VERSION, /* version */ NT_LIBRARY, /* type of module */ 0, /* init priority */ (STRPTR)lib_name, /* module name */ (STRPTR)lib_id + 6, (APTR)&LibInitStruct, REVISION, NULL }; AROS_UFH3 (LIBBASETYPEPTR, InitLib, AROS_UFHA(LIBBASETYPEPTR, Base, D0), AROS_UFHA(BPTR, seglist, A0), AROS_UFHA(struct ExecBase *, sysbase, A6) ) { AROS_USERFUNC_INIT Base->My_SegList = seglist; Base->My_SysBase = (APTR)sysbase; Base->testint = 0; USESYSBASE bug("InitLib\n"); if (!set_open_libraries()) { set_close_libraries(); return NULL; } return Base; AROS_USERFUNC_EXIT } AROS_LH1(LIBBASETYPEPTR, LibOpen, AROS_LHA (ULONG, version, D0), LIBBASETYPEPTR, Base, 1, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibOpen\n"); (void)version; Base->My_Test_Lib.lib_OpenCnt++; return Base; AROS_LIBFUNC_EXIT } __saveds APTR LibExpungeInternal(LIBBASETYPE *Base reg(a6)) { USESYSBASE APTR seglist; bug("LibExpungeInternal\n"); if (Base->My_Test_Lib.lib_OpenCnt) { return 0; } seglist = Base->My_SegList; Forbid(); Remove((struct Node*)Base); Permit(); FreeMem((APTR)Base - Base->My_Test_Lib.lib_NegSize, (LONG)Base->My_Test_Lib.lib_PosSize + (LONG)Base->My_Test_Lib.lib_NegSize); set_close_libraries(); return seglist; } AROS_LH0(BPTR, LibClose, LIBBASETYPEPTR, Base, 2, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibClose\n"); if (!(--Base->My_Test_Lib.lib_OpenCnt)) { return LibExpungeInternal(Base); } return 0; AROS_LIBFUNC_EXIT } AROS_LH1(BPTR, LibExpunge, AROS_LHA(LIBBASETYPEPTR, Base, D0), struct ExecBase *, sysBase, 3, LIBHEADNAME ) { AROS_LIBFUNC_INIT (void)sysBase; USESYSBASE bug("LibExpunge\n"); return LibExpungeInternal(Base); AROS_LIBFUNC_EXIT } AROS_LH0(LIBBASETYPEPTR, LibReserved, LIBBASETYPEPTR, Base, 4, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibReserved\n"); return 0; //return (APTR)LibReserved(); AROS_LIBFUNC_EXIT } // Space for your own functions // do not forget to update the FuncTable as well AROS_LH1(int, TestFunction, AROS_LHA(int, TestValue, D0), LIBBASETYPEPTR, Base, 5, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("TestFunction\n"); Base->testint = TestValue + Base->testint; return Base->testint; AROS_LIBFUNC_EXIT } // Functable -> Table of all functions in the Library, in right order - important! const APTR FuncTable[] = { &AROS_SLIB_ENTRY(LibOpen,LIBHEADNAME,1), &AROS_SLIB_ENTRY(LibClose,LIBHEADNAME,2), &AROS_SLIB_ENTRY(LibExpunge,LIBHEADNAME,3), &AROS_SLIB_ENTRY(LibReserved,LIBHEADNAME,4), &AROS_SLIB_ENTRY(TestFunction,LIBHEADNAME,5), (void *)-1 }; // AutoInit stuff void *__PROGRAM_ENTRIES__symbol_set_handler_missing; void *__LIBS__symbol_set_handler_missing; // end of AutoInitStuff </pre> Makefile <pre> VPATH = CFLAGS = -O2 -g -fomit-frame-pointer -W -Wall -Wno-parentheses CC = i386-aros-gcc LD = i386-aros-gcc LDFLAGS = -nostartfiles -Wl,-Map -Xlinker linkermap LIBS = -lautoinit -llibinit STRIP = i386-aros-strip --strip-unneeded --remove-section .comment OBJS = lib_header.o all: mytest.library mytest.library: $(OBJS) $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ lib_header.o: lib_header.c lib.h clean: rm -f *.o *.library *.ppu testlibrary linkermap </pre> Porting UNIX library to AROS - dealing with static variables which would make it easy to port such libraries to AROS, keeping the benefits of sharing them on disk, but losing the benefit of actually sharing them in memory. Our problem arises by the fact we want to share the actual code (the .text section of the library) and constant data, but we need to have per-task .bss and .data sections. If we get rid of our intention to share the .text and .rodata sections, things get quite easy: just load and relocate the library whenever it's open, by whoever it's open. It's like statically linking the library into the executable, except that the final linking is done at runtime. In the V0 branch, in workbench/hidds/hidd.nouveau was committed pcimock.hidd. This is a pci driver that allows mocking real PCI devices under linux-hosted. The main idea is to be able to run the real hardware driver under linux-hosted with as little changes as possible (some changes will always be needed though unless someone wants to write complete device simulator) so that driver's code paths can be executed and debugged using gdb. This was a very helpful capability when porting nouveau. Now it is externalized from nouveau.hidd and can be used by other people porting drivers. The pcimock.hidd can currently mock 4 different nvidia cards, 1 AGP bridge and also mock irq.hidd. What's the difference between this driver and the pcilinux.hidd? I used that one to develop many different HW drivers for aros. As far as I understood the intention of pcilinux.hidd it is supposed to get access to real hardware that is running under linux. The pcimock.hidd goal is to mock the hardware. For example my dev box is a PCIE system, but I still would like to run the AGP codes paths in nouveau under linux-hosted to check if they don't seg fault. The other case would be to run codes paths for hardware that the developer does not have (Fermi cards in my case). In the case of pcimock.hidd, the AROS driver's code paths will execute as long as you add proper mocking (for example fill in PCI config area or values for registers in BARs). This is an advantage for ported drivers - the code should already work (since it worked on another system) but there might have been mistakes made during porting which can be detected easily with gdb. In case you are writing your driver from scratch, pcilinux.hidd hidd will give you more advantage, since you can actually access the real hardware from linux-hosted. == Misc == ===APL, MPL, BSD, GPL and LGPL Licences=== The majority of AROS sources in licensed under AROS Public License ([http://aros.sourceforge.net/license.html APL]) which (to a degree) protects us from someone taking AROS sources and not contributing improvements back (for example MorphOS took some AROS source and then contributed changes back) It is written to allow the use of AROS code in other open source or commercial projects without exception whilst providing a mechanism so that improvements/additions can find their way back to the original source in one form or another. There are "3rd" party applications used by AROS that do not fall under this license, which are an extra "Contrib" download for convenience. Anyone can port GPL-ed network and sound drivers as AROSTCP and AHI are GPLed. Direct using (porting) [http://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs GPL]-ed code in other parts of AROS (gfx, sata, usb) is not possible because AROS license is not compatible with GPL. You need to utilize permissive licensed code like BSD or MIT/X11. BSD and MPL license are the closest to APL. APL however is not so compatible with LGPL/GPL. LGPL case - you cannot statically combine APL code with LGPL. You can, however thank to LGPL being "lesser" restrictive, use LGPL dynamically loaded libraries in APL codes. GPL case - you cannot combine APL code with GPL in any way if there is no explicit clause by GPLed code authors allowing that. If you do combine APL with GPL in "bad" ways described above - you have a problem (you violate GPL). This problem might result in everything in AROS becoming GPL or everything running or AROS becoming GPL (here I'm not sure really). The other scenario is that you are not allowed to legally distribute such code at all. To be honest I have grasped how to violate GPL, but I'm still no exactly sure what happens when you violate it (but I'm sure it's not anything nice) GPL software can run on top of non-GPL "system components" (see system components exception of GPL), but the other way around (non-GPL using GPL) leads to problems. This means applications like scout, or Quake III are ok (in the majority of cases). Theres no reason GPL drivers cannot be ported - but they cant be in AROS's ROM (requires linking APL code with GPL), nor can AROS depend on them (e.g. they must use existing apis). If they are launched (dynamically linked) by a user action that is allowed. It is also allowed to distribute such binaries together for convenience. GPL is not about statical or dynamic linking but is about executing process and function calls. These components - SFS, isapnp, Zune texteditor, AHi, network drivers, freetype, openuirl, BHFormat, Edit and (" dynamically loaded libraries") are LGPL, not GPL. Mesa/Nouveau stuff is MIT. Some user tools are GPL though. '''AROS (system)''' * system components (libraries/classes/devices/etc) cannot be GPL as they would propagate GPL to complete system as well as GPL is not compatible with MPL from which APL is based * system components can be LGPL v2 or a permissive license (MIT/BSD) * system applications can be anything you like (but still I would prefer APL or permissive so the code can be reused if needed) '''Contrib:''' * no rules - contrib does not impact AROS system since nothing in AROS system depends on contrib. About stealing code: The chances of this happening is exactly the same whether we are APL or GPL. If any closed-source option wanted to do it, there is no one that can validate otherwise. MorphOS has used some AROS codes, but contributed changes back. The rationale behind APL is that while it guarantees that the original developer will get the improvements back (to a certain degree - file based), the person who uses the codes does not have to open his original codes. BSD does not guarantee that the original developer gets improvements. GPL requires the person using the codes to open his codes as well. The copyright holders needs to stay - we just need information from them that the codes are available under APL (for example a checked-in file like in case of Poseidon). We don't do transfer of copyrights. ; Ultimately what can and cannot be done is up to the author(s) - not the licence. ===AROS source code tree=== * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-trunk.txt * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt Found this interesting (non-GPL) licensing 'anomaly' - to keep in mind for distributors. Programs that lose their license if sold ("non-profit only" licensed): contrib/aminet/comm/term/TinyTerminal contrib/aminet/dev/basic/bwBASIC contrib/aminet/text/edit/xdme contrib/fish/aroach contrib/fish/lotto contrib/fish/shuffle contrib/fish/touch + cdvdfs. Here is a list of all the GPL/GPLv2/GPLv3 licenses fossology found, what have explicit licenses in their comments. excluded LGPL, BSD/GPL dual licensed and programs (such as Prefs/Edit and BHFormat) <pre> AROS/rom/dbus/include/ AFL_v2.1 ,GPL_v2+ (supposedly AFL < 3 is GPL incompatible) AROS/workbench/classes/zune/betterstring/include/ GPL_v2+ AROS/workbench/classes/zune/texteditor/include/ GPL_v2+ AROS/workbench/classes/datatypes/gemimage/ GPL_v2+ GPL AROS/workbench/classes/datatypes/degas/ GPL_v2+ AROS/workbench/libs/openurl/README: GPL AROS/workbench/network/smbfs/documentation/ GPL_v2 AROS/workbench/network/smbfs/source_code/ GPL_v2+ AROS/workbench/network/stacks/AROSTCP/bsdsocket/kern/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/mmakefile.src conf.h GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/sys/ CMU ,GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/net/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/api/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/conf/conf.h: GPL_v2 AROS/workbench/network/stacks/AROSTCP/netinclude/net/radix.h: CMU ,GPL_v2 AROS/workbench/devs/AHI/AHI/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/COPYING: GPL AROS/workbench/devs/AHI/Docs/texinfo.tex: GPL_v2+ AROS/workbench/devs/AHI/COPYING: GPL AROS/workbench/devs/AHI/Drivers/EMU10kx/ GPL_v2+ AROS/workbench/devs/AHI/AHI-Handler/ GPL_v2+ AROS/workbench/devs/networks/rtl8029/ GPL GPL_v2+ AROS/workbench/devs/networks/pcnet32/ GPL GPL_v2+ AROS/workbench/devs/networks/ppp/LEGAL: GPL AROS/workbench/devs/networks/atheros5000/ GPL_v2+ AROS/workbench/devs/networks/rhine/ GPL_v2+ AROS/workbench/devs/networks/nForce/ GPL_v2+ GPL AROS/workbench/devs/networks/prism2/ GPL GPL_v2+ AROS/workbench/devs/networks/fec/LEGAL: GPL AROS/workbench/devs/networks/rtl8139/ GPL GPL_v2+ AROS/workbench/devs/networks/etherlink3/ GPL GPL_v2+ AROS/workbench/devs/networks/intelpro100/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8169/ GPL GPL_v2+ AROS/workbench/devs/networks/emac/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8168/ GPL GPL_v2+ AROS/workbench/devs/networks/realtek8180/ GPL_v2+ AROS/workbench/devs/networks/via-rhine/via-rhine.c: GPL_v2+ AROS/workbench/devs/networks/via-rhine/ GPL GPL_v2+ AROS/workbench/devs/networks/e1000/ GPL_v2 AROS/workbench/devs/networks/sis900/ GPL GPL_v2+ </pre> AHI: it has special provisions (COPYING.DRIVERS). The library is LGPL, preferences software is GPL and drivers can be anything without breaking GPL/LGPL. Network stack: well, we are long overdue for a new, IPv6 enabled network stack anyway, anyone interested? ;) Seriously though it seems like the glue code is GPL and as all the drivers. However some of the drivers are our own code, so they could be relicensed to LGPL. Same filter as the AROS trunk list. These should all be libraries or plugins - no programs. <pre> contrib/regina/utsname.h: GPL_v2+ contrib/mui/classes/nlist/include/default-align.h: GPL_v2+ contrib/mui/classes/nlist/include/amiga-align.h: GPL_v2+ contrib/mui/classes/BWins/include/MUI/BWin_mcc.h: GPL contrib/mui/classes/BWins/include/BWin_private_mcc.h: GPL contrib/mui/classes/BWins/COPYING: GPL_v2 contrib/mui/classes/BWins/MCC_BWins.readme: GPL_v2 contrib/mui/classes/thebar/include/default-align.h: GPL_v2+ contrib/mui/classes/thebar/include/amiga-align.h: GPL_v2+ contrib/gfx/libs/wazp3d/LEGAL: GPL contrib/gfx/libs/wazp3d/Wazp3D.readme: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.c: GPL contrib/libs/mpega/ GPL_v2+ </pre> http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt ===Types=== On AROS following rules apply: <pre> 1. BYTE/UBYTE is 8bit, WORD/UWORD is 16bit, LONG/ULONG is 32bit, QUAD/UQUAD is 64bit, the types are comparable with stdint types (int8_t, int16_t, int32_t, int64_t) 2. IPTR/SIPTR are integer types large enough to fit pointer, that is sizeof(IPTR) = sizeof(APTR) = 4 on 32bit system, and = 8 on 64bit system 3. ti_Data in TagList is large enough to hold a IPTR/APTR type. 4. never store a pointer in integer of type LONG. It may work (if the pointer has upper 32bits clear), but does not have to. Compiler should warn you about that. 5. If you are unsure about point 4, allocate your memory with MEMF_31BIT flag set. But don't expect that AROS internals will do the same. </pre> point 4 is actually important. * UBYTE/BYTE for 8bit * UWORD/WORD for 16bit * ULONG/LONG for 32bit * UQUAD/QUAD for 64bit <pre> UBYTE Unsigned 8 bit integer variable (byte). BYTE Signed 8 bit integer variable (byte). UWORD Unsigned 16 bit integer variable (word). WORD Signed 16 bit integer variable (word). ULONG Unsigned 32 bit integer variable (longword). LONG Signed 32 bit integer variable (longword). FLOAT 32 bit IEEE floating point variable. UQUAD Unsigned 64 bit integer variable. QUAD Signed 64 bit integer variable. DOUBLE 64bit IEEE floating point variable. BOOL Boolean variable, TRUE and FALSE are also defined in exec/types.h. VOID Void. APTR A generic pointer for multiple purposes - Arrays. STRPTR A pointer to a null-terminated string. IPTR Really important in AROS, the only way to declare a field that can contain both: an integer or a pointer. </pre> if you want to write really portable app, you may be interested in standard datatypes defined in C99: int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, intptr_t, uintptr_t. They are all defined in inttypes.h include file. In exec/types.h the following short-cuts are typedef'd. They are used often in AROS, so you should nearly always include exec/types.h and soon only they will be removed from sys/_types.h include, all types are now defined in include files named aros/types/xxx.h. (Preparation for C library split; sys/xxx.h include will only be available there when compiling with POSIX C library) Compiler specific types, like int and long might change their size. In case of AROS, similar to linux, int remains 32 bit whereas long grows to 64 bits in size. If you use Amiga-like data types, i.e. BYTE/UBYTE, WORD/UWORD, LONG/ULONG and QUAD/UQUAD or the C99 standard types (uint8_t and so on, see stdint.h include) then you should have less issues to solve than by using types without size guarantee. Of course, all pointers grow to 64 bytes using 64bit cpu. Most of the code can be just recompiled and will work. In rare cases, where e.g. pointers are casted to integers, a special care must be taken. Especially in the cases, where pointer is casted to LONG/ULONG (this code will break on 64 bit AROS) e.g. '#define IPTR ULONG'. With compiler delint patches which the majority of them are simple casting issues to make the compiler happy. Notice some of the changes involve introducing double casts. In very recent versions of GCC. Yes, the bulk of the double casts are for converting 32 bit addresses (ie from a 32 bit PCI DMA address register) to a 64 bit pointer. First cast is to IPTR (to expand to 64 bits, and prevent sign extension if the address is above 0x7FFFFFFF), and then to APTR. ULONG != IPTR except on 32bit .. so if you need to store pointers make sure and use IPTR and not ULONG (which some old code does). For this reason things like Taglist elements are 64bit (since the tag data can be a pointer). If your passing items on the stack you should use the STACKED attribute to make sure they are correctly aligned (on 64bit all items on the stack are 64bit..) There is more issues like using "== 0L" causes problems. ===Endian=== *BE *LE Use the macros from <endian.h> instead making a guess based upon architecture defines <pre> #if _BYTE_ORDER == _BIG_ENDIAN #elif _BYTE_ORDER == _LITTLE_ENDIAN #else + #error <whatever.h> - Byte order for this architecture is unsupported! </pre> ===SVN and GIT=== If you want to help develop AROS OS itself, you can * view current GIT/SVN entries [http://aros.sourceforge.net/ Aros Org website] or [https://github.com/aros-development-team/AROS Github], [https://github.com/ezrec older ezrec mirror], [https://github.com/michalsc/AROS/ older mirror], [https://trac.aros.org/trac/timeline TRAC], [], * awaiting update [http://repo.or.cz/w/AROS.git git repo], [http://www.ohloh.net/p/aros/commits ohloh] or [https://svn.aros.org/svn/aros/trunk/ svn repo] and access [Git version git://repo.or.cz/AROS.git here], * deprecated [https://www.gitorious.org/aros/aros/commit/a7fda9e ARIX commits] or [https://gitorious.org/aros/aros GIT old] If you have SVN access (early 2015 introduced a new SVN server, create a new account at trac aros org) and/or have obtained the source [http://aros.sourceforge.net/download.php AROS site] - you can compile the current build tools/environment using: > make development and follow this [http://aros.sourceforge.net/documentation/developers/compiling.php#building procedure] or [https://github.com/apiraino/aros_guide Guide] https://trac.aros.org/trac#Developing If you plan on contributing back changes, please post information about such changes first on this [http://mail.aros.org/mailman/listinfo/aros-dev/ mailing list] for more experience developers can validate whether they are correct. Then there are the nightly build machines. They svn update before the build and run configure as one of the next steps. autoconf might be added to the nightly build scripts. Our build relies on packages downloaded from Internet (SDL for example) - it always worked this way. The minimal requirement (when just building core AROS) is binutils and gcc. If you build contrib as well, you need many more packages to be downloaded. https://gitorious.org/aros/aros/commits/crosstools-II git://gitorious.org/aros/aros.git Branch crosstools-II there is only one commit on top of ABI_V1 <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-x86_64 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-x86_64 </pre> and <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-i386 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-i386 </pre> build OK. :''More information: [[Aros/Developer/Maintainer|AROS Maintainer Docs]]'' ===SDI Calls=== Integrate the 'SDI'-headers to allow easier porting to all amiga-like platforms. <pre> PUTCHARPROTO( PutTheChar, char c, struct SPrintfStream *s ) { // REAL CODE } </pre> have "SDI_compiler.h" and "SDI_hook.h" included its more organized like #include SDI/SDI_hook.h than #include SDI_hook.h option 1 --- i also use when back porting from amiga's.. <pre> #ifdef __AROS__ #include SDI/SDI_hook.h #else #include SDI_hook.h #endif </pre> also you can add the -i include/sdi/ location if you do not want to add or edit any files. Defining HOOKPROTO to IPTR name(struct IClass * cl, Object * obj, Msg msg); solved the problem A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. examine compiler/include/aros/symbolsets.h (AROS_LIBREQ) compiling mui stuff for aros setting -std=gnu99 is necessary (i have had -std=c99 most of the time). ===Locale with Flexcat=== Most languages have a locale, but not every app is localized, the only thing needed is to translate the "catalog" files. It is a case of locating the correct catalog and saving the translated version. For every app that lacks of your language catalog and is localized anyway, you should find (in the sources) files related to locale: * file.cd = catalog descriptor, contains base msg, with internal language (usually english) * language.ct = catalog translation, contains every translated msg, indexed as in the file.cd. Compare with other localized apps... Then, "make my_app-catalogs" should create and install your translated catalogs. ex : for, saying, sys:prefs/wanderer: on root of AROS sources, type: "make workbench-prefs-wanderer-catalogs" then (if you changed the .cd file): "make workbench-prefs-wanderer" For apps not localized, you have to adapt their code to support it, if it is possible... noticed the original .cd file has many (//) strings at the end of any voice, so added them also to the .ct file. That (//) is only for cd files. I'm highly recommending to use FlexCat for updating ct files, e.g. like this: flexcat app.cd deutsch.ct newctfile deutsch.ct You'll get error checking and new entries are marked in the resulting ct file. When editing .ct files, only change those lines containing translation and perhaps version string, nothing else. The rest is up to the relevant tool, flexcat. In order to update your translation, type in the following in your shell: flexcat xyz.cd xyz.ct NEWCTFILE xyz_upd.ct COPYMSGNEW This way you will not only make sure you have correct translation file but flexcat also pre-fills newly added strings with "*** NEW *** text. Even better tool for checking cd/ct/catalog files is catcheck, but this one is sadly only available for AmigaOS/68k... Some languages have variations, like portugues from portugal and portugues from brasil differs... This is the way to go. I will have a look at language files, but basically if those two languages differ you have to do two separated set of translation files, yes. (you could create a brazilian slang language localization too) * At system level localization for one language is a dot language file. (ex: locale:languages/klingon.language) * At app level localization is a dot catalog file (ex: locale:catalogs/klingon/system/libs/dos.catalog) * At sources level, the dot ct file, and "$language" dot cd files and some building framework. (ex: catalogs/my_app.ct catalogs/klingon.cd catalogs/mmakefile.src support.c support.h) Please, use Flexcat to generate CT files: FlexCat wanderer.cd NEWCTFILE=deutsch.ct Then fill the first 2 lines with something useful: <pre> ## version $VER: wanderer.catalog 1.1 (9.2.2006) ## language deutsch </pre> You can even update the CT-File: (This adds the new strings) FlexCat wanderer.cd deutsch.ct NEWCTFILE=deutsch.ct To compile a catalog you only need the .cd file and your translation (.ct file): FlexCat multiview.cd deutsch.ct CATALOG=MultiView.catalog [http://murks-ide.svn.sourceforge.net/viewvc/murks-ide/trunk/src/Catalogs/flexcat_linux?revision=100 Linux version of FlexCat] : [http://aros.sourceforge.net/documentation/developers/app-dev/localization.php#localization-for-non-developers More information] A script which compares the required version (i.e. the version which an application/module etc. tries to open) with the version of the existing CT files. The result is in this table: https://github.com/aros-translation-team/translations/wiki/Progress The following cases are highlighted: n/a i.e. CT misses at all version in existing CT file is lower than the required version It might be a bit difficult to participate if you haven't worked with Git before but alternatively you can send your CT files to our Slack channel. When the ct file has been generated via flexcat (flexcat keyshow.cd NEWCTFILE=spanish.ct) it has the following header: --------------------------------------------------------------------------------------------------------------- ## version $VER: <name>.catalog <ver>.<rev> (04.01.2021) ## language nolanguage ## codeset 0 ; --------------------------------------------------------------------------------------------------------------- Those values <ver>.<rev> are the version and revision of the CT file for the languaje or are the values of the application being localized? The <ver> part must match with version which the application tries to open. You can find the value either in the column "Required Version" in the table which I've linked above, our you can look in the git repository. For keyshow it would be https://github.com/aros-translation-team/keyshow. You can find in the file "catalog_version.h" the right version number. The <rev> part starts for new CT files with 0 and should be increased every time the CT file is updated. Updated several files and created a few more that were missing on the spanish catalog. The catalogs are in Git repositories at https://github.com/aros-translation-team a) You tell me your Github user name. I'll invite you. You can work directly with the Git repositories. b) You create Github forks of the catalog repositories and create pull requests. c) You send the CT files to mrustler gmx de ===C Utils Misc=== The AROS source uses at several places the __DATE__ macro to fill the date entry of a $VER tag. Problem is that c:version doesn't understand that date format (e.g. "May 21, 2011"). As a result the output of e.g. > "version c:shell full" contains "(null)". Is extending the version command to understand the format of __DATE__ the right solution for that problem? AmigaOs compilers should use __AMIGADATE__ macro or similar form, if it isn't implemented it could be emulated in makefile: -D__AMIGADATE__=\"$(shell date "+%d.%m.%Y")\" BTW. I think DD.MM.YYYY is better format than "Month DD YYY" because "Month DD YYY" is not localized in any way. "strnicmp" shouldn't work with NULL pointers The Situation: compiled a linklib using c++ object files (using the c++ cross compiler). compiled a C stub that uses the linklib (using the c++ cross compiler). Try to link them together (using the c++ cross compiler) with C object files (using the normal target c compiler) that need to use -nostartup = cant do because using the c++ files pulls in arosc (for stdio etc.) - so wants to have the autoinit stuff present. What can I do about this?? If it is possible to manually open it then what do I need to do exactly? === ENV === The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. 99% of the time that statement is true (not required) for pretty much every file in ENV: or do people change their default icons - and prefs settings - every boot? There seem to be a bad habit of late with developers changing things to reflect their own personal preference when the change isn't actually necessary - It would be nice if people could refrain from doing that in the tree without at least discussing it on the dev-list first (and with good reasoning unless they committed said work in the first place..) We're not keen on the pollution of the "S:" dir: it's meant to be for scripts. What's wrong with "ENV:"? Only the fact that it takes up RAM. I understand that for PCs with several gigabytes of RAM this is irrelevant. But let's remember about other machines. The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. How about implementing in the style of HappyENV then? RAM-disk handler that falls through to reading from ENVARC: if there is no such file stored in it already. Removes RAM usage for unchanged files, removes the need to copy ENVARC to ENV in startup-sequence. Shouldn't be too hard to make from AmberRAM, or even just extend AmberRAM to provide this service. Is it feasable to build a special version of AmberRAM handling ENV: that will try and copy the requested file from ENVARC: if it isnt found in ENV: ? Additionaly it could mark closed "files" as untouched - and expunge them from ENV: after a period of time to free up additional RAM:, or when the system is running low on free memory? Silenty disappearing files may not be a good plan. Would be nice if the following would work: ASSIGN :ENV SYS:Prefs/Env-Arc ADD ASSIGN :ENV RAM:ENV ADD Where new files put in ENV: end up in RAM:ENV, and opening files looks in RAM:ENV first, then SYS:Prefs/Env-Arc Well - that's essentially what im proposing but without the assigns - or need for a RAM:ENV directory. Adding it as a feature of AmberRAM sounds like the most memory efficient way (one handler to load in RAM) but that's only if it is possible to make it handle ENV: additionally to RAM:, and if it is even possible to add the proposed functionality (...and how to make it enable it when accessing ENV:). ===(AS)MP support=== If one has to recompile software for SMP multi core, is there any thing special one has to do to get software to run? Use task.resource if you need to query information about what tasks are running, and clear msgports completely when they are allocated. Most code should not need Forbid. Use Semaphores, Messages etc. to sync your own code. Accessing system structures is a different thing. Use the proper API whenever possible. How single structures will be protected in the future is still a moving target, at least it is not documented. And you should never use undocumented stuff Ideas on for SMP multi-core Another suggestion is ... Forbid/Permit function calls are meant to halt multitasking so as no other task could intervene with what ever the calling task is doing, e.g. setting semaphores. Disable/Enable calls are meant to halt interrupts and as a side effect they also halt task switching. One option is to make it compulsory to protect shared resources with semaphores and forbid the use of simple Forbid() calls as to protect something. Setting semaphore should be done if possible with atomic instructions (check and alter in one instruction). Or make the second concurrent ObtainSemaphore call halt the second calling task and force if possible a task switch which ever gives better results. Semaphores could store the owning tasks task pointer instead of boolean to make things easier. As long as the CPU initiates the DMA transfers through the OS, and the OS ensures that the transferred memory is within the region accessible to the user initiating the transfer, everything is fine. The CPU is the conductor, and the CPU by that has the control of which DMA transfer is initiated and which is not. All you need to do is to write device drivers reasonable. Hint: CachePreDMA and CachePostDMA exist. All the Os has to do is to verify that the memory regions to be transferred are valid, and prohibit direct access to the DMA control registers from user space. None of these algorithms imply huge costs. The current OS design doesn't really allow virtual memory in first place, Forbid() is again the problem. [http://www.tbs-software.com/guide/index.php?guide=autodocs.doc%2Fmemory.doc&node=1 memory.library API] seem to low level. IMHO the programs should not know how the swapping is implemented. I would just go for one new memory flag MEMF_SWAPPABLE that indicates that a certain memory region or a whole memory pool won't be accessed during Forbid()/Permit() etc. It only solves part of the problem, it only implements virtual memory and not memory protection. For the latter you need to be able make certain memory inaccessible by other programs, some memory read-only for one task and read-write for other tasks, etc. And I think this should be done in the same Address Space in order to avoid you constantly need to swap between different address spaces. So to summarize, if there are programs using this API we may provide a wrapper layer to get them working but I am not convinced this API should be the reference API with whom to provide VM to AROS programs. === Variadic === variadic functions (i.e. functions with an arbitrary amount of arguments). <pre> #include <stdarg.h> [...] char * STDARGS GetKeyWord(int value, char *def, ...) { [...] va_list va; [...] va_start(va, def); [...] va_end (args); </pre> Please keep with using stdarg rather than having va casted to a LONG * type and varargs handled manually. Doing so, prevents tons of casting, where a simple va_arg can be used. So, string = *((char **) args) instead of string=va_arg(va, char *). <pre> #include <stdio.h> #include <stdarg.h> int printf (const char * format, ...) { int retval; va_list args; va_start (args, format); retval = vfprintf (stdout, format, args); va_end (args); fflush (stdout); return retval; } /* printf */ </pre> Couldn't find varargs.h or stdarg.h. and have no use for AROS_SLOWSTACKHOOKS or AROS_SLOWSTACKTAGS. GCC looks for stdarg.h in a different place: /bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/include/stdarg.h Here is a path for a "normal" header: bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/../../../../i386-aros/sys-include/aros/system.h The use of vararg.h isn't supported by newer gcc versions. If you want your code to run on architectures that pass part of variadic arguments in a number of registers you need to use AROS_SLOWSTACK macros. Otherwise your program will not work on powerpc and x86_64 ports. Of course the SLOWSTACK stuff is not needed in a function that can use va_list, va_start, va_arg and va_end. It's only needed if you want to write functions like DoMethod or similar. #include <stdarg.h> should be enough no matter if you do cross or native compiling. If it does not work, something is wrong and should be corrected. Stdarg.h is here, Development:lib/gcc/i386-aros/4.2.2/include/ ...which is part of the compiler's default include paths. In other words, #include <stdarg.h> works out of the box, indeed. (sorry, I should have just tried it before invoking "search" or "find"...) furthermore, myprintf() as shown above won't work, because... printf(format, args); ...is wrong - the second argument does not match printf() prototype, it expects a argument list, but args is of type va_list (obviously) - so one has to use... vfprintf(stdout, format, args); ...instead, just like in the original printf(), and add fflush(stdout). additionally, one could use... int myarg = va_arg(args, int); ...between va_start() and va_end() to access individual arguments, where each call to va_arg() returns an argument casted to the desired type (here: "int") from the list given (here: "args") and advances to the next one. wrapping up vfprintf() and modifying the format string now is a major speedup! no more backslash-n typing! this has been haunting me for years! On MOS and AmigaOS, the NewObject variadic function is kept in the static library. It takes most of the parameters on the stack - thanks to that the implementation of NewObject calls the NewObjectA function. Everything works perfect, and the typical MUI macros may be easily used. This, however, is not the case when you compile for AROS. Here, NewObject is a variadic macro, not a function. Thanks such approach we do not need any custom compiler in case of systems, where the arguments of variadic functions are passed partially through registers and partially through the stack (This is the case of PPC and x86_64, this is also the reason why both OS4 and MOS require specially patched compilers). Since NewObject is a macro, the gcc's preprocessor expects the list of macros arguments enclosed within parentheses. In MUI macros it is not the case. Imagine the following test code: <pre> #define foo(a,b) ((a)+(b)) int loosy_function(int a, int b) { return foo(a,b); } </pre> This will compile and work, but the following piece of code: <pre> #define foo(a,b) ((a)+(b)) #define END ) int loosy_function(int a, int b) { return foo(a,b END; } </pre> will fail with the error: unterminated argument list invoking macro "foo" There are two ways of fixing your issue. Either create your new objects outside this huge MUI constructions, and in there use just a pointer, or get rid of the "End" macro and exchange it with "TAG_DONE)". Badly written software is, for example, casting va_list to an APTR or even doing so as if va_list were a plain table of function arguments. Such code needs to be fixed because it has very few chances to work anywhere but on author's machine ;) The problem is nOt that they assume sizeof(APTR) == 4, its that they often do not use APTR, and use ULONG to store pointers exclusively. If the code used APTR/IPTR as it should - most of the "problems" wouldn't exist. It would also help if people would start using variadic arguments properly. Many coders do assumptions which shall never be made. Instead, they should consider using stdarg.h file and all the va_* functions :) ===ABI=== In the head of our SVN repository there are now only 3 directories: <pre> admin/ branches/ trunk/ </pre> We have added two extra dirs there: tags and imports As discussed when we branch ABI V0 and [[Aros/Developer/ABIv1|ABI V1]] it would also be good to introduce tags. Normally this is done in a directory in the repository called tags. Currently we don't have this directory there. (We do have branches/tags that is a hack I have done because one doesn't have write access in the top directory. I think this directory is not clean and should be removed). The second directory I would introduce is an imports directory for implementing vendor branches as discussed in the svn [http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html book]. Currently we use code from several different projects and that code is stored inside the AROS tree; we seem to have problems with keeping this code up to date and merge our changes upstream. Maintainers of up stream projects like the MUI classes etc. have complained about this (to put it lightly). Introducing these vendor branches would make it easier to see what changes we have made and make patches to be sent upstream and make it easier to import newer upstream versions of their code. Although can't "copy" the vendor branch into the main branch because it's already there, so start with a "merge". Yes, the first step to make the code already in the repository compatible with the vendor branches will be the most difficult. The best way to do it the following way: * first import the version on which the current AROS code is based into the vendor branch * then import the new version over it in the vendor branch * finally merge the difference between these two version in the AROS code present in the repository. For example, place NList directly under vendor and not in a subdirectory like "contrib/zune/classes". Actually after we have a stable [http://aros.sourceforge.net/documentation/developers/specifications/drafts/abiv1.php ABIv1 (2012 or later)]. We need to move away as much as possible from the contrib directory to some other repositories. The reasons are ... * The AROS repository should be for the core AROS code. * other contrib projects should be tried to be compiled for all Amiga-like OSes. * The release scheme for AROS and the other programs should not have to be aligned. * Binary versions should be provided on aros-archives and on aminet and/or OS4Depot to install them. (Some clever programs should maybe be provided to make the life of distribution developers easier). * avoid parallel forks of programs for AROS and the other amiga OSes. If there is really a need for a place for hosting AROS projects we may investigate setting up such a server but then including bug tracking, governance, maillist, etc. for each project separately. I personally think there are already enough places like sourceforge, google code, savannah, etc. where people can go for hosting such projects. ==Links== * http://amigadocs.hokstad.com * http://amigadocs.hokstad.com/doku.php?id=dev-links In the future...? *AROS 64bit - SMP, Vulkan with OpenGL compability layer *AROS 32bit - keep for historic reasons What would you like to see implemented in AROS? ABIv1 completed, SMP (x86_64), SendMsg()/GetMsg() to support memory protection between target and destination, in that order. Michal Schulz and Jason McMullan have been toying with the question "What are the minimal changes needed to the AmigaOS 3.1 API to support SMP"? The answer so far seems to be "few, but subtle". For example, SysBase->ThisTask is no longer meaningful on SMP, but FindTask(NULL) is. Disable() and Forbid() are shockingly bad on performance, but adding a spinlock semaphore mode to SignalSemaphore will help new code on SMP. Leveraging a 'common' OS with a lot of machine support (Linux, MacOS, Windows, QNX, etc.) is something that AROS has been doing for quite a long time, and it is the biggest strength of AROS. This AROS experience and programming model, in the same way the Google's Android layers on top of Linux, or MacOS X layers on top of the Darwin/BSD kernel, as a first step * The graphics + layers subsystem could be implemented as a shim on top of a OpenGL ES implementation (ie on any modern Linux system, or the RaspberryPI's hardware, MacOS X, etc). - This also allows every window to be on its own 3D surface with backing store, allowing Wanderer (or a Commodity) rearrange/zoom/animate app windows without having to send a pile or refreshes to them * Use OpenAL as the sound backend * AROSTCP would be a thin layer over the native OS's TCP/IP stack * dos.library, poseidon.library, and input.device would be slim shims over the native APIs * If we move to loading all libraries' into the application's task space, instead of a single global instance of the library, this will allow SMP and MMU more easily. - Yes, it will require a lot of work in the libraries to make this transition - Yes, I do think it will be worth it in the end. * A 'fat binary' install format (or, maybe LLVM bytecode) that can be 'flattend' to the target architecture on installation. So, what would this 'AROS of the future' look like? * AmigaOS 3.x style API, with certain 'fundamental changes' to message passing * Uses the underlying OS' device drivers, so more AROS developer effort can go to user-visible features and bugfixes * Allows AROS applications to run side-by-side with the OS's native apps And why would anyone want to program on such a system? * AROS applications would run on any system that has the AROS Framework installed * AROS applications are pixel-for-pixel the same on all platforms. * Develop with the knowledge that you are guaranteed OpenGL and OpenAL, and the rest of the AROS Framework an option for mmake to dump its dependency of metatarget in a graphviz[*] input file. This should make it possible to visualize the dependencies and hopefully be inspiration for cleaning up some mess, circular or unneeded dependencies and so on. AmigaOS gcc 9 [https://franke.ms/amiga/gcc.wiki Old versions] able to create binaries for AmigaOS and [https://eab.abime.net/showthread.php?t=93813 Upgrading gcc versions] ==References== {{reflist}} {{status|50%}} {{BookCat}} t8xy7wn0fkpwqjx4rx8fwu6zq75kcd8 4668983 4668982 2026-09-05T18:34:53Z Jeff1138 301139 4668983 wikitext text/x-wiki {{ArosNav}} ==A technical overview of AROS== Google translation [http://translate.google.com/translate?hl=en&sl=auto&tl=de&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs German], [http://translate.google.com/translate?hl=en&sl=auto&tl=fr&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs French], [http://translate.google.com/translate?hl=en&sl=auto&tl=it&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Italian], [http://translate.google.com/translate?hl=en&sl=auto&tl=es&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Spanish], [http://translate.google.com/translate?hl=en&sl=auto&tl=hi&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Hindi], [http://translate.google.com/translate?hl=en&sl=auto&tl=zh-CN&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Chinese], [http://translate.google.com/translate?hl=en&sl=auto&tl=ru&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Russian], [http://translate.google.com/translate?hl=en&sl=auto&tl=pl&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Polish], [http://translate.google.com/translate?hl=en&sl=auto&tl=pt&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Portuguese] {{Uncited}} AROS,<ref>[http://aros.sourceforge.net/download.php References and sources]</ref> like AmigaOS (TM), is a [[w:Message passing|message-passing]], [[w:Preemption (computing)|preemptive]] [[w:Multitasking|multitasking]] [[w:Operating system|OS]]. It uses [[w:Reentrant (subroutine)|re-entrant]] shared libraries to save memory space. AROS is based around an executive library kernel (Exec) and two other libraries: * Exec (the "kernel", which is not a kernel in the modern sense), * Intuition (graphics and GUI, integrated into the system) and * AmigaDOS (Disk Operating System, the Metacomco's Tripos modified to work with Exec). The design philosophies of AmigaDOS and Intuition are rather different, the former adopting a C-like API and the latter creating an [http://www.basden.demon.co.uk/amiga/amiga.oo.html object-oriented], message passing aware environment for the programmer. The system base is the only absolute address in AmigaOS (located at 0x00000004) this does differ with AROS as AROS SysBase is automatically provided (no $4) but everything else is dynamically loaded. The OS is well known for delivering high performance due to its close connections with the hardware, while simultaneously having the flexibility to support re-targetable graphics (Cybergraphics) and retargetable audio subsystems (AHI). : Diagram showing relationships of libraries to system needed Remember, AROS is a [http://en.wikibooks.org/wiki/Aros/Developer/ABIv1 research] operating system, and while all contributions to the base AROS code are welcome, please contact the dev list first for any core changes. Writing applications for AROS does not have this requirement. While AROS appears and feels almost feature complete, it is still [[Aros/Developer/IncompleteAPIs|missing a small number of functions]] from the Amiga API. [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1201 This thread provides] information for setup, [http://www.aros.org/documentation/developers/index.php documentation] and whether you are interested in core OS changes and/or writing/porting software apps *you compile directly under AROS, which can be running on either real hardware, virtual hardware *in hosted mode under linux/window, cross-compile from that host OS (save your files as ISO-8859-15 encoding instead of UTF-8) [https://github.com/BlitterStudio/aros-compiler-docker Docker images] '''The repository''' for 64bit and 32bit ABIv1 all hardware platforms is [https://github.com/aros-development-team/AROS current development version]. There are many forks of this so that developers can work on their own and forward changes at a later date as discussed on the dev forum 64bit PC is one of two hardware platform with another fork called [https://github.com/deadwood2/AROS abiv11] which is used for Aros One x64 PC 32bit PC is the other fork [https://github.com/deadw00d/AROS/tree/alt-abiv0 repository for current stable PC version ABIv0 with backported ABIv1 features is located which is used on AROS One and Icaros x86 32bit based distros] this is for historic reasons Any [https://github.com/aros-development-team/AROS/issues bugs / issues can be added for ABIv1 issues]. The two individual PC forks have their own issues tab on their github webpages We have a [https://arosdevteam.slack.com/archives/CUFV48U3H slack here], discord on [https://discord.gg/UKp9qdEBuQ Discord@AmigaDev], ==Software Development for AROS== ===Programming languages=== ====Common to all==== 'The Developer Environment', which primarily supports C/C++ code, there are other programming languages available for AROS: '''Scripting''' :[[Aros/User/DOS|DOS]] :[[Aros/Developer/Docs/LUA|LUA]] :REXX [[Aros/Developer/Docs/Rexx|Regina (AROS' ARexx)]] ====Needs to be compiled/ported==== ::[[Aros/Developer/Docs/LLVM|LLVM]] ::Python [ Info], [], ::[https://ae.arosworld.org/index.php?board=11.0 FreePascal FPC Aros-Exec thread], [https://archives.arosworld.org/index.php?function=browse&cat=development/language fpc arm here is very old and will not work], FreePascal for AROS has its own [http://fpcaroswiki.alb42.de/ Wikibook], ::[http://sourceforge.net/projects/xamos/ X-Amos Basic] ::[http://sdlbasic.sourceforge.net/ SDLBasic] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[[Aros/Developer/Basic/Basic4SDL|Basic4SDL]] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[http://alvyn.sourceforge.net/ Alvyn] ([http://www.dusabledanslherbe.eu/AROSPage/MISC.14.html download]) ::[http://www.airsoftsoftwair.com/ Hollywood when enough users warrant a port - paid one time fee language] ::[[Aros/Developer/Docs/E|AmigaE Portable E]] ====Hardware Restricted==== '''Basic''' :[http://amos.pspuae.com/AmosProManual/contents/c1.html '''Amos Pro'''] [http://amos.pspuae.com/index.php?action=forum#1 compatible] [http://www.amigacoding.com/index.php/Main_Page commands] (all incomplete) :'''Blitz Basic''' [http://aros-exec.org/modules/newbb/viewtopic.php?post_id=46537#forumpost46537 none on AROS] :: [http://www.amiforce.de/main.php Amiblitz] on amiga(TM) emulator :'''Amiga Basic''' :: [ ACEBasic] '''Misc''' :Ruby [http://www.ruby-lang.org/en Info]/[https://archives.arosworld.org/index.php?function=browse&cat=development/language Ruby 32bit PC], ===Where to get the C/C++ Environment=== If you want to develop for AROS, its generally easier to be running linux hosted AROS development environment especially for C++, cross compiling the code. That's how most developers now are doing it. g++ is used to compile owb web browser as well as some other AROS software. If you were hoping for a rich set of C++ libraries or classes defined for the OS feature set, you might be disappointed. AROS Native compiling is possible, but you're much more likely to run into the odd bug(s) in the dev environment since it gets little testing and fixing by other developers. Is there a sftp software or scp over ssh available? Maybe. At least the security part would be handled by [https://github.com/jens-maus/amissl amissl] [https://archives.arosworld.org/index.php?function=browse&cat=network/misc port]. [https://github.com/BlitterStudio/dopus5 DOpus5] has recently added sftp support. See here for a [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1974&highlight=ssh&pid=12073#post_12073 ssh scp client] [https://arosdevteam.slack.com/join/shared_invite/enQtOTc4Mzg0NDIzNzQ0LWQ2NWZmNmMwNGIwNGEyNTgxNzU3MGFjMTk3ZThmOTQ1MTVjMzhmNTllYWQ0ZTUxMjBjMGE0Y2VjMDJmNTc5MzI#/shared-invite/email Slack Dev Forum] ====Cross compilers from Windows or Linux==== *Windows WSL2 walkthrough can be [https://arosnews.github.io/how-to-cross-compile-aros-hosted-wsl/ found here] you want to build AROS. No problem. Here are instructions for PC 64-bit: https://github.com/deadw00d/AROS/blob/master/INSTALL.md Here are instructions for PC 32-bit: https://github.com/deadw00d/AROS/blob/alt-abiv0/INSTALL.md And as always has been the case you can use the contrib archive to 'obtain' the development directory which contains the /native/ AROS gcc compiler and tools. That compiler is used to build AROS itself but can be used outside the AROS build process by providing --sysroot with indicated directory to cross compile for AROS. '''64 bit''' '''32 bit''' A good option for multiple OS is [https://axrt.org/index.php?tab=download-aros AxRuntime lets developers compile their Amiga API-based applications as Linux binaries being able to utilize modern development tools available on Linux, like IDEs, debuggers, profilers, etc] Older 32bit guides for Linux hosted compiler Please install these packages before moving to next step. Below is a reference list for Debian-based distributions. Reference build system was Ubuntu 18.04/20.04 amd64. subversion git-core gcc g++ make gawk bison flex bzip2 netpbm autoconf automake libx11-dev libxext-dev libc6-dev liblzo2-dev libxxf86vm-dev libpng-dev gcc-multilib libsdl1.2-dev byacc python-mako libxcursor-dev cmake zsh mingw64 Do all of these operations under home directory of your user or another directory where your user has write permissions. Specifically, in a section "Linux-i386", be sure first to build the cross-compiler (toolchain-alt-abiv0-i386) and only then AROS itself (alt-abiv0-linux-i386). Clone & build <pre> $ mkdir myrepo $ cd myrepo $ git clone https://github.com/deadw00d/AROS.git AROS $ cd AROS $ git checkout alt-abiv0 $ cd .. $ cp ./AROS/scripts/rebuild.sh . $ ./rebuild.sh </pre> Now to the build selection below - Linux-i386 Select toolchain-alt-abiv0-i386 - Select alt-abiv0-linux-i386 (DEBUG) Start AROS by: <pre> $ cd alt-abiv0-linux-i386/bin/linux-i386/AROS $ ./Arch/linux/AROSBootstrap </pre> Pc-i386 Select toolchain-alt-abiv0-i386 (if not built yet) - Select alt-abiv0-pc-i386 ISO image available in alt-abiv0-pc-i386/distfiles Now that we have linux-hosted build, we can resume native (option 2). Run ./rebuild.sh and selection option 2. Wait until it finished, then: <pre> $ cd alt-abiv0-pc-i386 $ make </pre> Now <pre> $ make bootiso </pre> Now, your compiler is located in toolchain-alt-abiv0-i386 directory and named i386-aros-gcc. Includes are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/include and libraries are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development.lib. This is how then can be passed to the compiler: /home/xxx/toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot /home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development -L/home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/lib ../toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot bin/linux-i386/AROS/Development local/helloworld/helloworld.c -o local/helloworld/helloworld Another method was using Debian like distros and download the gimmearos.sh script (on [http://archives.aros-exec.org/index.php?function=browse&cat=development/cross aros-archives]) to setup the developer environment by downloading necessary packages ... The gimmearos script is a good start in that direction, building the cross compilers and hosted AROS environment, but gimmearos.sh might be out of date or not be completely compatible with any given linux distro. In order to do that, you have to compile AROS yourself. Download AROS source archive not contrib. Compile AROS by entering the main directory ./configure make ([http://aros.sourceforge.net/documentation/developers/compiling.php More on compiling AROS]). The result will be a basic AROS system without development tools. To compile C++ on Linux, type 'make gnu-contrib-crosstools', creating the cross-compilers in ./bin/linux-i386/tools/, named i386-aros-gcc, etc. '''Note''': Currently, to make the cross compilers usable copy 'collect-aros' from tools/ to tools/i386-aros/bin/. At the moment the cross compilers if used from the Linux command line will only find it when it's there. If you want to compile native compilers (the Developer Environment), type 'make contrib-gnu-gcc', creating native compilers in AROS' System:Development/bin directory. When the output needs to be stripped <code>--strip-unneeded --remove-section .comment</code> The Obj-C backend should build out of the box. Open contrib/gnu/gcc/mmakefile.src and search for the line which contains "--enable-languages" and add "objc" to the list of languages that follows it. --enable-languages=c,c++,objc Better make it—enable-languages=c,c++,objc,obj-c++ ObjC++ is broken as soon as you try to use exceptions, but that might change in future GCC versions and it does not hurt having it there already. Do you need a cross-compiler or a real compiler? In the first case you can get away with just downloading the proper gcc archive, apply the patch and proceed with the normal gcc build. In the case of a real cross-compiler then when downloading the contrib sources, also need to download the normal sources, place the contrib sources into a directory called contrib, need to install autoconf+automake+perl+python, call ./configure, cd into the subdirectory and type make. to rebuild GCC with host == build == target == i386-pc-aros. So just get the vanilla sources and apply the patches without bothering about the build system? [https://vmwaros.blogspot.com/2019/10/a-pre-configured-development-machine.html pre-configured VM environment vmware virtual machine to develop AROS and AROS software] ====Native compilers for AROS==== Namely gcc for C or g++ for C++ are supplied with the [[Aros/Developer/Docs#The Developer Environment|Developer Environment]], which is already '''setup''' and part of any current AROS distribution like AROS One or the nightlies * Current GCC 6.5 (32bit) though moving to 10.5 and 15.1 (64bit) * Older software components. GNU GCC 4.x GNU BinUtils, GNU Fileutils 4.x, GNU Textutils and others usually deprecated On single partition systems and the Boot ISO, the AROS Developer environment is installed under "SYS:Development/". Systems with multiple partitions - such as a Work: partition - tend to install it to there instead, however it can be installed manually to any location. Please remember, if moving, that you will need to correct the Development packages 'install location' env variable to point to the new locations root - look in SYS:S/startup-sequence. <pre> Assign Development: SYS:Development Assign C: Development:bin ADD </pre> In the aros build instructions. you need to check out contrib and/or ports into your AROS source directory, as subdirs. then, assuming you are building in an external build dir, as you should, you simply configure and "make contrib" for instance or whatever submodule you might want to build. ===Beginners Tutorials in C C++=== As AROS is [http://eab.abime.net/showthread.php?t=29856 C based] API compatible to AmigaOS 3.x, so most of the information on programming C on the Amiga applies to AROS as well. Please note that there is a lot of AmigaOS 1.3 (1985-1989) and [https://www.markround.com/amigaguide AmigaOS AOS 2.x (1990-1992)] information around but OS3.1 is recommended but limited in amount. Brief overview of what is required to write AROS Applications # Using [[Aros/Developer/Docs/Libraries/Intuition|Intuition]] for basic screens/windows # Using graphics within windows via 8bit [[Aros/Developer/Docs/Libraries/Graphics|graphics]] and so onto 15-16-24bit [[Aros/Developer/Docs/Libraries/CGFX|cybergraphx]] # Load and save work to [[Aros/Developer/Docs/Libraries/DOS|dos]] disk drives # Using the [[Aros/Developer/Zune|ZUNE GUI Environment]] Writing native games require this extra information # Using [[Aros/Developer/AHIDrivers|AHI audio hardware independent API]] # Using USB joystick/joypad with the Poseidon USB stack through [[Aros/Developer/Docs/Libraries/LowLevel|LowLevel]] library Additional features that could be added later # Adding additional [[Aros/Developer/Docs/Libraries/Locale|Locale]] language translations to your program # Adding a [[Aros/Developer/Docs/Rexx|AREXX/Regina]] port to your application # Executing Amiga(TM) [[Aros/User/DOS|DOS]] commands from your application # Using [[Aros/Developer/Docs/Libraries/Icon|icons]] (.info files) and icon tooltypes (stack, version, and program startup options) # Local couch or IP based SANA2 networking co-op multi player gaming support Most AmigaOS programming books are nowadays very much out of date as most are from the late 1980s and do not cover later amigaOS releases like 3.1 for example, Rob Peck's book "Programmer's Guide to the Amiga". The Amiga ROM Kernel manuals aka RKMs like Libraries (3rd edition), Devices (), the AmigaDOS manual (3rd edition) and the Style Guide may have their uses. There are some reference examples from AmigaMail and Devcon notes (available again on an Amiga developers CD 2.1). For Arexx then "The Amiga Programmer's Guide to ARexx" by Eric Giguere, which was published by Commodore is useful as well as an "Arexx Cookbook". Curly brackets missing - try SHIFT + ALT + 7 or 0. * Beginners C Guide [http://www.iu.hio.no/~mark/CTutorial/CTutorial.html C Tutorial], * [http://thecguru.com/ C for beginners], * [http://fresh2refresh.com/c/c-basic-program/ C programming basics] for students, * [https://www.edx.org/courses Free Online course] from American Universities * Reference Amiga [http://amigadev.elowar.com/ API reference]. * AROS based c source can be found [[Aros/Developer/Docs/Examples|here]] and lots of example code can be found inside [https://github.com/aros-development-team AROS sources] themselves and from the contrib section of the archives from [https://github.com/aros-development-team/contrib Aros site], and study the AROS applications source code, e.g. the test programs from the Tests drawer (folder/directory). Take a look at the code of some smaller AROS programs might be a better and more up to date When you upload your builds, please write the architecture (like i386-aros, x86_64-aros, armPi-64 etc.) in the archive name and it is also advisable to write in the field "Requirements" what ABI (ABIv1 or for PC forks ABIv11 or ABIv0) ===Compiling C/C++ Code=== Native, although we have a IDE Integrated Development Environment (Murks), it does lack a debugger. Whilst others use a combination of a text editor and shell to edit code. Most though use an AROS hosted on Linux to take advantage of the better GCC tools like GDB and various IDEs. Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w (or F12 and w) within the directory with the source code. Type in sh to change the amiga shell into a unix shell. You can then type in ls (unix equivalent to amiga dir). Take a look [http://en.wikibooks.org/wiki/Linux_commands here] for more commands. For a single file program-name.c or program-name.cpp gcc -o program-name program-name.c or g++ -o program-name program-name.cpp or g++ -o test -Wall -g main.cc texturelib.cpp xmodelib.cc -lsdl -lgl To close the shell, click on the top left-hand corner to close (twice). Once to get back the aros shell and then again to close finally. Use [http://freshmeat.net/projects/cksfv/ cksfv] as a test. Some source code requires the addition of Amiga API libraries, like dos, which you can flag at the compile time as gcc -o julia.exe julia.c -ldos For DOS use -ldos as example and if you are compiling mui codes it will be -lmui or intuition -lintuition. Other missing symbols are due to linker libraries being necessary for linking in functions that aren't in the standard C libraries. For example some source code would need added -lz or -lm or -lpng or -larosc etc. use this in unix line command mode to search for 'search-item' in many .c files (*.cpp for c++, etc.) grep -l 'search-item' *.c If the program is not executable, try using parameter fno-common "Delete #?.o"? Or if you are using abcshell then "rm *.o" :''More information: [[Aros/Developer/Porting software]]'' === How to make Apps have AROS 64-bit specific support code === [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] AROS64 already uses 64bit addressing, it just doesn't setup the MMU for more than 4GB physical memory currently. When porting software to AROS64 it is "mostly" a case of converting ULONG's that are used to store pointers, into IPTR's instead, etc. Another quirk, is making sure items on the stack are the correct size by using the STACKED attribute for them. * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. compiling mui stuff for aros setting -std=gnu99 is necessary, had -std=c99 usually A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. crash which suggest memory corruption. From my experience porting from 32-bit to 64-bit these kinds of errors can happen if a pointer is passed somewhere via ULONG variable. Then half of the pointer is cut. To generate this error, please run AROSBootstrap with -m 1024. This will allocate heap to 64-bit address space which will make these errors immediatelly visible. These types of crashes are hard to debug. Disabled as little code as possible to stop corruption from occurring and then try to read from the code where it can be broken Crashing in tslf_freevec is another symptom of memory corruption and these memory corruptions will manifest differently on different setups. ==Coding conventions== As the AROS core source is a shared developer experience, there are rules regarding structure and style. When it comes to your creating your own app and coding, the structure and style should be your own, i.e. you should enjoy what you do and do it so that you can understand what is going on. ===Layout=== <syntaxhighlight lang="c"> static void 1st_function() { program exit(0); } int main(void) { 1st_function(); 2nd_function(); 3rd_function(); return 0; } </syntaxhighlight> <syntaxhighlight lang="c"> struct Screen * openscreen(void); struct Window *openwindow(struct Screen *screen, const char *title, LONG x, LONG y, LONG w, LONG h); VOID 1st_function(); VOID 2nd_function(); int main(int argc, char **argv) { program return 0; } /* main */ VOID 1st_function() { } VOID 2nd_function() { } </syntaxhighlight> ===General style=== This code is used by many people and therefore you should keep some things in mind when you submit source code: * Keep things simple * Keep the source clean * Always know what you are doing, if not flag it and describe what needs to be done... * Explain clearly/simply what you are doing * Remember that you write code once but that it is read many times by many people ===Comments=== AROS uses some of the comments in the source to generate the documentation. Therefore it's necessary to keep a certain format so the tools can find their information. Other comments are ignored but they should explain what you thought when you wrote the code. If you really can't think of an explanation, then don't write the code a second time like this: <pre> /* This adds 1 to t */ t ++; </pre> What we think of is this: <pre> /* Go on with next element */ t ++; </pre> ===Formatting=== This is only '''IMPORTANT''' if you are going to work on the core AROS code or contrib but not applications which may reside outside like on AROS Archives or other websites. <syntaxhighlight lang="c"> { /* a */ struct RastPort * rp; int a; /* b */ rp = NULL; a = 1; /* c */ if (a == 1) printf ("Init worked\n"); /* d */ if ( !(rp = Get_a_pointer_to_the_RastPort ( some , long , arguments ) ) || a <= 0 ) { printf ("Something failed\n"); return FAIL; } /* e */ a = printf ("My RastPort is %p, a=%d\n" , rp , a ); return OK; } </syntaxhighlight> Looks ugly, eh ? :-) Ok, here are the rules: <pre> If several lines contain similar code, put similar things below each other (see a and b); Put spaces between operands and operators Put braces {}, brackets [] and parentheses () below each other (d) if there is much code between. Brackets and parentheses may be in one line if the code between is small (c) Indent by 4 Spaces. Two indent levels may be abbreviated by one tab. </pre> '''Before committing please normalize the indentation - if you have a mixture of tabs and spaced - please always use spaces, 1 tab = 4 spaces.''' The reasons for this are: # While some editors can use an arbitrary sizes for tabs, it's a bit complicated to tell another editor which tab size was used by the one used to write the code. # Most code in AROS was written this way and your code should look like the rest. # You can print this code on any printer without special tools to "fix" the tabs. # Most editors have smart tabs which do exactly this. If your editor doesn't, write a bug report. If you have a function with many arguments (d, e) you should put the parentheses in lines of their own and each argument in one line (d) or put the first argument behind the opening parentheses (e) and each following argument in a line of its own with the comma in front. The closing parentheses is in a line of its own and aligned with the beginning of the expression (i.e. the a and not the opening parentheses or the printf()). Use a single blank line to separate logical blocks. Large comments should have a blank line before and after them, small comments should be put before the code they explain with only one blank line before them. If you see any TABS in AROS core sources then the suggestion is to "detab the file and commit that separately" either before or afterwards from making functionality changes. Make two commits instead of one. This makes it easier for others to see the real changes instead of having to dig through multiple lines of irrelevant diffs. ===Eliminating Global Variables=== i.e. pass variables to functions (local scope) or classes making it easier to track and debug your code. Any time you find that you need a particular thing in 'a lot of different places', chances are that all those places are conceptually related, and so you can create a class, a namespace, a function, or some other higher-level organizational unit to represent that relationship. This makes the program easier to understand. Bad Designs * All variables are global. * There are no standalone functions, only sub-procedures which act on the global variables. * Every sub-procedure is at least 500 lines to several thousand * Every sub-procedure has more than one task to perform * Copy-paste is preferred to writing methods, AND subtle changes are made in the middle of the code Good Designs * structure program into functions (C or basic) - top-down procedural approach * put in class(es) (freepascal or C++) - the object is fixed and you use methods to access the object <pre>  class String_List  {  private:  list<string> m_List;  // member  public:  void read_strings() { /* read strings into m_List */ }  void print_strings() { /* write contents of m_List to stdout */ }  void sort_strings() { /* sort contents of m_List */ }  void sort_strings_reverse() { /* reverse-sort contents of m_List */ }  void unique_strings() { /* remove duplicate strings */ }  };  int main()  {  String_List myList;  // local  myList.read_strings();  myList.sort_strings();  myList.print_strings();  myList.sort_strings_reverse();  myList.print_strings();  myList.unique_strings();  myList.print_strings();  return 0;  } </pre> This way it is very easy to replace the list with new list for debugging purposes, or replacing the methods without replacing the list, when you want different results. You only have to replace the content of the local variables. So create the structure that matches your data (linked lists, trees, arrays, etc.) and what to do with them (sorting, searching, etc.) <pre> .h usually contain #define #include typedef enum struct extern screen and window definitions (data structures) .c should contains functions and algorithms </pre> One way to look at it is that menu headings act as the .c file and sub-menu headings as functions. When you start a project, you place a couple of declarations in the include file. As the project continues, you place more and more declarations in the include file, some of which refer to or contain previous declarations. Before you know it, you have a real mess on your hands. The majority of your source files have knowledge of the data structures and directly reference elements from the structures. Making changes in an environment where many data structures directly refer to other data structures becomes, at best, a headache. Consider what happens when you change a data structure. Use good variables names to help clarify code and only comment when you need to explain why a certain programming approach was made. You're Refactoring Legacy Code, you see a global, you want to get rid of it. How do you do this? Exactly what to do depends on how the global is used. The first step is to find all uses of the global throughout the code, and get a feel for what the significance of the variable is and how it relates to the rest of the program. Pay particular attention to the "lifetime" of the variable (when it gets initialized, when it is first used, when it is last used, how it gets cleaned up). Then, you will probably make the global a data member of a class (for OO languages), or you will write some get/set functions. Converting to the Singleton Pattern is common, but you may discover that it makes more sense for the data element to be a member of an existing singleton, or maybe even an instance variable. # Create a basic read method, either as a class or a global function. Replace all reads with the access method, but leave the variable defined as a global. # Review each of the writes to the method and extract action functions one at a time. Unless two operations are coded identically in the original code, extract each write access separately. # Change the variable scope from global to local. # Analyze similar action functions to determine if any can be merged, i.e., there are no functional differences in the results of the function, just differences in the implementation details. # Review the calls to the read method and see if a more complex functionality should be applied. Follow the approach for writes and unless implementations are identical, create separate access functions. # Analyze the access functions for duplication. As returning variables by "passing by value" are forgotten, so "passing by reference" is often used instead. The reference is a pointer to the variable so the value is remembered when returned. Alternatives * Hidden Globals * Singleton Pattern * Database or TupleSpace * Context Object * Dependency Injection * Stateful Procedures ==AROS/AmigaOS APIs and Docs== <pre> Library: - Private data structure - Many public access methods Device: - Private data structure - Two (BeginIO/AbortIO) access methods Resource: - Public data structure - *NO* access methods </pre> And, being Amiga OS-compatible, there are exceptions to all of these. ===System Libraries=== The [http://developers.aros.org/ AROS Guide To Libraries] can be used as a guide to individual commands and old Dev Docs are used in application programming. Amiga/Aros styles libraries are very different from windows and linux libs. Typical .so/dll libraries are foreign to most Amiga-like OS *[[Aros/Developer/Docs/Libraries/AROSC|arosc.library]] *[[Aros/Developer/Docs/Libraries/AmigaGuide|amigaguide.library]] *[[Aros/Developer/Docs/Libraries/ASL|asl.library]] *[[Aros/Developer/Docs/Libraries/Bullet|bullet.library]] *[[Aros/Developer/Docs/Libraries/BSDsocket|bsdsocket.library]] *[[Aros/Developer/Docs/Libraries/CAMD|camd.library]] *[[Aros/Developer/Docs/Libraries/Codesets|codesets.library]] *[[Aros/Developer/Docs/Libraries/CGFX|cybergraphics.library]] *[[Aros/Developer/Docs/Libraries/CGXVIDEO|cgxvideo.library]] *[[Aros/Developer/Docs/Libraries/Commodities|commodities.library]] *[[Aros/Developer/Docs/Libraries/DataTypes|datatypes.library]] *[[Aros/Developer/Docs/Libraries/DiskFont|diskfont.library]] *[[Aros/Developer/Docs/Libraries/DOS|dos.library]] *[[Aros/Developer/Docs/Libraries/Exec|exec.library]] *[[Aros/Developer/Docs/Libraries/Expansion|expansion.library]] *[[Aros/Developer/Docs/Libraries/FreeType2|freetype.library]] *[[Aros/Developer/Docs/Libraries/GadTools|gadtools.library]] *[[Aros/Developer/Docs/Libraries/Graphics|graphics.library]] *[[Aros/Developer/Docs/Libraries/Icon|icon.library]] *[[Aros/Developer/Docs/Libraries/Identify|identify.library]] *[[Aros/Developer/Docs/Libraries/IFFParse|iffparse.library]] *[[Aros/Developer/Docs/Libraries/Intuition|intuition.library]] *[[Aros/Developer/Docs/Libraries/Keymap|keymap.library]] *[[Aros/Developer/Docs/Libraries/Layers|layers.library]] *[[Aros/Developer/Docs/Libraries/Locale|locale.library]] *[[Aros/Developer/Docs/Libraries/LowLevel|lowlevel.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingBas|mathieeesingbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubBas|mathieeedoubbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingTrans|mathieeesingtrans.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubTrans|mathieeedoubtrans.library]] *[[Aros/Developer/Docs/Libraries/Mathtrans|mathtrans.library]] *[[Aros/Developer/Docs/Libraries/MUIMaster|muimaster.library]] *[[Aros/Developer/Docs/Libraries/Partition|partition.library]] *[[Aros/Developer/Docs/Libraries/PopUpMenu|popupmenu.library]] *[[Aros/Developer/Docs/Libraries/OOP|oop.library]] *[[Aros/Developer/Docs/Libraries/Regina|regina.library]] *[[Aros/Developer/Docs/Libraries/Reqtools|reqtools.library]] *[[Aros/Developer/Docs/Libraries/RexxSysLib|rexxsyslib.library]] *[[Aros/Developer/Docs/Libraries/ScreenNotify|screennotify.library]] *[[Aros/Developer/Docs/Libraries/TTEngine|ttengine.library]] *[[Aros/Developer/Docs/Libraries/Thread|thread.library]] *[[Aros/Developer/Docs/Libraries/Utility|utility.library]] *[[Aros/Developer/Docs/Libraries/Xadmaster|xadmaster.library]] *[[Aros/Developer/Docs/Libraries/Workbench|workbench.library]] *[https://github.com/aros-development-team/AROS/commit/c82e86b8480277998014cc327b56c7664023a52f ClassAct Reaction boopsi class] ===AROS Subsystems=== # [[Aros/Developer/Zune|Zune MUI compatible GUI]] # [[Aros/Developer/AROSAppPackages|AROS Application Packages]] # AHI Audio Drivers - [[Aros/Developer/AHIDrivers|Usage]]/[[Aros/Developer/AHIDriversDev|Development]] # AROSTCP Sana2 Network Interface Drivers - [[Aros/Developer/NICDrivers|Usage]]/[[Aros/Developer/NICDriversDev|Development]] # [[Aros/Developer/AmiSSL|AmiSSL]] # gfx.hidd/cybergraphics Video Drivers - [[Aros/Developer/GfxDrivers|Usage]]/[[Aros/Developer/GfxDriversDev|Development]] # IO Device Drivers - [[Aros/Developer/IODeviceDrivers|Usage]]/[[Aros/Developer/IODeviceDriversDev|Development]] # USB Device Drivers - [[Aros/Developer/USBDrivers|Usage]]/[[Aros/Developer/USBDriversDev|Development]] # PCI Device Drivers - [[Aros/Developer/PCIDrivers|Usage]]/[[Aros/Developer/PCIDriversDev|Development]] # [http://www.libsdl.org/ SDL] [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2013&pid=13333#post_13333 SDL2 coding usage], [https://github.com/search?q=repo%3Aaros-development-team%2Fcontrib%20SDL2&type=code SDL2 commits], [https://github.com/aros-development-team/contrib/commit/c62c3c425c35bac19dadc23be092b0b13a66c76c SDL3 initial commit], [] # [[w:Gallium3D|Gallium 3D]] [http://www.mesa3d.org/ openGL aka Mesa] - [[Aros/Developer/OpenGL|Usage]]/[[Aros/Developer/OpenGLDev|Development]] [http://www.swiftless.com/opengltuts.html Swfitless] # A small subset of GTK2 through [http://sourceforge.net/projects/gtk-mui/ MUI-GTK] # Cairo 2D Engine - [[Aros/Developer/Cairo|Usage]]/[[Aros/Developer/Cairo|Development]] # [[Aros/Developer/Scalos|Scalos desktop API and plugin modules]] # [[Aros/Developer/VHI|VHI video driver]] ====HIDDs==== *[[Aros/Developer/Docs/HIDD/HIDDClass|hiddclass.hidd]] *[[Aros/Developer/Docs/HIDD/Graphics|graphics.hidd]] *[[Aros/Developer/Docs/HIDD/VesaGfx|vesagfx.hidd]] *[[Aros/Developer/Docs/HIDD/ATI|radeon.hidd]] *[[Aros/Developer/Docs/HIDD/NVidia|nvidia.hidd]] *[[Aros/Developer/Docs/HIDD/Nouveau|nouveau.hidd]] *[[Aros/Developer/Docs/HIDD/Kbd|kbd.hidd]] *[[Aros/Developer/Docs/HIDD/Mouse|mouse.hidd]] *[[Aros/Developer/Docs/HIDD/i2c|i2c.hidd]] *[[Aros/Developer/Docs/HIDD/IRQ|irq.hidd (deprecated)]] *[[Aros/Developer/Docs/HIDD/PCI|pci.hidd]] *[[Aros/Developer/Docs/HIDD/PCIPC|pcipc.hidd]] *[[Aros/Developer/Docs/HIDD/Serial|serial.hidd]] *[[Aros/Developer/Docs/HIDD/Thunderbolt|thunderbolt.hidd]] https://github.com/aros-development-team/AROS/commit/4f02ea691799aff3a01f60cfa5f9182c82fc57a8 HIDD are used for device/peripheral low level hardware support drivers. The HIDD system is split up into a collection of classes with a strict inheritance hierarchy. A HIDD class implements a device driver for a single device or in rare cases a group of devices and provides an interface for other programs and devices to access. In order to maintain portability of interfaces across a wide range of hardware this interface will in general not present the raw interface to the underlying hardware. Instead it will present a generic interface that describes many different hardware implementations. This allows for the best reuse of both interfaces and code. HIDD API is heavyweight though. You need to open a HIDD library, open oop.library, instantiate an object (even if there's no object); and object calls are more costly compared to plain library calls. Basically your task is to implement a subclass of hidd.ata.bus for your hardware. just implementing the XXXATA__Hidd_ATABus__xxxxxx methods for the Amiga chipset - and appropriate versions of the interface_xxx.c file(s). pretty much everything in probe.c could be ignored - just write a replacement scan for relevant amiga devices and store whatever info you need in the bus data? only the "SUPPORT_LEGACY" blocks might be related. You do not need to depend on PCI API. PCI is just a way to discover the hardware on PCs, etc. <hidd/pci.h> includes (at some depth) <interface/HW.h>, which defines IID_HW. This comes from the 'generic' HIDD class in: rom/hidds/hidd/hiddclass.conf did not split up HIDD and HW because they are always used in pair. It's the same as hidd/pci.h bringing definition for: PCI, PCIDriver and PCIDevice. PCI is actually PCIHW, just the name was not changed for backwards compatibility reasons. HW is a 'hub' where HIDD instances plug in. ATA HIDD aoHidd_ATABus_Use32Bit value is completely ignored unless ata.device first detects correct command line parameter. Yes. Unfortunately I was unable to find any comment in code or svn history with explanations. Looked at Linux source, there 32-bit PIO is also controller driver's property. Some of them enable it, some don't. Actually, switching the default to ON should be safe. ata.device is fail-safe at this because during IDENTIFY command it validates upper 16 bits, and if they appear to be zeroes in all 128 longwords, then 32-bit mode is switched off. But, nevertheless, I know how tricky hardware can be, so I decided not to change original behavior. If you think it's wrong in some cases, then it's possible to add one more attribute like aHidd_ATABus_Default32Bit. If set to YES, then this means that 32-bit PIO is safe to use by default. ====Devices==== *[[Aros/Developer/Docs/Devices/ATA|ata.device]] *[[Aros/Developer/Docs/Devices/Console|console.device]] *[[Aros/Developer/Docs/Devices/Narrator|narrator.device]] *[[Aros/Developer/Docs/Devices/Printer|printer.device]] *[[Aros/Developer/Docs/Devices/Trackdisk|trackdisk.device]] *[[Aros/Developer/Docs/Devices/AmberRAM|amberram.device]] *[[Aros/Developer/Docs/Devices/Timer|timer.device]] *[[Aros/Developer/Docs/Devices/|.device]] The Amiga used [[Aros/Developer/Docs/Devices|Devices]] to communicate with [http://aros-exec.org/modules/newbb/viewtopic.php?start=0&topic_id=3475&viewmode=flat&order=ASC additional hardware]. AROS has replaced these hardware devices with hidd equivalents but some are still retained for backwards compatibility. Local libraries/devices/handlers,etc. are supposed to override the ones in ROM if their version is higher than the one in ROM. Here is the list of commands exec default: {| class="wikitable" | CMD_CLEAR | Purge the buffer of the device |---- | CMD_READ | Playback Control |---- | CMD_STOP | Stopped the activity of the device |---- | CMD_FLUSH | Empty the queue of commands |---- | CMD_RESET | Reset a device |---- | CMD_WRITE | Playback Control |---- | CMD_INVALID | Create an error |---- | CMD_UPDATE | Gets updated device |---- | CMD_START | Will restart the device |---- |} While most other "stuff you communicate with" in AmigaOS are devices <ref>AMIGA ROM Kernel Reference Manual: Devices, 3rd Edition. Commodore-Amiga, Inc. Addison-Wesley, 1991. {{ISBN|0-201-56775-X}}</ref> that share a [http://gega.homelinux.net/AmigaDevDocs/ common base interface]. [[Aros/Developer/Docs/Devices1.3|OS 1.3 Device Drivers]]. ====Handlers==== :[[Aros/Developer/Docs/Handlers/Pipe|pipe.handler]] :[[Aros/Developer/Docs/Handlers/Port|port.handler]] :[[Aros/Developer/Docs/Handlers/SFS|sfs.handler]] :[[Aros/Developer/Docs/Handlers/FAT|fat.handler]] :[[Aros/Developer/Docs/Handlers/PFS|pfs.handler]] :[[Aros/Developer/Docs/Handlers/NTFS|fuse.handler]] :[[Aros/Developer/Docs/Handlers/FFS|ffs.handler]] filesystem handlers have their own separate system consisting of completely differently structured messages that dos.library use to pass requests (for things like reading, writing, getting directory contents etc.) to them. AROS originally went with implementing filesystem handlers as devices, which might arguably be more consistent with the rest of the AmigaOS API but which is quite incompatible with AmigaOS itself. However, it made it far harder to port filesystems and the gains were comparatively small, and so there's been a long standing goal of fixing this incompatibility. It has now, June 2011, been reintroduced to all AROS flavors. are argstr and argsize valid for the handler startup environment? DOS/RunHandler() calls DOS/CreateNewProcTags(), and then CallEntry() (in rom/dos/exit.c) to start the handler, so yes, argstr and argsize are *present* in the call signature of the handler. Granted, argstr will be NULL and argsize 0, but those values *are* passed to the handler function using: <pre> AROS_UFC3(ULONG, entry, AROS_UFCA(STRPTR, argptr, A0), AROS_UFCA(ULONG, argsize, D0), AROS_UFCA(struct ExecBase *, SysBase, A6)); </pre> Creating your own [without the whole build tree http://pagesperso-orange.fr/franck.charlet/temp/radeon.zip] and then <pre> make stub make make install </pre> SFS has two Root blocks, one at the start and one at the end of the disk. The Root blocks both contain the same information. They hold various information about the disk structure and have the locations of some important blocks used by the filesystem. The Root ObjectContainer contains the Root directory Object. The name of this Object is the name of the volume. It is identical to a normal directory Object. The Bitmap is used to keep track of free space. Each bit in a bitmap represents a single block. A set bit indicates a free block and a cleared bit a used block. AdminSpaceContainers are used to keep track of space which has been reserved for storing administration blocks. Only the Bitmap, the Root blocks and the actual data stored in files aren't stored in administration space. Administration space is allocated in chunks of 32 blocks at a time. A single AdminSpaceContainer can hold information about a large number of such areas each of which has its own little bitmap of 32 bits. Extents are stored in a B-Tree. The Root block holds a pointer to the root of the Extent B-Tree. Extents keep track of space in use by a specific file. Each fragment a file consists of has its own Extent. Extents are in a double linked list. The list can be used to locate the next or previous fragment of a file. Below is the standard block header. This header is found before EVERY type of block used in the filesystem, except data blocks. The id field is used to check if the block is of the correct type when it is being referred to using a BLCK pointer. The checksum field is the SUM of all LONGs in a block plus one, and then negated. When applying a checksum the checksum field itself should be set to zero. The checking a checksum the checksum is okay if the result of the checksum equals zero. The ownblock BLCK pointer points to the block itself. This field is an extra safety check to ensure we are using a valid block. Field Type Description id ULONG The id field is used to identify the type of block we are dealing with. It is used to make sure that when referencing a block we got a block of the correct type. The id consist of 4 bytes and each blocktype has its own unique foure letter code. checksum ULONG This field contains the sum of all longs in this block, plus one and then negated. The checksum can be used to check if the block hasn't been corrupted in any way. ownblock BLCK Points to itself, or in other words, this field contains the block number of this block. This is yet another way to check whether or not a block is valid. <pre> struct fsBlockHeader { ULONG id; ULONG checksum; BLCK ownblock; }; </pre> The algorithm to calculate the checksum of a block: <pre> ULONG calcchecksum(struct fsBlockHeader *block, LONG blocksize} { ULONG *data=(ULONG *)block; ULONG checksum=1; block->checksum=0; while(blocksize>0) { checksum+=*data++; blocksize-=4; } return(-checksum); } </pre> A Root block contains very important information about the structure of a SFS disk. It has information on the location and size of the disk, the blocksize used, locations of various important blocks, version information and some filesystem specific settings. A SFS disk has two Root blocks; one located at the start of the partition and one at the end. On startup the filesystem will check both Roots to see if it is a valid SFS disk. If either one is missing SFS can still continue (although at the moment it won't). A Root block could be missing on purpose. For example, if you extend the partition at the end (adding a few MB's) then SFS can detect this with the information stored in the Root block located at the beginning (since only the end-offset has changed). Same goes for the other way around, as long as you don't change start and end point at the same time. When a Root block is missing because the partition has been made a bit larger, then SFS will in the future be able to resize itself without re-formatting the disk. Field Type Description bheader struct fsBlockHeader Standard block header. version UWORD The version of the filesystem block structure. You can check this field to identify what version of the filesystem your dealing with it and to see if you can handle this structure correctly. Don't try to interpret the disk's structure when this field contains an unknown version number! sequencenumber UWORD Used to identify which Root block was written last in case the sequencenumber on both Root blocks don't match. datecreated ULONG Creation date of this volume. This is the date when the disk was last formatted and will never be changed. bits UBYTE Various settings, see below. <pre> pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. reserved1 ULONG[2] Reserved, leave zero. firstbyteh ULONG High 32-bits of a 64-bit number. This is the first byte of our partition relative to the start of the disk. firstbyte ULONG Low 32-bits of a 64-bit number. lastbyteh ULONG High 32-bits of a 64-bit number. This is the last byte (exclusive) of our partition relative to the start of the disk. lastbyte ULONG Low 32-bits of a 64-bit number. totalblocks ULONG The total number of blocks this partition consists of. blocksize ULONG The size of a block of this partition. reserved2 ULONG[2] Reserved, leave zero. reserved3 ULONG[8] Reserved, leave zero. bitmapbase BLCK Block number of the start of the Bitmap. adminspacecontainer BLCK Block number of the first AdminSpaceContainer. rootobjectcontainer BLCK Block number of the ObjectContainer which contains the root of the disk (this is where the volume name is stored). extentbnoderoot BLCK Block number of the root of the Extent B-Tree. reserved4 ULONG[4] Reserved, leave zero. </pre> <pre> struct fsRootBlock { struct fsBlockHeader bheader; UWORD version; UWORD sequencenumber; ULONG datecreated; UBYTE bits; UBYTE pad1; UWORD pad2; ULONG reserved1[2]; ULONG firstbyteh; ULONG firstbyte; ULONG lastbyteh; ULONG lastbyte; BLCK totalblocks; ULONG blocksize; ULONG reserved2[2]; ULONG reserved3[8]; BLCK bitmapbase; BLCK adminspacecontainer; BLCK rootobjectcontainer; BLCK extentbnoderoot; ULONG reserved4[4]; }; </pre> AdminSpaceContainers are used to store the location and bitmap of each administration space. The AdminSpaceContainers are located in a double linked list and they contain an array of fsAdminSpace structures. There is one fsAdminSpace structure for every administration space on disk. Field Type Description bheader struct fsBlockHeader Standard block header. next BLCK The next AdminSpaceContainer, or zero if it is the last in the chain. previous BLCK The previous AdminSpaceContainer, or zero if it is the first AdminSpaceContainer. bits UBYTE The number of bits in each in the bits ULONG in the fsAdminSpace structure. pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. adminspace struct fsAdminSpace An array of fsAdminSpace structures. The size of the array is determined by the current blocksize. <pre> struct fsAdminSpaceContainer { struct fsBlockHeader bheader; BLCK next; BLCK previous; UBYTE bits; UBYTE pad1; UWORD pad2; struct fsAdminSpace adminspace[0]; }; </pre> Field Type Description space BLCK The first block of an administration space. bits ULONG A small bitmap which is used to determine which blocks in an administration space are already in use. The number of bits in this bitmap is determined by the bits field in the AdminSpaceContainer. <pre> struct fsAdminSpace { BLCK space; ULONG bits; }; </pre> The fsBitmap structure is used for Bitmap blocks. A bitmap block is used to keep track of which space is in use and which isn't for a particular area of a disk. All bitmap blocks together keep track of the free space for an entire disk. The location of the first bitmap block is known and all other bitmap blocks are stored in order after the first one. Field Type Description bheader struct fsBlockHeader Standard block header. bitmap ULONG An array of ULONG's. These hold the actual information on which blocks are in use and which aren't. <pre> struct fsBitmap { struct fsBlockHeader bheader; ULONG bitmap[0]; }; </pre> Each bit in a bitmap block (except for the block header) represents a single block. If the bit is set than the block is free, and if the bit is clear then it is full. The first ULONG in the bitmap area of the first bitmap block represents blocks 0 through 31 on the disk. Bit 31 of this ULONG is block 0, 30 is block 1, and so on. Bit 0 of the first ULONG represents block 31. Below is a table to clarify how bitmaps work even further. The first column is the bitmap block number, the second column is the number of the ULONG in the bitmap array. The third column is the bit number in this ULONG, and the last column is the block which this specific bit, in this specific bitmap block represents. We'll assume here that a bitmap block has room for 120 ULONG's (meaning there is room for storing 32 * 120 bits). <pre> Bitmap block ULONG number Bit number Block represented 1 (first) 0 31 0 1 0 30 1 ... ... ... ... 1 0 1 30 1 0 0 31 1 1 31 32 ... ... ... ... 1 2 31 64 1 2 30 65 ... ... ... ... 1 119 0 3839 2 0 31 3840 2 0 30 3841 ... ... ... ... </pre> The last bitmap block doesn't need to be completely used. The unused bits (which belong to blocks which do not exist) all have to be clear, to indicate that these blocks are in use. The fsObjectContainer structure is used to hold a variable number of fsObjects structures (Objects) which have the same parent directory. Each ObjectContainer must contain at least one Object. If there is space in the ObjectContainer not used by the variable number of Objects then that space is zero filled. Objects always start at 2-byte boundaries, which means sometimes a padding byte is inserted between two Objects. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the parent Object, or 0 if this object has no parent (which is only the case for the Root directory). next BLCK The next ObjectContainer belonging to this directory, or zero if it is the last in the chain. previous BLCK The previous ObjectContainer belonging to this directory, or zero if it is the first ObjectContainer in this directory. object struct fsObject A variable number of fsObject structures. The number of structures depends on the individual sizes of each fsObject structure and the blocksize. These structures are located directly after each other with at most 1 byte of padding between them to get the structures aligned on a 2 byte boundary. <pre> struct fsObjectContainer { struct fsBlockHeader bheader; NODE parent; BLCK next; BLCK previous; struct fsObject object[0]; }; </pre> fsHashTable is the structure of a HashTable block. It functions much like the hash table found in FFS user directory blocks, except that it is stored in a separate block. This block contains a number of hash-chains (about 120 for a 512 byte block). Each hash-chain is a chain of Nodes. Each Node has a pointer to an Object and a pointer to the next entry in the hash-chain. Using such a hash-chain you can locate an object quickly by only knowing its name. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the directory Object this HashTable block belongs to. hashentry NODE An array of Nodes. Each Node represents the start of a hash-chain (singly linked). A hash-value is calculated using the name of a file or directory, and this value determines in which chain the Object is linked. If there are no entries in a hash-chain then the hashentry value is zero. <pre> struct fsHashTable { struct fsBlockHeader bheader; NODE parent; NODE hashentry[0]; }; </pre> To calculate the hash-value using a name of an Object as input use these routines: <pre> UWORD calchash(UBYTE *name) { UWORD hash=0; /* Calculates a hash value over the passed in string. The end of the string can be either a NUL byte or a slash. The hash function is the same as the one used in FastFileSystem set to international mode. */ while(name[hash]!=0 && name[hash]!='/') { hash++; } while(*name!=0 && *name!='/') { hash=hash*13+upperchar(*name++); } return((UWORD)(hash % (UWORD)((blocksize-sizeof(struct fsHashTable))>>2))); } UBYTE upperchar(UBYTE c) { if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z')) { c-=32; } return(c); } </pre> The BNodeContainer is used to store B-Trees. Currently only one B-Tree is in use by this filesystem and it is used to store the location of file data. The fsBNodeContainer structure contains two other structures. The fsBlockHeader structure and the BTreeContainer structure. Field Type Description bheader struct fsBlockHeader Standard block header. btc struct BTreeContainer Contains information about the B-Tree and its nodes contained in this block. <pre> struct fsBNodeContainer { struct fsBlockHeader bheader; struct BTreeContainer btc; }; </pre> First try and locate the Root block. It should start with "ROOT". SFS has two of these, one at the start of the partition and one at the end. One of the fields contains the block size, which will be the size of all important SFS blocks. The root block has the root object container, which contains information about files and directories in the root directory. The object containers basically hold one or more smaller structures that represent files and directories. Scanning them all should give you a list of files and directories. The root block also has the root of the Extent B-Tree. This is a standard B-Tree structure (not a binary tree) that is used commonly in all kinds of system, you can read about how they work on Wikipedia if needed. The B-Tree holds the information about *where* all the data is located for your files. To recover your files, I'd do this: * Find one of the root blocks, if not present, then figure out the block size your disk was using, and scan every block in turn to see if it looks like an ObjectContainer (check the fsBlockHeader's ID, check if the ownblock number is equal to the block you are currently scanning, and check its checksum). So if you currently have block 12, and you see a block with the correct id, and ownblock = 12 and its checksum is good, then that's probably a valid ObjectContainer. * With all the ObjectContainers found, you can extract filenames and directory names from these, but also the number of their first data block (in the field data) and the file size. For small files (less than blocksize) this data block will be enough to recover the data. For larger files, you might be lucky and all the remaining blocks are found after the first one (if the file was defragmented). You can't be sure of that though so... * For larger files, you need to find all the BNodeContainers. You could scan these in the same way you found all the ObjectContainers (look for blocks with the correct id, ownblock number and checksum). * With all the BNodeContainers found, you can try looking up the first data block of a file in the B-Tree structure. This is a bit complicated -- the B-Tree consists of non-leaf nodes (blocks that only contain pointers to other B-Tree blocks), the isLeaf flag indicates this. Or it can be a B-Tree leaf block. The leaf blocks contain extra information per entry (see https://hjohn.home.xs4all.nl/SFS/extents.htm) <pre> struct fsExtentBNode { ULONG key; ULONG next; ULONG prev; UWORD blocks; }; </pre> The key should be a block of a file (the first of a range), that is 1 to 65535 block long (depending the "blocks" field). If the file is split up into more parts, then "next" will contain block number of the next range of blocks. You need to look this up again in the B-Tree structure to find out how large it is. You can for the most part ignore the other structures (bitmap, admin containers). The fsObjects and B-tree containers is what you'll need to recover the data. ====Resources==== <pre> rom/storage/mmakefile.src rom/storage/storage.conf rom/storage/storage_device.c rom/storage/storage_ids.c rom/storage/storage_init.c rom/storage/storage_intern.h rom/storage/storage_mount.c rom/storage/storage_unit.c </pre> <pre> rom/storage/includes/device.h rom/storage/includes/unit.h rom/storage/includes/volume.h rom/storage/storage_intern.h </pre> <pre> </pre> *[[Aros/Developer/Docs/Resources/ACPI|acpi.resource]] *[[Aros/Developer/Docs/Resources/Battclock|battclock.resource]] *[[Aros/Developer/Docs/Resources/Bootloader|bootloader.resource]] *[[Aros/Developer/Docs/Resources/Cia|cia.resource]] *[[Aros/Developer/Docs/Resources/Filesystem|FileSystem.resource]] *[[Aros/Developer/Docs/Resources/Hostlib|hostlib.resource]] *[[Aros/Developer/Docs/Resources/Kernel|kernel.resource]] *[[Aros/Developer/Docs/Resources/Misc|misc.resource]] *[[Aros/Developer/Docs/Resources/Processor|processor.resource]] ==Debugging Code== Please use the [http://sourceforge.net/tracker/?group_id=43586&atid=439463 AROS Bug Tracker] if any issues are found. GRUB Command line list <pre> sysdebug usbdebug - allows to see Poseidon's log in debug output </pre> How do I get debugging out of InitResident ? If running i386 hosted on linux sysdebug=initresident on command line. This way you can enable any of listed flags. sysdebug=all stands for "everything" Have an executable (crosscompiled C++ code) which has 6 MB size on disk, but after loading it in memory, 250 MB RAM is taken. Any software that would split AROS executable into ELF part which would show actual size values? readelf -S executable it will show you all sections in elf file, including sizes and requested alignment. objdump -h filename That's will give you a quick overview of the sections and sizes. Ignore all the .debug.* sections. Would hazard a guess that you have a large .bss section. That's pretty common in C++. Next step: nm—size-sort filename | grep ' [bB] ' The last few will be your biggest consumers. Would suggest -C to demangle the symbols... ;) Suggest profiling the program (just use some printf's in the main loop for time spent in each part), it usually is quite easy to spot slow parts in games or apps. If someone has '#define IPTR ULONG' somewhere. To see where that define is, redefine IPTR in the source code that fails, just above the line that fails, and the preprocessor will tell you where it was defined first. ===How to setup gdb with AROS/hosted=== Download AROS sources (AROS-xxxxxxxx-source.tar.bz2, where xxxxxxxx is the current date) and AROS contrib sources (AROS-xxxxxxxx-contrib-source) from Untar-bzip2 and cd to the unpacked archive directory. > tar -xvjf AROS-xxxxxxxx-source.tar.bz2 > cd AROS-xxxxxxxx-source Check the link to "contrib" (contrib-source) inside directory, e.g. correct like this: > rm contrib > ln -s ../AROS-xxxxxxxx-contrib-source.tar.bz2 contrib Make sure you have the correct locale setting, otherwise compilation will fail at some point. See [http://aros.sourceforge.net/documentation/developers/compiling.php#setting-the-locale-to-iso8859 here] (or link below) for more on that. You might have to enter this: > export LANG="en_US.ISO-8859-1" Now configure for a debug build - see "./configure --help" for more - here are two examples: > ./configure—enable-debug=stack,modules,symbols > ./configure—enable-debug=all You may "make" now, or choose a separate directory for your build (e.g. for easy removal), for example if compiling for i386 architecture you could create a directory like this: > mkdir linux-i386 > cd linux-i386 > ../AROS/configure—enable-debug=stack,symbols,modules When done configuring you're ready to go: > make Building AROS takes some time - minutes on fast machines (e.g. 2.5&nbsp;GHz quadcore), up to hours on slower machines. The result will be AROS Linux hosted with gdb debugging enabled. See aros.org documentation for more on compiling AROS, including more [http://aros.sourceforge.net/documentation/developers/compiling.php --enable-debug] options. When finished, enter bin/linux-i386/AROS directory (replace "linux-i386" with your compilation target platform, e.g. linux-x86_64, etc.) inside the unpacked archive directory. This directory contains the required .gdbinit file for properly running AROS inside gdb. > cd bin/linux-i386/AROS Run AROS (here: with 128MB of memory) from gdb: > gdb—args boot/aros-unix -m 128 or > gdb—args boot/arosboot -m 128 (gdb) r Watch the shell output - in case AROS complains about "LoadKeyCode2RawKeyTable: Loading "DEVS:Keymaps/X11/keycode2rawkey.table" failed!" you should also see some instructions on how to create a keymap table. (see link above "more on compiling", too.) Quit gdb, and try default keymap table: (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y > cd ../../.. > make default-x11keymaptable Re-run AROS, as described above. Try e.g. RAros (= right windows key) + W to open a shell. If this doesn't work you have to create a keymap table yourself, quit gdb again, and make a new keytable: > make change-x11keymaptable A window will open. Watch the window's title bar, and follow the instructions. When done, re-run AROS. RAros + W should now open a shell. Next, compile your program with gdb support. When you start GDB is there a warning which says warning: File "<whatever>/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to ... If so start gdb with "-ix .gdbinit" <pre> Summary - In short: * build AROS with debugging support (i.e. ./configure --enable-debug=all) * build your application with debugging support (i.e. option -g) * run AROS in the GNU debugger (you may use the GUI frontend "ddd" which simplifies usage a bit) * start your application * use the commands "findaddr" and "add-symbol-file" as written in the debugging manual * if the debugger doesn't find the source code of your application use the "dir" command of the debugger. </pre> ===How to use gdb=== In AROS open a shell, then (in host shell) use CTRL-Z to go into gdb. Use "b Exec_CreatePool" (one of the functions used early on by startup code in programs) to add a breakpoint, then "cont" and gdb will interrupt somewhere early during startup of "program". Use "bt" to show backtrace and "loadseg" for "??" entries. One of them will be for "program". After that you can use "disassemble program". One thing you need to make sure is that .gdbinit you have in your build directory is the same as in source tree. It has been modified some time ago, but the build system does not refresh it - you need to copy it manually To recap, please read our debugging [http://aros.sourceforge.net/documentation/developers/debugging.php manual]: To detect segfaulting when loading, try... ./configure—enable-debug—with-optimization="-O2" Because crash or no crash may depend on optimization. For newer compilers maybe this helps... --with-optimization=-"-O2 -fno-strict-aliasing" One way to make crashes less random (more easily reproducible) is to activate the munging of free memory in rom/exec/freemem.c which is normally commented out: <pre> Index: freemem.c =================================================================== --- freemem.c (revision 34289) +++ freemem.c (working copy) @@ -154,11 +154,12 @@ * created with their TCB placed in the tc_MemEntry list. The workaround * is to avoid munging when FreeMem() is called with task switching disabled. */ + /* DOH! it doesn't work even this way. What's wrong??? - * - * if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) - * MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); */ + + if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) + MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); } </pre> Mungwall can be turned on at runtime. Currently this works in all hosted versions. Just specify "mungwall" on kernel command line and it works. It can work on native too. In order to enable it you need to parse kernel command line, and if "mungwall" is present, set EXECF_MungWall bit in IntExecBase.IntFlags. This needs to be done before the first AllocMem() for obvious reasons. And never reset back this flag! If you change it on a working system, you are doomed. Hosted ports do the processing in rom/exec/prepareexecbase.c --enable-debug=mungwall option in configure still works but is going obsolete. A kludge in rom/exec/allocmem.c is responsible for this and it needs to be removed when the transition is done. BTW, on i386-pc port it can be activated by "mungwall" argument on command line, you don't need to rebuild AROS. New mungwall affects not only AllocMem()/FreeMem(), but also pools. I also tested it with AllocAbs(), seems to work correctly. Runtime mungwall works on: * pc-i386 * pc-x86_64 * linux-i386 * linux-x86_64 * darwin-x86 * linux-ppc Works on all hosted ports, if the port itself is working. * amiga-m68k * Not on sam440-ppc and efika-chrp-ppc, even if they would be able to be built at moment. Does not work on (for now, need NVRAM support) When starting my freshly rebuilt i386-linux-aros which was compiled with full debugging support I get sometimes the error "Program exited with code 0377". Add the following to your .gdbinit: set follow-fork-mode child Here are some of the custom AROS gdb functions (defined in ".gdbinit" file) to resolve "in ?? ()" entries in backtrace: <pre> #0 0xb7ffd424 in __kernel_vsyscall () #1 0xb7e2a657 in sigsuspend () from /lib/libc.so.6 #2 0xb7c63900 in ?? () #3 0xb7c640e3 in ?? () #4 0xb7c641e0 in ?? () </pre> You can use loadseg 0xb7c63900 loadframe 2 or loadbt and some others. Use "help " for a little help text. If the commands do not work try "loadkick" first. Use "thistask", "taskready", "taskwait" to get list of AROS tasks. "bttask " shows backtrace of a task which is in ready or in wait queue and "loadseg" to resolve "??" entries in it's backtrace ("loadframe" would not work as it assume current running task). ===Native debugging tools for AROS=== to enable debugging at boot time entering the GRUB menu editing line (E key) and adding "debug=memory" to your boot line, then press Ctrl+X to complete booting. SYS:Tools/Debug/'''Bifteck''' Open a shell and enter the line below to run Biftek and grab the debug messages collected in RAM into a text file. tools/debug/bifteck > ram:debug.txt and certainly does not open a window. It is a shell tool and only dumps data located from the debug location. It is therefore important to 'catch' that debug data as soon as possible (before it gets overridden). You should invoke bifteck at the first opportunity before doing anything else. You can use the TO option to store bifteck output to a file or you can pipe it manually to a file. SYS:Tools/Debug/'''Sashimi''' - displays error messages One suggestion is to do a bug() debugging. Each time bug() is executed it will be output on sashimi. You include <aros/debug.h> and place bug("something\n"); in your source code at location though which control passes. To get the output - open an aros shell SYS:Tools/Debug/sashimi > RAM:out.txt '''Ctrl C''' to end the output to the RAM Disk. # open shell, and type # ram: (to switch to ram drive) # System:Tools/Debug/Sashimi > mylogfile.txt # open AHI prefs using wanderer (or use another opened shell) # play test sound # close AHI prefs # shell still open with Sashimi running: press ctrl-c to break Sashimi and return to prompt. # in shell: copy mylogfile.txt System: (or to your required location) SYS:Utilities/'''Snoopy''' - monitors OS function calls, run "Sashimi" to see Snoopy's output SYS:Tools/'''WiMP''' - the Window (and Screens) Manipulation Program You can use the -E option of gcc to find out how preprocessor macros are expanded. ===Errors=== crash in strcasecmp usually means that one of its arguments is NULL. empty space between these two names, prossibly some invisible character Old Amiga [http://www.amigacoding.com/index.php?title=Guru_codes&redirect=no Guru Codes] If the crash is in intuition. Sometimes, if it relates to text, a null pointer sets it off. an uninitialised pointer can have any address (this is a common fault). Compiling on 64bit, Many old code would not properly typecast when doing pointer-integer conversions and thus at least throw a warning. This can easily be located and fixed. [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. * Fix (change IPTR/SIPTR back to ULONG/LONG) the few places which really rely on ULONG/LONG being exactly 32 bit. That's for things like pixel (ARGB) buffers, structs written/read to disk, colormaps, but probably not much else. Then again, many current compilers also throw a warning when you try to assign a pointer value to an integer and the integer is possibly too small. This happens under .NET for example when a 64 bit pointer is assigned to something like an ULONG - so exactly the case which you described. === AI === Multimodal Context Prompt <--- Model <---> Agent ---> End user engine Gemini LMStudio Qwen Comfyui etc Recent, self hosting locally on laptops, mini pcs or desktops with '''quantization''' 4bit has reduced memory requirements but still require 16Gb+ and no high end gpu for text based *[https://lmstudio.ai/download LMstudio single gpu], Google Gemma 4 Model *[ 12B QAT] Alibaba Cloud's [https://huggingface.co/ Qwen] team series of large language models LLMs *[https://huggingface.co/models?other=qwen3 Qwen 3], [], *[https://huggingface.co/models?other=qwen2 Qwen 2], [https://huggingface.co/Qwen/Qwen2.5-Coder-32B qwen 2.5 Coder], Small models *[ glm-ocr] *[ medGemma] *[ qwen 3.5-4b] *[https://github.com/sipeed/picoclaw picoclaw claude] Bigger LLMs but with settings *[https://ollama.com/download Ollama single gpu] *[https://github.com/ggml-org/llama.cpp/releases llama.CPP multi gpus], *[ VLM multiple gpus], Multimedia *[ Kimi K3], For the full experience #Training learning using 1+ high end GPUs at least 16GB VRAM per GPU card or 64Gb+ of unified, 16Core CPU with at least 64Gb of RAM system memory, though training can take weeks #Inference with custom asics or GPUs *[ MiniMax H3] for audio and video but gpu 8Gb+ *[https://github.com/jamiepine/voicebox voicebox] *[https://github.com/ideogram-oss/ideogram4 ideogram4] *[https://github.com/calesthio/OpenMontage OpenMontage] <pre> Text to Audio --\ Text to Video --/ Reference Video --> Video and Audio output </pre> === Example === <syntaxhighlight lang="c"> /* 1. Header for your name,date,purpose of program. 2. Pre-processor directives. This will include the #includes for files you want to add. 3. Includes for function prototypes if necessary. 4. Main() Create Pointers for Libraries and any Window you want to open. 5. Open necessary libraries. 6. Check if open exit program if fail. 7. Open a window exit program if fail. 8. Add your program 9. Close Window 10 Close Libraries. 11 End Program. */ /* standard os included headers <.h> */ #include <dos/dos.h> #include <dos/dosasl.h> #include <dos/dosextens.h> #include <dos/exall.h> #include <dos/rdargs.h> #include <exec/memory.h> #include <exec/types.h> #include <utility/utility.h> #include <intuition/intuition.h> /* define as unresolved external references (proto/xxx.h) and compiler will link to auto(matically) open library */ #include <proto/arossupport.h> #include <proto/dos.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/graphics.h> #include <proto/cybergraphics.h> #include <proto/datatypes.h> #include <proto/icon.h> #include <workbench/workbench.h> #include <workbench/icon.h> #include <datatypes/pictureclass.h> #include <proto/muimaster.h> #include <libraries/mui.h> #include proto/bsdsocket.h #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* my own headers ".h" */ #define CTRL_C (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) #define isDir(fib) ((fib)->fib_DirEntryType >= 0) #define ARG_TEMPLATE "FILE/A,ALL/S,QUIET/S,W=WIDTH/N,H=HEIGHT/N,M=METHOD,DEFTOOL" int main(void) { return retval; } /* main */ </syntaxhighlight> If you used c++, there is not yet c++ support in our shared library system. The easiest way to create / compile a shared library would be to use the AROS build system but the libraries can be created manually. You have to create a ROMTAG structure and some header files. A shared library is built with the %build_module macro with a line like this: %build_module mmake=MetaTarget modname=mylib modtype=library files=SourceFiles This macro can build different AROS module types, like devices, Zune classes, HIDDs, etc. <pre> ##begin config version 1.0 ##end config ##begin functionlist void func1(LONG a, LONG b) int func2(char *s, ULONG a) ##end functionlist </pre> Alternatively, <pre> #ifndef LIB_H #define LIB_H #define __NOLIBBASE__ #include <exec/libraries.h> #include <exec/semaphores.h> #include <dos/dos.h> #ifdef __AROS__ //#include <aros/debug.h> #define reg(x) #define __saveds #endif #define USESYSBASE struct ExecBase *SysBase = Base->My_SysBase; struct MyTestBase { struct Library My_Test_Lib; struct ExecBase *My_SysBase; APTR My_SegList; int testint; }; #endif </pre> <pre> /*--------------------------------------------------------------------------*/ /* Resident header written for mytest.library */ /*--------------------------------------------------------------------------*/ #define __NOLIBBASE__ #define VERSION 1 #define REVISION 0 #define LIBHEADNAME mytest #define LIBHEADNAMESTR "mytest" #define COMPDATE "04.10.2015" #define VERS "1.0" #define LIBBASETYPE struct MyTestBase #define LIBBASETYPEPTR LIBBASETYPE * #include <aros/debug.h> #include <exec/exec.h> #include <proto/exec.h> #include <exec/resident.h> #include <exec/nodes.h> #include <exec/libraries.h> #include <aros/symbolsets.h> #include "lib.h" const UBYTE lib_name[] = LIBHEADNAMESTR ".library"; const UBYTE lib_id[] = "$VER: " LIBHEADNAMESTR ".library " VERS " (" COMPDATE ") by ALB42\n"; extern const APTR FuncTable[]; AROS_UFP3 (LIBBASETYPEPTR, InitLib, AROS_UFPA(LIBBASETYPEPTR, Base, D0), AROS_UFPA(BPTR, seglist, A0), AROS_UFPA(struct ExecBase *, sysbase, A6) ); static struct LibInitStruct { IPTR LibSize; const APTR *FuncTable; const struct DataTable *DataTable; APTR InitFunc; } const LibInitStruct = { sizeof(LIBBASETYPE), FuncTable, NULL, (APTR)InitLib }; const struct Resident romtag = { RTC_MATCHWORD, /* match word */ (APTR)&romtag, /* back pointer */ (APTR)(&romtag + 1), /* skip pointer */ RTF_AUTOINIT | RTF_EXTENDED,/* flags */ VERSION, /* version */ NT_LIBRARY, /* type of module */ 0, /* init priority */ (STRPTR)lib_name, /* module name */ (STRPTR)lib_id + 6, (APTR)&LibInitStruct, REVISION, NULL }; AROS_UFH3 (LIBBASETYPEPTR, InitLib, AROS_UFHA(LIBBASETYPEPTR, Base, D0), AROS_UFHA(BPTR, seglist, A0), AROS_UFHA(struct ExecBase *, sysbase, A6) ) { AROS_USERFUNC_INIT Base->My_SegList = seglist; Base->My_SysBase = (APTR)sysbase; Base->testint = 0; USESYSBASE bug("InitLib\n"); if (!set_open_libraries()) { set_close_libraries(); return NULL; } return Base; AROS_USERFUNC_EXIT } AROS_LH1(LIBBASETYPEPTR, LibOpen, AROS_LHA (ULONG, version, D0), LIBBASETYPEPTR, Base, 1, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibOpen\n"); (void)version; Base->My_Test_Lib.lib_OpenCnt++; return Base; AROS_LIBFUNC_EXIT } __saveds APTR LibExpungeInternal(LIBBASETYPE *Base reg(a6)) { USESYSBASE APTR seglist; bug("LibExpungeInternal\n"); if (Base->My_Test_Lib.lib_OpenCnt) { return 0; } seglist = Base->My_SegList; Forbid(); Remove((struct Node*)Base); Permit(); FreeMem((APTR)Base - Base->My_Test_Lib.lib_NegSize, (LONG)Base->My_Test_Lib.lib_PosSize + (LONG)Base->My_Test_Lib.lib_NegSize); set_close_libraries(); return seglist; } AROS_LH0(BPTR, LibClose, LIBBASETYPEPTR, Base, 2, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibClose\n"); if (!(--Base->My_Test_Lib.lib_OpenCnt)) { return LibExpungeInternal(Base); } return 0; AROS_LIBFUNC_EXIT } AROS_LH1(BPTR, LibExpunge, AROS_LHA(LIBBASETYPEPTR, Base, D0), struct ExecBase *, sysBase, 3, LIBHEADNAME ) { AROS_LIBFUNC_INIT (void)sysBase; USESYSBASE bug("LibExpunge\n"); return LibExpungeInternal(Base); AROS_LIBFUNC_EXIT } AROS_LH0(LIBBASETYPEPTR, LibReserved, LIBBASETYPEPTR, Base, 4, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibReserved\n"); return 0; //return (APTR)LibReserved(); AROS_LIBFUNC_EXIT } // Space for your own functions // do not forget to update the FuncTable as well AROS_LH1(int, TestFunction, AROS_LHA(int, TestValue, D0), LIBBASETYPEPTR, Base, 5, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("TestFunction\n"); Base->testint = TestValue + Base->testint; return Base->testint; AROS_LIBFUNC_EXIT } // Functable -> Table of all functions in the Library, in right order - important! const APTR FuncTable[] = { &AROS_SLIB_ENTRY(LibOpen,LIBHEADNAME,1), &AROS_SLIB_ENTRY(LibClose,LIBHEADNAME,2), &AROS_SLIB_ENTRY(LibExpunge,LIBHEADNAME,3), &AROS_SLIB_ENTRY(LibReserved,LIBHEADNAME,4), &AROS_SLIB_ENTRY(TestFunction,LIBHEADNAME,5), (void *)-1 }; // AutoInit stuff void *__PROGRAM_ENTRIES__symbol_set_handler_missing; void *__LIBS__symbol_set_handler_missing; // end of AutoInitStuff </pre> Makefile <pre> VPATH = CFLAGS = -O2 -g -fomit-frame-pointer -W -Wall -Wno-parentheses CC = i386-aros-gcc LD = i386-aros-gcc LDFLAGS = -nostartfiles -Wl,-Map -Xlinker linkermap LIBS = -lautoinit -llibinit STRIP = i386-aros-strip --strip-unneeded --remove-section .comment OBJS = lib_header.o all: mytest.library mytest.library: $(OBJS) $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ lib_header.o: lib_header.c lib.h clean: rm -f *.o *.library *.ppu testlibrary linkermap </pre> Porting UNIX library to AROS - dealing with static variables which would make it easy to port such libraries to AROS, keeping the benefits of sharing them on disk, but losing the benefit of actually sharing them in memory. Our problem arises by the fact we want to share the actual code (the .text section of the library) and constant data, but we need to have per-task .bss and .data sections. If we get rid of our intention to share the .text and .rodata sections, things get quite easy: just load and relocate the library whenever it's open, by whoever it's open. It's like statically linking the library into the executable, except that the final linking is done at runtime. In the V0 branch, in workbench/hidds/hidd.nouveau was committed pcimock.hidd. This is a pci driver that allows mocking real PCI devices under linux-hosted. The main idea is to be able to run the real hardware driver under linux-hosted with as little changes as possible (some changes will always be needed though unless someone wants to write complete device simulator) so that driver's code paths can be executed and debugged using gdb. This was a very helpful capability when porting nouveau. Now it is externalized from nouveau.hidd and can be used by other people porting drivers. The pcimock.hidd can currently mock 4 different nvidia cards, 1 AGP bridge and also mock irq.hidd. What's the difference between this driver and the pcilinux.hidd? I used that one to develop many different HW drivers for aros. As far as I understood the intention of pcilinux.hidd it is supposed to get access to real hardware that is running under linux. The pcimock.hidd goal is to mock the hardware. For example my dev box is a PCIE system, but I still would like to run the AGP codes paths in nouveau under linux-hosted to check if they don't seg fault. The other case would be to run codes paths for hardware that the developer does not have (Fermi cards in my case). In the case of pcimock.hidd, the AROS driver's code paths will execute as long as you add proper mocking (for example fill in PCI config area or values for registers in BARs). This is an advantage for ported drivers - the code should already work (since it worked on another system) but there might have been mistakes made during porting which can be detected easily with gdb. In case you are writing your driver from scratch, pcilinux.hidd hidd will give you more advantage, since you can actually access the real hardware from linux-hosted. == Misc == ===APL, MPL, BSD, GPL and LGPL Licences=== The majority of AROS sources in licensed under AROS Public License ([http://aros.sourceforge.net/license.html APL]) which (to a degree) protects us from someone taking AROS sources and not contributing improvements back (for example MorphOS took some AROS source and then contributed changes back) It is written to allow the use of AROS code in other open source or commercial projects without exception whilst providing a mechanism so that improvements/additions can find their way back to the original source in one form or another. There are "3rd" party applications used by AROS that do not fall under this license, which are an extra "Contrib" download for convenience. Anyone can port GPL-ed network and sound drivers as AROSTCP and AHI are GPLed. Direct using (porting) [http://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs GPL]-ed code in other parts of AROS (gfx, sata, usb) is not possible because AROS license is not compatible with GPL. You need to utilize permissive licensed code like BSD or MIT/X11. BSD and MPL license are the closest to APL. APL however is not so compatible with LGPL/GPL. LGPL case - you cannot statically combine APL code with LGPL. You can, however thank to LGPL being "lesser" restrictive, use LGPL dynamically loaded libraries in APL codes. GPL case - you cannot combine APL code with GPL in any way if there is no explicit clause by GPLed code authors allowing that. If you do combine APL with GPL in "bad" ways described above - you have a problem (you violate GPL). This problem might result in everything in AROS becoming GPL or everything running or AROS becoming GPL (here I'm not sure really). The other scenario is that you are not allowed to legally distribute such code at all. To be honest I have grasped how to violate GPL, but I'm still no exactly sure what happens when you violate it (but I'm sure it's not anything nice) GPL software can run on top of non-GPL "system components" (see system components exception of GPL), but the other way around (non-GPL using GPL) leads to problems. This means applications like scout, or Quake III are ok (in the majority of cases). Theres no reason GPL drivers cannot be ported - but they cant be in AROS's ROM (requires linking APL code with GPL), nor can AROS depend on them (e.g. they must use existing apis). If they are launched (dynamically linked) by a user action that is allowed. It is also allowed to distribute such binaries together for convenience. GPL is not about statical or dynamic linking but is about executing process and function calls. These components - SFS, isapnp, Zune texteditor, AHi, network drivers, freetype, openuirl, BHFormat, Edit and (" dynamically loaded libraries") are LGPL, not GPL. Mesa/Nouveau stuff is MIT. Some user tools are GPL though. '''AROS (system)''' * system components (libraries/classes/devices/etc) cannot be GPL as they would propagate GPL to complete system as well as GPL is not compatible with MPL from which APL is based * system components can be LGPL v2 or a permissive license (MIT/BSD) * system applications can be anything you like (but still I would prefer APL or permissive so the code can be reused if needed) '''Contrib:''' * no rules - contrib does not impact AROS system since nothing in AROS system depends on contrib. About stealing code: The chances of this happening is exactly the same whether we are APL or GPL. If any closed-source option wanted to do it, there is no one that can validate otherwise. MorphOS has used some AROS codes, but contributed changes back. The rationale behind APL is that while it guarantees that the original developer will get the improvements back (to a certain degree - file based), the person who uses the codes does not have to open his original codes. BSD does not guarantee that the original developer gets improvements. GPL requires the person using the codes to open his codes as well. The copyright holders needs to stay - we just need information from them that the codes are available under APL (for example a checked-in file like in case of Poseidon). We don't do transfer of copyrights. ; Ultimately what can and cannot be done is up to the author(s) - not the licence. ===AROS source code tree=== * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-trunk.txt * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt Found this interesting (non-GPL) licensing 'anomaly' - to keep in mind for distributors. Programs that lose their license if sold ("non-profit only" licensed): contrib/aminet/comm/term/TinyTerminal contrib/aminet/dev/basic/bwBASIC contrib/aminet/text/edit/xdme contrib/fish/aroach contrib/fish/lotto contrib/fish/shuffle contrib/fish/touch + cdvdfs. Here is a list of all the GPL/GPLv2/GPLv3 licenses fossology found, what have explicit licenses in their comments. excluded LGPL, BSD/GPL dual licensed and programs (such as Prefs/Edit and BHFormat) <pre> AROS/rom/dbus/include/ AFL_v2.1 ,GPL_v2+ (supposedly AFL < 3 is GPL incompatible) AROS/workbench/classes/zune/betterstring/include/ GPL_v2+ AROS/workbench/classes/zune/texteditor/include/ GPL_v2+ AROS/workbench/classes/datatypes/gemimage/ GPL_v2+ GPL AROS/workbench/classes/datatypes/degas/ GPL_v2+ AROS/workbench/libs/openurl/README: GPL AROS/workbench/network/smbfs/documentation/ GPL_v2 AROS/workbench/network/smbfs/source_code/ GPL_v2+ AROS/workbench/network/stacks/AROSTCP/bsdsocket/kern/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/mmakefile.src conf.h GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/sys/ CMU ,GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/net/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/api/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/conf/conf.h: GPL_v2 AROS/workbench/network/stacks/AROSTCP/netinclude/net/radix.h: CMU ,GPL_v2 AROS/workbench/devs/AHI/AHI/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/COPYING: GPL AROS/workbench/devs/AHI/Docs/texinfo.tex: GPL_v2+ AROS/workbench/devs/AHI/COPYING: GPL AROS/workbench/devs/AHI/Drivers/EMU10kx/ GPL_v2+ AROS/workbench/devs/AHI/AHI-Handler/ GPL_v2+ AROS/workbench/devs/networks/rtl8029/ GPL GPL_v2+ AROS/workbench/devs/networks/pcnet32/ GPL GPL_v2+ AROS/workbench/devs/networks/ppp/LEGAL: GPL AROS/workbench/devs/networks/atheros5000/ GPL_v2+ AROS/workbench/devs/networks/rhine/ GPL_v2+ AROS/workbench/devs/networks/nForce/ GPL_v2+ GPL AROS/workbench/devs/networks/prism2/ GPL GPL_v2+ AROS/workbench/devs/networks/fec/LEGAL: GPL AROS/workbench/devs/networks/rtl8139/ GPL GPL_v2+ AROS/workbench/devs/networks/etherlink3/ GPL GPL_v2+ AROS/workbench/devs/networks/intelpro100/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8169/ GPL GPL_v2+ AROS/workbench/devs/networks/emac/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8168/ GPL GPL_v2+ AROS/workbench/devs/networks/realtek8180/ GPL_v2+ AROS/workbench/devs/networks/via-rhine/via-rhine.c: GPL_v2+ AROS/workbench/devs/networks/via-rhine/ GPL GPL_v2+ AROS/workbench/devs/networks/e1000/ GPL_v2 AROS/workbench/devs/networks/sis900/ GPL GPL_v2+ </pre> AHI: it has special provisions (COPYING.DRIVERS). The library is LGPL, preferences software is GPL and drivers can be anything without breaking GPL/LGPL. Network stack: well, we are long overdue for a new, IPv6 enabled network stack anyway, anyone interested? ;) Seriously though it seems like the glue code is GPL and as all the drivers. However some of the drivers are our own code, so they could be relicensed to LGPL. Same filter as the AROS trunk list. These should all be libraries or plugins - no programs. <pre> contrib/regina/utsname.h: GPL_v2+ contrib/mui/classes/nlist/include/default-align.h: GPL_v2+ contrib/mui/classes/nlist/include/amiga-align.h: GPL_v2+ contrib/mui/classes/BWins/include/MUI/BWin_mcc.h: GPL contrib/mui/classes/BWins/include/BWin_private_mcc.h: GPL contrib/mui/classes/BWins/COPYING: GPL_v2 contrib/mui/classes/BWins/MCC_BWins.readme: GPL_v2 contrib/mui/classes/thebar/include/default-align.h: GPL_v2+ contrib/mui/classes/thebar/include/amiga-align.h: GPL_v2+ contrib/gfx/libs/wazp3d/LEGAL: GPL contrib/gfx/libs/wazp3d/Wazp3D.readme: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.c: GPL contrib/libs/mpega/ GPL_v2+ </pre> http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt ===Types=== On AROS following rules apply: <pre> 1. BYTE/UBYTE is 8bit, WORD/UWORD is 16bit, LONG/ULONG is 32bit, QUAD/UQUAD is 64bit, the types are comparable with stdint types (int8_t, int16_t, int32_t, int64_t) 2. IPTR/SIPTR are integer types large enough to fit pointer, that is sizeof(IPTR) = sizeof(APTR) = 4 on 32bit system, and = 8 on 64bit system 3. ti_Data in TagList is large enough to hold a IPTR/APTR type. 4. never store a pointer in integer of type LONG. It may work (if the pointer has upper 32bits clear), but does not have to. Compiler should warn you about that. 5. If you are unsure about point 4, allocate your memory with MEMF_31BIT flag set. But don't expect that AROS internals will do the same. </pre> point 4 is actually important. * UBYTE/BYTE for 8bit * UWORD/WORD for 16bit * ULONG/LONG for 32bit * UQUAD/QUAD for 64bit <pre> UBYTE Unsigned 8 bit integer variable (byte). BYTE Signed 8 bit integer variable (byte). UWORD Unsigned 16 bit integer variable (word). WORD Signed 16 bit integer variable (word). ULONG Unsigned 32 bit integer variable (longword). LONG Signed 32 bit integer variable (longword). FLOAT 32 bit IEEE floating point variable. UQUAD Unsigned 64 bit integer variable. QUAD Signed 64 bit integer variable. DOUBLE 64bit IEEE floating point variable. BOOL Boolean variable, TRUE and FALSE are also defined in exec/types.h. VOID Void. APTR A generic pointer for multiple purposes - Arrays. STRPTR A pointer to a null-terminated string. IPTR Really important in AROS, the only way to declare a field that can contain both: an integer or a pointer. </pre> if you want to write really portable app, you may be interested in standard datatypes defined in C99: int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, intptr_t, uintptr_t. They are all defined in inttypes.h include file. In exec/types.h the following short-cuts are typedef'd. They are used often in AROS, so you should nearly always include exec/types.h and soon only they will be removed from sys/_types.h include, all types are now defined in include files named aros/types/xxx.h. (Preparation for C library split; sys/xxx.h include will only be available there when compiling with POSIX C library) Compiler specific types, like int and long might change their size. In case of AROS, similar to linux, int remains 32 bit whereas long grows to 64 bits in size. If you use Amiga-like data types, i.e. BYTE/UBYTE, WORD/UWORD, LONG/ULONG and QUAD/UQUAD or the C99 standard types (uint8_t and so on, see stdint.h include) then you should have less issues to solve than by using types without size guarantee. Of course, all pointers grow to 64 bytes using 64bit cpu. Most of the code can be just recompiled and will work. In rare cases, where e.g. pointers are casted to integers, a special care must be taken. Especially in the cases, where pointer is casted to LONG/ULONG (this code will break on 64 bit AROS) e.g. '#define IPTR ULONG'. With compiler delint patches which the majority of them are simple casting issues to make the compiler happy. Notice some of the changes involve introducing double casts. In very recent versions of GCC. Yes, the bulk of the double casts are for converting 32 bit addresses (ie from a 32 bit PCI DMA address register) to a 64 bit pointer. First cast is to IPTR (to expand to 64 bits, and prevent sign extension if the address is above 0x7FFFFFFF), and then to APTR. ULONG != IPTR except on 32bit .. so if you need to store pointers make sure and use IPTR and not ULONG (which some old code does). For this reason things like Taglist elements are 64bit (since the tag data can be a pointer). If your passing items on the stack you should use the STACKED attribute to make sure they are correctly aligned (on 64bit all items on the stack are 64bit..) There is more issues like using "== 0L" causes problems. ===Endian=== *BE *LE Use the macros from <endian.h> instead making a guess based upon architecture defines <pre> #if _BYTE_ORDER == _BIG_ENDIAN #elif _BYTE_ORDER == _LITTLE_ENDIAN #else + #error <whatever.h> - Byte order for this architecture is unsupported! </pre> ===SVN and GIT=== If you want to help develop AROS OS itself, you can * view current GIT/SVN entries [http://aros.sourceforge.net/ Aros Org website] or [https://github.com/aros-development-team/AROS Github], [https://github.com/ezrec older ezrec mirror], [https://github.com/michalsc/AROS/ older mirror], [https://trac.aros.org/trac/timeline TRAC], [], * awaiting update [http://repo.or.cz/w/AROS.git git repo], [http://www.ohloh.net/p/aros/commits ohloh] or [https://svn.aros.org/svn/aros/trunk/ svn repo] and access [Git version git://repo.or.cz/AROS.git here], * deprecated [https://www.gitorious.org/aros/aros/commit/a7fda9e ARIX commits] or [https://gitorious.org/aros/aros GIT old] If you have SVN access (early 2015 introduced a new SVN server, create a new account at trac aros org) and/or have obtained the source [http://aros.sourceforge.net/download.php AROS site] - you can compile the current build tools/environment using: > make development and follow this [http://aros.sourceforge.net/documentation/developers/compiling.php#building procedure] or [https://github.com/apiraino/aros_guide Guide] https://trac.aros.org/trac#Developing If you plan on contributing back changes, please post information about such changes first on this [http://mail.aros.org/mailman/listinfo/aros-dev/ mailing list] for more experience developers can validate whether they are correct. Then there are the nightly build machines. They svn update before the build and run configure as one of the next steps. autoconf might be added to the nightly build scripts. Our build relies on packages downloaded from Internet (SDL for example) - it always worked this way. The minimal requirement (when just building core AROS) is binutils and gcc. If you build contrib as well, you need many more packages to be downloaded. https://gitorious.org/aros/aros/commits/crosstools-II git://gitorious.org/aros/aros.git Branch crosstools-II there is only one commit on top of ABI_V1 <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-x86_64 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-x86_64 </pre> and <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-i386 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-i386 </pre> build OK. :''More information: [[Aros/Developer/Maintainer|AROS Maintainer Docs]]'' ===SDI Calls=== Integrate the 'SDI'-headers to allow easier porting to all amiga-like platforms. <pre> PUTCHARPROTO( PutTheChar, char c, struct SPrintfStream *s ) { // REAL CODE } </pre> have "SDI_compiler.h" and "SDI_hook.h" included its more organized like #include SDI/SDI_hook.h than #include SDI_hook.h option 1 --- i also use when back porting from amiga's.. <pre> #ifdef __AROS__ #include SDI/SDI_hook.h #else #include SDI_hook.h #endif </pre> also you can add the -i include/sdi/ location if you do not want to add or edit any files. Defining HOOKPROTO to IPTR name(struct IClass * cl, Object * obj, Msg msg); solved the problem A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. examine compiler/include/aros/symbolsets.h (AROS_LIBREQ) compiling mui stuff for aros setting -std=gnu99 is necessary (i have had -std=c99 most of the time). ===Locale with Flexcat=== Most languages have a locale, but not every app is localized, the only thing needed is to translate the "catalog" files. It is a case of locating the correct catalog and saving the translated version. For every app that lacks of your language catalog and is localized anyway, you should find (in the sources) files related to locale: * file.cd = catalog descriptor, contains base msg, with internal language (usually english) * language.ct = catalog translation, contains every translated msg, indexed as in the file.cd. Compare with other localized apps... Then, "make my_app-catalogs" should create and install your translated catalogs. ex : for, saying, sys:prefs/wanderer: on root of AROS sources, type: "make workbench-prefs-wanderer-catalogs" then (if you changed the .cd file): "make workbench-prefs-wanderer" For apps not localized, you have to adapt their code to support it, if it is possible... noticed the original .cd file has many (//) strings at the end of any voice, so added them also to the .ct file. That (//) is only for cd files. I'm highly recommending to use FlexCat for updating ct files, e.g. like this: flexcat app.cd deutsch.ct newctfile deutsch.ct You'll get error checking and new entries are marked in the resulting ct file. When editing .ct files, only change those lines containing translation and perhaps version string, nothing else. The rest is up to the relevant tool, flexcat. In order to update your translation, type in the following in your shell: flexcat xyz.cd xyz.ct NEWCTFILE xyz_upd.ct COPYMSGNEW This way you will not only make sure you have correct translation file but flexcat also pre-fills newly added strings with "*** NEW *** text. Even better tool for checking cd/ct/catalog files is catcheck, but this one is sadly only available for AmigaOS/68k... Some languages have variations, like portugues from portugal and portugues from brasil differs... This is the way to go. I will have a look at language files, but basically if those two languages differ you have to do two separated set of translation files, yes. (you could create a brazilian slang language localization too) * At system level localization for one language is a dot language file. (ex: locale:languages/klingon.language) * At app level localization is a dot catalog file (ex: locale:catalogs/klingon/system/libs/dos.catalog) * At sources level, the dot ct file, and "$language" dot cd files and some building framework. (ex: catalogs/my_app.ct catalogs/klingon.cd catalogs/mmakefile.src support.c support.h) Please, use Flexcat to generate CT files: FlexCat wanderer.cd NEWCTFILE=deutsch.ct Then fill the first 2 lines with something useful: <pre> ## version $VER: wanderer.catalog 1.1 (9.2.2006) ## language deutsch </pre> You can even update the CT-File: (This adds the new strings) FlexCat wanderer.cd deutsch.ct NEWCTFILE=deutsch.ct To compile a catalog you only need the .cd file and your translation (.ct file): FlexCat multiview.cd deutsch.ct CATALOG=MultiView.catalog [http://murks-ide.svn.sourceforge.net/viewvc/murks-ide/trunk/src/Catalogs/flexcat_linux?revision=100 Linux version of FlexCat] : [http://aros.sourceforge.net/documentation/developers/app-dev/localization.php#localization-for-non-developers More information] A script which compares the required version (i.e. the version which an application/module etc. tries to open) with the version of the existing CT files. The result is in this table: https://github.com/aros-translation-team/translations/wiki/Progress The following cases are highlighted: n/a i.e. CT misses at all version in existing CT file is lower than the required version It might be a bit difficult to participate if you haven't worked with Git before but alternatively you can send your CT files to our Slack channel. When the ct file has been generated via flexcat (flexcat keyshow.cd NEWCTFILE=spanish.ct) it has the following header: --------------------------------------------------------------------------------------------------------------- ## version $VER: <name>.catalog <ver>.<rev> (04.01.2021) ## language nolanguage ## codeset 0 ; --------------------------------------------------------------------------------------------------------------- Those values <ver>.<rev> are the version and revision of the CT file for the languaje or are the values of the application being localized? The <ver> part must match with version which the application tries to open. You can find the value either in the column "Required Version" in the table which I've linked above, our you can look in the git repository. For keyshow it would be https://github.com/aros-translation-team/keyshow. You can find in the file "catalog_version.h" the right version number. The <rev> part starts for new CT files with 0 and should be increased every time the CT file is updated. Updated several files and created a few more that were missing on the spanish catalog. The catalogs are in Git repositories at https://github.com/aros-translation-team a) You tell me your Github user name. I'll invite you. You can work directly with the Git repositories. b) You create Github forks of the catalog repositories and create pull requests. c) You send the CT files to mrustler gmx de ===C Utils Misc=== The AROS source uses at several places the __DATE__ macro to fill the date entry of a $VER tag. Problem is that c:version doesn't understand that date format (e.g. "May 21, 2011"). As a result the output of e.g. > "version c:shell full" contains "(null)". Is extending the version command to understand the format of __DATE__ the right solution for that problem? AmigaOs compilers should use __AMIGADATE__ macro or similar form, if it isn't implemented it could be emulated in makefile: -D__AMIGADATE__=\"$(shell date "+%d.%m.%Y")\" BTW. I think DD.MM.YYYY is better format than "Month DD YYY" because "Month DD YYY" is not localized in any way. "strnicmp" shouldn't work with NULL pointers The Situation: compiled a linklib using c++ object files (using the c++ cross compiler). compiled a C stub that uses the linklib (using the c++ cross compiler). Try to link them together (using the c++ cross compiler) with C object files (using the normal target c compiler) that need to use -nostartup = cant do because using the c++ files pulls in arosc (for stdio etc.) - so wants to have the autoinit stuff present. What can I do about this?? If it is possible to manually open it then what do I need to do exactly? === ENV === The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. 99% of the time that statement is true (not required) for pretty much every file in ENV: or do people change their default icons - and prefs settings - every boot? There seem to be a bad habit of late with developers changing things to reflect their own personal preference when the change isn't actually necessary - It would be nice if people could refrain from doing that in the tree without at least discussing it on the dev-list first (and with good reasoning unless they committed said work in the first place..) We're not keen on the pollution of the "S:" dir: it's meant to be for scripts. What's wrong with "ENV:"? Only the fact that it takes up RAM. I understand that for PCs with several gigabytes of RAM this is irrelevant. But let's remember about other machines. The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. How about implementing in the style of HappyENV then? RAM-disk handler that falls through to reading from ENVARC: if there is no such file stored in it already. Removes RAM usage for unchanged files, removes the need to copy ENVARC to ENV in startup-sequence. Shouldn't be too hard to make from AmberRAM, or even just extend AmberRAM to provide this service. Is it feasable to build a special version of AmberRAM handling ENV: that will try and copy the requested file from ENVARC: if it isnt found in ENV: ? Additionaly it could mark closed "files" as untouched - and expunge them from ENV: after a period of time to free up additional RAM:, or when the system is running low on free memory? Silenty disappearing files may not be a good plan. Would be nice if the following would work: ASSIGN :ENV SYS:Prefs/Env-Arc ADD ASSIGN :ENV RAM:ENV ADD Where new files put in ENV: end up in RAM:ENV, and opening files looks in RAM:ENV first, then SYS:Prefs/Env-Arc Well - that's essentially what im proposing but without the assigns - or need for a RAM:ENV directory. Adding it as a feature of AmberRAM sounds like the most memory efficient way (one handler to load in RAM) but that's only if it is possible to make it handle ENV: additionally to RAM:, and if it is even possible to add the proposed functionality (...and how to make it enable it when accessing ENV:). ===(AS)MP support=== If one has to recompile software for SMP multi core, is there any thing special one has to do to get software to run? Use task.resource if you need to query information about what tasks are running, and clear msgports completely when they are allocated. Most code should not need Forbid. Use Semaphores, Messages etc. to sync your own code. Accessing system structures is a different thing. Use the proper API whenever possible. How single structures will be protected in the future is still a moving target, at least it is not documented. And you should never use undocumented stuff Ideas on for SMP multi-core Another suggestion is ... Forbid/Permit function calls are meant to halt multitasking so as no other task could intervene with what ever the calling task is doing, e.g. setting semaphores. Disable/Enable calls are meant to halt interrupts and as a side effect they also halt task switching. One option is to make it compulsory to protect shared resources with semaphores and forbid the use of simple Forbid() calls as to protect something. Setting semaphore should be done if possible with atomic instructions (check and alter in one instruction). Or make the second concurrent ObtainSemaphore call halt the second calling task and force if possible a task switch which ever gives better results. Semaphores could store the owning tasks task pointer instead of boolean to make things easier. As long as the CPU initiates the DMA transfers through the OS, and the OS ensures that the transferred memory is within the region accessible to the user initiating the transfer, everything is fine. The CPU is the conductor, and the CPU by that has the control of which DMA transfer is initiated and which is not. All you need to do is to write device drivers reasonable. Hint: CachePreDMA and CachePostDMA exist. All the Os has to do is to verify that the memory regions to be transferred are valid, and prohibit direct access to the DMA control registers from user space. None of these algorithms imply huge costs. The current OS design doesn't really allow virtual memory in first place, Forbid() is again the problem. [http://www.tbs-software.com/guide/index.php?guide=autodocs.doc%2Fmemory.doc&node=1 memory.library API] seem to low level. IMHO the programs should not know how the swapping is implemented. I would just go for one new memory flag MEMF_SWAPPABLE that indicates that a certain memory region or a whole memory pool won't be accessed during Forbid()/Permit() etc. It only solves part of the problem, it only implements virtual memory and not memory protection. For the latter you need to be able make certain memory inaccessible by other programs, some memory read-only for one task and read-write for other tasks, etc. And I think this should be done in the same Address Space in order to avoid you constantly need to swap between different address spaces. So to summarize, if there are programs using this API we may provide a wrapper layer to get them working but I am not convinced this API should be the reference API with whom to provide VM to AROS programs. === Variadic === variadic functions (i.e. functions with an arbitrary amount of arguments). <pre> #include <stdarg.h> [...] char * STDARGS GetKeyWord(int value, char *def, ...) { [...] va_list va; [...] va_start(va, def); [...] va_end (args); </pre> Please keep with using stdarg rather than having va casted to a LONG * type and varargs handled manually. Doing so, prevents tons of casting, where a simple va_arg can be used. So, string = *((char **) args) instead of string=va_arg(va, char *). <pre> #include <stdio.h> #include <stdarg.h> int printf (const char * format, ...) { int retval; va_list args; va_start (args, format); retval = vfprintf (stdout, format, args); va_end (args); fflush (stdout); return retval; } /* printf */ </pre> Couldn't find varargs.h or stdarg.h. and have no use for AROS_SLOWSTACKHOOKS or AROS_SLOWSTACKTAGS. GCC looks for stdarg.h in a different place: /bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/include/stdarg.h Here is a path for a "normal" header: bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/../../../../i386-aros/sys-include/aros/system.h The use of vararg.h isn't supported by newer gcc versions. If you want your code to run on architectures that pass part of variadic arguments in a number of registers you need to use AROS_SLOWSTACK macros. Otherwise your program will not work on powerpc and x86_64 ports. Of course the SLOWSTACK stuff is not needed in a function that can use va_list, va_start, va_arg and va_end. It's only needed if you want to write functions like DoMethod or similar. #include <stdarg.h> should be enough no matter if you do cross or native compiling. If it does not work, something is wrong and should be corrected. Stdarg.h is here, Development:lib/gcc/i386-aros/4.2.2/include/ ...which is part of the compiler's default include paths. In other words, #include <stdarg.h> works out of the box, indeed. (sorry, I should have just tried it before invoking "search" or "find"...) furthermore, myprintf() as shown above won't work, because... printf(format, args); ...is wrong - the second argument does not match printf() prototype, it expects a argument list, but args is of type va_list (obviously) - so one has to use... vfprintf(stdout, format, args); ...instead, just like in the original printf(), and add fflush(stdout). additionally, one could use... int myarg = va_arg(args, int); ...between va_start() and va_end() to access individual arguments, where each call to va_arg() returns an argument casted to the desired type (here: "int") from the list given (here: "args") and advances to the next one. wrapping up vfprintf() and modifying the format string now is a major speedup! no more backslash-n typing! this has been haunting me for years! On MOS and AmigaOS, the NewObject variadic function is kept in the static library. It takes most of the parameters on the stack - thanks to that the implementation of NewObject calls the NewObjectA function. Everything works perfect, and the typical MUI macros may be easily used. This, however, is not the case when you compile for AROS. Here, NewObject is a variadic macro, not a function. Thanks such approach we do not need any custom compiler in case of systems, where the arguments of variadic functions are passed partially through registers and partially through the stack (This is the case of PPC and x86_64, this is also the reason why both OS4 and MOS require specially patched compilers). Since NewObject is a macro, the gcc's preprocessor expects the list of macros arguments enclosed within parentheses. In MUI macros it is not the case. Imagine the following test code: <pre> #define foo(a,b) ((a)+(b)) int loosy_function(int a, int b) { return foo(a,b); } </pre> This will compile and work, but the following piece of code: <pre> #define foo(a,b) ((a)+(b)) #define END ) int loosy_function(int a, int b) { return foo(a,b END; } </pre> will fail with the error: unterminated argument list invoking macro "foo" There are two ways of fixing your issue. Either create your new objects outside this huge MUI constructions, and in there use just a pointer, or get rid of the "End" macro and exchange it with "TAG_DONE)". Badly written software is, for example, casting va_list to an APTR or even doing so as if va_list were a plain table of function arguments. Such code needs to be fixed because it has very few chances to work anywhere but on author's machine ;) The problem is nOt that they assume sizeof(APTR) == 4, its that they often do not use APTR, and use ULONG to store pointers exclusively. If the code used APTR/IPTR as it should - most of the "problems" wouldn't exist. It would also help if people would start using variadic arguments properly. Many coders do assumptions which shall never be made. Instead, they should consider using stdarg.h file and all the va_* functions :) ===ABI=== In the head of our SVN repository there are now only 3 directories: <pre> admin/ branches/ trunk/ </pre> We have added two extra dirs there: tags and imports As discussed when we branch ABI V0 and [[Aros/Developer/ABIv1|ABI V1]] it would also be good to introduce tags. Normally this is done in a directory in the repository called tags. Currently we don't have this directory there. (We do have branches/tags that is a hack I have done because one doesn't have write access in the top directory. I think this directory is not clean and should be removed). The second directory I would introduce is an imports directory for implementing vendor branches as discussed in the svn [http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html book]. Currently we use code from several different projects and that code is stored inside the AROS tree; we seem to have problems with keeping this code up to date and merge our changes upstream. Maintainers of up stream projects like the MUI classes etc. have complained about this (to put it lightly). Introducing these vendor branches would make it easier to see what changes we have made and make patches to be sent upstream and make it easier to import newer upstream versions of their code. Although can't "copy" the vendor branch into the main branch because it's already there, so start with a "merge". Yes, the first step to make the code already in the repository compatible with the vendor branches will be the most difficult. The best way to do it the following way: * first import the version on which the current AROS code is based into the vendor branch * then import the new version over it in the vendor branch * finally merge the difference between these two version in the AROS code present in the repository. For example, place NList directly under vendor and not in a subdirectory like "contrib/zune/classes". Actually after we have a stable [http://aros.sourceforge.net/documentation/developers/specifications/drafts/abiv1.php ABIv1 (2012 or later)]. We need to move away as much as possible from the contrib directory to some other repositories. The reasons are ... * The AROS repository should be for the core AROS code. * other contrib projects should be tried to be compiled for all Amiga-like OSes. * The release scheme for AROS and the other programs should not have to be aligned. * Binary versions should be provided on aros-archives and on aminet and/or OS4Depot to install them. (Some clever programs should maybe be provided to make the life of distribution developers easier). * avoid parallel forks of programs for AROS and the other amiga OSes. If there is really a need for a place for hosting AROS projects we may investigate setting up such a server but then including bug tracking, governance, maillist, etc. for each project separately. I personally think there are already enough places like sourceforge, google code, savannah, etc. where people can go for hosting such projects. ==Links== * http://amigadocs.hokstad.com * http://amigadocs.hokstad.com/doku.php?id=dev-links In the future...? *AROS 64bit - SMP, Vulkan with OpenGL compability layer *AROS 32bit - keep for historic reasons What would you like to see implemented in AROS? ABIv1 completed, SMP (x86_64), SendMsg()/GetMsg() to support memory protection between target and destination, in that order. Michal Schulz and Jason McMullan have been toying with the question "What are the minimal changes needed to the AmigaOS 3.1 API to support SMP"? The answer so far seems to be "few, but subtle". For example, SysBase->ThisTask is no longer meaningful on SMP, but FindTask(NULL) is. Disable() and Forbid() are shockingly bad on performance, but adding a spinlock semaphore mode to SignalSemaphore will help new code on SMP. Leveraging a 'common' OS with a lot of machine support (Linux, MacOS, Windows, QNX, etc.) is something that AROS has been doing for quite a long time, and it is the biggest strength of AROS. This AROS experience and programming model, in the same way the Google's Android layers on top of Linux, or MacOS X layers on top of the Darwin/BSD kernel, as a first step * The graphics + layers subsystem could be implemented as a shim on top of a OpenGL ES implementation (ie on any modern Linux system, or the RaspberryPI's hardware, MacOS X, etc). - This also allows every window to be on its own 3D surface with backing store, allowing Wanderer (or a Commodity) rearrange/zoom/animate app windows without having to send a pile or refreshes to them * Use OpenAL as the sound backend * AROSTCP would be a thin layer over the native OS's TCP/IP stack * dos.library, poseidon.library, and input.device would be slim shims over the native APIs * If we move to loading all libraries' into the application's task space, instead of a single global instance of the library, this will allow SMP and MMU more easily. - Yes, it will require a lot of work in the libraries to make this transition - Yes, I do think it will be worth it in the end. * A 'fat binary' install format (or, maybe LLVM bytecode) that can be 'flattend' to the target architecture on installation. So, what would this 'AROS of the future' look like? * AmigaOS 3.x style API, with certain 'fundamental changes' to message passing * Uses the underlying OS' device drivers, so more AROS developer effort can go to user-visible features and bugfixes * Allows AROS applications to run side-by-side with the OS's native apps And why would anyone want to program on such a system? * AROS applications would run on any system that has the AROS Framework installed * AROS applications are pixel-for-pixel the same on all platforms. * Develop with the knowledge that you are guaranteed OpenGL and OpenAL, and the rest of the AROS Framework an option for mmake to dump its dependency of metatarget in a graphviz[*] input file. This should make it possible to visualize the dependencies and hopefully be inspiration for cleaning up some mess, circular or unneeded dependencies and so on. AmigaOS gcc 9 [https://franke.ms/amiga/gcc.wiki Old versions] able to create binaries for AmigaOS and [https://eab.abime.net/showthread.php?t=93813 Upgrading gcc versions] ==References== {{reflist}} {{status|50%}} {{BookCat}} rpstz2px7etbpw28381hudnrbec86og 4668984 4668983 2026-09-05T18:35:42Z Jeff1138 301139 4668984 wikitext text/x-wiki {{ArosNav}} ==A technical overview of AROS== Google translation [http://translate.google.com/translate?hl=en&sl=auto&tl=de&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs German], [http://translate.google.com/translate?hl=en&sl=auto&tl=fr&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs French], [http://translate.google.com/translate?hl=en&sl=auto&tl=it&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Italian], [http://translate.google.com/translate?hl=en&sl=auto&tl=es&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Spanish], [http://translate.google.com/translate?hl=en&sl=auto&tl=hi&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Hindi], [http://translate.google.com/translate?hl=en&sl=auto&tl=zh-CN&u=http%3A%2F%2Fen.wikibooks.org%2Fwiki%2FAros%2FDeveloper%2FDocs Chinese], [http://translate.google.com/translate?hl=en&sl=auto&tl=ru&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Russian], [http://translate.google.com/translate?hl=en&sl=auto&tl=pl&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Polish], [http://translate.google.com/translate?hl=en&sl=auto&tl=pt&u=http%3A%2F%2Fen.wikibooks.org%2Fw%2Findex.php%3Ftitle%3DAros%2FDeveloper%2FDocs Portuguese] {{Uncited}} AROS,<ref>[http://aros.sourceforge.net/download.php References and sources]</ref> like AmigaOS (TM), is a [[w:Message passing|message-passing]], [[w:Preemption (computing)|preemptive]] [[w:Multitasking|multitasking]] [[w:Operating system|OS]]. It uses [[w:Reentrant (subroutine)|re-entrant]] shared libraries to save memory space. AROS is based around an executive library kernel (Exec) and two other libraries: * Exec (the "kernel", which is not a kernel in the modern sense), * Intuition (graphics and GUI, integrated into the system) and * AmigaDOS (Disk Operating System, the Metacomco's Tripos modified to work with Exec). The design philosophies of AmigaDOS and Intuition are rather different, the former adopting a C-like API and the latter creating an [http://www.basden.demon.co.uk/amiga/amiga.oo.html object-oriented], message passing aware environment for the programmer. The system base is the only absolute address in AmigaOS (located at 0x00000004) this does differ with AROS as AROS SysBase is automatically provided (no $4) but everything else is dynamically loaded. The OS is well known for delivering high performance due to its close connections with the hardware, while simultaneously having the flexibility to support re-targetable graphics (Cybergraphics) and retargetable audio subsystems (AHI). : Diagram showing relationships of libraries to system needed Remember, AROS is a [http://en.wikibooks.org/wiki/Aros/Developer/ABIv1 research] operating system, and while all contributions to the base AROS code are welcome, please contact the dev list first for any core changes. Writing applications for AROS does not have this requirement. While AROS appears and feels almost feature complete, it is still [[Aros/Developer/IncompleteAPIs|missing a small number of functions]] from the Amiga API. [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1201 This thread provides] information for setup, [http://www.aros.org/documentation/developers/index.php documentation] and whether you are interested in core OS changes and/or writing/porting software apps *you compile directly under AROS, which can be running on either real hardware, virtual hardware *in hosted mode under linux/window, cross-compile from that host OS (save your files as ISO-8859-15 encoding instead of UTF-8) [https://github.com/BlitterStudio/aros-compiler-docker Docker images] '''The repository''' for 64bit and 32bit ABIv1 all hardware platforms is [https://github.com/aros-development-team/AROS current development version]. There are many forks of this so that developers can work on their own and forward changes at a later date as discussed on the dev forum 64bit PC is one of two hardware platform with another fork called [https://github.com/deadwood2/AROS abiv11] which is used for Aros One x64 PC 32bit PC is the other fork [https://github.com/deadw00d/AROS/tree/alt-abiv0 repository for current stable PC version ABIv0 with backported ABIv1 features is located which is used on AROS One and Icaros x86 32bit based distros] this is for historic reasons Any [https://github.com/aros-development-team/AROS/issues bugs / issues can be added for ABIv1 issues]. The two individual PC forks have their own issues tab on their github webpages We have a [https://arosdevteam.slack.com/archives/CUFV48U3H slack here], discord on [https://discord.gg/UKp9qdEBuQ Discord@AmigaDev], ==Software Development for AROS== ===Programming languages=== ====Common to all==== 'The Developer Environment', which primarily supports C/C++ code, there are other scripting programming languages available :[[Aros/User/DOS|DOS]] :[[Aros/Developer/Docs/LUA|LUA]] :REXX [[Aros/Developer/Docs/Rexx|Regina (AROS' ARexx)]] ====Needs to be compiled/ported==== ::[[Aros/Developer/Docs/LLVM|LLVM]] ::Python [ Info], [], ::[https://ae.arosworld.org/index.php?board=11.0 FreePascal FPC Aros-Exec thread], [https://archives.arosworld.org/index.php?function=browse&cat=development/language fpc arm here is very old and will not work], FreePascal for AROS has its own [http://fpcaroswiki.alb42.de/ Wikibook], ::[http://sourceforge.net/projects/xamos/ X-Amos Basic] ::[http://sdlbasic.sourceforge.net/ SDLBasic] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[[Aros/Developer/Basic/Basic4SDL|Basic4SDL]] ([https://archives.arosworld.org/index.php?function=browse&cat=development/language ]) ::[http://alvyn.sourceforge.net/ Alvyn] ([http://www.dusabledanslherbe.eu/AROSPage/MISC.14.html download]) ::[http://www.airsoftsoftwair.com/ Hollywood when enough users warrant a port - paid one time fee language] ::[[Aros/Developer/Docs/E|AmigaE Portable E]] ====Hardware Restricted==== '''Basic''' :[http://amos.pspuae.com/AmosProManual/contents/c1.html '''Amos Pro'''] [http://amos.pspuae.com/index.php?action=forum#1 compatible] [http://www.amigacoding.com/index.php/Main_Page commands] (all incomplete) :'''Blitz Basic''' [http://aros-exec.org/modules/newbb/viewtopic.php?post_id=46537#forumpost46537 none on AROS] :: [http://www.amiforce.de/main.php Amiblitz] on amiga(TM) emulator :'''Amiga Basic''' :: [ ACEBasic] '''Misc''' :Ruby [http://www.ruby-lang.org/en Info]/[https://archives.arosworld.org/index.php?function=browse&cat=development/language Ruby 32bit PC], ===Where to get the C/C++ Environment=== If you want to develop for AROS, its generally easier to be running linux hosted AROS development environment especially for C++, cross compiling the code. That's how most developers now are doing it. g++ is used to compile owb web browser as well as some other AROS software. If you were hoping for a rich set of C++ libraries or classes defined for the OS feature set, you might be disappointed. AROS Native compiling is possible, but you're much more likely to run into the odd bug(s) in the dev environment since it gets little testing and fixing by other developers. Is there a sftp software or scp over ssh available? Maybe. At least the security part would be handled by [https://github.com/jens-maus/amissl amissl] [https://archives.arosworld.org/index.php?function=browse&cat=network/misc port]. [https://github.com/BlitterStudio/dopus5 DOpus5] has recently added sftp support. See here for a [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=1974&highlight=ssh&pid=12073#post_12073 ssh scp client] [https://arosdevteam.slack.com/join/shared_invite/enQtOTc4Mzg0NDIzNzQ0LWQ2NWZmNmMwNGIwNGEyNTgxNzU3MGFjMTk3ZThmOTQ1MTVjMzhmNTllYWQ0ZTUxMjBjMGE0Y2VjMDJmNTc5MzI#/shared-invite/email Slack Dev Forum] ====Cross compilers from Windows or Linux==== *Windows WSL2 walkthrough can be [https://arosnews.github.io/how-to-cross-compile-aros-hosted-wsl/ found here] you want to build AROS. No problem. Here are instructions for PC 64-bit: https://github.com/deadw00d/AROS/blob/master/INSTALL.md Here are instructions for PC 32-bit: https://github.com/deadw00d/AROS/blob/alt-abiv0/INSTALL.md And as always has been the case you can use the contrib archive to 'obtain' the development directory which contains the /native/ AROS gcc compiler and tools. That compiler is used to build AROS itself but can be used outside the AROS build process by providing --sysroot with indicated directory to cross compile for AROS. '''64 bit''' '''32 bit''' A good option for multiple OS is [https://axrt.org/index.php?tab=download-aros AxRuntime lets developers compile their Amiga API-based applications as Linux binaries being able to utilize modern development tools available on Linux, like IDEs, debuggers, profilers, etc] Older 32bit guides for Linux hosted compiler Please install these packages before moving to next step. Below is a reference list for Debian-based distributions. Reference build system was Ubuntu 18.04/20.04 amd64. subversion git-core gcc g++ make gawk bison flex bzip2 netpbm autoconf automake libx11-dev libxext-dev libc6-dev liblzo2-dev libxxf86vm-dev libpng-dev gcc-multilib libsdl1.2-dev byacc python-mako libxcursor-dev cmake zsh mingw64 Do all of these operations under home directory of your user or another directory where your user has write permissions. Specifically, in a section "Linux-i386", be sure first to build the cross-compiler (toolchain-alt-abiv0-i386) and only then AROS itself (alt-abiv0-linux-i386). Clone & build <pre> $ mkdir myrepo $ cd myrepo $ git clone https://github.com/deadw00d/AROS.git AROS $ cd AROS $ git checkout alt-abiv0 $ cd .. $ cp ./AROS/scripts/rebuild.sh . $ ./rebuild.sh </pre> Now to the build selection below - Linux-i386 Select toolchain-alt-abiv0-i386 - Select alt-abiv0-linux-i386 (DEBUG) Start AROS by: <pre> $ cd alt-abiv0-linux-i386/bin/linux-i386/AROS $ ./Arch/linux/AROSBootstrap </pre> Pc-i386 Select toolchain-alt-abiv0-i386 (if not built yet) - Select alt-abiv0-pc-i386 ISO image available in alt-abiv0-pc-i386/distfiles Now that we have linux-hosted build, we can resume native (option 2). Run ./rebuild.sh and selection option 2. Wait until it finished, then: <pre> $ cd alt-abiv0-pc-i386 $ make </pre> Now <pre> $ make bootiso </pre> Now, your compiler is located in toolchain-alt-abiv0-i386 directory and named i386-aros-gcc. Includes are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/include and libraries are in alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development.lib. This is how then can be passed to the compiler: /home/xxx/toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot /home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development -L/home/xxx/alt-abiv0-linux-i386-d/bin/linux-i386/AROS/Development/lib ../toolchain-alt-abiv0-i386/i386-aros-gcc --sysroot bin/linux-i386/AROS/Development local/helloworld/helloworld.c -o local/helloworld/helloworld Another method was using Debian like distros and download the gimmearos.sh script (on [http://archives.aros-exec.org/index.php?function=browse&cat=development/cross aros-archives]) to setup the developer environment by downloading necessary packages ... The gimmearos script is a good start in that direction, building the cross compilers and hosted AROS environment, but gimmearos.sh might be out of date or not be completely compatible with any given linux distro. In order to do that, you have to compile AROS yourself. Download AROS source archive not contrib. Compile AROS by entering the main directory ./configure make ([http://aros.sourceforge.net/documentation/developers/compiling.php More on compiling AROS]). The result will be a basic AROS system without development tools. To compile C++ on Linux, type 'make gnu-contrib-crosstools', creating the cross-compilers in ./bin/linux-i386/tools/, named i386-aros-gcc, etc. '''Note''': Currently, to make the cross compilers usable copy 'collect-aros' from tools/ to tools/i386-aros/bin/. At the moment the cross compilers if used from the Linux command line will only find it when it's there. If you want to compile native compilers (the Developer Environment), type 'make contrib-gnu-gcc', creating native compilers in AROS' System:Development/bin directory. When the output needs to be stripped <code>--strip-unneeded --remove-section .comment</code> The Obj-C backend should build out of the box. Open contrib/gnu/gcc/mmakefile.src and search for the line which contains "--enable-languages" and add "objc" to the list of languages that follows it. --enable-languages=c,c++,objc Better make it—enable-languages=c,c++,objc,obj-c++ ObjC++ is broken as soon as you try to use exceptions, but that might change in future GCC versions and it does not hurt having it there already. Do you need a cross-compiler or a real compiler? In the first case you can get away with just downloading the proper gcc archive, apply the patch and proceed with the normal gcc build. In the case of a real cross-compiler then when downloading the contrib sources, also need to download the normal sources, place the contrib sources into a directory called contrib, need to install autoconf+automake+perl+python, call ./configure, cd into the subdirectory and type make. to rebuild GCC with host == build == target == i386-pc-aros. So just get the vanilla sources and apply the patches without bothering about the build system? [https://vmwaros.blogspot.com/2019/10/a-pre-configured-development-machine.html pre-configured VM environment vmware virtual machine to develop AROS and AROS software] ====Native compilers for AROS==== Namely gcc for C or g++ for C++ are supplied with the [[Aros/Developer/Docs#The Developer Environment|Developer Environment]], which is already '''setup''' and part of any current AROS distribution like AROS One or the nightlies * Current GCC 6.5 (32bit) though moving to 10.5 and 15.1 (64bit) * Older software components. GNU GCC 4.x GNU BinUtils, GNU Fileutils 4.x, GNU Textutils and others usually deprecated On single partition systems and the Boot ISO, the AROS Developer environment is installed under "SYS:Development/". Systems with multiple partitions - such as a Work: partition - tend to install it to there instead, however it can be installed manually to any location. Please remember, if moving, that you will need to correct the Development packages 'install location' env variable to point to the new locations root - look in SYS:S/startup-sequence. <pre> Assign Development: SYS:Development Assign C: Development:bin ADD </pre> In the aros build instructions. you need to check out contrib and/or ports into your AROS source directory, as subdirs. then, assuming you are building in an external build dir, as you should, you simply configure and "make contrib" for instance or whatever submodule you might want to build. ===Beginners Tutorials in C C++=== As AROS is [http://eab.abime.net/showthread.php?t=29856 C based] API compatible to AmigaOS 3.x, so most of the information on programming C on the Amiga applies to AROS as well. Please note that there is a lot of AmigaOS 1.3 (1985-1989) and [https://www.markround.com/amigaguide AmigaOS AOS 2.x (1990-1992)] information around but OS3.1 is recommended but limited in amount. Brief overview of what is required to write AROS Applications # Using [[Aros/Developer/Docs/Libraries/Intuition|Intuition]] for basic screens/windows # Using graphics within windows via 8bit [[Aros/Developer/Docs/Libraries/Graphics|graphics]] and so onto 15-16-24bit [[Aros/Developer/Docs/Libraries/CGFX|cybergraphx]] # Load and save work to [[Aros/Developer/Docs/Libraries/DOS|dos]] disk drives # Using the [[Aros/Developer/Zune|ZUNE GUI Environment]] Writing native games require this extra information # Using [[Aros/Developer/AHIDrivers|AHI audio hardware independent API]] # Using USB joystick/joypad with the Poseidon USB stack through [[Aros/Developer/Docs/Libraries/LowLevel|LowLevel]] library Additional features that could be added later # Adding additional [[Aros/Developer/Docs/Libraries/Locale|Locale]] language translations to your program # Adding a [[Aros/Developer/Docs/Rexx|AREXX/Regina]] port to your application # Executing Amiga(TM) [[Aros/User/DOS|DOS]] commands from your application # Using [[Aros/Developer/Docs/Libraries/Icon|icons]] (.info files) and icon tooltypes (stack, version, and program startup options) # Local couch or IP based SANA2 networking co-op multi player gaming support Most AmigaOS programming books are nowadays very much out of date as most are from the late 1980s and do not cover later amigaOS releases like 3.1 for example, Rob Peck's book "Programmer's Guide to the Amiga". The Amiga ROM Kernel manuals aka RKMs like Libraries (3rd edition), Devices (), the AmigaDOS manual (3rd edition) and the Style Guide may have their uses. There are some reference examples from AmigaMail and Devcon notes (available again on an Amiga developers CD 2.1). For Arexx then "The Amiga Programmer's Guide to ARexx" by Eric Giguere, which was published by Commodore is useful as well as an "Arexx Cookbook". Curly brackets missing - try SHIFT + ALT + 7 or 0. * Beginners C Guide [http://www.iu.hio.no/~mark/CTutorial/CTutorial.html C Tutorial], * [http://thecguru.com/ C for beginners], * [http://fresh2refresh.com/c/c-basic-program/ C programming basics] for students, * [https://www.edx.org/courses Free Online course] from American Universities * Reference Amiga [http://amigadev.elowar.com/ API reference]. * AROS based c source can be found [[Aros/Developer/Docs/Examples|here]] and lots of example code can be found inside [https://github.com/aros-development-team AROS sources] themselves and from the contrib section of the archives from [https://github.com/aros-development-team/contrib Aros site], and study the AROS applications source code, e.g. the test programs from the Tests drawer (folder/directory). Take a look at the code of some smaller AROS programs might be a better and more up to date When you upload your builds, please write the architecture (like i386-aros, x86_64-aros, armPi-64 etc.) in the archive name and it is also advisable to write in the field "Requirements" what ABI (ABIv1 or for PC forks ABIv11 or ABIv0) ===Compiling C/C++ Code=== Native, although we have a IDE Integrated Development Environment (Murks), it does lack a debugger. Whilst others use a combination of a text editor and shell to edit code. Most though use an AROS hosted on Linux to take advantage of the better GCC tools like GDB and various IDEs. Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w (or F12 and w) within the directory with the source code. Type in sh to change the amiga shell into a unix shell. You can then type in ls (unix equivalent to amiga dir). Take a look [http://en.wikibooks.org/wiki/Linux_commands here] for more commands. For a single file program-name.c or program-name.cpp gcc -o program-name program-name.c or g++ -o program-name program-name.cpp or g++ -o test -Wall -g main.cc texturelib.cpp xmodelib.cc -lsdl -lgl To close the shell, click on the top left-hand corner to close (twice). Once to get back the aros shell and then again to close finally. Use [http://freshmeat.net/projects/cksfv/ cksfv] as a test. Some source code requires the addition of Amiga API libraries, like dos, which you can flag at the compile time as gcc -o julia.exe julia.c -ldos For DOS use -ldos as example and if you are compiling mui codes it will be -lmui or intuition -lintuition. Other missing symbols are due to linker libraries being necessary for linking in functions that aren't in the standard C libraries. For example some source code would need added -lz or -lm or -lpng or -larosc etc. use this in unix line command mode to search for 'search-item' in many .c files (*.cpp for c++, etc.) grep -l 'search-item' *.c If the program is not executable, try using parameter fno-common "Delete #?.o"? Or if you are using abcshell then "rm *.o" :''More information: [[Aros/Developer/Porting software]]'' === How to make Apps have AROS 64-bit specific support code === [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] AROS64 already uses 64bit addressing, it just doesn't setup the MMU for more than 4GB physical memory currently. When porting software to AROS64 it is "mostly" a case of converting ULONG's that are used to store pointers, into IPTR's instead, etc. Another quirk, is making sure items on the stack are the correct size by using the STACKED attribute for them. * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. compiling mui stuff for aros setting -std=gnu99 is necessary, had -std=c99 usually A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. crash which suggest memory corruption. From my experience porting from 32-bit to 64-bit these kinds of errors can happen if a pointer is passed somewhere via ULONG variable. Then half of the pointer is cut. To generate this error, please run AROSBootstrap with -m 1024. This will allocate heap to 64-bit address space which will make these errors immediatelly visible. These types of crashes are hard to debug. Disabled as little code as possible to stop corruption from occurring and then try to read from the code where it can be broken Crashing in tslf_freevec is another symptom of memory corruption and these memory corruptions will manifest differently on different setups. ==Coding conventions== As the AROS core source is a shared developer experience, there are rules regarding structure and style. When it comes to your creating your own app and coding, the structure and style should be your own, i.e. you should enjoy what you do and do it so that you can understand what is going on. ===Layout=== <syntaxhighlight lang="c"> static void 1st_function() { program exit(0); } int main(void) { 1st_function(); 2nd_function(); 3rd_function(); return 0; } </syntaxhighlight> <syntaxhighlight lang="c"> struct Screen * openscreen(void); struct Window *openwindow(struct Screen *screen, const char *title, LONG x, LONG y, LONG w, LONG h); VOID 1st_function(); VOID 2nd_function(); int main(int argc, char **argv) { program return 0; } /* main */ VOID 1st_function() { } VOID 2nd_function() { } </syntaxhighlight> ===General style=== This code is used by many people and therefore you should keep some things in mind when you submit source code: * Keep things simple * Keep the source clean * Always know what you are doing, if not flag it and describe what needs to be done... * Explain clearly/simply what you are doing * Remember that you write code once but that it is read many times by many people ===Comments=== AROS uses some of the comments in the source to generate the documentation. Therefore it's necessary to keep a certain format so the tools can find their information. Other comments are ignored but they should explain what you thought when you wrote the code. If you really can't think of an explanation, then don't write the code a second time like this: <pre> /* This adds 1 to t */ t ++; </pre> What we think of is this: <pre> /* Go on with next element */ t ++; </pre> ===Formatting=== This is only '''IMPORTANT''' if you are going to work on the core AROS code or contrib but not applications which may reside outside like on AROS Archives or other websites. <syntaxhighlight lang="c"> { /* a */ struct RastPort * rp; int a; /* b */ rp = NULL; a = 1; /* c */ if (a == 1) printf ("Init worked\n"); /* d */ if ( !(rp = Get_a_pointer_to_the_RastPort ( some , long , arguments ) ) || a <= 0 ) { printf ("Something failed\n"); return FAIL; } /* e */ a = printf ("My RastPort is %p, a=%d\n" , rp , a ); return OK; } </syntaxhighlight> Looks ugly, eh ? :-) Ok, here are the rules: <pre> If several lines contain similar code, put similar things below each other (see a and b); Put spaces between operands and operators Put braces {}, brackets [] and parentheses () below each other (d) if there is much code between. Brackets and parentheses may be in one line if the code between is small (c) Indent by 4 Spaces. Two indent levels may be abbreviated by one tab. </pre> '''Before committing please normalize the indentation - if you have a mixture of tabs and spaced - please always use spaces, 1 tab = 4 spaces.''' The reasons for this are: # While some editors can use an arbitrary sizes for tabs, it's a bit complicated to tell another editor which tab size was used by the one used to write the code. # Most code in AROS was written this way and your code should look like the rest. # You can print this code on any printer without special tools to "fix" the tabs. # Most editors have smart tabs which do exactly this. If your editor doesn't, write a bug report. If you have a function with many arguments (d, e) you should put the parentheses in lines of their own and each argument in one line (d) or put the first argument behind the opening parentheses (e) and each following argument in a line of its own with the comma in front. The closing parentheses is in a line of its own and aligned with the beginning of the expression (i.e. the a and not the opening parentheses or the printf()). Use a single blank line to separate logical blocks. Large comments should have a blank line before and after them, small comments should be put before the code they explain with only one blank line before them. If you see any TABS in AROS core sources then the suggestion is to "detab the file and commit that separately" either before or afterwards from making functionality changes. Make two commits instead of one. This makes it easier for others to see the real changes instead of having to dig through multiple lines of irrelevant diffs. ===Eliminating Global Variables=== i.e. pass variables to functions (local scope) or classes making it easier to track and debug your code. Any time you find that you need a particular thing in 'a lot of different places', chances are that all those places are conceptually related, and so you can create a class, a namespace, a function, or some other higher-level organizational unit to represent that relationship. This makes the program easier to understand. Bad Designs * All variables are global. * There are no standalone functions, only sub-procedures which act on the global variables. * Every sub-procedure is at least 500 lines to several thousand * Every sub-procedure has more than one task to perform * Copy-paste is preferred to writing methods, AND subtle changes are made in the middle of the code Good Designs * structure program into functions (C or basic) - top-down procedural approach * put in class(es) (freepascal or C++) - the object is fixed and you use methods to access the object <pre>  class String_List  {  private:  list<string> m_List;  // member  public:  void read_strings() { /* read strings into m_List */ }  void print_strings() { /* write contents of m_List to stdout */ }  void sort_strings() { /* sort contents of m_List */ }  void sort_strings_reverse() { /* reverse-sort contents of m_List */ }  void unique_strings() { /* remove duplicate strings */ }  };  int main()  {  String_List myList;  // local  myList.read_strings();  myList.sort_strings();  myList.print_strings();  myList.sort_strings_reverse();  myList.print_strings();  myList.unique_strings();  myList.print_strings();  return 0;  } </pre> This way it is very easy to replace the list with new list for debugging purposes, or replacing the methods without replacing the list, when you want different results. You only have to replace the content of the local variables. So create the structure that matches your data (linked lists, trees, arrays, etc.) and what to do with them (sorting, searching, etc.) <pre> .h usually contain #define #include typedef enum struct extern screen and window definitions (data structures) .c should contains functions and algorithms </pre> One way to look at it is that menu headings act as the .c file and sub-menu headings as functions. When you start a project, you place a couple of declarations in the include file. As the project continues, you place more and more declarations in the include file, some of which refer to or contain previous declarations. Before you know it, you have a real mess on your hands. The majority of your source files have knowledge of the data structures and directly reference elements from the structures. Making changes in an environment where many data structures directly refer to other data structures becomes, at best, a headache. Consider what happens when you change a data structure. Use good variables names to help clarify code and only comment when you need to explain why a certain programming approach was made. You're Refactoring Legacy Code, you see a global, you want to get rid of it. How do you do this? Exactly what to do depends on how the global is used. The first step is to find all uses of the global throughout the code, and get a feel for what the significance of the variable is and how it relates to the rest of the program. Pay particular attention to the "lifetime" of the variable (when it gets initialized, when it is first used, when it is last used, how it gets cleaned up). Then, you will probably make the global a data member of a class (for OO languages), or you will write some get/set functions. Converting to the Singleton Pattern is common, but you may discover that it makes more sense for the data element to be a member of an existing singleton, or maybe even an instance variable. # Create a basic read method, either as a class or a global function. Replace all reads with the access method, but leave the variable defined as a global. # Review each of the writes to the method and extract action functions one at a time. Unless two operations are coded identically in the original code, extract each write access separately. # Change the variable scope from global to local. # Analyze similar action functions to determine if any can be merged, i.e., there are no functional differences in the results of the function, just differences in the implementation details. # Review the calls to the read method and see if a more complex functionality should be applied. Follow the approach for writes and unless implementations are identical, create separate access functions. # Analyze the access functions for duplication. As returning variables by "passing by value" are forgotten, so "passing by reference" is often used instead. The reference is a pointer to the variable so the value is remembered when returned. Alternatives * Hidden Globals * Singleton Pattern * Database or TupleSpace * Context Object * Dependency Injection * Stateful Procedures ==AROS/AmigaOS APIs and Docs== <pre> Library: - Private data structure - Many public access methods Device: - Private data structure - Two (BeginIO/AbortIO) access methods Resource: - Public data structure - *NO* access methods </pre> And, being Amiga OS-compatible, there are exceptions to all of these. ===System Libraries=== The [http://developers.aros.org/ AROS Guide To Libraries] can be used as a guide to individual commands and old Dev Docs are used in application programming. Amiga/Aros styles libraries are very different from windows and linux libs. Typical .so/dll libraries are foreign to most Amiga-like OS *[[Aros/Developer/Docs/Libraries/AROSC|arosc.library]] *[[Aros/Developer/Docs/Libraries/AmigaGuide|amigaguide.library]] *[[Aros/Developer/Docs/Libraries/ASL|asl.library]] *[[Aros/Developer/Docs/Libraries/Bullet|bullet.library]] *[[Aros/Developer/Docs/Libraries/BSDsocket|bsdsocket.library]] *[[Aros/Developer/Docs/Libraries/CAMD|camd.library]] *[[Aros/Developer/Docs/Libraries/Codesets|codesets.library]] *[[Aros/Developer/Docs/Libraries/CGFX|cybergraphics.library]] *[[Aros/Developer/Docs/Libraries/CGXVIDEO|cgxvideo.library]] *[[Aros/Developer/Docs/Libraries/Commodities|commodities.library]] *[[Aros/Developer/Docs/Libraries/DataTypes|datatypes.library]] *[[Aros/Developer/Docs/Libraries/DiskFont|diskfont.library]] *[[Aros/Developer/Docs/Libraries/DOS|dos.library]] *[[Aros/Developer/Docs/Libraries/Exec|exec.library]] *[[Aros/Developer/Docs/Libraries/Expansion|expansion.library]] *[[Aros/Developer/Docs/Libraries/FreeType2|freetype.library]] *[[Aros/Developer/Docs/Libraries/GadTools|gadtools.library]] *[[Aros/Developer/Docs/Libraries/Graphics|graphics.library]] *[[Aros/Developer/Docs/Libraries/Icon|icon.library]] *[[Aros/Developer/Docs/Libraries/Identify|identify.library]] *[[Aros/Developer/Docs/Libraries/IFFParse|iffparse.library]] *[[Aros/Developer/Docs/Libraries/Intuition|intuition.library]] *[[Aros/Developer/Docs/Libraries/Keymap|keymap.library]] *[[Aros/Developer/Docs/Libraries/Layers|layers.library]] *[[Aros/Developer/Docs/Libraries/Locale|locale.library]] *[[Aros/Developer/Docs/Libraries/LowLevel|lowlevel.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingBas|mathieeesingbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubBas|mathieeedoubbas.library]] *[[Aros/Developer/Docs/Libraries/MathIEEESingTrans|mathieeesingtrans.library]] *[[Aros/Developer/Docs/Libraries/MathIEEEDoubTrans|mathieeedoubtrans.library]] *[[Aros/Developer/Docs/Libraries/Mathtrans|mathtrans.library]] *[[Aros/Developer/Docs/Libraries/MUIMaster|muimaster.library]] *[[Aros/Developer/Docs/Libraries/Partition|partition.library]] *[[Aros/Developer/Docs/Libraries/PopUpMenu|popupmenu.library]] *[[Aros/Developer/Docs/Libraries/OOP|oop.library]] *[[Aros/Developer/Docs/Libraries/Regina|regina.library]] *[[Aros/Developer/Docs/Libraries/Reqtools|reqtools.library]] *[[Aros/Developer/Docs/Libraries/RexxSysLib|rexxsyslib.library]] *[[Aros/Developer/Docs/Libraries/ScreenNotify|screennotify.library]] *[[Aros/Developer/Docs/Libraries/TTEngine|ttengine.library]] *[[Aros/Developer/Docs/Libraries/Thread|thread.library]] *[[Aros/Developer/Docs/Libraries/Utility|utility.library]] *[[Aros/Developer/Docs/Libraries/Xadmaster|xadmaster.library]] *[[Aros/Developer/Docs/Libraries/Workbench|workbench.library]] *[https://github.com/aros-development-team/AROS/commit/c82e86b8480277998014cc327b56c7664023a52f ClassAct Reaction boopsi class] ===AROS Subsystems=== # [[Aros/Developer/Zune|Zune MUI compatible GUI]] # [[Aros/Developer/AROSAppPackages|AROS Application Packages]] # AHI Audio Drivers - [[Aros/Developer/AHIDrivers|Usage]]/[[Aros/Developer/AHIDriversDev|Development]] # AROSTCP Sana2 Network Interface Drivers - [[Aros/Developer/NICDrivers|Usage]]/[[Aros/Developer/NICDriversDev|Development]] # [[Aros/Developer/AmiSSL|AmiSSL]] # gfx.hidd/cybergraphics Video Drivers - [[Aros/Developer/GfxDrivers|Usage]]/[[Aros/Developer/GfxDriversDev|Development]] # IO Device Drivers - [[Aros/Developer/IODeviceDrivers|Usage]]/[[Aros/Developer/IODeviceDriversDev|Development]] # USB Device Drivers - [[Aros/Developer/USBDrivers|Usage]]/[[Aros/Developer/USBDriversDev|Development]] # PCI Device Drivers - [[Aros/Developer/PCIDrivers|Usage]]/[[Aros/Developer/PCIDriversDev|Development]] # [http://www.libsdl.org/ SDL] [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2013&pid=13333#post_13333 SDL2 coding usage], [https://github.com/search?q=repo%3Aaros-development-team%2Fcontrib%20SDL2&type=code SDL2 commits], [https://github.com/aros-development-team/contrib/commit/c62c3c425c35bac19dadc23be092b0b13a66c76c SDL3 initial commit], [] # [[w:Gallium3D|Gallium 3D]] [http://www.mesa3d.org/ openGL aka Mesa] - [[Aros/Developer/OpenGL|Usage]]/[[Aros/Developer/OpenGLDev|Development]] [http://www.swiftless.com/opengltuts.html Swfitless] # A small subset of GTK2 through [http://sourceforge.net/projects/gtk-mui/ MUI-GTK] # Cairo 2D Engine - [[Aros/Developer/Cairo|Usage]]/[[Aros/Developer/Cairo|Development]] # [[Aros/Developer/Scalos|Scalos desktop API and plugin modules]] # [[Aros/Developer/VHI|VHI video driver]] ====HIDDs==== *[[Aros/Developer/Docs/HIDD/HIDDClass|hiddclass.hidd]] *[[Aros/Developer/Docs/HIDD/Graphics|graphics.hidd]] *[[Aros/Developer/Docs/HIDD/VesaGfx|vesagfx.hidd]] *[[Aros/Developer/Docs/HIDD/ATI|radeon.hidd]] *[[Aros/Developer/Docs/HIDD/NVidia|nvidia.hidd]] *[[Aros/Developer/Docs/HIDD/Nouveau|nouveau.hidd]] *[[Aros/Developer/Docs/HIDD/Kbd|kbd.hidd]] *[[Aros/Developer/Docs/HIDD/Mouse|mouse.hidd]] *[[Aros/Developer/Docs/HIDD/i2c|i2c.hidd]] *[[Aros/Developer/Docs/HIDD/IRQ|irq.hidd (deprecated)]] *[[Aros/Developer/Docs/HIDD/PCI|pci.hidd]] *[[Aros/Developer/Docs/HIDD/PCIPC|pcipc.hidd]] *[[Aros/Developer/Docs/HIDD/Serial|serial.hidd]] *[[Aros/Developer/Docs/HIDD/Thunderbolt|thunderbolt.hidd]] https://github.com/aros-development-team/AROS/commit/4f02ea691799aff3a01f60cfa5f9182c82fc57a8 HIDD are used for device/peripheral low level hardware support drivers. The HIDD system is split up into a collection of classes with a strict inheritance hierarchy. A HIDD class implements a device driver for a single device or in rare cases a group of devices and provides an interface for other programs and devices to access. In order to maintain portability of interfaces across a wide range of hardware this interface will in general not present the raw interface to the underlying hardware. Instead it will present a generic interface that describes many different hardware implementations. This allows for the best reuse of both interfaces and code. HIDD API is heavyweight though. You need to open a HIDD library, open oop.library, instantiate an object (even if there's no object); and object calls are more costly compared to plain library calls. Basically your task is to implement a subclass of hidd.ata.bus for your hardware. just implementing the XXXATA__Hidd_ATABus__xxxxxx methods for the Amiga chipset - and appropriate versions of the interface_xxx.c file(s). pretty much everything in probe.c could be ignored - just write a replacement scan for relevant amiga devices and store whatever info you need in the bus data? only the "SUPPORT_LEGACY" blocks might be related. You do not need to depend on PCI API. PCI is just a way to discover the hardware on PCs, etc. <hidd/pci.h> includes (at some depth) <interface/HW.h>, which defines IID_HW. This comes from the 'generic' HIDD class in: rom/hidds/hidd/hiddclass.conf did not split up HIDD and HW because they are always used in pair. It's the same as hidd/pci.h bringing definition for: PCI, PCIDriver and PCIDevice. PCI is actually PCIHW, just the name was not changed for backwards compatibility reasons. HW is a 'hub' where HIDD instances plug in. ATA HIDD aoHidd_ATABus_Use32Bit value is completely ignored unless ata.device first detects correct command line parameter. Yes. Unfortunately I was unable to find any comment in code or svn history with explanations. Looked at Linux source, there 32-bit PIO is also controller driver's property. Some of them enable it, some don't. Actually, switching the default to ON should be safe. ata.device is fail-safe at this because during IDENTIFY command it validates upper 16 bits, and if they appear to be zeroes in all 128 longwords, then 32-bit mode is switched off. But, nevertheless, I know how tricky hardware can be, so I decided not to change original behavior. If you think it's wrong in some cases, then it's possible to add one more attribute like aHidd_ATABus_Default32Bit. If set to YES, then this means that 32-bit PIO is safe to use by default. ====Devices==== *[[Aros/Developer/Docs/Devices/ATA|ata.device]] *[[Aros/Developer/Docs/Devices/Console|console.device]] *[[Aros/Developer/Docs/Devices/Narrator|narrator.device]] *[[Aros/Developer/Docs/Devices/Printer|printer.device]] *[[Aros/Developer/Docs/Devices/Trackdisk|trackdisk.device]] *[[Aros/Developer/Docs/Devices/AmberRAM|amberram.device]] *[[Aros/Developer/Docs/Devices/Timer|timer.device]] *[[Aros/Developer/Docs/Devices/|.device]] The Amiga used [[Aros/Developer/Docs/Devices|Devices]] to communicate with [http://aros-exec.org/modules/newbb/viewtopic.php?start=0&topic_id=3475&viewmode=flat&order=ASC additional hardware]. AROS has replaced these hardware devices with hidd equivalents but some are still retained for backwards compatibility. Local libraries/devices/handlers,etc. are supposed to override the ones in ROM if their version is higher than the one in ROM. Here is the list of commands exec default: {| class="wikitable" | CMD_CLEAR | Purge the buffer of the device |---- | CMD_READ | Playback Control |---- | CMD_STOP | Stopped the activity of the device |---- | CMD_FLUSH | Empty the queue of commands |---- | CMD_RESET | Reset a device |---- | CMD_WRITE | Playback Control |---- | CMD_INVALID | Create an error |---- | CMD_UPDATE | Gets updated device |---- | CMD_START | Will restart the device |---- |} While most other "stuff you communicate with" in AmigaOS are devices <ref>AMIGA ROM Kernel Reference Manual: Devices, 3rd Edition. Commodore-Amiga, Inc. Addison-Wesley, 1991. {{ISBN|0-201-56775-X}}</ref> that share a [http://gega.homelinux.net/AmigaDevDocs/ common base interface]. [[Aros/Developer/Docs/Devices1.3|OS 1.3 Device Drivers]]. ====Handlers==== :[[Aros/Developer/Docs/Handlers/Pipe|pipe.handler]] :[[Aros/Developer/Docs/Handlers/Port|port.handler]] :[[Aros/Developer/Docs/Handlers/SFS|sfs.handler]] :[[Aros/Developer/Docs/Handlers/FAT|fat.handler]] :[[Aros/Developer/Docs/Handlers/PFS|pfs.handler]] :[[Aros/Developer/Docs/Handlers/NTFS|fuse.handler]] :[[Aros/Developer/Docs/Handlers/FFS|ffs.handler]] filesystem handlers have their own separate system consisting of completely differently structured messages that dos.library use to pass requests (for things like reading, writing, getting directory contents etc.) to them. AROS originally went with implementing filesystem handlers as devices, which might arguably be more consistent with the rest of the AmigaOS API but which is quite incompatible with AmigaOS itself. However, it made it far harder to port filesystems and the gains were comparatively small, and so there's been a long standing goal of fixing this incompatibility. It has now, June 2011, been reintroduced to all AROS flavors. are argstr and argsize valid for the handler startup environment? DOS/RunHandler() calls DOS/CreateNewProcTags(), and then CallEntry() (in rom/dos/exit.c) to start the handler, so yes, argstr and argsize are *present* in the call signature of the handler. Granted, argstr will be NULL and argsize 0, but those values *are* passed to the handler function using: <pre> AROS_UFC3(ULONG, entry, AROS_UFCA(STRPTR, argptr, A0), AROS_UFCA(ULONG, argsize, D0), AROS_UFCA(struct ExecBase *, SysBase, A6)); </pre> Creating your own [without the whole build tree http://pagesperso-orange.fr/franck.charlet/temp/radeon.zip] and then <pre> make stub make make install </pre> SFS has two Root blocks, one at the start and one at the end of the disk. The Root blocks both contain the same information. They hold various information about the disk structure and have the locations of some important blocks used by the filesystem. The Root ObjectContainer contains the Root directory Object. The name of this Object is the name of the volume. It is identical to a normal directory Object. The Bitmap is used to keep track of free space. Each bit in a bitmap represents a single block. A set bit indicates a free block and a cleared bit a used block. AdminSpaceContainers are used to keep track of space which has been reserved for storing administration blocks. Only the Bitmap, the Root blocks and the actual data stored in files aren't stored in administration space. Administration space is allocated in chunks of 32 blocks at a time. A single AdminSpaceContainer can hold information about a large number of such areas each of which has its own little bitmap of 32 bits. Extents are stored in a B-Tree. The Root block holds a pointer to the root of the Extent B-Tree. Extents keep track of space in use by a specific file. Each fragment a file consists of has its own Extent. Extents are in a double linked list. The list can be used to locate the next or previous fragment of a file. Below is the standard block header. This header is found before EVERY type of block used in the filesystem, except data blocks. The id field is used to check if the block is of the correct type when it is being referred to using a BLCK pointer. The checksum field is the SUM of all LONGs in a block plus one, and then negated. When applying a checksum the checksum field itself should be set to zero. The checking a checksum the checksum is okay if the result of the checksum equals zero. The ownblock BLCK pointer points to the block itself. This field is an extra safety check to ensure we are using a valid block. Field Type Description id ULONG The id field is used to identify the type of block we are dealing with. It is used to make sure that when referencing a block we got a block of the correct type. The id consist of 4 bytes and each blocktype has its own unique foure letter code. checksum ULONG This field contains the sum of all longs in this block, plus one and then negated. The checksum can be used to check if the block hasn't been corrupted in any way. ownblock BLCK Points to itself, or in other words, this field contains the block number of this block. This is yet another way to check whether or not a block is valid. <pre> struct fsBlockHeader { ULONG id; ULONG checksum; BLCK ownblock; }; </pre> The algorithm to calculate the checksum of a block: <pre> ULONG calcchecksum(struct fsBlockHeader *block, LONG blocksize} { ULONG *data=(ULONG *)block; ULONG checksum=1; block->checksum=0; while(blocksize>0) { checksum+=*data++; blocksize-=4; } return(-checksum); } </pre> A Root block contains very important information about the structure of a SFS disk. It has information on the location and size of the disk, the blocksize used, locations of various important blocks, version information and some filesystem specific settings. A SFS disk has two Root blocks; one located at the start of the partition and one at the end. On startup the filesystem will check both Roots to see if it is a valid SFS disk. If either one is missing SFS can still continue (although at the moment it won't). A Root block could be missing on purpose. For example, if you extend the partition at the end (adding a few MB's) then SFS can detect this with the information stored in the Root block located at the beginning (since only the end-offset has changed). Same goes for the other way around, as long as you don't change start and end point at the same time. When a Root block is missing because the partition has been made a bit larger, then SFS will in the future be able to resize itself without re-formatting the disk. Field Type Description bheader struct fsBlockHeader Standard block header. version UWORD The version of the filesystem block structure. You can check this field to identify what version of the filesystem your dealing with it and to see if you can handle this structure correctly. Don't try to interpret the disk's structure when this field contains an unknown version number! sequencenumber UWORD Used to identify which Root block was written last in case the sequencenumber on both Root blocks don't match. datecreated ULONG Creation date of this volume. This is the date when the disk was last formatted and will never be changed. bits UBYTE Various settings, see below. <pre> pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. reserved1 ULONG[2] Reserved, leave zero. firstbyteh ULONG High 32-bits of a 64-bit number. This is the first byte of our partition relative to the start of the disk. firstbyte ULONG Low 32-bits of a 64-bit number. lastbyteh ULONG High 32-bits of a 64-bit number. This is the last byte (exclusive) of our partition relative to the start of the disk. lastbyte ULONG Low 32-bits of a 64-bit number. totalblocks ULONG The total number of blocks this partition consists of. blocksize ULONG The size of a block of this partition. reserved2 ULONG[2] Reserved, leave zero. reserved3 ULONG[8] Reserved, leave zero. bitmapbase BLCK Block number of the start of the Bitmap. adminspacecontainer BLCK Block number of the first AdminSpaceContainer. rootobjectcontainer BLCK Block number of the ObjectContainer which contains the root of the disk (this is where the volume name is stored). extentbnoderoot BLCK Block number of the root of the Extent B-Tree. reserved4 ULONG[4] Reserved, leave zero. </pre> <pre> struct fsRootBlock { struct fsBlockHeader bheader; UWORD version; UWORD sequencenumber; ULONG datecreated; UBYTE bits; UBYTE pad1; UWORD pad2; ULONG reserved1[2]; ULONG firstbyteh; ULONG firstbyte; ULONG lastbyteh; ULONG lastbyte; BLCK totalblocks; ULONG blocksize; ULONG reserved2[2]; ULONG reserved3[8]; BLCK bitmapbase; BLCK adminspacecontainer; BLCK rootobjectcontainer; BLCK extentbnoderoot; ULONG reserved4[4]; }; </pre> AdminSpaceContainers are used to store the location and bitmap of each administration space. The AdminSpaceContainers are located in a double linked list and they contain an array of fsAdminSpace structures. There is one fsAdminSpace structure for every administration space on disk. Field Type Description bheader struct fsBlockHeader Standard block header. next BLCK The next AdminSpaceContainer, or zero if it is the last in the chain. previous BLCK The previous AdminSpaceContainer, or zero if it is the first AdminSpaceContainer. bits UBYTE The number of bits in each in the bits ULONG in the fsAdminSpace structure. pad1 UBYTE Reserved, leave zero. pad2 UWORD Reserved, leave zero. adminspace struct fsAdminSpace An array of fsAdminSpace structures. The size of the array is determined by the current blocksize. <pre> struct fsAdminSpaceContainer { struct fsBlockHeader bheader; BLCK next; BLCK previous; UBYTE bits; UBYTE pad1; UWORD pad2; struct fsAdminSpace adminspace[0]; }; </pre> Field Type Description space BLCK The first block of an administration space. bits ULONG A small bitmap which is used to determine which blocks in an administration space are already in use. The number of bits in this bitmap is determined by the bits field in the AdminSpaceContainer. <pre> struct fsAdminSpace { BLCK space; ULONG bits; }; </pre> The fsBitmap structure is used for Bitmap blocks. A bitmap block is used to keep track of which space is in use and which isn't for a particular area of a disk. All bitmap blocks together keep track of the free space for an entire disk. The location of the first bitmap block is known and all other bitmap blocks are stored in order after the first one. Field Type Description bheader struct fsBlockHeader Standard block header. bitmap ULONG An array of ULONG's. These hold the actual information on which blocks are in use and which aren't. <pre> struct fsBitmap { struct fsBlockHeader bheader; ULONG bitmap[0]; }; </pre> Each bit in a bitmap block (except for the block header) represents a single block. If the bit is set than the block is free, and if the bit is clear then it is full. The first ULONG in the bitmap area of the first bitmap block represents blocks 0 through 31 on the disk. Bit 31 of this ULONG is block 0, 30 is block 1, and so on. Bit 0 of the first ULONG represents block 31. Below is a table to clarify how bitmaps work even further. The first column is the bitmap block number, the second column is the number of the ULONG in the bitmap array. The third column is the bit number in this ULONG, and the last column is the block which this specific bit, in this specific bitmap block represents. We'll assume here that a bitmap block has room for 120 ULONG's (meaning there is room for storing 32 * 120 bits). <pre> Bitmap block ULONG number Bit number Block represented 1 (first) 0 31 0 1 0 30 1 ... ... ... ... 1 0 1 30 1 0 0 31 1 1 31 32 ... ... ... ... 1 2 31 64 1 2 30 65 ... ... ... ... 1 119 0 3839 2 0 31 3840 2 0 30 3841 ... ... ... ... </pre> The last bitmap block doesn't need to be completely used. The unused bits (which belong to blocks which do not exist) all have to be clear, to indicate that these blocks are in use. The fsObjectContainer structure is used to hold a variable number of fsObjects structures (Objects) which have the same parent directory. Each ObjectContainer must contain at least one Object. If there is space in the ObjectContainer not used by the variable number of Objects then that space is zero filled. Objects always start at 2-byte boundaries, which means sometimes a padding byte is inserted between two Objects. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the parent Object, or 0 if this object has no parent (which is only the case for the Root directory). next BLCK The next ObjectContainer belonging to this directory, or zero if it is the last in the chain. previous BLCK The previous ObjectContainer belonging to this directory, or zero if it is the first ObjectContainer in this directory. object struct fsObject A variable number of fsObject structures. The number of structures depends on the individual sizes of each fsObject structure and the blocksize. These structures are located directly after each other with at most 1 byte of padding between them to get the structures aligned on a 2 byte boundary. <pre> struct fsObjectContainer { struct fsBlockHeader bheader; NODE parent; BLCK next; BLCK previous; struct fsObject object[0]; }; </pre> fsHashTable is the structure of a HashTable block. It functions much like the hash table found in FFS user directory blocks, except that it is stored in a separate block. This block contains a number of hash-chains (about 120 for a 512 byte block). Each hash-chain is a chain of Nodes. Each Node has a pointer to an Object and a pointer to the next entry in the hash-chain. Using such a hash-chain you can locate an object quickly by only knowing its name. Field Type Description bheader struct fsBlockHeader Standard block header. parent NODE The node number of the directory Object this HashTable block belongs to. hashentry NODE An array of Nodes. Each Node represents the start of a hash-chain (singly linked). A hash-value is calculated using the name of a file or directory, and this value determines in which chain the Object is linked. If there are no entries in a hash-chain then the hashentry value is zero. <pre> struct fsHashTable { struct fsBlockHeader bheader; NODE parent; NODE hashentry[0]; }; </pre> To calculate the hash-value using a name of an Object as input use these routines: <pre> UWORD calchash(UBYTE *name) { UWORD hash=0; /* Calculates a hash value over the passed in string. The end of the string can be either a NUL byte or a slash. The hash function is the same as the one used in FastFileSystem set to international mode. */ while(name[hash]!=0 && name[hash]!='/') { hash++; } while(*name!=0 && *name!='/') { hash=hash*13+upperchar(*name++); } return((UWORD)(hash % (UWORD)((blocksize-sizeof(struct fsHashTable))>>2))); } UBYTE upperchar(UBYTE c) { if((c>=224 && c<=254 && c!=247) || (c>='a' && c<='z')) { c-=32; } return(c); } </pre> The BNodeContainer is used to store B-Trees. Currently only one B-Tree is in use by this filesystem and it is used to store the location of file data. The fsBNodeContainer structure contains two other structures. The fsBlockHeader structure and the BTreeContainer structure. Field Type Description bheader struct fsBlockHeader Standard block header. btc struct BTreeContainer Contains information about the B-Tree and its nodes contained in this block. <pre> struct fsBNodeContainer { struct fsBlockHeader bheader; struct BTreeContainer btc; }; </pre> First try and locate the Root block. It should start with "ROOT". SFS has two of these, one at the start of the partition and one at the end. One of the fields contains the block size, which will be the size of all important SFS blocks. The root block has the root object container, which contains information about files and directories in the root directory. The object containers basically hold one or more smaller structures that represent files and directories. Scanning them all should give you a list of files and directories. The root block also has the root of the Extent B-Tree. This is a standard B-Tree structure (not a binary tree) that is used commonly in all kinds of system, you can read about how they work on Wikipedia if needed. The B-Tree holds the information about *where* all the data is located for your files. To recover your files, I'd do this: * Find one of the root blocks, if not present, then figure out the block size your disk was using, and scan every block in turn to see if it looks like an ObjectContainer (check the fsBlockHeader's ID, check if the ownblock number is equal to the block you are currently scanning, and check its checksum). So if you currently have block 12, and you see a block with the correct id, and ownblock = 12 and its checksum is good, then that's probably a valid ObjectContainer. * With all the ObjectContainers found, you can extract filenames and directory names from these, but also the number of their first data block (in the field data) and the file size. For small files (less than blocksize) this data block will be enough to recover the data. For larger files, you might be lucky and all the remaining blocks are found after the first one (if the file was defragmented). You can't be sure of that though so... * For larger files, you need to find all the BNodeContainers. You could scan these in the same way you found all the ObjectContainers (look for blocks with the correct id, ownblock number and checksum). * With all the BNodeContainers found, you can try looking up the first data block of a file in the B-Tree structure. This is a bit complicated -- the B-Tree consists of non-leaf nodes (blocks that only contain pointers to other B-Tree blocks), the isLeaf flag indicates this. Or it can be a B-Tree leaf block. The leaf blocks contain extra information per entry (see https://hjohn.home.xs4all.nl/SFS/extents.htm) <pre> struct fsExtentBNode { ULONG key; ULONG next; ULONG prev; UWORD blocks; }; </pre> The key should be a block of a file (the first of a range), that is 1 to 65535 block long (depending the "blocks" field). If the file is split up into more parts, then "next" will contain block number of the next range of blocks. You need to look this up again in the B-Tree structure to find out how large it is. You can for the most part ignore the other structures (bitmap, admin containers). The fsObjects and B-tree containers is what you'll need to recover the data. ====Resources==== <pre> rom/storage/mmakefile.src rom/storage/storage.conf rom/storage/storage_device.c rom/storage/storage_ids.c rom/storage/storage_init.c rom/storage/storage_intern.h rom/storage/storage_mount.c rom/storage/storage_unit.c </pre> <pre> rom/storage/includes/device.h rom/storage/includes/unit.h rom/storage/includes/volume.h rom/storage/storage_intern.h </pre> <pre> </pre> *[[Aros/Developer/Docs/Resources/ACPI|acpi.resource]] *[[Aros/Developer/Docs/Resources/Battclock|battclock.resource]] *[[Aros/Developer/Docs/Resources/Bootloader|bootloader.resource]] *[[Aros/Developer/Docs/Resources/Cia|cia.resource]] *[[Aros/Developer/Docs/Resources/Filesystem|FileSystem.resource]] *[[Aros/Developer/Docs/Resources/Hostlib|hostlib.resource]] *[[Aros/Developer/Docs/Resources/Kernel|kernel.resource]] *[[Aros/Developer/Docs/Resources/Misc|misc.resource]] *[[Aros/Developer/Docs/Resources/Processor|processor.resource]] ==Debugging Code== Please use the [http://sourceforge.net/tracker/?group_id=43586&atid=439463 AROS Bug Tracker] if any issues are found. GRUB Command line list <pre> sysdebug usbdebug - allows to see Poseidon's log in debug output </pre> How do I get debugging out of InitResident ? If running i386 hosted on linux sysdebug=initresident on command line. This way you can enable any of listed flags. sysdebug=all stands for "everything" Have an executable (crosscompiled C++ code) which has 6 MB size on disk, but after loading it in memory, 250 MB RAM is taken. Any software that would split AROS executable into ELF part which would show actual size values? readelf -S executable it will show you all sections in elf file, including sizes and requested alignment. objdump -h filename That's will give you a quick overview of the sections and sizes. Ignore all the .debug.* sections. Would hazard a guess that you have a large .bss section. That's pretty common in C++. Next step: nm—size-sort filename | grep ' [bB] ' The last few will be your biggest consumers. Would suggest -C to demangle the symbols... ;) Suggest profiling the program (just use some printf's in the main loop for time spent in each part), it usually is quite easy to spot slow parts in games or apps. If someone has '#define IPTR ULONG' somewhere. To see where that define is, redefine IPTR in the source code that fails, just above the line that fails, and the preprocessor will tell you where it was defined first. ===How to setup gdb with AROS/hosted=== Download AROS sources (AROS-xxxxxxxx-source.tar.bz2, where xxxxxxxx is the current date) and AROS contrib sources (AROS-xxxxxxxx-contrib-source) from Untar-bzip2 and cd to the unpacked archive directory. > tar -xvjf AROS-xxxxxxxx-source.tar.bz2 > cd AROS-xxxxxxxx-source Check the link to "contrib" (contrib-source) inside directory, e.g. correct like this: > rm contrib > ln -s ../AROS-xxxxxxxx-contrib-source.tar.bz2 contrib Make sure you have the correct locale setting, otherwise compilation will fail at some point. See [http://aros.sourceforge.net/documentation/developers/compiling.php#setting-the-locale-to-iso8859 here] (or link below) for more on that. You might have to enter this: > export LANG="en_US.ISO-8859-1" Now configure for a debug build - see "./configure --help" for more - here are two examples: > ./configure—enable-debug=stack,modules,symbols > ./configure—enable-debug=all You may "make" now, or choose a separate directory for your build (e.g. for easy removal), for example if compiling for i386 architecture you could create a directory like this: > mkdir linux-i386 > cd linux-i386 > ../AROS/configure—enable-debug=stack,symbols,modules When done configuring you're ready to go: > make Building AROS takes some time - minutes on fast machines (e.g. 2.5&nbsp;GHz quadcore), up to hours on slower machines. The result will be AROS Linux hosted with gdb debugging enabled. See aros.org documentation for more on compiling AROS, including more [http://aros.sourceforge.net/documentation/developers/compiling.php --enable-debug] options. When finished, enter bin/linux-i386/AROS directory (replace "linux-i386" with your compilation target platform, e.g. linux-x86_64, etc.) inside the unpacked archive directory. This directory contains the required .gdbinit file for properly running AROS inside gdb. > cd bin/linux-i386/AROS Run AROS (here: with 128MB of memory) from gdb: > gdb—args boot/aros-unix -m 128 or > gdb—args boot/arosboot -m 128 (gdb) r Watch the shell output - in case AROS complains about "LoadKeyCode2RawKeyTable: Loading "DEVS:Keymaps/X11/keycode2rawkey.table" failed!" you should also see some instructions on how to create a keymap table. (see link above "more on compiling", too.) Quit gdb, and try default keymap table: (gdb) q The program is running. Quit anyway (and kill it)? (y or n) y > cd ../../.. > make default-x11keymaptable Re-run AROS, as described above. Try e.g. RAros (= right windows key) + W to open a shell. If this doesn't work you have to create a keymap table yourself, quit gdb again, and make a new keytable: > make change-x11keymaptable A window will open. Watch the window's title bar, and follow the instructions. When done, re-run AROS. RAros + W should now open a shell. Next, compile your program with gdb support. When you start GDB is there a warning which says warning: File "<whatever>/.gdbinit" auto-loading has been declined by your `auto-load safe-path' set to ... If so start gdb with "-ix .gdbinit" <pre> Summary - In short: * build AROS with debugging support (i.e. ./configure --enable-debug=all) * build your application with debugging support (i.e. option -g) * run AROS in the GNU debugger (you may use the GUI frontend "ddd" which simplifies usage a bit) * start your application * use the commands "findaddr" and "add-symbol-file" as written in the debugging manual * if the debugger doesn't find the source code of your application use the "dir" command of the debugger. </pre> ===How to use gdb=== In AROS open a shell, then (in host shell) use CTRL-Z to go into gdb. Use "b Exec_CreatePool" (one of the functions used early on by startup code in programs) to add a breakpoint, then "cont" and gdb will interrupt somewhere early during startup of "program". Use "bt" to show backtrace and "loadseg" for "??" entries. One of them will be for "program". After that you can use "disassemble program". One thing you need to make sure is that .gdbinit you have in your build directory is the same as in source tree. It has been modified some time ago, but the build system does not refresh it - you need to copy it manually To recap, please read our debugging [http://aros.sourceforge.net/documentation/developers/debugging.php manual]: To detect segfaulting when loading, try... ./configure—enable-debug—with-optimization="-O2" Because crash or no crash may depend on optimization. For newer compilers maybe this helps... --with-optimization=-"-O2 -fno-strict-aliasing" One way to make crashes less random (more easily reproducible) is to activate the munging of free memory in rom/exec/freemem.c which is normally commented out: <pre> Index: freemem.c =================================================================== --- freemem.c (revision 34289) +++ freemem.c (working copy) @@ -154,11 +154,12 @@ * created with their TCB placed in the tc_MemEntry list. The workaround * is to avoid munging when FreeMem() is called with task switching disabled. */ + /* DOH! it doesn't work even this way. What's wrong??? - * - * if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) - * MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); */ + + if ((SysBase->TDNestCnt < 0) && (SysBase->IDNestCnt < 0)) + MUNGE_BLOCK(memoryBlock, MEMFILL_FREE, byteSize); } </pre> Mungwall can be turned on at runtime. Currently this works in all hosted versions. Just specify "mungwall" on kernel command line and it works. It can work on native too. In order to enable it you need to parse kernel command line, and if "mungwall" is present, set EXECF_MungWall bit in IntExecBase.IntFlags. This needs to be done before the first AllocMem() for obvious reasons. And never reset back this flag! If you change it on a working system, you are doomed. Hosted ports do the processing in rom/exec/prepareexecbase.c --enable-debug=mungwall option in configure still works but is going obsolete. A kludge in rom/exec/allocmem.c is responsible for this and it needs to be removed when the transition is done. BTW, on i386-pc port it can be activated by "mungwall" argument on command line, you don't need to rebuild AROS. New mungwall affects not only AllocMem()/FreeMem(), but also pools. I also tested it with AllocAbs(), seems to work correctly. Runtime mungwall works on: * pc-i386 * pc-x86_64 * linux-i386 * linux-x86_64 * darwin-x86 * linux-ppc Works on all hosted ports, if the port itself is working. * amiga-m68k * Not on sam440-ppc and efika-chrp-ppc, even if they would be able to be built at moment. Does not work on (for now, need NVRAM support) When starting my freshly rebuilt i386-linux-aros which was compiled with full debugging support I get sometimes the error "Program exited with code 0377". Add the following to your .gdbinit: set follow-fork-mode child Here are some of the custom AROS gdb functions (defined in ".gdbinit" file) to resolve "in ?? ()" entries in backtrace: <pre> #0 0xb7ffd424 in __kernel_vsyscall () #1 0xb7e2a657 in sigsuspend () from /lib/libc.so.6 #2 0xb7c63900 in ?? () #3 0xb7c640e3 in ?? () #4 0xb7c641e0 in ?? () </pre> You can use loadseg 0xb7c63900 loadframe 2 or loadbt and some others. Use "help " for a little help text. If the commands do not work try "loadkick" first. Use "thistask", "taskready", "taskwait" to get list of AROS tasks. "bttask " shows backtrace of a task which is in ready or in wait queue and "loadseg" to resolve "??" entries in it's backtrace ("loadframe" would not work as it assume current running task). ===Native debugging tools for AROS=== to enable debugging at boot time entering the GRUB menu editing line (E key) and adding "debug=memory" to your boot line, then press Ctrl+X to complete booting. SYS:Tools/Debug/'''Bifteck''' Open a shell and enter the line below to run Biftek and grab the debug messages collected in RAM into a text file. tools/debug/bifteck > ram:debug.txt and certainly does not open a window. It is a shell tool and only dumps data located from the debug location. It is therefore important to 'catch' that debug data as soon as possible (before it gets overridden). You should invoke bifteck at the first opportunity before doing anything else. You can use the TO option to store bifteck output to a file or you can pipe it manually to a file. SYS:Tools/Debug/'''Sashimi''' - displays error messages One suggestion is to do a bug() debugging. Each time bug() is executed it will be output on sashimi. You include <aros/debug.h> and place bug("something\n"); in your source code at location though which control passes. To get the output - open an aros shell SYS:Tools/Debug/sashimi > RAM:out.txt '''Ctrl C''' to end the output to the RAM Disk. # open shell, and type # ram: (to switch to ram drive) # System:Tools/Debug/Sashimi > mylogfile.txt # open AHI prefs using wanderer (or use another opened shell) # play test sound # close AHI prefs # shell still open with Sashimi running: press ctrl-c to break Sashimi and return to prompt. # in shell: copy mylogfile.txt System: (or to your required location) SYS:Utilities/'''Snoopy''' - monitors OS function calls, run "Sashimi" to see Snoopy's output SYS:Tools/'''WiMP''' - the Window (and Screens) Manipulation Program You can use the -E option of gcc to find out how preprocessor macros are expanded. ===Errors=== crash in strcasecmp usually means that one of its arguments is NULL. empty space between these two names, prossibly some invisible character Old Amiga [http://www.amigacoding.com/index.php?title=Guru_codes&redirect=no Guru Codes] If the crash is in intuition. Sometimes, if it relates to text, a null pointer sets it off. an uninitialised pointer can have any address (this is a common fault). Compiling on 64bit, Many old code would not properly typecast when doing pointer-integer conversions and thus at least throw a warning. This can easily be located and fixed. [http://www.aros.org/cs/documentation/developers/app-dev/portable.php Portable code] * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. * Fix (change IPTR/SIPTR back to ULONG/LONG) the few places which really rely on ULONG/LONG being exactly 32 bit. That's for things like pixel (ARGB) buffers, structs written/read to disk, colormaps, but probably not much else. Then again, many current compilers also throw a warning when you try to assign a pointer value to an integer and the integer is possibly too small. This happens under .NET for example when a 64 bit pointer is assigned to something like an ULONG - so exactly the case which you described. === AI === Multimodal Context Prompt <--- Model <---> Agent ---> End user engine Gemini LMStudio Qwen Comfyui etc Recent, self hosting locally on laptops, mini pcs or desktops with '''quantization''' 4bit has reduced memory requirements but still require 16Gb+ and no high end gpu for text based *[https://lmstudio.ai/download LMstudio single gpu], Google Gemma 4 Model *[ 12B QAT] Alibaba Cloud's [https://huggingface.co/ Qwen] team series of large language models LLMs *[https://huggingface.co/models?other=qwen3 Qwen 3], [], *[https://huggingface.co/models?other=qwen2 Qwen 2], [https://huggingface.co/Qwen/Qwen2.5-Coder-32B qwen 2.5 Coder], Small models *[ glm-ocr] *[ medGemma] *[ qwen 3.5-4b] *[https://github.com/sipeed/picoclaw picoclaw claude] Bigger LLMs but with settings *[https://ollama.com/download Ollama single gpu] *[https://github.com/ggml-org/llama.cpp/releases llama.CPP multi gpus], *[ VLM multiple gpus], Multimedia *[ Kimi K3], For the full experience #Training learning using 1+ high end GPUs at least 16GB VRAM per GPU card or 64Gb+ of unified, 16Core CPU with at least 64Gb of RAM system memory, though training can take weeks #Inference with custom asics or GPUs *[ MiniMax H3] for audio and video but gpu 8Gb+ *[https://github.com/jamiepine/voicebox voicebox] *[https://github.com/ideogram-oss/ideogram4 ideogram4] *[https://github.com/calesthio/OpenMontage OpenMontage] <pre> Text to Audio --\ Text to Video --/ Reference Video --> Video and Audio output </pre> === Example === <syntaxhighlight lang="c"> /* 1. Header for your name,date,purpose of program. 2. Pre-processor directives. This will include the #includes for files you want to add. 3. Includes for function prototypes if necessary. 4. Main() Create Pointers for Libraries and any Window you want to open. 5. Open necessary libraries. 6. Check if open exit program if fail. 7. Open a window exit program if fail. 8. Add your program 9. Close Window 10 Close Libraries. 11 End Program. */ /* standard os included headers <.h> */ #include <dos/dos.h> #include <dos/dosasl.h> #include <dos/dosextens.h> #include <dos/exall.h> #include <dos/rdargs.h> #include <exec/memory.h> #include <exec/types.h> #include <utility/utility.h> #include <intuition/intuition.h> /* define as unresolved external references (proto/xxx.h) and compiler will link to auto(matically) open library */ #include <proto/arossupport.h> #include <proto/dos.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/graphics.h> #include <proto/cybergraphics.h> #include <proto/datatypes.h> #include <proto/icon.h> #include <workbench/workbench.h> #include <workbench/icon.h> #include <datatypes/pictureclass.h> #include <proto/muimaster.h> #include <libraries/mui.h> #include proto/bsdsocket.h #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> /* my own headers ".h" */ #define CTRL_C (SetSignal(0L,0L) & SIGBREAKF_CTRL_C) #define isDir(fib) ((fib)->fib_DirEntryType >= 0) #define ARG_TEMPLATE "FILE/A,ALL/S,QUIET/S,W=WIDTH/N,H=HEIGHT/N,M=METHOD,DEFTOOL" int main(void) { return retval; } /* main */ </syntaxhighlight> If you used c++, there is not yet c++ support in our shared library system. The easiest way to create / compile a shared library would be to use the AROS build system but the libraries can be created manually. You have to create a ROMTAG structure and some header files. A shared library is built with the %build_module macro with a line like this: %build_module mmake=MetaTarget modname=mylib modtype=library files=SourceFiles This macro can build different AROS module types, like devices, Zune classes, HIDDs, etc. <pre> ##begin config version 1.0 ##end config ##begin functionlist void func1(LONG a, LONG b) int func2(char *s, ULONG a) ##end functionlist </pre> Alternatively, <pre> #ifndef LIB_H #define LIB_H #define __NOLIBBASE__ #include <exec/libraries.h> #include <exec/semaphores.h> #include <dos/dos.h> #ifdef __AROS__ //#include <aros/debug.h> #define reg(x) #define __saveds #endif #define USESYSBASE struct ExecBase *SysBase = Base->My_SysBase; struct MyTestBase { struct Library My_Test_Lib; struct ExecBase *My_SysBase; APTR My_SegList; int testint; }; #endif </pre> <pre> /*--------------------------------------------------------------------------*/ /* Resident header written for mytest.library */ /*--------------------------------------------------------------------------*/ #define __NOLIBBASE__ #define VERSION 1 #define REVISION 0 #define LIBHEADNAME mytest #define LIBHEADNAMESTR "mytest" #define COMPDATE "04.10.2015" #define VERS "1.0" #define LIBBASETYPE struct MyTestBase #define LIBBASETYPEPTR LIBBASETYPE * #include <aros/debug.h> #include <exec/exec.h> #include <proto/exec.h> #include <exec/resident.h> #include <exec/nodes.h> #include <exec/libraries.h> #include <aros/symbolsets.h> #include "lib.h" const UBYTE lib_name[] = LIBHEADNAMESTR ".library"; const UBYTE lib_id[] = "$VER: " LIBHEADNAMESTR ".library " VERS " (" COMPDATE ") by ALB42\n"; extern const APTR FuncTable[]; AROS_UFP3 (LIBBASETYPEPTR, InitLib, AROS_UFPA(LIBBASETYPEPTR, Base, D0), AROS_UFPA(BPTR, seglist, A0), AROS_UFPA(struct ExecBase *, sysbase, A6) ); static struct LibInitStruct { IPTR LibSize; const APTR *FuncTable; const struct DataTable *DataTable; APTR InitFunc; } const LibInitStruct = { sizeof(LIBBASETYPE), FuncTable, NULL, (APTR)InitLib }; const struct Resident romtag = { RTC_MATCHWORD, /* match word */ (APTR)&romtag, /* back pointer */ (APTR)(&romtag + 1), /* skip pointer */ RTF_AUTOINIT | RTF_EXTENDED,/* flags */ VERSION, /* version */ NT_LIBRARY, /* type of module */ 0, /* init priority */ (STRPTR)lib_name, /* module name */ (STRPTR)lib_id + 6, (APTR)&LibInitStruct, REVISION, NULL }; AROS_UFH3 (LIBBASETYPEPTR, InitLib, AROS_UFHA(LIBBASETYPEPTR, Base, D0), AROS_UFHA(BPTR, seglist, A0), AROS_UFHA(struct ExecBase *, sysbase, A6) ) { AROS_USERFUNC_INIT Base->My_SegList = seglist; Base->My_SysBase = (APTR)sysbase; Base->testint = 0; USESYSBASE bug("InitLib\n"); if (!set_open_libraries()) { set_close_libraries(); return NULL; } return Base; AROS_USERFUNC_EXIT } AROS_LH1(LIBBASETYPEPTR, LibOpen, AROS_LHA (ULONG, version, D0), LIBBASETYPEPTR, Base, 1, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibOpen\n"); (void)version; Base->My_Test_Lib.lib_OpenCnt++; return Base; AROS_LIBFUNC_EXIT } __saveds APTR LibExpungeInternal(LIBBASETYPE *Base reg(a6)) { USESYSBASE APTR seglist; bug("LibExpungeInternal\n"); if (Base->My_Test_Lib.lib_OpenCnt) { return 0; } seglist = Base->My_SegList; Forbid(); Remove((struct Node*)Base); Permit(); FreeMem((APTR)Base - Base->My_Test_Lib.lib_NegSize, (LONG)Base->My_Test_Lib.lib_PosSize + (LONG)Base->My_Test_Lib.lib_NegSize); set_close_libraries(); return seglist; } AROS_LH0(BPTR, LibClose, LIBBASETYPEPTR, Base, 2, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibClose\n"); if (!(--Base->My_Test_Lib.lib_OpenCnt)) { return LibExpungeInternal(Base); } return 0; AROS_LIBFUNC_EXIT } AROS_LH1(BPTR, LibExpunge, AROS_LHA(LIBBASETYPEPTR, Base, D0), struct ExecBase *, sysBase, 3, LIBHEADNAME ) { AROS_LIBFUNC_INIT (void)sysBase; USESYSBASE bug("LibExpunge\n"); return LibExpungeInternal(Base); AROS_LIBFUNC_EXIT } AROS_LH0(LIBBASETYPEPTR, LibReserved, LIBBASETYPEPTR, Base, 4, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("LibReserved\n"); return 0; //return (APTR)LibReserved(); AROS_LIBFUNC_EXIT } // Space for your own functions // do not forget to update the FuncTable as well AROS_LH1(int, TestFunction, AROS_LHA(int, TestValue, D0), LIBBASETYPEPTR, Base, 5, LIBHEADNAME ) { AROS_LIBFUNC_INIT USESYSBASE bug("TestFunction\n"); Base->testint = TestValue + Base->testint; return Base->testint; AROS_LIBFUNC_EXIT } // Functable -> Table of all functions in the Library, in right order - important! const APTR FuncTable[] = { &AROS_SLIB_ENTRY(LibOpen,LIBHEADNAME,1), &AROS_SLIB_ENTRY(LibClose,LIBHEADNAME,2), &AROS_SLIB_ENTRY(LibExpunge,LIBHEADNAME,3), &AROS_SLIB_ENTRY(LibReserved,LIBHEADNAME,4), &AROS_SLIB_ENTRY(TestFunction,LIBHEADNAME,5), (void *)-1 }; // AutoInit stuff void *__PROGRAM_ENTRIES__symbol_set_handler_missing; void *__LIBS__symbol_set_handler_missing; // end of AutoInitStuff </pre> Makefile <pre> VPATH = CFLAGS = -O2 -g -fomit-frame-pointer -W -Wall -Wno-parentheses CC = i386-aros-gcc LD = i386-aros-gcc LDFLAGS = -nostartfiles -Wl,-Map -Xlinker linkermap LIBS = -lautoinit -llibinit STRIP = i386-aros-strip --strip-unneeded --remove-section .comment OBJS = lib_header.o all: mytest.library mytest.library: $(OBJS) $(LD) $(LDFLAGS) $^ $(LIBS) -o $@ lib_header.o: lib_header.c lib.h clean: rm -f *.o *.library *.ppu testlibrary linkermap </pre> Porting UNIX library to AROS - dealing with static variables which would make it easy to port such libraries to AROS, keeping the benefits of sharing them on disk, but losing the benefit of actually sharing them in memory. Our problem arises by the fact we want to share the actual code (the .text section of the library) and constant data, but we need to have per-task .bss and .data sections. If we get rid of our intention to share the .text and .rodata sections, things get quite easy: just load and relocate the library whenever it's open, by whoever it's open. It's like statically linking the library into the executable, except that the final linking is done at runtime. In the V0 branch, in workbench/hidds/hidd.nouveau was committed pcimock.hidd. This is a pci driver that allows mocking real PCI devices under linux-hosted. The main idea is to be able to run the real hardware driver under linux-hosted with as little changes as possible (some changes will always be needed though unless someone wants to write complete device simulator) so that driver's code paths can be executed and debugged using gdb. This was a very helpful capability when porting nouveau. Now it is externalized from nouveau.hidd and can be used by other people porting drivers. The pcimock.hidd can currently mock 4 different nvidia cards, 1 AGP bridge and also mock irq.hidd. What's the difference between this driver and the pcilinux.hidd? I used that one to develop many different HW drivers for aros. As far as I understood the intention of pcilinux.hidd it is supposed to get access to real hardware that is running under linux. The pcimock.hidd goal is to mock the hardware. For example my dev box is a PCIE system, but I still would like to run the AGP codes paths in nouveau under linux-hosted to check if they don't seg fault. The other case would be to run codes paths for hardware that the developer does not have (Fermi cards in my case). In the case of pcimock.hidd, the AROS driver's code paths will execute as long as you add proper mocking (for example fill in PCI config area or values for registers in BARs). This is an advantage for ported drivers - the code should already work (since it worked on another system) but there might have been mistakes made during porting which can be detected easily with gdb. In case you are writing your driver from scratch, pcilinux.hidd hidd will give you more advantage, since you can actually access the real hardware from linux-hosted. == Misc == ===APL, MPL, BSD, GPL and LGPL Licences=== The majority of AROS sources in licensed under AROS Public License ([http://aros.sourceforge.net/license.html APL]) which (to a degree) protects us from someone taking AROS sources and not contributing improvements back (for example MorphOS took some AROS source and then contributed changes back) It is written to allow the use of AROS code in other open source or commercial projects without exception whilst providing a mechanism so that improvements/additions can find their way back to the original source in one form or another. There are "3rd" party applications used by AROS that do not fall under this license, which are an extra "Contrib" download for convenience. Anyone can port GPL-ed network and sound drivers as AROSTCP and AHI are GPLed. Direct using (porting) [http://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs GPL]-ed code in other parts of AROS (gfx, sata, usb) is not possible because AROS license is not compatible with GPL. You need to utilize permissive licensed code like BSD or MIT/X11. BSD and MPL license are the closest to APL. APL however is not so compatible with LGPL/GPL. LGPL case - you cannot statically combine APL code with LGPL. You can, however thank to LGPL being "lesser" restrictive, use LGPL dynamically loaded libraries in APL codes. GPL case - you cannot combine APL code with GPL in any way if there is no explicit clause by GPLed code authors allowing that. If you do combine APL with GPL in "bad" ways described above - you have a problem (you violate GPL). This problem might result in everything in AROS becoming GPL or everything running or AROS becoming GPL (here I'm not sure really). The other scenario is that you are not allowed to legally distribute such code at all. To be honest I have grasped how to violate GPL, but I'm still no exactly sure what happens when you violate it (but I'm sure it's not anything nice) GPL software can run on top of non-GPL "system components" (see system components exception of GPL), but the other way around (non-GPL using GPL) leads to problems. This means applications like scout, or Quake III are ok (in the majority of cases). Theres no reason GPL drivers cannot be ported - but they cant be in AROS's ROM (requires linking APL code with GPL), nor can AROS depend on them (e.g. they must use existing apis). If they are launched (dynamically linked) by a user action that is allowed. It is also allowed to distribute such binaries together for convenience. GPL is not about statical or dynamic linking but is about executing process and function calls. These components - SFS, isapnp, Zune texteditor, AHi, network drivers, freetype, openuirl, BHFormat, Edit and (" dynamically loaded libraries") are LGPL, not GPL. Mesa/Nouveau stuff is MIT. Some user tools are GPL though. '''AROS (system)''' * system components (libraries/classes/devices/etc) cannot be GPL as they would propagate GPL to complete system as well as GPL is not compatible with MPL from which APL is based * system components can be LGPL v2 or a permissive license (MIT/BSD) * system applications can be anything you like (but still I would prefer APL or permissive so the code can be reused if needed) '''Contrib:''' * no rules - contrib does not impact AROS system since nothing in AROS system depends on contrib. About stealing code: The chances of this happening is exactly the same whether we are APL or GPL. If any closed-source option wanted to do it, there is no one that can validate otherwise. MorphOS has used some AROS codes, but contributed changes back. The rationale behind APL is that while it guarantees that the original developer will get the improvements back (to a certain degree - file based), the person who uses the codes does not have to open his original codes. BSD does not guarantee that the original developer gets improvements. GPL requires the person using the codes to open his codes as well. The copyright holders needs to stay - we just need information from them that the codes are available under APL (for example a checked-in file like in case of Poseidon). We don't do transfer of copyrights. ; Ultimately what can and cannot be done is up to the author(s) - not the licence. ===AROS source code tree=== * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-trunk.txt * http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt Found this interesting (non-GPL) licensing 'anomaly' - to keep in mind for distributors. Programs that lose their license if sold ("non-profit only" licensed): contrib/aminet/comm/term/TinyTerminal contrib/aminet/dev/basic/bwBASIC contrib/aminet/text/edit/xdme contrib/fish/aroach contrib/fish/lotto contrib/fish/shuffle contrib/fish/touch + cdvdfs. Here is a list of all the GPL/GPLv2/GPLv3 licenses fossology found, what have explicit licenses in their comments. excluded LGPL, BSD/GPL dual licensed and programs (such as Prefs/Edit and BHFormat) <pre> AROS/rom/dbus/include/ AFL_v2.1 ,GPL_v2+ (supposedly AFL < 3 is GPL incompatible) AROS/workbench/classes/zune/betterstring/include/ GPL_v2+ AROS/workbench/classes/zune/texteditor/include/ GPL_v2+ AROS/workbench/classes/datatypes/gemimage/ GPL_v2+ GPL AROS/workbench/classes/datatypes/degas/ GPL_v2+ AROS/workbench/libs/openurl/README: GPL AROS/workbench/network/smbfs/documentation/ GPL_v2 AROS/workbench/network/smbfs/source_code/ GPL_v2+ AROS/workbench/network/stacks/AROSTCP/bsdsocket/kern/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/mmakefile.src conf.h GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/sys/ CMU ,GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/net/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/api/ GPL_v2 AROS/workbench/network/stacks/AROSTCP/bsdsocket/conf/conf.h: GPL_v2 AROS/workbench/network/stacks/AROSTCP/netinclude/net/radix.h: CMU ,GPL_v2 AROS/workbench/devs/AHI/AHI/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/ GPL_v2+ AROS/workbench/devs/AHI/AddAudioModes/COPYING: GPL AROS/workbench/devs/AHI/Docs/texinfo.tex: GPL_v2+ AROS/workbench/devs/AHI/COPYING: GPL AROS/workbench/devs/AHI/Drivers/EMU10kx/ GPL_v2+ AROS/workbench/devs/AHI/AHI-Handler/ GPL_v2+ AROS/workbench/devs/networks/rtl8029/ GPL GPL_v2+ AROS/workbench/devs/networks/pcnet32/ GPL GPL_v2+ AROS/workbench/devs/networks/ppp/LEGAL: GPL AROS/workbench/devs/networks/atheros5000/ GPL_v2+ AROS/workbench/devs/networks/rhine/ GPL_v2+ AROS/workbench/devs/networks/nForce/ GPL_v2+ GPL AROS/workbench/devs/networks/prism2/ GPL GPL_v2+ AROS/workbench/devs/networks/fec/LEGAL: GPL AROS/workbench/devs/networks/rtl8139/ GPL GPL_v2+ AROS/workbench/devs/networks/etherlink3/ GPL GPL_v2+ AROS/workbench/devs/networks/intelpro100/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8169/ GPL GPL_v2+ AROS/workbench/devs/networks/emac/ GPL GPL_v2+ AROS/workbench/devs/networks/rtl8168/ GPL GPL_v2+ AROS/workbench/devs/networks/realtek8180/ GPL_v2+ AROS/workbench/devs/networks/via-rhine/via-rhine.c: GPL_v2+ AROS/workbench/devs/networks/via-rhine/ GPL GPL_v2+ AROS/workbench/devs/networks/e1000/ GPL_v2 AROS/workbench/devs/networks/sis900/ GPL GPL_v2+ </pre> AHI: it has special provisions (COPYING.DRIVERS). The library is LGPL, preferences software is GPL and drivers can be anything without breaking GPL/LGPL. Network stack: well, we are long overdue for a new, IPv6 enabled network stack anyway, anyone interested? ;) Seriously though it seems like the glue code is GPL and as all the drivers. However some of the drivers are our own code, so they could be relicensed to LGPL. Same filter as the AROS trunk list. These should all be libraries or plugins - no programs. <pre> contrib/regina/utsname.h: GPL_v2+ contrib/mui/classes/nlist/include/default-align.h: GPL_v2+ contrib/mui/classes/nlist/include/amiga-align.h: GPL_v2+ contrib/mui/classes/BWins/include/MUI/BWin_mcc.h: GPL contrib/mui/classes/BWins/include/BWin_private_mcc.h: GPL contrib/mui/classes/BWins/COPYING: GPL_v2 contrib/mui/classes/BWins/MCC_BWins.readme: GPL_v2 contrib/mui/classes/thebar/include/default-align.h: GPL_v2+ contrib/mui/classes/thebar/include/amiga-align.h: GPL_v2+ contrib/gfx/libs/wazp3d/LEGAL: GPL contrib/gfx/libs/wazp3d/Wazp3D.readme: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/soft3d_opengl.c: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.h: GPL contrib/gfx/libs/wazp3d/Wazp3D-src/Wazp3D.c: GPL contrib/libs/mpega/ GPL_v2+ </pre> http://www.evillabs.net/AROS/Audit-2012-03-14/AROS-contrib.txt ===Types=== On AROS following rules apply: <pre> 1. BYTE/UBYTE is 8bit, WORD/UWORD is 16bit, LONG/ULONG is 32bit, QUAD/UQUAD is 64bit, the types are comparable with stdint types (int8_t, int16_t, int32_t, int64_t) 2. IPTR/SIPTR are integer types large enough to fit pointer, that is sizeof(IPTR) = sizeof(APTR) = 4 on 32bit system, and = 8 on 64bit system 3. ti_Data in TagList is large enough to hold a IPTR/APTR type. 4. never store a pointer in integer of type LONG. It may work (if the pointer has upper 32bits clear), but does not have to. Compiler should warn you about that. 5. If you are unsure about point 4, allocate your memory with MEMF_31BIT flag set. But don't expect that AROS internals will do the same. </pre> point 4 is actually important. * UBYTE/BYTE for 8bit * UWORD/WORD for 16bit * ULONG/LONG for 32bit * UQUAD/QUAD for 64bit <pre> UBYTE Unsigned 8 bit integer variable (byte). BYTE Signed 8 bit integer variable (byte). UWORD Unsigned 16 bit integer variable (word). WORD Signed 16 bit integer variable (word). ULONG Unsigned 32 bit integer variable (longword). LONG Signed 32 bit integer variable (longword). FLOAT 32 bit IEEE floating point variable. UQUAD Unsigned 64 bit integer variable. QUAD Signed 64 bit integer variable. DOUBLE 64bit IEEE floating point variable. BOOL Boolean variable, TRUE and FALSE are also defined in exec/types.h. VOID Void. APTR A generic pointer for multiple purposes - Arrays. STRPTR A pointer to a null-terminated string. IPTR Really important in AROS, the only way to declare a field that can contain both: an integer or a pointer. </pre> if you want to write really portable app, you may be interested in standard datatypes defined in C99: int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, intptr_t, uintptr_t. They are all defined in inttypes.h include file. In exec/types.h the following short-cuts are typedef'd. They are used often in AROS, so you should nearly always include exec/types.h and soon only they will be removed from sys/_types.h include, all types are now defined in include files named aros/types/xxx.h. (Preparation for C library split; sys/xxx.h include will only be available there when compiling with POSIX C library) Compiler specific types, like int and long might change their size. In case of AROS, similar to linux, int remains 32 bit whereas long grows to 64 bits in size. If you use Amiga-like data types, i.e. BYTE/UBYTE, WORD/UWORD, LONG/ULONG and QUAD/UQUAD or the C99 standard types (uint8_t and so on, see stdint.h include) then you should have less issues to solve than by using types without size guarantee. Of course, all pointers grow to 64 bytes using 64bit cpu. Most of the code can be just recompiled and will work. In rare cases, where e.g. pointers are casted to integers, a special care must be taken. Especially in the cases, where pointer is casted to LONG/ULONG (this code will break on 64 bit AROS) e.g. '#define IPTR ULONG'. With compiler delint patches which the majority of them are simple casting issues to make the compiler happy. Notice some of the changes involve introducing double casts. In very recent versions of GCC. Yes, the bulk of the double casts are for converting 32 bit addresses (ie from a 32 bit PCI DMA address register) to a 64 bit pointer. First cast is to IPTR (to expand to 64 bits, and prevent sign extension if the address is above 0x7FFFFFFF), and then to APTR. ULONG != IPTR except on 32bit .. so if you need to store pointers make sure and use IPTR and not ULONG (which some old code does). For this reason things like Taglist elements are 64bit (since the tag data can be a pointer). If your passing items on the stack you should use the STACKED attribute to make sure they are correctly aligned (on 64bit all items on the stack are 64bit..) There is more issues like using "== 0L" causes problems. ===Endian=== *BE *LE Use the macros from <endian.h> instead making a guess based upon architecture defines <pre> #if _BYTE_ORDER == _BIG_ENDIAN #elif _BYTE_ORDER == _LITTLE_ENDIAN #else + #error <whatever.h> - Byte order for this architecture is unsupported! </pre> ===SVN and GIT=== If you want to help develop AROS OS itself, you can * view current GIT/SVN entries [http://aros.sourceforge.net/ Aros Org website] or [https://github.com/aros-development-team/AROS Github], [https://github.com/ezrec older ezrec mirror], [https://github.com/michalsc/AROS/ older mirror], [https://trac.aros.org/trac/timeline TRAC], [], * awaiting update [http://repo.or.cz/w/AROS.git git repo], [http://www.ohloh.net/p/aros/commits ohloh] or [https://svn.aros.org/svn/aros/trunk/ svn repo] and access [Git version git://repo.or.cz/AROS.git here], * deprecated [https://www.gitorious.org/aros/aros/commit/a7fda9e ARIX commits] or [https://gitorious.org/aros/aros GIT old] If you have SVN access (early 2015 introduced a new SVN server, create a new account at trac aros org) and/or have obtained the source [http://aros.sourceforge.net/download.php AROS site] - you can compile the current build tools/environment using: > make development and follow this [http://aros.sourceforge.net/documentation/developers/compiling.php#building procedure] or [https://github.com/apiraino/aros_guide Guide] https://trac.aros.org/trac#Developing If you plan on contributing back changes, please post information about such changes first on this [http://mail.aros.org/mailman/listinfo/aros-dev/ mailing list] for more experience developers can validate whether they are correct. Then there are the nightly build machines. They svn update before the build and run configure as one of the next steps. autoconf might be added to the nightly build scripts. Our build relies on packages downloaded from Internet (SDL for example) - it always worked this way. The minimal requirement (when just building core AROS) is binutils and gcc. If you build contrib as well, you need many more packages to be downloaded. https://gitorious.org/aros/aros/commits/crosstools-II git://gitorious.org/aros/aros.git Branch crosstools-II there is only one commit on top of ABI_V1 <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-x86_64 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-x86_64 </pre> and <pre> ../../aros-src/AROS/configure --enable-ccache --with-portssources=~/aros/Sources --target=pc-i386 --with-aros-toolchain-install=/home/weissms/media/data/aros/test/crosstools/pc-i386 </pre> build OK. :''More information: [[Aros/Developer/Maintainer|AROS Maintainer Docs]]'' ===SDI Calls=== Integrate the 'SDI'-headers to allow easier porting to all amiga-like platforms. <pre> PUTCHARPROTO( PutTheChar, char c, struct SPrintfStream *s ) { // REAL CODE } </pre> have "SDI_compiler.h" and "SDI_hook.h" included its more organized like #include SDI/SDI_hook.h than #include SDI_hook.h option 1 --- i also use when back porting from amiga's.. <pre> #ifdef __AROS__ #include SDI/SDI_hook.h #else #include SDI_hook.h #endif </pre> also you can add the -i include/sdi/ location if you do not want to add or edit any files. Defining HOOKPROTO to IPTR name(struct IClass * cl, Object * obj, Msg msg); solved the problem A MUI application most likely needs only the HOOKPROTOxxx SDI macros. They are compatible with AROS, only the attributes (hook, object attribute) must be given in the right order. examine compiler/include/aros/symbolsets.h (AROS_LIBREQ) compiling mui stuff for aros setting -std=gnu99 is necessary (i have had -std=c99 most of the time). ===Locale with Flexcat=== Most languages have a locale, but not every app is localized, the only thing needed is to translate the "catalog" files. It is a case of locating the correct catalog and saving the translated version. For every app that lacks of your language catalog and is localized anyway, you should find (in the sources) files related to locale: * file.cd = catalog descriptor, contains base msg, with internal language (usually english) * language.ct = catalog translation, contains every translated msg, indexed as in the file.cd. Compare with other localized apps... Then, "make my_app-catalogs" should create and install your translated catalogs. ex : for, saying, sys:prefs/wanderer: on root of AROS sources, type: "make workbench-prefs-wanderer-catalogs" then (if you changed the .cd file): "make workbench-prefs-wanderer" For apps not localized, you have to adapt their code to support it, if it is possible... noticed the original .cd file has many (//) strings at the end of any voice, so added them also to the .ct file. That (//) is only for cd files. I'm highly recommending to use FlexCat for updating ct files, e.g. like this: flexcat app.cd deutsch.ct newctfile deutsch.ct You'll get error checking and new entries are marked in the resulting ct file. When editing .ct files, only change those lines containing translation and perhaps version string, nothing else. The rest is up to the relevant tool, flexcat. In order to update your translation, type in the following in your shell: flexcat xyz.cd xyz.ct NEWCTFILE xyz_upd.ct COPYMSGNEW This way you will not only make sure you have correct translation file but flexcat also pre-fills newly added strings with "*** NEW *** text. Even better tool for checking cd/ct/catalog files is catcheck, but this one is sadly only available for AmigaOS/68k... Some languages have variations, like portugues from portugal and portugues from brasil differs... This is the way to go. I will have a look at language files, but basically if those two languages differ you have to do two separated set of translation files, yes. (you could create a brazilian slang language localization too) * At system level localization for one language is a dot language file. (ex: locale:languages/klingon.language) * At app level localization is a dot catalog file (ex: locale:catalogs/klingon/system/libs/dos.catalog) * At sources level, the dot ct file, and "$language" dot cd files and some building framework. (ex: catalogs/my_app.ct catalogs/klingon.cd catalogs/mmakefile.src support.c support.h) Please, use Flexcat to generate CT files: FlexCat wanderer.cd NEWCTFILE=deutsch.ct Then fill the first 2 lines with something useful: <pre> ## version $VER: wanderer.catalog 1.1 (9.2.2006) ## language deutsch </pre> You can even update the CT-File: (This adds the new strings) FlexCat wanderer.cd deutsch.ct NEWCTFILE=deutsch.ct To compile a catalog you only need the .cd file and your translation (.ct file): FlexCat multiview.cd deutsch.ct CATALOG=MultiView.catalog [http://murks-ide.svn.sourceforge.net/viewvc/murks-ide/trunk/src/Catalogs/flexcat_linux?revision=100 Linux version of FlexCat] : [http://aros.sourceforge.net/documentation/developers/app-dev/localization.php#localization-for-non-developers More information] A script which compares the required version (i.e. the version which an application/module etc. tries to open) with the version of the existing CT files. The result is in this table: https://github.com/aros-translation-team/translations/wiki/Progress The following cases are highlighted: n/a i.e. CT misses at all version in existing CT file is lower than the required version It might be a bit difficult to participate if you haven't worked with Git before but alternatively you can send your CT files to our Slack channel. When the ct file has been generated via flexcat (flexcat keyshow.cd NEWCTFILE=spanish.ct) it has the following header: --------------------------------------------------------------------------------------------------------------- ## version $VER: <name>.catalog <ver>.<rev> (04.01.2021) ## language nolanguage ## codeset 0 ; --------------------------------------------------------------------------------------------------------------- Those values <ver>.<rev> are the version and revision of the CT file for the languaje or are the values of the application being localized? The <ver> part must match with version which the application tries to open. You can find the value either in the column "Required Version" in the table which I've linked above, our you can look in the git repository. For keyshow it would be https://github.com/aros-translation-team/keyshow. You can find in the file "catalog_version.h" the right version number. The <rev> part starts for new CT files with 0 and should be increased every time the CT file is updated. Updated several files and created a few more that were missing on the spanish catalog. The catalogs are in Git repositories at https://github.com/aros-translation-team a) You tell me your Github user name. I'll invite you. You can work directly with the Git repositories. b) You create Github forks of the catalog repositories and create pull requests. c) You send the CT files to mrustler gmx de ===C Utils Misc=== The AROS source uses at several places the __DATE__ macro to fill the date entry of a $VER tag. Problem is that c:version doesn't understand that date format (e.g. "May 21, 2011"). As a result the output of e.g. > "version c:shell full" contains "(null)". Is extending the version command to understand the format of __DATE__ the right solution for that problem? AmigaOs compilers should use __AMIGADATE__ macro or similar form, if it isn't implemented it could be emulated in makefile: -D__AMIGADATE__=\"$(shell date "+%d.%m.%Y")\" BTW. I think DD.MM.YYYY is better format than "Month DD YYY" because "Month DD YYY" is not localized in any way. "strnicmp" shouldn't work with NULL pointers The Situation: compiled a linklib using c++ object files (using the c++ cross compiler). compiled a C stub that uses the linklib (using the c++ cross compiler). Try to link them together (using the c++ cross compiler) with C object files (using the normal target c compiler) that need to use -nostartup = cant do because using the c++ files pulls in arosc (for stdio etc.) - so wants to have the autoinit stuff present. What can I do about this?? If it is possible to manually open it then what do I need to do exactly? === ENV === The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. 99% of the time that statement is true (not required) for pretty much every file in ENV: or do people change their default icons - and prefs settings - every boot? There seem to be a bad habit of late with developers changing things to reflect their own personal preference when the change isn't actually necessary - It would be nice if people could refrain from doing that in the tree without at least discussing it on the dev-list first (and with good reasoning unless they committed said work in the first place..) We're not keen on the pollution of the "S:" dir: it's meant to be for scripts. What's wrong with "ENV:"? Only the fact that it takes up RAM. I understand that for PCs with several gigabytes of RAM this is irrelevant. But let's remember about other machines. The philosophy behind ENV: is that keeping configuration files there allows you to 'Use' preferences by keeping a copy in ENVARC: intact. However in some cases (like this one) it is not required. How about implementing in the style of HappyENV then? RAM-disk handler that falls through to reading from ENVARC: if there is no such file stored in it already. Removes RAM usage for unchanged files, removes the need to copy ENVARC to ENV in startup-sequence. Shouldn't be too hard to make from AmberRAM, or even just extend AmberRAM to provide this service. Is it feasable to build a special version of AmberRAM handling ENV: that will try and copy the requested file from ENVARC: if it isnt found in ENV: ? Additionaly it could mark closed "files" as untouched - and expunge them from ENV: after a period of time to free up additional RAM:, or when the system is running low on free memory? Silenty disappearing files may not be a good plan. Would be nice if the following would work: ASSIGN :ENV SYS:Prefs/Env-Arc ADD ASSIGN :ENV RAM:ENV ADD Where new files put in ENV: end up in RAM:ENV, and opening files looks in RAM:ENV first, then SYS:Prefs/Env-Arc Well - that's essentially what im proposing but without the assigns - or need for a RAM:ENV directory. Adding it as a feature of AmberRAM sounds like the most memory efficient way (one handler to load in RAM) but that's only if it is possible to make it handle ENV: additionally to RAM:, and if it is even possible to add the proposed functionality (...and how to make it enable it when accessing ENV:). ===(AS)MP support=== If one has to recompile software for SMP multi core, is there any thing special one has to do to get software to run? Use task.resource if you need to query information about what tasks are running, and clear msgports completely when they are allocated. Most code should not need Forbid. Use Semaphores, Messages etc. to sync your own code. Accessing system structures is a different thing. Use the proper API whenever possible. How single structures will be protected in the future is still a moving target, at least it is not documented. And you should never use undocumented stuff Ideas on for SMP multi-core Another suggestion is ... Forbid/Permit function calls are meant to halt multitasking so as no other task could intervene with what ever the calling task is doing, e.g. setting semaphores. Disable/Enable calls are meant to halt interrupts and as a side effect they also halt task switching. One option is to make it compulsory to protect shared resources with semaphores and forbid the use of simple Forbid() calls as to protect something. Setting semaphore should be done if possible with atomic instructions (check and alter in one instruction). Or make the second concurrent ObtainSemaphore call halt the second calling task and force if possible a task switch which ever gives better results. Semaphores could store the owning tasks task pointer instead of boolean to make things easier. As long as the CPU initiates the DMA transfers through the OS, and the OS ensures that the transferred memory is within the region accessible to the user initiating the transfer, everything is fine. The CPU is the conductor, and the CPU by that has the control of which DMA transfer is initiated and which is not. All you need to do is to write device drivers reasonable. Hint: CachePreDMA and CachePostDMA exist. All the Os has to do is to verify that the memory regions to be transferred are valid, and prohibit direct access to the DMA control registers from user space. None of these algorithms imply huge costs. The current OS design doesn't really allow virtual memory in first place, Forbid() is again the problem. [http://www.tbs-software.com/guide/index.php?guide=autodocs.doc%2Fmemory.doc&node=1 memory.library API] seem to low level. IMHO the programs should not know how the swapping is implemented. I would just go for one new memory flag MEMF_SWAPPABLE that indicates that a certain memory region or a whole memory pool won't be accessed during Forbid()/Permit() etc. It only solves part of the problem, it only implements virtual memory and not memory protection. For the latter you need to be able make certain memory inaccessible by other programs, some memory read-only for one task and read-write for other tasks, etc. And I think this should be done in the same Address Space in order to avoid you constantly need to swap between different address spaces. So to summarize, if there are programs using this API we may provide a wrapper layer to get them working but I am not convinced this API should be the reference API with whom to provide VM to AROS programs. === Variadic === variadic functions (i.e. functions with an arbitrary amount of arguments). <pre> #include <stdarg.h> [...] char * STDARGS GetKeyWord(int value, char *def, ...) { [...] va_list va; [...] va_start(va, def); [...] va_end (args); </pre> Please keep with using stdarg rather than having va casted to a LONG * type and varargs handled manually. Doing so, prevents tons of casting, where a simple va_arg can be used. So, string = *((char **) args) instead of string=va_arg(va, char *). <pre> #include <stdio.h> #include <stdarg.h> int printf (const char * format, ...) { int retval; va_list args; va_start (args, format); retval = vfprintf (stdout, format, args); va_end (args); fflush (stdout); return retval; } /* printf */ </pre> Couldn't find varargs.h or stdarg.h. and have no use for AROS_SLOWSTACKHOOKS or AROS_SLOWSTACKTAGS. GCC looks for stdarg.h in a different place: /bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/include/stdarg.h Here is a path for a "normal" header: bin/linux-i386/tools/lib/gcc/i386-aros/4.2.2/../../../../i386-aros/sys-include/aros/system.h The use of vararg.h isn't supported by newer gcc versions. If you want your code to run on architectures that pass part of variadic arguments in a number of registers you need to use AROS_SLOWSTACK macros. Otherwise your program will not work on powerpc and x86_64 ports. Of course the SLOWSTACK stuff is not needed in a function that can use va_list, va_start, va_arg and va_end. It's only needed if you want to write functions like DoMethod or similar. #include <stdarg.h> should be enough no matter if you do cross or native compiling. If it does not work, something is wrong and should be corrected. Stdarg.h is here, Development:lib/gcc/i386-aros/4.2.2/include/ ...which is part of the compiler's default include paths. In other words, #include <stdarg.h> works out of the box, indeed. (sorry, I should have just tried it before invoking "search" or "find"...) furthermore, myprintf() as shown above won't work, because... printf(format, args); ...is wrong - the second argument does not match printf() prototype, it expects a argument list, but args is of type va_list (obviously) - so one has to use... vfprintf(stdout, format, args); ...instead, just like in the original printf(), and add fflush(stdout). additionally, one could use... int myarg = va_arg(args, int); ...between va_start() and va_end() to access individual arguments, where each call to va_arg() returns an argument casted to the desired type (here: "int") from the list given (here: "args") and advances to the next one. wrapping up vfprintf() and modifying the format string now is a major speedup! no more backslash-n typing! this has been haunting me for years! On MOS and AmigaOS, the NewObject variadic function is kept in the static library. It takes most of the parameters on the stack - thanks to that the implementation of NewObject calls the NewObjectA function. Everything works perfect, and the typical MUI macros may be easily used. This, however, is not the case when you compile for AROS. Here, NewObject is a variadic macro, not a function. Thanks such approach we do not need any custom compiler in case of systems, where the arguments of variadic functions are passed partially through registers and partially through the stack (This is the case of PPC and x86_64, this is also the reason why both OS4 and MOS require specially patched compilers). Since NewObject is a macro, the gcc's preprocessor expects the list of macros arguments enclosed within parentheses. In MUI macros it is not the case. Imagine the following test code: <pre> #define foo(a,b) ((a)+(b)) int loosy_function(int a, int b) { return foo(a,b); } </pre> This will compile and work, but the following piece of code: <pre> #define foo(a,b) ((a)+(b)) #define END ) int loosy_function(int a, int b) { return foo(a,b END; } </pre> will fail with the error: unterminated argument list invoking macro "foo" There are two ways of fixing your issue. Either create your new objects outside this huge MUI constructions, and in there use just a pointer, or get rid of the "End" macro and exchange it with "TAG_DONE)". Badly written software is, for example, casting va_list to an APTR or even doing so as if va_list were a plain table of function arguments. Such code needs to be fixed because it has very few chances to work anywhere but on author's machine ;) The problem is nOt that they assume sizeof(APTR) == 4, its that they often do not use APTR, and use ULONG to store pointers exclusively. If the code used APTR/IPTR as it should - most of the "problems" wouldn't exist. It would also help if people would start using variadic arguments properly. Many coders do assumptions which shall never be made. Instead, they should consider using stdarg.h file and all the va_* functions :) ===ABI=== In the head of our SVN repository there are now only 3 directories: <pre> admin/ branches/ trunk/ </pre> We have added two extra dirs there: tags and imports As discussed when we branch ABI V0 and [[Aros/Developer/ABIv1|ABI V1]] it would also be good to introduce tags. Normally this is done in a directory in the repository called tags. Currently we don't have this directory there. (We do have branches/tags that is a hack I have done because one doesn't have write access in the top directory. I think this directory is not clean and should be removed). The second directory I would introduce is an imports directory for implementing vendor branches as discussed in the svn [http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html book]. Currently we use code from several different projects and that code is stored inside the AROS tree; we seem to have problems with keeping this code up to date and merge our changes upstream. Maintainers of up stream projects like the MUI classes etc. have complained about this (to put it lightly). Introducing these vendor branches would make it easier to see what changes we have made and make patches to be sent upstream and make it easier to import newer upstream versions of their code. Although can't "copy" the vendor branch into the main branch because it's already there, so start with a "merge". Yes, the first step to make the code already in the repository compatible with the vendor branches will be the most difficult. The best way to do it the following way: * first import the version on which the current AROS code is based into the vendor branch * then import the new version over it in the vendor branch * finally merge the difference between these two version in the AROS code present in the repository. For example, place NList directly under vendor and not in a subdirectory like "contrib/zune/classes". Actually after we have a stable [http://aros.sourceforge.net/documentation/developers/specifications/drafts/abiv1.php ABIv1 (2012 or later)]. We need to move away as much as possible from the contrib directory to some other repositories. The reasons are ... * The AROS repository should be for the core AROS code. * other contrib projects should be tried to be compiled for all Amiga-like OSes. * The release scheme for AROS and the other programs should not have to be aligned. * Binary versions should be provided on aros-archives and on aminet and/or OS4Depot to install them. (Some clever programs should maybe be provided to make the life of distribution developers easier). * avoid parallel forks of programs for AROS and the other amiga OSes. If there is really a need for a place for hosting AROS projects we may investigate setting up such a server but then including bug tracking, governance, maillist, etc. for each project separately. I personally think there are already enough places like sourceforge, google code, savannah, etc. where people can go for hosting such projects. ==Links== * http://amigadocs.hokstad.com * http://amigadocs.hokstad.com/doku.php?id=dev-links In the future...? *AROS 64bit - SMP, Vulkan with OpenGL compability layer *AROS 32bit - keep for historic reasons What would you like to see implemented in AROS? ABIv1 completed, SMP (x86_64), SendMsg()/GetMsg() to support memory protection between target and destination, in that order. Michal Schulz and Jason McMullan have been toying with the question "What are the minimal changes needed to the AmigaOS 3.1 API to support SMP"? The answer so far seems to be "few, but subtle". For example, SysBase->ThisTask is no longer meaningful on SMP, but FindTask(NULL) is. Disable() and Forbid() are shockingly bad on performance, but adding a spinlock semaphore mode to SignalSemaphore will help new code on SMP. Leveraging a 'common' OS with a lot of machine support (Linux, MacOS, Windows, QNX, etc.) is something that AROS has been doing for quite a long time, and it is the biggest strength of AROS. This AROS experience and programming model, in the same way the Google's Android layers on top of Linux, or MacOS X layers on top of the Darwin/BSD kernel, as a first step * The graphics + layers subsystem could be implemented as a shim on top of a OpenGL ES implementation (ie on any modern Linux system, or the RaspberryPI's hardware, MacOS X, etc). - This also allows every window to be on its own 3D surface with backing store, allowing Wanderer (or a Commodity) rearrange/zoom/animate app windows without having to send a pile or refreshes to them * Use OpenAL as the sound backend * AROSTCP would be a thin layer over the native OS's TCP/IP stack * dos.library, poseidon.library, and input.device would be slim shims over the native APIs * If we move to loading all libraries' into the application's task space, instead of a single global instance of the library, this will allow SMP and MMU more easily. - Yes, it will require a lot of work in the libraries to make this transition - Yes, I do think it will be worth it in the end. * A 'fat binary' install format (or, maybe LLVM bytecode) that can be 'flattend' to the target architecture on installation. So, what would this 'AROS of the future' look like? * AmigaOS 3.x style API, with certain 'fundamental changes' to message passing * Uses the underlying OS' device drivers, so more AROS developer effort can go to user-visible features and bugfixes * Allows AROS applications to run side-by-side with the OS's native apps And why would anyone want to program on such a system? * AROS applications would run on any system that has the AROS Framework installed * AROS applications are pixel-for-pixel the same on all platforms. * Develop with the knowledge that you are guaranteed OpenGL and OpenAL, and the rest of the AROS Framework an option for mmake to dump its dependency of metatarget in a graphviz[*] input file. This should make it possible to visualize the dependencies and hopefully be inspiration for cleaning up some mess, circular or unneeded dependencies and so on. AmigaOS gcc 9 [https://franke.ms/amiga/gcc.wiki Old versions] able to create binaries for AmigaOS and [https://eab.abime.net/showthread.php?t=93813 Upgrading gcc versions] ==References== {{reflist}} {{status|50%}} {{BookCat}} bfy0rqzhy03vaeexifwatvy9sypkv65 Aros/Developer/Zune 0 13165 4668973 4634674 2026-09-05T17:57:00Z Jeff1138 301139 4668973 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation, some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== [http://library.morphzone.org/Event_Driven_Programming,_Notifications Notifications] are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide gives information about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) and [http://guidetoamigacompatibleprogramming.googlecode.com/svn-history/r6/trunk/english/CAP_4.txt MUI] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, located in the SYS:Tests/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[http://www.liquido2.com/tutorial/ An Introduction to AMIGA Programming Using C] *[http://www.pcguru.plus.com/tutorial/introduction.html Programming AmigaOS in C] *[http://library.morphzone.org/Magic_User_Interface_Programming Magic User Interface Programming] at [http://www.morphzone.org morphzone.org] *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *MUI Reference information from AmigaOS documentation can be found e.g. [http://utilitybase.com/forum/index.php?action=vtopic&forum=13 utilitybase.com/forum/...] or at [http://utilitybase.com/ref/ utilitybase.com/ref], it has a section on MUI. (Note: Information at that site is a little outdated, but still very helpful.) (2011-10-31: utilitybase.com currently down.) ==Tools== ===MUIBuilder=== A [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool native build] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. This [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=5578&forum=1&post_id=52900#forumpost52900 thread] discussed using the m68k build and [http://www.mazze-online.de/files/mbtest.zip diff] file which modifications were necessary to make it build-able under AROS. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] qs74a7i73z8vanct844l9535dakfat1 4668974 4668973 2026-09-05T17:59:39Z Jeff1138 301139 4668974 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation, some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== Notifications are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide gives information about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) and [http://guidetoamigacompatibleprogramming.googlecode.com/svn-history/r6/trunk/english/CAP_4.txt MUI] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, located in the SYS:Tests/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[http://www.liquido2.com/tutorial/ An Introduction to AMIGA Programming Using C] *[http://www.pcguru.plus.com/tutorial/introduction.html Programming AmigaOS in C] *[http://library.morphzone.org/Magic_User_Interface_Programming Magic User Interface Programming] at [http://www.morphzone.org morphzone.org] *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *MUI Reference information from AmigaOS documentation can be found e.g. [http://utilitybase.com/forum/index.php?action=vtopic&forum=13 utilitybase.com/forum/...] or at [http://utilitybase.com/ref/ utilitybase.com/ref], it has a section on MUI. (Note: Information at that site is a little outdated, but still very helpful.) (2011-10-31: utilitybase.com currently down.) ==Tools== ===MUIBuilder=== A [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool native build] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. This [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=5578&forum=1&post_id=52900#forumpost52900 thread] discussed using the m68k build and [http://www.mazze-online.de/files/mbtest.zip diff] file which modifications were necessary to make it build-able under AROS. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] oy8tpdppi9ybdezz6ybob987wk3c1gd 4668975 4668974 2026-09-05T18:01:00Z Jeff1138 301139 4668975 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== Notifications are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide gives information about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) and [http://guidetoamigacompatibleprogramming.googlecode.com/svn-history/r6/trunk/english/CAP_4.txt MUI] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, located in the SYS:Tests/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[http://www.liquido2.com/tutorial/ An Introduction to AMIGA Programming Using C] *[http://www.pcguru.plus.com/tutorial/introduction.html Programming AmigaOS in C] *[http://library.morphzone.org/Magic_User_Interface_Programming Magic User Interface Programming] at [http://www.morphzone.org morphzone.org] *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *MUI Reference information from AmigaOS documentation can be found e.g. [http://utilitybase.com/forum/index.php?action=vtopic&forum=13 utilitybase.com/forum/...] or at [http://utilitybase.com/ref/ utilitybase.com/ref], it has a section on MUI. (Note: Information at that site is a little outdated, but still very helpful.) (2011-10-31: utilitybase.com currently down.) ==Tools== ===MUIBuilder=== A [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool native build] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. This [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=5578&forum=1&post_id=52900#forumpost52900 thread] discussed using the m68k build and [http://www.mazze-online.de/files/mbtest.zip diff] file which modifications were necessary to make it build-able under AROS. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] cz14v9fgkd2urcrqfossnqbfkrk8bi3 4668976 4668975 2026-09-05T18:02:58Z Jeff1138 301139 4668976 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== Notifications are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, located in the SYS:Tests/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[http://www.liquido2.com/tutorial/ An Introduction to AMIGA Programming Using C] *[http://www.pcguru.plus.com/tutorial/introduction.html Programming AmigaOS in C] *[http://library.morphzone.org/Magic_User_Interface_Programming Magic User Interface Programming] at [http://www.morphzone.org morphzone.org] *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *MUI Reference information from AmigaOS documentation can be found e.g. [http://utilitybase.com/forum/index.php?action=vtopic&forum=13 utilitybase.com/forum/...] or at [http://utilitybase.com/ref/ utilitybase.com/ref], it has a section on MUI. (Note: Information at that site is a little outdated, but still very helpful.) (2011-10-31: utilitybase.com currently down.) ==Tools== ===MUIBuilder=== A [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool native build] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. This [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=5578&forum=1&post_id=52900#forumpost52900 thread] discussed using the m68k build and [http://www.mazze-online.de/files/mbtest.zip diff] file which modifications were necessary to make it build-able under AROS. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] 1re5nrvuji3k8mz6cev2f5pmzurudee 4668977 4668976 2026-09-05T18:04:05Z Jeff1138 301139 4668977 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== Notifications are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, maybe located in the SYS:Demos/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[http://www.liquido2.com/tutorial/ An Introduction to AMIGA Programming Using C] *[http://www.pcguru.plus.com/tutorial/introduction.html Programming AmigaOS in C] *[http://library.morphzone.org/Magic_User_Interface_Programming Magic User Interface Programming] at [http://www.morphzone.org morphzone.org] *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *MUI Reference information from AmigaOS documentation can be found e.g. [http://utilitybase.com/forum/index.php?action=vtopic&forum=13 utilitybase.com/forum/...] or at [http://utilitybase.com/ref/ utilitybase.com/ref], it has a section on MUI. (Note: Information at that site is a little outdated, but still very helpful.) (2011-10-31: utilitybase.com currently down.) ==Tools== ===MUIBuilder=== A [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool native build] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. This [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=5578&forum=1&post_id=52900#forumpost52900 thread] discussed using the m68k build and [http://www.mazze-online.de/files/mbtest.zip diff] file which modifications were necessary to make it build-able under AROS. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] jtgwemt1bcd11yb26x4m9xatpghtlnk 4668978 4668977 2026-09-05T18:05:08Z Jeff1138 301139 4668978 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== Notifications are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, maybe located in the SYS:Demos/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[http://www.liquido2.com/tutorial/ An Introduction to AMIGA Programming Using C] *[http://www.pcguru.plus.com/tutorial/introduction.html Programming AmigaOS in C] *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *MUI Reference information from AmigaOS documentation can be found e.g. [http://utilitybase.com/forum/index.php?action=vtopic&forum=13 utilitybase.com/forum/...] or at [http://utilitybase.com/ref/ utilitybase.com/ref], it has a section on MUI. (Note: Information at that site is a little outdated, but still very helpful.) (2011-10-31: utilitybase.com currently down.) ==Tools== ===MUIBuilder=== A [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool native build] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. This [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=5578&forum=1&post_id=52900#forumpost52900 thread] discussed using the m68k build and [http://www.mazze-online.de/files/mbtest.zip diff] file which modifications were necessary to make it build-able under AROS. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] m6o98vlorsg921lyfvtqwm00iru67tb 4668979 4668978 2026-09-05T18:07:16Z Jeff1138 301139 4668979 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== Notifications are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, maybe located in the SYS:Demos/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://www.liquido2.com/tutorial/ An Introduction to AMIGA Programming Using C] ==Tools== ===MUIBuilder=== A [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool native build] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. This [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=5578&forum=1&post_id=52900#forumpost52900 thread] discussed using the m68k build and [http://www.mazze-online.de/files/mbtest.zip diff] file which modifications were necessary to make it build-able under AROS. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] qkqu3bedqpv5w9zaeq6tnhl36smj60s 4668980 4668979 2026-09-05T18:08:02Z Jeff1138 301139 4668980 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== Notifications are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, maybe located in the SYS:Demos/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] ==Tools== ===MUIBuilder=== A [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool native build] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. This [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=5578&forum=1&post_id=52900#forumpost52900 thread] discussed using the m68k build and [http://www.mazze-online.de/files/mbtest.zip diff] file which modifications were necessary to make it build-able under AROS. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [http://archives.aros-exec.org/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] 5v4pxj8dsydueptb352rmso3aws2svj 4668981 4668980 2026-09-05T18:13:20Z Jeff1138 301139 4668981 wikitext text/x-wiki {{ArosNav}} ==Introduction== <pre> version muimaster.library is 19 for 3.8 is 20 for 3.9 is for 4.0 dynamic tabs simplification is for 5.0 </pre> Zune is an object-oriented GUI toolkit. It is nearly a clone (at both API and Look&Feel level) of MUI, a well-known Amiga shareware product by Stefan Stuntz. Therefore, MUI developers will feel at home here, while others will discover the concepts and qualities that Zune shares with MUI. The programmer has a much easier time to design its GUI: no need for hardcoded values, Zune is font-sensitive, and adapts to any window size due to its layout system. He/she mostly needs to only specify the semantic of its GUI to Zune, which will arrange the low-level details automatically. Zune is based on the [https://library.morph.zone/Short_BOOPSI_Overview BOOPSI] system, the framework inherited from AmigaOS (TM) for object-oriented programming in C. Zune [[Aros/Developer/Zune/Classes|classes]] does not derive from existing BOOPSI gadget classes; instead, the Notify class (base class of the Zune hierarchy) derives from the BOOPSI root class. * Many AROS GUI components (windows, requesters, gadgets, images) are now programmed in an object-oriented way, using the BOOPSI/Zune toolkit. * Every such component is created as an object, not as a pointer to a system structure. That means no more filling structures with data. * Objects are manipulated using methods and by passing tags via the SetAttrs() function. Creating Prefs from scratch with using our Zune Prefs classes. A good introduction to the BOOPSI system is the [http://amigadev.elowar.com/read/ADCD_2.1/Libraries_Manual_guide/node01FF.html Chapter 12, "BOOPSI - Object-oriented Intuition"]. Here BOOPSI NewObject() has been replaced by MUI_NewObject(), DisposeObject() becomes MUI_DisposeObject(), etc. ==Prerequisites== Some knowledge of [http://wiki.answers.com/Q/What_are_the_concepts_of_object_oriented_programming OOP] {{w|object-oriented programming}} is more than welcome. Knowing AROS APIs and concepts like [[Aros/Developer/Docs/Libraries/Intuition|taglists]] and BOOPSI is essential. As Zune is a MUI clone, all the documentation pertaining to MUI is applicable to Zune. In particular, the latest available MUI developer kit and MUI autodocs can be found at [http://main.aminet.net/dev/mui/mui38dev.lha here]. In this LHA archive, 2 documents are warmly recommended: '''MUIdev.guide''', the MUI programmer documentation and '''PSI.c''' source code, demonstrating Zune practices like OOP and dynamic object creation ==Zune basics and conventions== MUI (= Zune) sticks a prefix on the start to signify what is being access/changed: * MUIA_ attribute * MUIM_ method * MUIV_ special values ==BOOPSI Primer/Concepts== ===Class=== A class is defined by its name, its parent class and a dispatcher. '''name''': either a string for the public classes, so that they may be used by any program in the system, or none if its a private class used only by a single application. '''parent class''': all BOOPSI classes are forming a hierarchy rooted at the class aptly named rootclass. It allows each subclass to implement its own version of specific parent operation, or to fall back on the one provided by its parent. Also known as base class or super class. '''dispatcher''': it gives access to all operations (called methods) provided by this class, ensuring that each operation is handled by the proper code or passed to its super class. BOOPSI type for a class is Class * also known as IClass. ===Object=== An object is an instance of class: each object has its specific data, but all objects of the same class share the same behavior. An object has several classes if we count the parents of its true class (the most derived one) up to the rootclass. BOOPSI type for an object is Object *. It has no field you can directly access. When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If the documentation says that something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. ===Attribute=== An attribute is related to the instance data of each object: you can not access these data directly, you can only set or get the attributes provided by an object to modify its internal state. An attribute is implemented as a Tag (ULONG value or'ed with TAG_USER). GetAttr() and SetAttrs() are used to modify an object's attributes. Attributes can be one or more of the following: Initialization-settable (I) : the attribute can be given as parameter at the object creation. Settable (S) : You can set this attribute at any time (or at least, not only creation). Gettable (G) : You can get the value of this attribute. ===Method=== A BOOPSI method is a function which receives as parameters an object, a class and a message: object: the object you act on class: the considered class for this object. message: contains a method ID which determines the function to call within a dispatcher, and is followed by its parameters. To send a message to an object, use DoMethod(). It will use the true class first. If the class implements this method, it will handle it. Else it will try its parent class, until the message is handled or the rootclass is reached (in this case, the unknown message is silently discarded). Summary, before a method can act on an object, it needs a BOOPSI message <pre> Function BOOPSI Method NewObject() OM_NEW DisposeObject() OM_DISPOSE SetAttrs()/SetGadgetAttrs() OM_SET GetAttr() OM_GET </pre> ==BOOPSI Examples== Let's see basic examples of this OOP framework: Getting an attribute We'll query a MUI String object for its content: <syntaxhighlight lang="c"> void f(Object *string) { IPTR result; GetAttr(string, MUIA_String_Contents, &result); printf("String content is: %s\n", (STRPTR)result); } </syntaxhighlight> Object * is the type of BOOPSI objects. IPTR must be used for the type of the result, which can be an integer or a pointer. An IPTR is always written in memory, so using a smaller type would lead to memory corruption! Here we query a MUI String object for its content: MUIA_String_Contents, as any other attribute, is a ULONG (it's a Tag) Zune applications use more often the get() and XGET() macros instead: <syntaxhighlight lang="c"> get(string, MUIA_String_Contents, &result); result = XGET(string, MUIA_String_Contents); </syntaxhighlight> Setting an attribute Let's change the content of our string: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_String_Contents, (IPTR)"hello", TAG_DONE); </syntaxhighlight> Pointers parameters must be casted to IPTR to avoid warnings. After the object parameter, a taglist is passed to SetAttrs and thus must end with TAG_DONE. You'll find the set() macro useful: <syntaxhighlight lang="c"> set(string, MUIA_String_Contents, (IPTR)"hello"); </syntaxhighlight> But it's only with SetAttrs() that you can set several attributes at once: <syntaxhighlight lang="c"> SetAttrs(string, MUIA_Disabled, TRUE, MUIA_String_Contents, (IPTR)"hmmm...", TAG_DONE); </syntaxhighlight> Calling a method Let's see the most called method in a Zune program, the event processing method called in your main loop: <syntaxhighlight lang="c"> result = DoMethod(obj, MUIM_Application_NewInput, (IPTR)&sigs); </syntaxhighlight> Parameters are not a taglist, and thus don't end with TAG_DONE. You have to cast pointers to IPTR to avoid warnings. =="Hello world" example sourcecode== [http://www.aros.org/documentation/developers/zune/images/hello.png Screenshot 'Hello World'] <syntaxhighlight lang="c"> // gcc hello.c -lmui #include <exec/types.h> #include <libraries/mui.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> int main(void) { Object *wnd, *app, *but; // GUI creation app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "Hello world!", WindowContents, VGroup, Child, TextObject, MUIA_Text_Contents, "\33cHello world!\nHow are you?", End, Child, but = SimpleButton("_Ok"), End, End, End; if (app != NULL) { ULONG sigs = 0; // Click Close gadget or hit Escape to quit DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Click the button to quit DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR)app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); // Open the window set(wnd, MUIA_Window_Open, TRUE); // Check that the window opened if (XGET(wnd, MUIA_Window_Open)) { // Main loop while((LONG)DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } } // Destroy our application and all its objects MUI_DisposeObject(app); } return 0; } </syntaxhighlight> ===Remarks/General=== We don't manually open libraries, it's done automatically for us. ===GUI creation=== We use a macro-based language to easily build our GUI. A Zune application has always 1 and only 1 Application object: : <code>app = ApplicationObject,</code> An application can have 0, 1 or more Window objects. Most often a single one: : <code>SubWindow, wnd = WindowObject,</code> Be nice, give a title to the window: : <code>MUIA_Window_Title, "Hello world!",</code> A window must have 1 and only 1 child, usually a group. This one is vertical, that means that its children will be arranged vertically: : <code>WindowContents, VGroup,</code> A group must have at least 1 child, here it's just a text: : <code> Child, TextObject,</code> Zune accepts various escape codes (here, to center the text) and newlines: : <code> MUIA_Text_Contents, "\33cHello world!\nHow are you?",</code> An End macro must match every xxxObject macro (here, TextObject): : <code>End,</code> Let's add a second child to our group, a button! With a keyboard shortcut o indicated by an underscore: : <code>Child, but = SimpleButton("_Ok"),</code> Finish the group: : <code>End,</code> Finish the window: : <code>End,</code> Finish the application: : <code>End;</code> So, who still needs a GUI builder? :-) ===Error handling=== If any of the object in the application tree can't be created, Zune destroys all the objects already created and application creation fails. If not, you have a fully working application: <syntaxhighlight lang="c"> if (app != NULL) { ...</syntaxhighlight> When you're done, just call MUI_DisposeObject() on your application object to destroy all the objects currently in the application, and free all the resources: <syntaxhighlight lang="c"> ... MUI_DisposeObject(app); }</syntaxhighlight> ===Notifications=== Notifications are the simplest way to react on events. The principle? We want to be notified when a certain attribute of a certain object is set to a certain value: : DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, Here we'll listen to the MUIA_Window_CloseRequest of our Window object and be notified whenever this attribute is set to TRUE. So what happens when a notification is triggered? A message is sent to an object, here we tell our Application to return MUIV_Application_ReturnID_Quit on the next event loop iteration: : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); As we can specify anything we want here, we have to tell the number of extra parameters we are supplying to MUIM_Notify: here, 2 parameters. For the button, we listen to its MUIA_Pressed attribute: it's set to FALSE whenever the button is being released (reacting when it's pressed is bad practice, you may want to release the mouse outside of the button to cancel your action - plus we want to see how it looks when it's pressed). The action is the same as the previous, send a message to the application: : DoMethod(but, MUIM_Notify, MUIA_Pressed, FALSE, : (IPTR)app, 2, : MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); ===Opening the window=== Windows aren't open until you ask them to: : set(wnd, MUIA_Window_Open, TRUE); If all goes well, your window should be displayed at this point. But it can fail! So don't forget to check by querying the attribute, which should be TRUE: : if (XGET(wnd, MUIA_Window_Open)) ===Main loop=== Let me introduce you my lil' friend, the ideal Zune event loop: : ULONG sigs = 0; Don't forget to initialize the signals to 0 ... The test of the loop is the MUIM_Application_NewInput method: : ... : while((LONG) DoMethod(app, MUIM_Application_NewInput, (IPTR)&sigs) : != MUIV_Application_ReturnID_Quit) It takes as input the signals of the events it has to process (result from Wait(), or 0), will modify this value to place the signals Zune is waiting for (for the next Wait()) and will return a value. This return value mechanism was historically the only way to react on events, but it was ugly and has been deprecated in favor of custom classes and object-oriented design. The body of the loop is quite empty, we only wait for signals and handle Ctrl-C to break out of the loop: <syntaxhighlight lang="c"> { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C); if (sigs & SIGBREAKF_CTRL_C) break; } } </syntaxhighlight> ===Conclusion=== This program gets you started with Zune, and allows you to toy with GUI design, but not more. ==Notification actions== Notification allows you to respond to events your application/gui or any other object might cause. Due to the attribute and method based nature of Zune, and a few special attributes, most applications can be almost completely automated through the use of Notification(s). As seen in hello.c, you use MUIM_Notify to call a method if a certain condition happens. If you want your application to react in a specific way to events, you can use one of these schemes: * Set An attribute. You can automate the passing of values from gadgets, ::etc to other gadgets. Setting values may also trigger other notification ::events. * Invoke a method, for example: ::'''MUIM_Application_ReturnID:''' you can ask your application to return an :: arbitrary ID on the next loop iteration, and check for the value in :: the loop. This is the dirty old way of doing things. :: '''MUIM_CallHook,''' to call a standard Amiga callback hook: this is an ::average choice, not object-oriented but not that ugly either. ::'''custom method:''' the method belongs to one of your custom class. It ::is the best solution as it supports object-oriented design in ::applications. It needs you to create custom classes so it may not ::the easiest for beginners or people in a hurry. ==Zune Examples/Tutorials== *some [https://arosarchives.os4depot.net/?function=showfile&file=development/example/mui_examples.i386-aros.zip c src examples] *Being an AmigaOS3.x MUI clone, all AmigaOS3.x MUI code serves as example code for using AROS Zune. *MUI example sourcecode "PSI.c", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] *[http://archive.is/20121225201004/robertnegro.wordpress.com/2012/10/30/aros-zune-programming-tutorials-for-beginners/ Good examples of Zune Main Classes] *AROS itself contains lots of Zune examples. Download AROS sources and AROS contrib sources archives, take a look at the sourcecode of Zune programs. A good starting point are the Zune test programs, maybe located in the SYS:Demos/Zune folder of AROS' binary distributions (e.g. the nightly build) - their sources can be found in the "test/Zune" folder of the AROS source archive. *[[Aros/Developer/Zune/Examples|Zune example code collection]] Some other good examples are here: *[https://github.com/emartisoft/AmigaOS3.X-MUI-Examples Examples] *[http://code.google.com/p/guidetoamigacompatibleprogramming/source/browse/#svn/trunk/english Shinkuro's] Cross-Platform Guide about compatible programming on Amiga-related platforms (Amiga, AROS, MorphOS) ==Zune Reference== *[http://aros.sourceforge.net/documentation/developers/zune-dev/index.php AROS Zune Development Manual] at [http://www.aros.org aros.org] *[http://web.archive.org/web/20110526115419/http://www.sasg.com/mui/autodocs/index.html MUI Autodocs] online at [http://www.sasg.com sasg.com] *MUI (=Zune) reference guide "MUIDev.guide", found in [http://ftp.sunet.se/pub/aminet/dev/mui/mui38dev.lha MUI3.8 developer archive] ==Tools== ===MUIBuilder=== [https://arosarchives.os4depot.net/index.php?function=browse&cat=development/guitool Mui Builder] and [http://sourceforge.net/projects/muibuilder/ sourceforge svn repository] has been started and [[Aros/Developer/ZuneFurther]] documentation can be read. v3 is W.I.P. so it is not recommended for now. Summary * added "#define MUI_OBSOLETE" to get some deprecated but needed defines * changed/added some #include * changed variable name Object to obj because Object is a type * changed the Hook for the callback function * last not least: added main.c which calls the functions to open/close the GUI. Just go ahead and create your GUIS under any version of AROS or under amiga 68k version and do some modifications (which would be necessary for MorphOS/AmigaOS3/AmigaOS4, too). ===ChocolateCastle=== The [https://arosarchives.os4depot.net/index.php?function=browse&cat=development/guitool binary] which makes creating MUI classes and applications easier. Programmers using this system often avoid writing custom classes, being discouraged by a lot of boring and schematical typing. A significant part of a typical custom class may be generated automatically. This is usually 2 to 5 kB of source code. Automating this work speeds programming up and helps avoiding simple typing errors. ==Errors== <pre> Message Solution SetAttrs() is vararg version of SetAttrsA() and expects a complete taglist so you must add TAG_DONE and not TAG_END. </pre> <pre> Message Solution </pre> <pre> Message undefined symbols ... KeyString Solution finally replaced KeyString(0,256,'f') by MUIA_CreateObject(MUIO_String,"f",256) </pre> <pre> Message undefined symbols... GetAttr Solution you need: #include <proto/intuition.h> </pre> <pre> Message Solution </pre> <pre> Message Solution #define MUI_OBSOLETE </pre> {{BookCat}} [[ru:Zune]] cjxsfems7vcqme1zfzaiyknu8kgg437 User:MikeAssad~enwikibooks 2 22682 4668927 2872605 2026-09-05T12:31:14Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668927 wikitext text/x-wiki [http://en.wikipedia.org/wiki/User:MikeAssad My user page on Wikipedia] {| cellspacing="1" cellpadding="1" style="background: #f7fff8;{{Text default color}}; border: 1px solid #88a; padding: 5px; font-size: 80%;" |- style="text-align: left;" | style="width: 88px; padding-left: 6px;" | [[Image:Wikimedia.png|65px]] | {| | style="background: #43a976;{{Text default color}}; text-align: center;" |'''Licensing rights granted to Wikimedia Foundation''' |- style="text-align: left;" | I grant non-exclusive permission for the [[Wikimedia|Wikimedia Foundation Inc.]] to relicense my text and media contributions, including any images, audio clips, or video clips, under any [[copyleft]] license that it chooses, provided it maintains the free and open spirit of the [[GFDL]]. This permission acknowledges that future licensing needs of the Wikimedia projects may need adapting in unforseen fashions to facilitate other uses, formats, and locations. It is given for as long as this banner remains. '''Note: This banner is under construction, and is subject to major changes pending [[Template talk:WikimediaMediaLicensing|discussions]]''' |} |} 6rix8rz18z9h1hmcvcenbx53bvxkdkd User:Snarius~enwikibooks 2 26811 4668994 2886505 2026-09-05T19:05:44Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668994 wikitext text/x-wiki {{wikipediapar||User:Snargle}} <span style="border:1px solid black; background-color:#ddd;{{Text default color}}; padding-right:1em"> <span style="-display:none">&dArr;</span><span style="display:none; -display:inline">V</span> read the red box <span style="-display:none">&dArr;</span><span style="display:none; -display:inline">V</span></span> {{userbox|#449944|#558855|blep|Formerly [[User:Snarius]]}} I've helped out with a few books, namely: *[[Super NES Programming]]--I'm the main contributor, check it out. *[[Down'n'dirty Blacksmithing]], total splitting, gave it some pics. *[[Knowing Knoppix]], total splitting again, some cleanup *[[Digital Photography]], Split what needs to be splat *[[The Way of the Program]], split it into smaller. barrel-sized pieces. Cleaned it up a bit, too. *[[Template:ArosNav]] made navbar (still dont want to know whar AROS is) *[[The Legend of Zelda: The Wind Waker]] split, added template (update:it's deleted as a copyvio) *[[Linux Guide]]--kinda split it *[[N64 Programming]]--uploaded/wikified And: {{MultiLicensePD}} qecnr911bxpg9dn0cb148bptqx39gnz User:Yanka ronin 2 33909 4668917 992367 2026-09-05T12:06:43Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668917 wikitext text/x-wiki {{{1|Welcome, {{PAGENAME}}!}}} {| style="background:white;{{text default color}}border:1px solid #abd5f5;; padding:0px; border-spacing:0px;" ! style="background:#d0e5f5;{{text default color}}" | [[Wikibooks:Welcome, newcomers|Getting started]] with Wikibooks |- | style="padding:5px;" | * Wikibooks is a collection of open-source textbooks. Find out [[WB:WIW|what this means]]. * To sign your name (on talk pages), use four tildes, like this: &#126;&#126;&#126;&#126; * For help in using the wiki, see the [[Help:Editing|editing guide]]. * Explore, [[Wikibooks:Be bold|be bold]], and have fun! |} Come introduce yourself at the [[WB:SLN|new users]] page. If you have any questions, you can ask there or contact me personally. ''(''<sub>Donovan</sub>|[[User:Geocachernemesis|Geocachernemesis]]|<sup>[[User_talk:Geocachernemesis|Interact]]</sup>'')'' 01:46, 16 July 2005 (UTC) isb0wq93uv0i7s92q1gpdl623ot5dg4 User:Mats.kirknes~enwikibooks 2 34202 4669003 2871435 2026-09-05T19:20:31Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669003 wikitext text/x-wiki {{{1|Welcome, {{PAGENAME}}!}}} {| style="background:white;{{text default color}}; border:1px solid #abd5f5;; padding:0px; border-spacing:0px;" ! style="background:#d0e5f5;{{text default color}};" | [[Wikibooks:Welcome, newcomers|Getting started]] with Wikibooks |- | style="padding:5px;" | * Wikibooks is a collection of open-source textbooks. Find out [[WB:WIW|what this means]]. * To sign your name (on talk pages), use four tildes, like this: &#126;&#126;&#126;&#126; * For help in using the wiki, see the [[Help:Editing|editing guide]]. * Explore, [[Wikibooks:Be bold|be bold]], and have fun! |} Come introduce yourself at the [[WB:SLN|new users]] page. If you have any questions, you can ask there or contact me personally. ''(''<sub>Donovan</sub>|[[User:Geocachernemesis|Geocachernemesis]]|<sup>[[User_talk:Geocachernemesis|Interact]]</sup>'')'' 11:57, 19 July 2005 (UTC) 6o7xq01hoqavjkxq3fkteu2tfrohzb9 User talk:Magbatz~enwikibooks 3 35169 4669051 2923041 2026-09-06T06:35:41Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669051 wikitext text/x-wiki {{{1|Welcome, {{PAGENAME}}!}}} {| style="background:white;{{text default color}}; border:1px solid #abd5f5;; padding:0px; border-spacing:0px;" ! style="background:#d0e5f5;{{text default color}};" | [[Wikibooks:Welcome, newcomers|Getting started]] with Wikibooks |- | style="padding:5px;" | * Wikibooks is a collection of open-source textbooks. Find out [[WB:WIW|what this means]]. * To sign your name (on talk pages), use four tildes, like this: &#126;&#126;&#126;&#126; * For help in using the wiki, see the [[Help:Editing|editing guide]]. * Explore, [[Wikibooks:Be bold|be bold]], and have fun! |} Come introduce yourself at the [[WB:SLN|new users]] page. If you have any questions, you can ask there or contact me personally. Thanks for helping to fight vandalism on Wikibooks. We need more people like you, your contribution is greatly appreciated.:) ''(''<sub>Donovan</sub>|[[User:Geocachernemesis|Geocachernemesis]]|<sup>[[User_talk:Geocachernemesis|Interact]]</sup>'')'' 02:57, 29 July 2005 (UTC) == Your account will be renamed == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> Hello, The developer team at Wikimedia is making some changes to how accounts work, as part of our on-going efforts to provide new and better tools for our users like cross-wiki notifications. These changes will mean you have the same account name everywhere. This will let us give you new features that will help you edit and discuss better, and allow more flexible user permissions for tools. One of the side-effects of this is that user accounts will now have to be unique across all 900 Wikimedia wikis. See [[m:Special:MyLanguage/Single User Login finalisation announcement|the announcement]] for more information. Unfortunately, your account clashes with another account also called Magbatz. To make sure that both of you can use all Wikimedia projects in future, we have reserved the name Magbatz~enwikibooks that only you will have. If you like it, you don't have to do anything. If you do not like it, you can [[Special:GlobalRenameRequest|pick out a different name]]. Your account will still work as before, and you will be credited for all your edits made so far, but you will have to use the new account name when you log in. Sorry for the inconvenience. Yours,<br />[[m:User:Keegan (WMF)|Keegan Peterzell]]<br />Community Liaison, Wikimedia Foundation </div> 23:24, 17 March 2015 (UTC) <!-- SUL finalisation notification --> == Renamed == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> This account has been renamed as part of [[m:Special:MyLanguage/Single User Login finalisation announcement|single-user login finalisation]]. If you own this account you can [[{{#special:userlogin}}|log in using your previous username and password]] for more information. If you do not like this account's new name, you can choose your own using this form after logging in: [[{{#special:GlobalRenameRequest}}]]. -- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) </div> 05:13, 19 April 2015 (UTC) <!-- SUL post-rename notification --> 2xfdcmsbbrutloqdn0iv96q75q9jnxr User:Xerol 2 45931 4668988 1891592 2026-09-05T19:00:24Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668988 wikitext text/x-wiki ==Notices and other stuff== <div style="margin: 10px; background-color: #EEFFEE;{{Text default color}}; border: 1px solid #807070; padding: 5px;">Somewhat active again, see Projects below for where I'll be working.</div> ==Useful Links== Mostly for my use, but also because some of these are hard to find: *[[Wikibooks:Vandalism in progress]] *[[Wikibooks:Deletion_policy]] ==Contact Me== *AIM: XerolOplan *ICQ: 125672905 *MSN: xeroloplan@hotmail.com *Yahoo: xerol3 *My [[w:User:Xerol|Wikipedia userpage]]. Even when I'm inactive I still read wikipedia so if you post on my talk page, I'll get the notice. I'm also on the Wikibooks IRC channel most of the time. ==Projects== *[[User:Xerol/TemplateSandbox|Template Sandbox]] ===Diagrams and Illustrations=== I'll be making nice vector diagrams whereever helpful, probably putting them up on [[commons:User:Xerol|commons]]. ===My Cleanup Tasks=== See [[User:Xerol/Cleanup]]. ===Templates=== ====General Template Cleanup==== *{{Tlx|AttentionTemplate}} *{{Tlx|AttentionTemplateDoc}} ====SoftwareVersion templates and Manual of Style==== Working on templates for use in the SoftwareVersions project. ==Miscellaneous== Feel free to comment in each section; feedback is always appreciated, especially if I'm wrong. q1j83iwg38l7td3gmks6ll2ppef5f21 User:Kalden~enwikibooks 2 62807 4669000 2865823 2026-09-05T19:16:13Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669000 wikitext text/x-wiki <div class="plainlinks" style="font-size:90%; background-color:#FFFFFF;{{text default color}}; text-align:center; border-bottom: 2px solid #D8DAE7; border-top: 2px solid #D8DAE7;"> [http://fr.wikipedia.org/wiki/Utilisateur:Kalden fr.wikipédia.org] - [http://fr.wikibooks.org/wiki/Utilisateur:Kalden fr.wikibooks.org] - [http://en.wikibooks.org/wiki/Utilisateur:Kalden en.wikibooks.org] - [http://oss.wikicities.com/wiki/User:Kalden wikicities.org] - [http://timebreach.free.fr/userinfo.php?uid=1 timebreach.sourceforge.net] </div> <br clear="all" /> == Presentation == I'm student in computer science at [[w:École supérieure d'informatique|École supérieure d'informatique]], after i was in [[w:iut de montpellier|iut de montpellier]]. I like [[w:linux|linux]]. I use[[w:gentoo|gentoo]] and [[w:suse|suse]]. I've create [[Time Breach]]. If you have some discussion use my page. thanks. hwbe917rmmkd05ujpsvyjmvrb0ayka4 User:Karl Wick/Test/Test 2 2 66072 4669007 402086 2026-09-05T19:22:40Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669007 wikitext text/x-wiki <div class="noprint" style="border:1px solid gold; background:cornsilk;{{text default color}}; padding: 4px; text-align: center; float: right;"><small> ''On WP:'' <br> [[w:Octet rule|Octet rule]] </small></div> If the article can be illustrated with pictures, find an appropriate place to position these images and get them from [[w:Wikimedia Commons|Wikimedia Commons]]. For more information, see [[Wikipedia:Picture tutorial]] and [[Wikipedia:Images]] left float, with caption: <div class="floatleft">[[Image:NAME|Alt text]]<br>Caption</div> <br> <br> <br> <br> [[Wikipedia:Extended image syntax]] qldcwqrehzjqrh3d1dbgucm41ewbcu1 User:Rotemliss 2 90227 4668924 1554927 2026-09-05T12:23:39Z ShakespeareFan00 46022 4668924 wikitext text/x-wiki {{userboxtop}} {{user language|he|N}} {{user language|en|3}} {{user language|ar|1}} {{userboxbottom}} [[Image:Wikistress3D 1 v3.jpg|left|150px]] I signed up to Wikibooks on 19 August 2006. {{Userpage}} == User map in Wikimedia Foundation == {| class="toccolours" style="clear: both; direction: ltr; text-align: center; width: 100%;" |- ! Multilingual | colspan="6" | {| style="background-color: transparent; color:inherit; width: 100%;" | [[Image:Commons-logo.svg|30px|Commons]] [[commons:User:Rotemliss|Commons]] | [[Image:Wikimedia Community Logo.svg|30px|Meta]] [[m:User:Rotemliss|Meta]] | [[Image:Mediawiki-logo.png|30px|MediaWiki]] [[mw:User:Rotemliss|MediaWiki]] | [[Image:Wikispecies-logo.svg|30px|Wikispecies]] [[wikispecies:User:Rotemliss|Wikispecies]] |} |- ! English (en) | [[Image:Wikipedia-logo-en.png|30px|Wikipedia]] [[w:en:User:Rotemliss|Wikipedia]] | [[Image:Wiktionary-logo-en.png|30px|Wiktionary]] [[wikt:en:User:Rotemliss|Wiktionary]] | [[Image:Wikiquote-logo-en.png|30px|Wikiquote]] [[q:en:User:Rotemliss|Wikiquote]] | [[Image:Wikibooks-logo-en.png|30px|Wikibooks]] '''Wikibooks''' | | |- ! Français (fr) | [[Image:Wikipedia-logo-fr.png|30px|Wikipédia]] [[w:fr:Utilisateur:Rotemliss|Wikipédia]] | | | | | |- ! עברית (he) | [[Image:Wikipedia-logo-he.png|30px|ויקיפדיה]] [[w:he:משתמש:Rotemliss|ויקיפדיה]] (sysop) | [[Image:Wiktionary-logo-he.png|30px|ויקימילון]] [[wikt:he:משתמש:Rotemliss|ויקימילון]] | [[Image:Wikiquote-logo-he.png|30px|ויקיציטוט]] [[q:he:משתמש:Rotemliss|ויקיציטוט]] (sysop) | [[Image:Wikibooks-logo-he.png|30px|ויקיספר]] [[:he:משתמש:Rotemliss|ויקיספר]] (sysop, bureaucrat) | [[Image:Wikisource-logo-he.png|30px|ויקיטקסט]] [[s:he:משתמש:Rotemliss|ויקיטקסט]] (sysop) | [[Image:Wikinews-logo-he.png|30px|ויקיחדשות]] [[n:he:משתמש:Rotemliss|ויקיחדשות]] (sysop) |- ! ייִדיש (yi) | [[Image:Wikipedia-logo-yi.png|30px|װיקיפּעדיע]] [[w:yi:באַניצער:Rotemliss|װיקיפּעדיע]] | | | | | |} [[he:משתמש:Rotemliss]] d09zz4ss46bgkt2tthf0cmmfzliu5kt User:Amrykid 2 96088 4669001 605496 2026-09-05T19:16:41Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669001 wikitext text/x-wiki ==Userboxes== <div style="float: left; border:solid red 1px; margin: 1px;"> {| cellspacing="0" style="width: 238px; background: blue;{{text default color}};" | style="width: 45px; height: 45px; background: red;{{text default color}};text-align: center; font-size: 14pt;" | '''[[User:Amrykid|Amrykid]]''' | style="font-size: 8pt; padding: 4pt; line-height: 1.25em;" | this user has a account on wikipedia |} </div> ==Links== *[http://www.Wikipedia.org/wiki/User:Amrykid Wikipedia Account] *[http://en.Wikiversity.org/wiki/User:Amrykid Wikiversity Account] ==Books== ld7yaobv81zm3w0eufmby0fmzaepi9z 4669002 4669001 2026-09-05T19:20:01Z ShakespeareFan00 46022 4669002 wikitext text/x-wiki ==Userboxes== <div style="float: left; border:solid red 1px; margin: 1px;"> {| cellspacing="0" style="width: 238px; background: blue;color:white;" | style="width: 45px; height: 45px; background: red;{{text default color}};text-align: center; font-size: 14pt;" | '''[[User:Amrykid|Amrykid]]''' | style="font-size: 8pt; padding: 4pt; line-height: 1.25em;" | this user has a account on wikipedia |} </div> ==Links== *[http://www.Wikipedia.org/wiki/User:Amrykid Wikipedia Account] *[http://en.Wikiversity.org/wiki/User:Amrykid Wikiversity Account] ==Books== sktyro84t6uhbkszksfgw9tgvsqfshx User:SBJohnny/Unused Redirect 2 97098 4669016 1662856 2026-09-05T19:31:22Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669016 wikitext text/x-wiki {| style="width:80%;border:solid #999 1px;background:#F8F8F8;{{Text default color}};margin:0.5em auto;clear:all" | style="width: 52px; text-align: center;" | [[Image:Warning_icon.png|Warning]] | style="vertical-align: middle;" | This redirect '''will''' be deleted very soon. Please begin updating your bookmarks and webpages.<br/>The new location of this book or module is [[{{{1}}}]] |} <!-- time dependent inclusion of page into candidates for speedy deletion, until then categorize it in Unused Redirects --> <includeonly> {{#ifexpr:({{CURRENTMONTH}} >= {{REVISIONMONTH}}+1 or {{CURRENTYEAR}} > {{REVISIONYEAR}}) and {{CURRENTDAY}} >= {{REVISIONDAY}}| [[Category:Candidates for speedy deletion]]|[[Category:Unused Redirects/{{#switch:"{{REVISIONMONTH}}" | "01" = January | "02" = Febrary | "03" = March | "04" = April | "05" = May | "06" = June | "07" = July | "08" = August | "09" = September | "10" = October | "11" = November | "12" = December }} {{REVISIONYEAR}}]]}}</includeonly><noinclude> This template marks a page as being an archived redirect, which will be maintained for a period of time in case external sites are linked to this page. *'''''Always''''' use the form <nowiki>{{Unused Redirect|NEWPAGENAME}}</nowiki> *Make sure to blank the page when adding this tag (including the redirect... this template will provide the redirect). *Please do not subst. ''This adds page to [[:Category:Candidates for speedy deletion]] after a month'' == See Also == *{{tl1|rfd|reason}} *{{tl|Impending Doom}} </noinclude> 083uebx3mw1wg6oq7brrtdclzbderke User:Herraotic/Intermediate Mathematics 2 107587 4668996 718559 2026-09-05T19:10:39Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668996 wikitext text/x-wiki ===Welcome to '''Intermediate Mathematics'''=== The objective of this book is to provide a thorough explanation of intermediate mathematics also referred to as GCSE Higher Mathematics, though it could also be used for any other course with similar requirements. This book is currently not based on a specification as we are attempting to cover all topics, from all perspectives. {| style="background-color: transparent;color:inherit;" | colspan="3" | [[/Introduction/]] · [[/About/]] · [[/Q&A|Ask a question!]] |- | style="vertical-align:top; width:25%" | ; Module 1 - Part 1 * Estimation * Multiplying & dividing with decimals * Exact calculations * Summary about numbers * Factors & multiples * Prime numbers * Tests of divisibility * Prime factorisation * HCF & LCM * Rules of indices | style="vertical-align:top; width:25%" | ; Module 2 - Part 1 * ... * ... | style="vertical-align:top; width:25%" | ; Module 3 - Part 1 * ... * ... | style="vertical-align:top; width:25%" | ; Module 4 - Part 1 * ... * ... |- | style="vertical-align:top; width:25%" | ; Module 1 - Part 2 * ... * ... | style="vertical-align:top; width:25%"| ; Module 2 - Part 2 * ... * ... | style="vertical-align:top; width:25%" | ; Module 3 - Part 2 * ... * ... | style="vertical-align:top; width:25%" | ; Module 4 - Part 2 * ... * ... |} mm5hpskgptq8xa6nbs2flkh3wl6qkq5 User:Kijog/sandbox2 2 109288 4669019 4622029 2026-09-05T20:10:59Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669019 wikitext text/x-wiki {| style="text-align: center; background: #ffffff;{{Text default color}}; border: solid 10px #D3D3D3" rules="all" ! style="background-color: #D3D3D3;{{Text default color}};text-align: center" colspan="3"| The Colours [[Image:Flag of Wales (1959).svg|20px]] Yr Lliwiau |- ! Saesneg ! ! Cymraeg |- | Red | style="background-color:red;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Coch |- | Orange | style="background-color:orange;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Oren |- | Yellow | style="background-color:yellow;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Melyn |- | Green | style="background-color:green;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Gwyrdd |- | Blue | style="background-color:blue;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Glas |- | Purple | style="background-color:purple;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Glasgoch |- | Brown | style="background-color:brown;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Brown |- | Pink | style="background-color:pink;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Pinc |- | White | style="background-color:white;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Gwyn |- | Grey | style="background-color:gray;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Llwyd |- | Black | style="background-color:black;{{Text default color}};" | &nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | Du |} {{Infobox Language |name=Welsh |nativename=Cymraeg |familycolor=Indo-European |pronunciation=[kəmˈrɑːɨɡ] |states=[[United Kingdom]], [[Argentina]], [[United States]], [[Canada]], [[Australia]], [[New Zealand]] |region=[[Wales]], [[Chubut]] |speakers=700,000+:<br>— Wales: 611,000<ref>http://www.bwrdd-yr-iaith.org.uk/cynnwys.php?pID=109&nID=2122&langID=2</ref><br>— [[England]]: 133,000<ref>http://www.ibiblio.org/pub/archives/welsh-l/welsh-l/1993/Mar/More-Welsh-Speakers</ref><br>— [[Chubut Province|Chubut]], [[Argentina]]: 5,000<ref>http://www.bbc.co.uk/dna/h2g2/A1163503</ref><br>— [[Canada]]: 3,160<ref>http://www.ethnologue.com/show_country.asp?name=CA</ref><br>— [[United States|USA]]: 2,655<ref>http://www.usenglish.org/foundation/research/lia/languages_of_the_usa.pdf</ref> |fam2=[[Celtic languages|Celtic]] |fam3=[[Insular Celtic languages|Insular Celtic]] |fam4=[[Brythonic languages|Brythonic]] |nation=[[Wales]] |script=[[Latin alphabet]] ([[Welsh alphabet|Welsh variant]]) |map=[[Image:Siaradwyr y Gymraeg ym Mhrif Ardaloedd Cymru.png|center|thumb|300px|Percentage of Welsh speakers by [[Subdivisions of Wales|principal area]]]] |iso1=cy |iso2b=wel|iso2t=cym |iso3=cym}} '''Welsh''' (''{{lang|cy|Cymraeg}}'' or ''{{lang|cy|y Gymraeg}}'', [[International Phonetic Alphabet|pronounced]] {{IPA|[kəmˈrɑːɨɡ]}}, {{IPA|[ə ɡəmˈrɑːɨɡ]}}), is a member of the [[Brythonic]] branch of [[Celtic languages|Celtic]] spoken natively in [[Wales]] (''Cymru''), in [[England]] by some along the Welsh border, and in the [[Welsh settlement in Argentina|Welsh immigrant colony]] in the [[Chubut Valley]], in [[Argentina|Argentine]] [[Patagonia]]. There are also speakers of Welsh throughout the world, most notably in the rest of [[Great Britain]], the [[United States]], [[Canada]] and [[Australia]]. Due to the increasing use of the [[English language]] the numbers of Welsh speakers had been declining for decades. However, following a number of measures, including the introduction of the [[Welsh Language Act 1993]], Welsh has enjoyed a strong revival in recent years and has an equal status with English in the public sector in Wales. It is the most spoken Celtic language. See [[Welsh English]] for the [[English language]] as spoken in Wales. ==Status== [[image:wales.cardiff.slow.arp.750pix.jpg|thumb|left|Bilingual road markings in Wales]] The 2004 Welsh Language Use Survey shows 21.7% of the population of Wales are Welsh speakers. This is an increase from 20.5% in the [[Census 2001|2001 census]], and from 18.5% in 1991. The 2001 census also shows that about 25% of Welsh residents were born outside Wales. The number of Welsh speakers in the rest of Britain is unknown. In [[1993]], [[S4C]], the Welsh-language TV channel published the results of a survey into the numbers of people who speak or understand Welsh, and this estimated that there were some 133,000 Welsh-speakers living in [[England]], about 50,000 of them in the [[Greater London]] area and border towns and villages in the Welsh Marches such as [[Oswestry]]. <ref>[http://www.ibiblio.org/pub/archives/welsh-l/welsh-l/1993/Mar/More-Welsh-Speakers Summary of 1993 S4C survey]</ref> Historically, large numbers of Welsh people spoke only Welsh, but [[monoglot]] Welsh speakers are now virtually non-existent. Almost without exception, Welsh speakers also speak English (or, among those in [[Chubut Province]], [[Spanish language|Spanish]]). However, a large number of Welsh speakers are more comfortable expressing themselves in Welsh than in English. A speaker's choice of language can vary according to the subject domain and the social context (known in linguistics as [[code-switching]]). Although Welsh is a minority language, support for the language grew during the second half of the [[20th century]], along with the rise of organisations such as the [[Welsh nationalism|nationalist]] political party [[Plaid Cymru]] and the Welsh Language Society, [[Cymdeithas yr Iaith Gymraeg]]. Welsh as a first language is largely concentrated in the less urban north and west of Wales, principally [[Gwynedd]], [[Denbighshire]] (''{{lang|cy|Sir Ddinbych}}''), [[Anglesey]] (''{{lang|cy|Ynys Môn}}''), [[Carmarthenshire]] (''{{lang|cy|Sir Gaerfyrddin}}''), north [[Pembrokeshire]] (''{{lang|cy|Sir Benfro}}''), [[Ceredigion]], parts of west [[Glamorgan]] (''{{lang|cy|Morgannwg}}''), north-west and extreme south-west [[Powys]], although first-language and other fluent speakers can be found throughout Wales. [[Image:Callaghan_Square_sign_Cardiff_Caerdydd_200507.jpg|thumb|Bilingual road sign in [[Cardiff]].]] Welsh is a [[living language]], used in conversation by thousands and seen throughout Wales. The [[Welsh Language Act 1993]] and the [[Government of Wales Act 1998]] provide that the Welsh and English languages should be treated equally. Public bodies are required to prepare and implement a Welsh Language Scheme. Local councils and the [[Welsh Assembly]] use Welsh as an official language, issuing official literature and publicity in Welsh versions (e.g. letters to parents from schools, library information, and council information) and all road signs in Wales should be in English and Welsh, including the Welsh versions of place names. The teaching of Welsh is now compulsory in all schools in Wales up to age 16, and this has had a major effect in stabilising and to some extent reversing the decline in the language. It means, for example, that even the children of English monoglot migrants to Wales grow up with a knowledge of the language. However, the vast majority of people in the main population centres of South Wales do not use the language in daily life. The UK government has ratified the [[European Charter for Regional or Minority Languages]] in respect to Welsh. The language has greatly increased its prominence since the creation of the television channel [[S4C]] in November [[1982]], which broadcasts exclusively in Welsh during peak viewing hours. The main evening television news provided by the [[BBC]] in Welsh is [http://www.bbc.co.uk/cymru/live/newyddion.ram available for download] (Real Media). Since December [[2001]] the British Government has planned to ensure that all immigrants know [[English language|English]]. It remains to be seen if Welsh will be considered a separate case. At present, a knowledge of either Welsh, English or [[Scottish Gaelic]] is sufficient for [[naturalisation]] purposes and it is believed that this policy will be continued in any proposed changes to the law. ==History== {| border="0" cellpadding="5" <!--margin="1"--> style="text-align:right;background-color:#ffffd9;{{Text default color}};margin-left:10px" |style="background-color:#ffffd9;{{Text default color}};"|<timeline> ImageSize = width:240 height:700 PlotArea = right:40 top:10 left:40 bottom:10 DateFormat = yyyy TimeAxis = orientation:vertical order:reverse Period = from:500 till:2006 AlignBars = early ScaleMajor = unit:year increment:200 start:500 Colors = id:canvas value:rgb(1,1,0.85) BackgroundColors = canvas:canvas PlotData = width:15 color:blue bar:test from:500 till:800 shift:(10,0) text:Early Welsh PlotData = width:15 color:black bar:test from:800 till:1050 shift:(10,0) text:[[Old Welsh language|Old Welsh]] PlotData = width:15 color:white bar:test from:1050 till:1250 shift:(10,0) text:[[Middle Welsh language|Middle Welsh]] PlotData = width:15 color:red bar:test from:1250 till:1588 shift:(10,0) text:Early Modern Welsh PlotData = width:15 color:green bar:test from:1588 till:2006 shift:(10,0) text:Late Modern Welsh PlotData = bar:test at:1588 mark:(line,white) at:1588 shift:(10,0) text:1588 William Morgan's Welsh~Bible published bar:test at:1993 mark:(line,white) at:1983 shift:(10,0) text:1993 Welsh Language Act bar:test at:2001 mark:(line,white) at:2006 shift:(10,0) text:2001 Number of speakers increase~in the national Census </timeline> |} Like most languages, there are identifiable periods within the history of Welsh, although the boundaries between these are often indistinct. ===Old Welsh=== The earliest extant sources of a language identifiable as Welsh go back to about the 6th century, and the language of this period is known as ''Early Welsh''. Very little of this language remains. The next main period, somewhat better attested, is [[Old Welsh language|Old Welsh]] (''{{lang|cy|Hen Gymraeg}}'') ([[9th century|9th]] to [[11th century|11th]] centuries); [[poetry]] from both Wales and [[Scotland]] has been preserved in this form of the language. As [[Anglo-Saxons|Germanic]] and [[Gaels|Gaelic]] colonisation of Great Britain proceeded, the Brythonic speakers in Wales were split off from those in northern England, speaking [[Cumbrian language|Cumbrian]], and those in the south-west, speaking what would become [[Cornish language|Cornish]], and so the languages diverged. Both ''Canu Aneirin'' and ''Canu Taliesin'' were in this era. ===Middle Welsh=== ''[[Middle Welsh language|Middle Welsh]]'' (or ''{{lang|cy|Cymraeg Canol}}'') is the label attached to the Welsh of the [[12th century|12th]] to [[14th century|14th]] centuries, of which much more remains than for any earlier period. This is the language of nearly all surviving early manuscripts of the ''[[Mabinogion]]'', although the tales themselves are certainly much older. It is also the language of the existing [[Welsh law]] manuscripts. Middle Welsh is reasonably intelligible, albeit with some work, to a modern-day Welsh speaker. ===Modern Welsh=== Modern Welsh can be divided into two periods. The first, ''Early Modern Welsh'' ran from the [[14th century]] to roughly the end of the [[16th century]] and was the language used by [[Dafydd ap Gwilym]]. ====Late Modern Welsh==== ''Late Modern Welsh'' began with the publication of [[William Morgan (Bible translator)|William Morgan]]'s [[Welsh Bible|translation of the Bible]] in [[1588]]. Like its English counterpart, the [[King James Version of the Bible|King James Version]], this proved to have a strong stabilising effect on the language, and indeed the language today still bears the same ''Late Modern'' label as Morgan's language. Of course, many minor changes have occurred since then. ====19th century==== The language enjoyed a further boost in the [[19th century]], with the publication of some of the first complete and concise Welsh [[dictionary|dictionaries]]. Early work by Welsh [[lexicography|lexicographic]] pioneers such as [[Daniel Silvan Evans]] ensured that the language was documented as accurately as possible, and modern dictionaries such as the ''{{lang|cy|[[Geiriadur Prifysgol Cymru]]}}'' (the [[University of Wales]] Dictionary), are direct descendants of these dictionaries. However, the influx of English workers during the [[Industrial Revolution]] in Wales from about [[1800]] led to a substantial dilution of the Welsh-speaking population of Wales. English migrants seldom learnt Welsh and their Welsh colleagues tended to speak English in mixed Welsh–English contexts, and bilingualism became almost universal. The legal status of Welsh was inferior to that of English, and so English gradually came to prevail, except in the most rural areas, particularly in north west and mid Wales. An important exception, however, was in the [[non-conformist]] churches, which were strongly associated with the Welsh language. ====20th and 21st centuries==== By the twentieth century, the numbers of Welsh speakers were shrinking at a rate which suggested that it would be extinct within a few generations. The 10-yearly [[census]] first started to ask language questions in [[1891]], by which time 54% of the population still spoke Welsh. The percentage fell with every subsequent census, until reaching an all-time low in [[1981]] (19%). In [[1991]] the position was stable (19% as in 1981) and in the most recent census, [[as of 2001|2001]], it has risen to 21% able to speak Welsh. The [[Census 2001|2001 census]] also recorded that 20% could read Welsh, 18% could write Welsh, and 24% could understand Welsh. Furthermore, the highest proportion of Welsh speakers was among young people, which bodes well for the future of Welsh. In 2001, 39% of children aged 10 to 15 were able to speak, read and write Welsh (many of them having learned it in school), compared with 25% of 16 to 19 year olds. However, the percentage of Welsh speakers in areas where Welsh is spoken by the majority is still in decline. It seems that the rise of [[Welsh nationalism]] rallied supporters of the language, and the establishment of Welsh television and radio found a mass audience which was encouraged in the retention of its Welsh. Perhaps most important of all, at the end of the twentieth century it became compulsory for all school children to learn Welsh up to age 16, and this both reinforced the language in Welsh-speaking areas and reintroduced at least an elementary knowledge of it in areas which had become more or less wholly Anglophone. The decline in the percentage of people in Wales who can speak Welsh has now been halted, and there are even signs of a modest recovery. However, although Welsh is the daily language in many parts of Wales, English is almost universally understood. ==Orthography== {{main|Welsh alphabet}} Welsh is written in a version of the [[Latin alphabet]] consisting of 28 letters, of which eight are [[digraph (orthography)|digraph]]s treated as single letters for [[collation]]: : a, b, c, ch, d, dd, e, f, ff, g, ng, h, i, l, ll, m, n, o, p, ph, r, rh, s, t, th, u, w, y The letters ''j'' and ''v'', although not originally used to write Welsh, have been borrowed from the [[English alphabet]], and are most commonly used only within names, although there are a few exceptions. The most common [[diacritic]] is the [[circumflex]], which is used in some cases to mark a [[vowel length|long vowel]]. ==Grammar== ===Phonology=== ====Consonants==== Welsh has the following [[consonant]] [[phoneme]]s: {| class="wikitable" |- style="background: #efefef;{{Text default color}};" | &nbsp; ! scope="col" | [[bilabial consonant|Bilabial]] ! scope="col" | [[labiodental consonant|Labiodental]] ! scope="col" | [[labiovelar consonant|Labiovelar]] ! scope="col" | [[dental consonant|Dental]] ! scope="col" | [[alveolar consonant|Alveolar]] ! scope="col" | Alveolar<br />[[lateral consonant|lateral]] ! scope="col" | [[postalveolar consonant|Postalveolar]] ! scope="col" | [[palatal consonant|Palatal]] ! scope="col" | [[velar consonant|Velar]] ! scope="col" | [[glottal consonant|Glottal]] |- ! scope="row" style="background: #efefef;{{Text default color}};" | '''[[plosive consonant|Plosive]]''' | style="text-align:center;" | {{IPA|p&nbsp;&nbsp;b}} | &nbsp; | &nbsp; | &nbsp; | style="text-align:center;" | {{IPA|t&nbsp;&nbsp;d}} | &nbsp; | &nbsp; | &nbsp; | style="text-align:center;" | {{IPA|k&nbsp;&nbsp;g}} | &nbsp; |- ! scope="row" style="background: #efefef;{{Text default color}};" | '''[[affricate consonant|Affricate]]''' | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; | style="text-align:center;" | {{IPA|(tʃ)&nbsp;&nbsp;(dʒ)}} | &nbsp; | &nbsp; | &nbsp; |- ! scope="row" style="background: #efefef;{{Text default color}};" | '''[[nasal consonant|Nasal]]''' | style="text-align:center;" | {{IPA|(m̥)&nbsp;&nbsp;m}} | &nbsp; | &nbsp; | &nbsp; | style="text-align:center;" | {{IPA|(n̥)&nbsp;&nbsp;n}} | &nbsp; | &nbsp; | &nbsp; | style="text-align:center;" | {{IPA|(ŋ̊)&nbsp;&nbsp;ŋ}} | &nbsp; |- ! scope="row" style="background: #efefef;{{Text default color}};" | '''[[fricative consonant|Fricative]]''' | &nbsp; | style="text-align:center;" | {{IPA|f&nbsp;&nbsp;v}} | &nbsp; | style="text-align:center;" | {{IPA|θ&nbsp;&nbsp;ð}} | style="text-align:center;" | {{IPA|s&nbsp;&nbsp;(z) }} | style="text-align:center;" | {{IPA|ɬ}} | style="text-align:center;" | {{IPA|ʃ}} | &nbsp; | style="text-align:center;" | {{IPA|x}} | style="text-align:center;" | {{IPA|h}} |- ! scope="row" style="background: #efefef;{{Text default color}};" | '''[[Trill consonant|Trill]]''' | &nbsp; | &nbsp; | &nbsp; | &nbsp; | style="text-align:center;" | {{IPA|r̥&nbsp;&nbsp;r}} | &nbsp; | &nbsp; | &nbsp; | &nbsp; | &nbsp; |- ! scope="row" style="background: #efefef;{{Text default color}};" | '''[[Approximant]]''' | &nbsp; | &nbsp; | style="text-align:center;" | {{IPA|w}} | &nbsp; | &nbsp; | style="text-align:center;" | {{IPA|l}} | &nbsp; | style="text-align:center;" | {{IPA|j}} | &nbsp; | &nbsp; |} {{IPA|/z/}} occurs only in unassimilated [[loanword]]s. {{IPA|/tʃ/}} and {{IPA|/dʒ/}} occur mainly in loanwords, but also in some dialects as developments from {{IPA|/tj/}} and {{IPA|/dj/}}; the [[voiceless consonant|voiceless]] [[nasal consonant|nasals]] {{IPA|/m̥/}}, {{IPA|/n̥/}}, {{IPA|/ŋ̊/}} occur only as a consequence of [[Welsh morphology#Initial consonant mutation|nasal mutation]]. ====Vowels==== [[Image:Welsh vowel chart.svg|thumb|300px|A chart plotting the vowel [[formant]]s of a Welsh speaker from [[Bangor, Wales|Bangor]].]] {|class="wikitable" ! [[Monophthong]]s ! [[Front vowel|Front]] ! [[Central vowel|Central]] ! [[Back vowel|Back]] |- | '''[[Close vowel|Close]]''' | style="text-align:center;" | {{IPA|iː}} | style="text-align:center;" | {{IPA|ɨː}} | style="text-align:center;" | {{IPA|uː}} |- | '''[[Near-close vowel|Near-close]]''' | style="text-align:center;" | {{IPA|ɪ}} | style="text-align:center;" | {{IPA|ɨ̞}} | style="text-align:center;" | {{IPA|ʊ}} |- | '''[[Close mid vowel|Close mid]]''' | style="text-align:center;" | {{IPA|eː}} | rowspan=2 style="text-align:center;" | {{IPA|ə}} | style="text-align:center;" | {{IPA|oː}} |- | '''[[Open mid vowel|Open mid]]''' | style="text-align:center;" | {{IPA|ɛ}} | style="text-align:center;" | {{IPA|ɔ}} |- | '''[[Open vowel|Open]]''' | style="text-align:center;" | {{IPA|a}} | &nbsp; | style="text-align:center;" | {{IPA|ɑː}} |} The vowels {{IPA|/ɨ̞/}} and {{IPA|/ɨː/}} occur only in Northern dialects; in Southern dialects they are replaced by {{IPA|/ɪ/}} and {{IPA|/iː/}} respectively. In Southern dialects, the contrast between long and short vowels is found in stressed [[syllable]]s only; in Northern dialects, the contrast is found only in stressed ''word-final'' syllables (including monosyllabic words). The vowel {{IPA|/ə/}} does not occur in the final syllable of words (except a few monosyllables). {|class="wikitable" ! [[Diphthong]]s ! Second component<br />is front ! Second component<br />is central ! Second component<br />is back |- | '''First component is close''' | &nbsp; | style="text-align:center;" | {{IPA|ʊɨ}} | style="text-align:center;" | {{IPA|ɪu, ɨu}} |- | '''First component is mid''' | style="text-align:center;" | {{IPA|əi, ɔi}} | style="text-align:center;" | {{IPA|əɨ, ɔɨ}} | style="text-align:center;" | {{IPA|ɛu, əu}} |- | '''First component is open''' | style="text-align:center;" | {{IPA|ai}} | style="text-align:center;" | {{IPA|aɨ, ɑːɨ}} | style="text-align:center;" | {{IPA|au}} |} The diphthongs containing {{IPA|/ɨ/}} occur only in Northern dialects; in Southern dialects {{IPA|/ʊɨ/}} is replaced by {{IPA|/ʊi/}}, {{IPA|/ɨu, əɨ, ɔɨ/}} are merged with {{IPA|/ɪu, əi, ɔi/}}, and {{IPA|/aɨ, ɑːɨ/}} are merged with {{IPA|/ai/}}. ====Stress==== [[Stress (linguistics)|Stress]] in polysyllabic words occurs most commonly on the [[wikt:penultimate|penultimate]] [[syllable]], more rarely on the final syllable. The positioning of the stress means that related words or concepts (or even [[plural]]s) can sound quite different, as syllables are added to the end of a word and the stress moves correspondingly, e.g.: : ''{{lang|cy|ysgrif}}'' — {{IPA|/ˈəsgriv/}} — an article or essay : ''{{lang|cy|ysgrifen}}'' — {{IPA|/əsˈgriven/}} — writing : ''{{lang|cy|ysgrifennydd}}'' — {{IPA|/əsgriˈvenɨð/}} — a secretary : ''{{lang|cy|ysgrifenyddes}}'' — {{IPA|/əsgriveˈnəðes/}} — a female secretary (Note also how adding a syllable to ''{{lang|cy|ysgrifennydd}}'' to form ''{{lang|cy|ysgrifenyddes}}'' changes the pronunciation of the second "y". This is because the pronunciation of "y" depends on whether or not it is in the final syllable.) The connection between the Welsh word ''{{lang|cy|ysgrif}}'' and the [[Latin language|Latin]] ''{{lang|la|scribo}}'' "I write", from which it is derived, is fairly clear, taking [[Historical linguistics|diachronic sound shifts]] into account. ===Morphology=== {{main|Welsh morphology}} Welsh [[morphology (linguistics)|morphology]] has much in common with that of the other modern [[Insular Celtic languages]], such as the use of initial [[consonant mutation]]s, and the use of so-called "conjugated prepositions" ([[preposition]]s that fuse with the personal [[pronoun]]s that are their [[object (grammar)|object]]). Welsh [[noun]]s belong to one of two [[grammatical gender]]s, masculine and feminine, but are not inflected for [[declension|case]]. Welsh has a variety of different endings to indicate the [[plural]], and two endings to indicate the [[grammatical number|singular]] of some nouns. In spoken Welsh, [[verb]] inflection is indicated primarily by the use of [[auxiliary verb]]s, rather than by the inflection of the main verb. In literary Welsh, on the other hand, inflection of the main verb is usual. === Other features of Welsh grammar === ====Possessives as object pronouns==== The Welsh for "I like Rhodri" is "''{{lang|cy|Dw i'n hoffi Rhodri}}''" ("I am liking [of] Rhodri"), but "I like ''him''" is "''{{lang|cy|Dw i'n '''ei''' hoffi fe}}''" — literally, "I am ''his'' liking him"; "I like ''you''" is "''{{lang|cy|Dw i'n '''dy''' hoffi di}}''" ("I am ''your'' liking you"), etc. ====Significant use of auxiliary verbs==== While English can either use verbs directly (e.g. "I go") or with the aid of an [[auxiliary verb]] ("I am going", here using "to be" as the auxiliary), non-literary Welsh inclines very strongly towards the latter use. In the [[present tense]], all verbs are used with the auxiliary "''{{lang|cy|bod}}''" (to be), so "''{{lang|cy|dw i'n mynd}}''" is literally "I am going", but also means simply "I go". In the [[past tense|past]] and [[future tense|future]] tenses, there are [[inflected language|inflected]] forms of all verbs (which are invariably used in the written language), but it is more common nowadays in speech to use the [[verbal noun]] (''{{lang|cy|berfenw}}'', loosely equal to the [[infinitive]] in English) together with the inflected form of "''{{lang|cy|gwneud}}''" (to do), so "I went" can be "''{{lang|cy|mi es i}}''" or "''{{lang|cy|mi wnes i fynd}}''" and "I will go" can be "''{{lang|cy|mi a' i}}''" or "''{{lang|cy|mi wna i fynd}}''". There is also a future form using the auxiliary ''{{lang|cy|bod}}'', giving "''{{lang|cy|fydda i'n mynd}}''" (perhaps best translated as "I will be going") and an [[imperfect tense]] (a continuous/habitual past tense) also using "''{{lang|cy|bod}}''", with "''{{lang|cy|roeddwn i'n mynd}}''" meaning "I used to go/I was going". ====Affirmative markers==== ''{{lang|cy|Mi}}'' or ''{{lang|cy|fe}}'' is often placed before inflected verbs to show that they are declarative. In the present and imperfect of the verb ''{{lang|cy|bod}}'' (to be), ''{{lang|cy|yr}}'' is used instead. ''Mi'' is mainly restricted to colloquial Northern Welsh, with ''fe'' predominating in the South and in the formal or literary register. Such marking of the declarative is, in any case, rather less common in higher registers. == Counting system == The traditional counting system used by the Welsh language is [[vigesimal]], i.e. based on twenties, as in [[French language|French]] numbers 80-99, where numbers from 11–14 are "''x'' on ten", 16–19 are "''x'' on fifteen" (though 18 is more usually "two nines"); numbers from 21–39 are "1–19 on twenty", 40 is "two twenties", 60 is "three twenties", etc. There is also a decimal counting system, favoured by younger people, more common in South Wales, and which appears to be commonly used in Patagonian Welsh, where numbers are "''x'' tens ''y''", e.g. thirty-five in decimal is ''{{lang|cy|tri deg pump}}'' (three ten five) while in vigesimal it is ''{{lang|cy|pymtheg ar hugain}}'' (fifteen – itself "five-ten" – on twenty). A further complication is that while there is only one word for "one" (''{{lang|cy|un}}'') there are masculine and feminine forms of the numbers "two" (''{{lang|cy|dau}}'' and ''{{lang|cy|dwy}}''), "three" (''{{lang|cy|tri}}'' and ''{{lang|cy|tair}}'') and "four" (''{{lang|cy|pedwar}}'' and ''{{lang|cy|pedair}}''), which must agree with the [[grammatical gender]] of the objects being counted, though this rule is less strictly observed with the decimal counting system. {|class="wikitable" ! Number ! Vigesimal system ! Decimal system |- | 1 | colspan="2" style="text-align: center;" | {{lang|cy|un}} |- | 2 | colspan="2" style="text-align: center;" | {{lang|cy|dau}} (m), {{lang|cy|dwy}} (f) |- | 3 | colspan="2" style="text-align: center;" | {{lang|cy|tri}} (m), {{lang|cy|tair}} (f) |- | 4 | colspan="2" style="text-align: center;" | {{lang|cy|pedwar}} (m), {{lang|cy|pedair}} (f) |- | 5 | colspan="2" style="text-align: center;" | {{lang|cy|pump}} |- | 6 | colspan="2" style="text-align: center;" | {{lang|cy|chwech}} |- | 7 | colspan="2" style="text-align: center;" | {{lang|cy|saith}} |- | 8 | colspan="2" style="text-align: center;" | {{lang|cy|wyth}} |- | 9 | colspan="2" style="text-align: center;" | {{lang|cy|naw}} |- | 10 | colspan="2" style="text-align: center;" | {{lang|cy|deg}} |- | 11 | {{lang|cy|un ar ddeg}} | {{lang|cy|un deg un}} |- | 12 | {{lang|cy|deuddeg}} | {{lang|cy|un deg dau}} |- | 13 | {{lang|cy|tri/tair ar ddeg}} | {{lang|cy|un deg tri}} |- | 14 | {{lang|cy|pedwar/pedair ar ddeg}} | {{lang|cy|un deg pedwar}} |- | 15 | {{lang|cy|pymtheg}} | {{lang|cy|un deg pump}} |- | 16 | {{lang|cy|un ar bymtheg}} | {{lang|cy|un deg chwech}} |- | 17 | {{lang|cy|dau/dwy ar bymtheg}} | {{lang|cy|un deg saith}} |- | 18 | {{lang|cy|deunaw}} ("two nines") | {{lang|cy|un deg wyth}} |- | 19 | {{lang|cy|pedwar/pedair ar bymtheg}} | {{lang|cy|un deg naw}} |- | 20 | {{lang|cy|ugain}} | {{lang|cy|dau ddeg}} |- | 21 | {{lang|cy|un ar hugain}} | {{lang|cy|dau ddeg un}} |- | 22 | {{lang|cy|dau/dwy ar hugain}} | {{lang|cy|dau ddeg dau}} |- | 23 | {{lang|cy|tri/tair ar hugain}} | {{lang|cy|dau ddeg tri}} |- | 24 | {{lang|cy|pedwar/pedair ar hugain}} | {{lang|cy|dau ddeg pedwar}} |- | 25 | {{lang|cy|pump ar hugain}} | {{lang|cy|dau ddeg pump}} |- | 26 | {{lang|cy|chwech ar hugain}} | {{lang|cy|dau ddeg chwech}} |- | 27 | {{lang|cy|saith ar hugain}} | {{lang|cy|dau ddeg saith}} |- | 28 | {{lang|cy|wyth ar hugain}} | {{lang|cy|dau ddeg wyth}} |- | 29 | {{lang|cy|naw ar hugain }} | {{lang|cy|dau ddeg naw}} |- | 30 | {{lang|cy|deg ar hugain}} | {{lang|cy|tri deg}} |- | 31 | {{lang|cy|un ar ddeg ar hugain}} | {{lang|cy|tri deg un}} |- | 32 | {{lang|cy|deuddeg ar hugain}} | {{lang|cy|tri deg dau}} |- | etc. | | |- | 40 | {{lang|cy|deugain}} ("two twenties") | {{lang|cy|pedwar deg}} |- | 41 | {{lang|cy|deugain ac un}} | {{lang|cy|pedwar deg un}} |- | 50 | {{lang|cy|hanner cant}} ("half a hundred") | {{lang|cy|pump deg}} |- | 51 | {{lang|cy|hanner cant ac un}} | {{lang|cy|pum deg un}} |- | 60 | {{lang|cy|trigain}} | {{lang|cy|chwe deg}} |- | 61 | {{lang|cy|trigain ac un}} | {{lang|cy|chwe deg un}} |- | 70 | {{lang|cy|deg a thrigain}} | saith deg |- | 71 | {{lang|cy|un ar ddeg a thrigain}} | {{lang|cy|saith deg un}} |- | 80 | {{lang|cy|pedwar ugain}} | {{lang|cy|wyth deg}} |- | 81 | {{lang|cy|pedwar ugain ac un}} | {{lang|cy|wyth deg un}} |- | 90 | {{lang|cy|deg a phedwar ugain}} | {{lang|cy|naw deg}} |- | 91 | {{lang|cy|un ar ddeg a phedwar ugain}} | {{lang|cy|naw deg un}} |- | 100 | colspan="2" style="text-align: center;" | {{lang|cy|cant}} |- | 200 | colspan="2" style="text-align: center;" | {{lang|cy|dau gant}} |- | 300 | colspan="2" style="text-align: center;" | {{lang|cy|tri chant}} |- | 400 | colspan="2" style="text-align: center;" | {{lang|cy|pedwar cant}} |- | 500 | colspan="2" style="text-align: center;" | {{lang|cy|pum cant}} |- | 600 | colspan="2" style="text-align: center;" | {{lang|cy|chwe chant}} |- | 1000 | colspan="2" style="text-align: center;" | {{lang|cy|mil}} |- | 2000 | colspan="2" style="text-align: center;" | {{lang|cy|dwy fil}} |- | 1,000,000 | colspan="2" style="text-align: center;" | {{lang|cy|miliwn}} |- | 1,000,000,000 | colspan="2" style="text-align: center;" | {{lang|cy|biliwn}} |} '''Notes''': * The words ''{{lang|cy|deg}}'' (ten), ''{{lang|cy|deuddeg}}'' (twelve) and ''{{lang|cy|pymtheg}}'' (fifteen) often become ''{{lang|cy|deng}}'', ''{{lang|cy|deuddeng}}'' and ''{{lang|cy|pymtheng}}'' respectively when before a word beginning with "m", e.g. ''{{lang|cy|deng munud}}'' (ten minutes), ''{{lang|cy|deuddeng milltir}}'' (twelve miles), ''{{lang|cy|pymtheng mlynedd}}'' (fifteen years). * The numbers ''{{lang|cy|pump}}'' (five), ''{{lang|cy|chwech}}'' (six) and ''{{lang|cy|cant}}'' (hundred) drop the final consonant when they stand immediately in front of a noun, e.g. ''{{lang|cy|pum potel}}'' (five bottles), ''{{lang|cy|chwe llwy}}'' (six spoons), ''{{lang|cy|can punt}}'' (a hundred pounds). * Larger numbers tend to use the decimal system, e.g. 1,965 ''{{lang|cy|mil, naw cant chwe deg pump}}''. An exception to this rule is when referring to years, where after the number of thousands, the individual digits are spoken, e.g. 1965 ''{{lang|cy|mil naw chwe(ch) pump}}''. This system appears to have broken down for years after 2000, e.g. 2005 is ''{{lang|cy|dwy fil a phump}}''. * The number ''miliwn'' is feminine, and ''biliwn'' is masculine. It is necessary for the gender of these to be different as they can both mutate to ''filiwn''. Two million is therefore ''dwy filiwn'', and two billion is ''dau filiwn''. ==Dialects== [[Dialect]]ical differences are very evident in the spoken, and to a lesser extent the written, language. A convenient, if slightly simplistic, classification is into ''North Walian'' and ''South Walian'' forms (or "''{{lang|cy|Gog}}''" and "''{{lang|cy|Hwntw}}''" based on the word for North, ''{{lang|cy|gogledd}}'', and the South Walian word for "them over there"). The differences between dialects encompass vocabulary, pronunciation and grammar, although particularly in the last regard the differences are in fact relatively minor. Much more fine-grained classifications exist beyond north and south: the book ''{{lang|cy|Cymraeg, Cymrâg, Cymrêg: cyflwyno'r tafodieithoedd}}'',<ref>Thomas, B. and Thomas, P. W. ''{{lang|cy|Cymraeg, Cymrâg, Cymrêg: cyflwyno'r tafodieithoedd}}'', published by Gwasg Taf, {{#isbn:0-948469-14-5}}. Out of print</ref> about Welsh dialects was accompanied by a cassette containing recordings of fourteen different speakers demonstrating aspects of different dialects. The book refers to the earlier ''Linguistic Geography of Wales''<ref>Thomas, A. R. [[1973]] ''Linguistic Geography of Wales''</ref> as describing six different regions which could be identified as having words specific to those regions. Another dialect is [[Patagonian Welsh]], which has developed since the start of the [[Welsh settlement in Argentina]] in [[1865]]; it includes [[Spanish language|Spanish]] loanwords and terms for local features. An example of the difference between North and South Walian usage would be the question "Do you want a cup of tea?" In the North this would typically be "''{{lang|cy|Dach chi isio panad?}}''", while in the South the question "''{{lang|cy|Dych chi moyn dishgled?}}''" would be more likely. An example of a pronunciation difference between Northern and Southern Welsh is the tendency of Southern dialects to "lisp" the letter "s", e.g. ''{{lang|cy|mis}}'' (month), would tend to be pronounced {{IPA|[miːs]}} in the north, and {{IPA|[miːʃ]}} in the south. In fact, the difference between dialects of modern spoken Welsh pale into insignificance compared to the difference between the spoken and literary languages. The latter is significantly more formal and is the language of [[Welsh Bible|Welsh translations]] of the [[Bible]], amongst other things (although the ''{{lang|cy|Beibl Cymraeg Newydd}}'' — New Welsh Bible — is significantly less formal than the traditional [[1588]] [[Bible]]). Gareth King, author of a Welsh grammar, observes that "The difference between these two is much greater than between the virtually identical colloquial and literary forms of English" and goes so far as to state "that there are good grounds for regarding them as separate languages". He comments that whilst colloquial Welsh is a mother tongue requiring no special learning to acquire, literary Welsh is the mother tongue of no-one, and must be taught to people.<ref>King, G. ''Modern Welsh: a comprehensive grammar'', published by Routledge, {{#isbn:0-415-09269-8}} p3</ref> Although the question "Do you want a cup of tea?" is not likely to occur in literary Welsh usage, if it did it would be along the lines of "''{{lang|cy|A oes arnoch eisiau cwpanaid o de?}}''" Amongst the characteristics of the literary, as against the spoken, language are a higher dependence on inflected verb forms, a shift in the usage of some of the tenses, a reduction in the explicit use of pronouns (since the information is usually conveyed in the verb/preposition inflections) and a greatly reduced tendency to substitute [[English language|English]] loanwords for native Welsh words. ==Diglossia: Literary vs. Colloquial Welsh== Modern Welsh can be written in two varieties - '''Colloquial Welsh''' (''Cymraeg llafar'') or '''Literary Welsh''' (''Cymraeg llenyddol''). The grammar described on this page is that of Colloquial Welsh, which is used for speech and informal writing. Literary Welsh is closer to the form of Welsh used in the 1588 translation of the Bible and is found in official documents and other formal [[Register (linguistics)|registers]], including much literature. As a standardised form, literary Welsh shows little if any of the dialectal variation found in colloquial Welsh. Some differences include {| class="wikitable" |- ! Literary Welsh ! Colloquial Welsh |- | Can omit subject pronouns ([[Pro-drop language|pro-drop]]) | Subject pronouns rarely omitted |- | Extensive use of simple verb forms | Extensive use of periphrastic verb forms |- | No distinction between simple present and future (e.g. ''gwelaf'' "I see"/"I shall see") | Simple form expresses only future (e.g. ''gwela i'' "I'll see") |- | Subjunctive verb forms | Subjunctive in fixed idioms |- | 3rd.pl ending = ''–nt'' | 3rd.pl ending = ''–n'' |} In addition, more archaic pronouns and forms of mutation may be observed in Literary Welsh. A complete grammar of Literary Welsh can be found in ''A Grammar of Welsh'' (1980) by Stephen J. Williams. Currently, most Welsh writing, especially that found on the Internet or in magazines, is closer to the '''Colloquial''' form. This is also becoming more common in artistic literature. ===Examples of sentences in literary and colloquial Welsh=== {| class="wikitable" |- ! English ! Literary Welsh ! Colloquial Welsh |- | I get up early every day | Codaf yn gynnar bob dydd | Dw i'n codi'n gynnar bob dydd |- | I'll get up early tomorrow | Codaf yn gynnar yfory | Coda i'n gynnar fory/wna i godi'n gynnar fory |- | S/he had not stood there long | Ni safasai yno'n hir | Doedd hi/o ddim wedi sefyll yno'n hir |- | They'll sleep only when there's a need | Ni chysgant ond pan fo angen | Byddan nhw ddim ond yn cysgu pan fydd angen |- |} ==Welsh in education== The decade around [[1840]] was a period of great social upheaval in Wales, manifested in the [[Chartism|Chartist]] movement, which culminated in 20,000 people marching on [[Newport]] in [[1839]] resulting in a [[riot]] when 20 people were killed by soldiers defending the Westgate Hotel, and the [[Rebecca Riots]] when [[tollbooth]]s on [[turnpikes]] were systematically destroyed. This unrest brought the state of education in Wales to the attention of the English establishment, as social reformers of the time considered education as a means of dealing with social ills. ''[[The Times]]'' newspaper was prominent among those who considered that the lack of education of the Welsh people was the root cause of most of the problems, although the population was generally literate in Welsh because of the activities of [[Sunday School]]s and the need to read the Bible. In July [[1846]], three commissioners, R. R. W. Lingen, Jellynger C. Symons and H. R. Vaughan Johnson, were appointed to inquire into the state of education in Wales; the Commissioners were all [[Anglican]]s, and hence unsympathetic to the Non-conformist majority in Wales, and were monoglot English-speakers. The Commissioners presented their report to the Government on [[1 July]] [[1847]] in three large blue-bound volumes. This report quickly became known as ''{{lang|cy|Brad y Llyfrau Gleision}}'' (The [[Treachery of the Blue Books]]) as, apart from documenting the state of education in Wales, the Commissioners were also free with their comments disparaging the language, Non-conformity, and the morals of the Welsh people in general. An immediate effect of the report was for a belief to take root in the minds of ordinary people that the only way for Welsh people to get on in the world was through the medium of English, and an inferiority complex developed about the Welsh language whose effects have not yet been completely eradicated. The historian Professor [[Kenneth O. Morgan]] referred to the significance of the report and its consequences as "the [[Massacre of Glencoe|Glencoe]] and the [[Amritsar massacre|Amritsar]] of Welsh history". In the later [[19th century]] virtually all teaching in the schools of Wales was in English, even in areas where the pupils barely understood English. Some schools used the [[Welsh Not]], a piece of wood, often bearing the letters "WN", which was hung around the neck of any pupil caught speaking Welsh. The pupil could pass it on to any schoolmate heard speaking Welsh, with the pupil wearing it at the end of the day being given a beating. Towards the beginning of the 20th century this policy slowly began to change, partly owing to the efforts of [[Owen Morgan Edwards]] when he became chief inspector of schools for Wales in [[1907]]. The [[Aberystwyth]] Welsh School (''{{lang|cy|Ysgol Gymraeg Aberystwyth}}'') was founded in [[1939]] by Sir Ifan ap Owen Edwards, the son of O.M. Edwards as the first Welsh Primary School. The headteacher was Norah Isaac. {{lang|cy|Ysgol Gymraeg}} is still a very successful school and now there are Welsh language primary schools all over the country. Ysgol Glan Clwyd was established in [[Rhyl]] in [[1955]] as the first Welsh language school to teach to a secondary level. Welsh is now widely used in [[education]]. All Welsh universities teach some courses in Welsh (most notably the [[University of Wales, Bangor]] and the [[University of Wales, Aberystwyth]]) but are primarily English language. Under the [[National Curriculum]], [[Education in Wales|schoolchildren in Wales]] must study Welsh up to the age of 16. Over a quarter of children in Wales attend schools which teach predominantly through the medium of Welsh. <ref>Figures for 2002-03: [http://www.bwrdd-yr-iaith.org.uk/cynnwys.php?pID=219&langID=2 ''Welsh medium or bilingual provision''], [[Welsh Language Board]]</ref>. The remainder study Welsh as a second language in English-medium schools. Specialist teachers of Welsh called ''{{lang|cy|Athrawon Bro}}'' support the teaching of Welsh in the National Curriculum. ==Welsh in information technology== Welsh has a substantial presence on the Internet, ranging from formal lists of terminology in a variety of fields <ref>The [http://www.e-gymraeg.org/bwrdd-yr-iaith/termau/default.aspx?lang=en Welsh National Database of Standardised Terminology] was [http://www.bwrdd-yr-iaith.org.uk/cynnwys.php?pID=241&langID=2&nID=640 released in March 2006].</ref> to Welsh language interfaces for parts of [[Microsoft Windows XP]], a variety of [[Linux distribution]]s, and some online services to [[blog]]s kept in Welsh.<ref>Selections of Welsh-language blogs are listed on the sites [http://rhithfro.com Y Rhithfro] and [http://blogiadur.com Blogiadur].</ref> ==Welsh in warfare== Secure communications are often difficult to achieve in wartime. [[Cryptography]] can be used to protect messages, but codes can be broken. Therefore, little-known languages are sometimes encoded, so that even if the code is broken, the message is still in a language few people know. For example, [[Navajo language|Navajo]] [[code talker]]s were used by the [[Military of the United States|United States military]] during [[World War II]]. Similarly, the [[Royal Welch Fusiliers]], a Welsh regiment serving in [[Bosnia and Herzegovina|Bosnia]], used Welsh for emergency communications that needed to be secure.<ref>{{cite news | last = Heath | first = Tony | title = Welsh speak up for their ancient tongue|work = [[The Independent]] | pages = 6 | date = 1996-08-26}}</ref> During the 1982 [[Falklands War]] between [[Argentina]] and the United Kingdom, there were stories of British soldiers speaking Welsh with captured Argentinian soldiers who were descendants of [[Welsh settlement in Argentina|Welsh immigrants to the Chubut Valley]] in [[Patagonia]].{{Fact|date=February 2007}} ==Welsh in popular culture== In the summer of 2006, [[List of Big Brother 2006 housemates (UK)#Glyn|Glyn Wise]] and [[List of Big Brother 2006 housemates (UK)#Imogen|Imogen Thomas]] entered the [[Big Brother UK|Big Brother house]]. These were two fluent Welsh speakers and regularly spoke to each other through the Welsh language. This increased the awareness of the Welsh language dramatically in young people. ==See also== {{portalpar|Wales}} *[[Welsh Tract]] *[[Welsh Bible]] *[[List of Welsh principal areas by percentage Welsh language]] *[[Languages in the United Kingdom]] *[[Welsh Language Board]] *[[List of Welsh people]] *[[List of Welsh language authors]] *[[List of Welsh language poets (6th century to c.1600)]] *[[Association of Welsh Translators and Interpreters]] *[[Honourable Society of Cymmrodorion]] *[[Llanfairpwllgwyngyllgogerychwyrndrobwllllantysiliogogogoch]] ==References== <references/> *J.W.Aitchison and H.Carter. ''Language,Economy and Society. The changing fortunes of the Welsh Language in the Twentieth Century''. Cardiff. University of Wales Press. 2000. *J.W.Aitchison and H.Carter. ''Spreading the Word. The Welsh Language 2001''. Y Lolfa. 2004 ==External links== {{InterWiki|code=cy}} {{Commonscat|Welsh language}} ===About the language=== *{{ethnologue|code=cym}} *[http://users.comlab.ox.ac.uk/geraint.jones/about.welsh/ History and status of the Welsh language] *[http://www.gwybodiadur.co.uk Gwybodiadur: a Welsh informationary] *[http://www.bbc.co.uk/wales/storyofwelsh The Story of Welsh]: programme details for series from [[BBC Wales]] *[http://www.cymru.ac.uk/newpages/external/e4106.asp The University of Wales Centre for Advanced Welsh and Celtic Studies] *[http://www.llgc.org.uk/drych/drych_s088.htm The Blue Books of 1847] — [[National Library of Wales]] Digital Mirror. *[http://www.summerlands.com/crossroads/celticlanguage/labara4.html A Taste of Welsh Verse] * [http://www.welshlanguageact.org/ Welsh Language Act website] * [http://www.deddfiaith.org/ Gwefan Deddf Iaith Newydd] * [http://news.bbc.co.uk/1/hi/wales/4308262.stm Welsh Scrabble available (BBC News link)] ===Dictionaries=== {{wiktionarylang|code=cy}} * [http://www.geiriadur.net/ Welsh–English & English-Welsh Dictionary from the University of Wales, Lampeter] * [http://www.cymru.ac.uk/geiriadur/ {{lang|cy|Geiriadur Prifysgol Cymru}}: University of Wales Dictionary of the Welsh Language], a historical dictionary of Welsh (with a [http://www.cymru.ac.uk/geiriadur/gpc_pdfs.htm second edition] in progress, including an embryonic on-line version) ===Learning the language=== * [http://www.bbc.co.uk/learnwelsh BBC Learn Welsh] * [http://www.cs.cf.ac.uk/fun/welsh/ A Welsh Course] by Mark Nodine * [http://www.clwbmalucachu.co.uk Clwb malu cachu], a website for Welsh learners * [http://www.learnons4c.co.uk/home.php Learn Welsh with S4C] * [http://www.swan.ac.uk/dace/e-wlpan/ E-Wlpan, Swansea University] * [http://www.bangor.ac.uk/ll/database/form_welsh4adults.php.en University of Wales, Bangor - a list of Welsh class venues throughout North West Wales] {{Spoken Wikipedia|Welsh_language.ogg|2005-05-12}}{{Celtic languages}} [[Category:Brythonic languages]] [[Category:Languages of the United Kingdom]] [[Category:Spoken articles]] [[Category:Wales|Language]] [[Category:Welsh culture]] [[Category:Welsh language|Welsh language]] qwuaurnw4nf7igvda5cr087up9l1krf User:Dr. K~enwikibooks 2 118587 4669010 2855011 2026-09-05T19:24:38Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669010 wikitext text/x-wiki I made this account after a student telling me about [[Prentice Hall Chemistry]], a book series I have found quite reliable in keeping up with new information. == Things to do == *[[:Category:User templates]] - I have found quite an interest in these userboxes that I have heard about. Since this Wikiproject is fairly new is there another Wikiproject with more userboxes? I will check Wikipedia first it seems that is the main project. This is a test userbox that I have written in html code to practice <div style="float: left; border:solid #FFFF00 1px; margin: 1px;"> <table cellspacing="0" style="width: 238px; background: #FFFF99;{{text default color}};"> <tr> <td style="width: 45px; height: 45px; background: #FFFF00;{{text default color}}; text-align: center; font-size: 14pt;"> Chem </td> <td style="font-size: 8pt; padding: 4pt; line-height: 1.25em;">This user works as a [[w:Chemist|Chemist]] for his [[:Category:Wikibookian chemists|profession]].</td> </tr> </table> </div> djqt902esarfw63wyyy1pgcf898svmv User talk:West Brom 4ever~enwikibooks 3 121707 4669063 2945181 2026-09-06T06:41:39Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669063 wikitext text/x-wiki {{{1|Welcome, {{PAGENAME}}!}}} {| style="background:white;{{text default color}}; border:1px solid #abd5f5;; padding:0px; border-spacing:0px;" ! style="background:#d0e5f5;{{text default color}};" | [[Wikibooks:Welcome, newcomers|Getting started]] with Wikibooks |- | style="padding:5px;" | * Wikibooks is a collection of open-source textbooks. Find out [[WB:WIW|what this means]]. * To sign your name (on talk pages), use four tildes, like this: &#126;&#126;&#126;&#126; * For help in using the wiki, see the [[Help:Editing|editing guide]]. * Explore, [[Wikibooks:Be bold|be bold]], and have fun! |} Come introduce yourself at the [[WB:SLN|new users]] page. If you have any questions, you can ask there or contact me personally. [[User:West Brom 4ever|West Brom 4ever]] 19:39, 13 May 2007 (UTC) == Thanks for welcome :) == - :) --[[User:Millosh|Millosh]] 18:26, 18 June 2007 (UTC) == Your account will be renamed == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> Hello, The developer team at Wikimedia is making some changes to how accounts work, as part of our on-going efforts to provide new and better tools for our users like cross-wiki notifications. These changes will mean you have the same account name everywhere. This will let us give you new features that will help you edit and discuss better, and allow more flexible user permissions for tools. One of the side-effects of this is that user accounts will now have to be unique across all 900 Wikimedia wikis. See [[m:Special:MyLanguage/Single User Login finalisation announcement|the announcement]] for more information. Unfortunately, your account clashes with another account also called West Brom 4ever. To make sure that both of you can use all Wikimedia projects in future, we have reserved the name West Brom 4ever~enwikibooks that only you will have. If you like it, you don't have to do anything. If you do not like it, you can [[Special:GlobalRenameRequest|pick out a different name]]. Your account will still work as before, and you will be credited for all your edits made so far, but you will have to use the new account name when you log in. Sorry for the inconvenience. Yours,<br />[[m:User:Keegan (WMF)|Keegan Peterzell]]<br />Community Liaison, Wikimedia Foundation </div> 23:51, 17 March 2015 (UTC) <!-- SUL finalisation notification --> == Renamed == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> This account has been renamed as part of [[m:Special:MyLanguage/Single User Login finalisation announcement|single-user login finalisation]]. If you own this account you can [[{{#special:userlogin}}|log in using your previous username and password]] for more information. If you do not like this account's new name, you can choose your own using this form after logging in: [[{{#special:GlobalRenameRequest}}]]. -- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) </div> 05:38, 19 April 2015 (UTC) <!-- SUL post-rename notification --> e63qxo3qsqole1ifo0mn8zgwikv4hoy Abstract Algebra/Quaternions 0 123378 4669024 4668488 2026-09-05T22:12:37Z Rgdboer 1021217 /* Historic instances */ copyedit 4669024 wikitext text/x-wiki {{TOC right}} The algebra of '''Quaternions''' is a structure first studied by the Irish mathematician [[w:en:William Rowan Hamilton|William Rowan Hamilton]] which extends the two-dimensional complex numbers to four dimensions. Multiplication is non-commutative in quaternions, a feature which enables its representation of three-dimensional rotation. Hamilton's provocative discovery of quaternions founded the field of [[Abstract Algebra/Hypercomplex numbers|hypercomplex numbers]]. Suggestive methods like dot products and cross products implicit in quaternion products enabled algebraic description of geometry now widely applied in science and engineering. ==Definitions== [[File:Inscription on Broom Bridge (Dublin) regarding the discovery of Quaternions multiplication by Sir William Rowan Hamilton.jpg|right|thumb|Quaternion plaque on Broom Bridge, Dublin, which says: {{center/top}} Here as he walked by<br>on the 16th of October 1843<br>Sir William Rowan Hamilton<br>in a flash of genius discovered<br>the fundamental formula for<br>quaternion multiplication {{math|1=''i''<sup>2</sup> = ''j''<sup>2</sup> = ''k''<sup>2</sup> = ''ijk'' = −1}} & cut it on a stone of this bridge {{center/end}} ]] A '''Quaternion''' corresponds to an ordered 4-tuple <math>q=(a,b,c,d)</math>, where <math>a,b,c,d\in\mathbb{R}</math>. A quaternion is denoted <math>q=a + b i + c j + d k</math>. The sum <math> b i + c j + d k</math> is called the '''vector part''' of ''q'', and ''a'' is the '''real part'''. Hamilton coined the term ''vector'' in this context. Subsequent developments have extended the usage of the term ''vector'' to any element of a linear space. The vectors in H form a 3-dimensional subspace ''V''. The set of all quaternions is denoted by <math>\mathbb{H}</math>. It is straightforward to define component-wise addition and scalar multiplication on <math>\mathbb{H}</math>, making it a [[Abstract Algebra/Vector Spaces|real vector space]]. Multiplication follows the rules of the "quaternion group" Q<sub>8</sub> = {1, -1, i, -i, j, -j, k, -k} that Hamilton carved into a stone of Broom Bridge, Dublin: :<math>i^2 = j^2 = k^2 = ijk = -1</math> The rules for the pairwise multiplication of <math>i</math>, <math>j</math>, and <math>k</math> are: :<math> ij=k,\ \ jk=i,\ \ ki=j </math> (positive cyclic products) :<math>ji=-k,\ \ kj=-i,\ \ ik=-j</math> (negative cyclic products). Using these, one can define a general rule for multiplication of quaternions. Because quaternion multiplication is ''not'' commutative, <math>\mathbb{H}</math> is a ''not'' a field. However, every nonzero quaternion has a multiplicative inverse (see below), so the quaternions are an example of a '''division ring'''. It is important to note that the non-commutative nature of quaternion multiplication makes it impossible to define the quotient <math>p/q</math> of two quaternions ''p'' and ''q'' unambiguously, as the quantities <math>pq^{-1}</math> and <math>q^{-1}p</math> are generally different. Like the more familiar complex numbers, the quaternions have a '''conjugation''', often denoted by a superscript star: <math>q^*</math>. The conjugate of the quaternion <math>q=a+bi+cj+dk</math> is <math>q^*=a-bi-cj-dk</math>. As is the case for the complex numbers, the product <math>qq^*</math> is always a positive real number equal to the sum of the squares of the quaternion's components. The '''norm ''' of a quaternion is the square root of <math>qq^*</math>. If ''pq'' is the product of two quaternions, then <math>(pq)(pq)^* = (p p^*)(q q^*),</math> implying that <math>\mathbb{H}</math> forms a [[Associative Composition Algebra|composition algebra]]. The multiplicative inverse of a non-zero quaternion <math>q</math> is given by :<math>q^{-1}=\frac{q^*}{qq^*}</math> where division is defined since <math>qq^* \ne 0.</math> Unlike in the complex case, the conjugate <math>q^*</math> of a quaternion <math>q</math> can be computed algebraically: :<math>q^*=-\frac{1}{2}(q+iqi+jqj+kqk)</math>. ==Versors and elliptic space== William Kingdon Clifford used Hamilton’s quaternions to explicate rotation geometry as an elliptic space with its own variety of lines, parallels, and surfaces. The ideas were reviewed in 1948 by Lemaitre and Coxeter and that sketch has these definitions: A '''versor''' is a quaternion of norm one, thus it lies on a 3-dimensional sphere found in the 4-space of quaternions. The versors are given by Euler's formula for complex numbers where the imaginary unit is taken from the unit sphere in the 3-space of vector quaternions: :<math>v = \cos c + s \sin c = e^{cs} , \ \ s^2 = -1 .</math> The '''distance''' between two versors ''u'' and ''v'' is <math>d(u,v) = \arccos (u v^* + v u^*)/2 .</math> A '''right parataxy''' on elliptic space is effected by multiplying on the right by a versor <math>v = e^{cs} .</math> Similarly a '''left parataxy''' arises from left multiplication. In recognition of his contribution to elliptic geometry, a parataxy is called a ''Clifford translation''. The '''general displacement''' of elliptic space is a combination of two parataxies, one left, one right:<math>x \mapsto u x v .</math> Note that if <math>u = v^* ,</math> then the real line in the quaternions is fixed and the displacement is a rotation of the 3-space of quaternion vectors. The term '''line''' is appropriated for elliptic geometry. These lines are ''not'' straight, but they are parametrized by real numbers. Each line is associated with a '''right versor''' like ''s'' when ''c'' = &pi;/2 in ''v''. Then <math>L = \{ e^{cs} : c \in R \}</math> is a typical elliptic line. It corresponds to the axis of the rotation :<math>x \mapsto e^{cs} x e^{-cx} .</math> Now for ''u'' not on ''L'', there are two '''Clifford parallels''' to ''L'' through ''u'': :<math>\{u e^{cs} : c \in R \}, \quad \{e^{cs} u : c \in R \} .</math> For fixed right versors ''r'' and ''s'', a Clifford surface can be formed as a union of Clifford parallels or as :<math>\{ e^{cs} e^{dr} : b, c \in R \} .</math> To form elliptic space from versors, two versors ''u'' and ''v'' are equivalent if ''u'' + ''v'' = 0. Modulo this equivalence, the versors, their algebra and geometry, represent elliptic space. ==Linear viewpoint== Quaternions may be represented by 2×2 matrices with complex number entries: the place of <math>i, j, k </math> is taken by these arrays: :<math>\begin{pmatrix} i & 0 \\ 0 & -i \end{pmatrix}, \quad \begin{pmatrix} 0 & 1 \\ -1 & 0 \end{pmatrix}, \quad \begin{pmatrix} 0 & i \\ i & 0 \end{pmatrix}.</math> One uses matrix multiplication to verify that these expressions obey the rules of presentation of Q<sub>8</sub>. M(2,C) denotes the full algebra of 2×2 complex matrices, which has eight real dimensions, and sustains a representation of <math>\mathbb{H}</math> as a four-dimensional subalgebra. The linear properties of <math>\mathbb{H}</math> and M(2,C) assure the fidelity of the representation once the copy of Q<sub>8</sub> has been identified. Quaternions, like other associative hypercomplex systems of the 19th century, eventually were viewed as matrix algebras in the 20th century. However, in 1853 Hamilton included biquaternions in his book of ''Lectures on Quaternions''. '''Biquaternions''' are quaternions with complex number coefficients, sometimes called ''complex quaternions''. Biquaternions form an algebra isomorphic to M(2,C). If the rows or columns of a matrix are proportional, then the [[Linear Algebra/Definition of Determinant|determinant]] is zero, and there is no inverse. Nevertheless, such matrices have been used in physical science to represent events on a light-path from the origin. Authors Silberstein and Lanczos refer to this algebra as the biquaternions, but other writers have abandoned the label: Elie Cartan used M(2,C) extensively in ''The Theory of Spinors'' (1938), and Wolfgang Pauli, in his matrix mechanics of the atom, caused himself to be associated with M(2,C). ===Pauli Spin Matrices=== Quaternions are closely related to the Pauli spin matrices of Quantum Mechanics. The Pauli matrices are often denoted as<br /> :<math>\sigma_1=\begin{pmatrix}0 & 1 \\ 1 & 0\end{pmatrix}</math> , <math>\sigma_2=\begin{pmatrix}0 & -i \\ i & 0\end{pmatrix}</math> , <math>\sigma_3=\begin{pmatrix}1 & 0 \\ 0 & -1\end{pmatrix}</math> (Where <math>i</math> is the well known quantity <math>\sqrt{-1}</math> of complex numbers) The 2×2 identity matrix is sometimes taken as <math>\sigma_0</math>. Thus <math>S</math>, the real linear span of the matrices <math>\sigma_0</math>, <math>i\sigma_1</math>, <math>i\sigma_2</math> and <math>i\sigma_3</math>, is isomorphic to <math>\mathbb{H}</math>. For example, take this matrix product: :<math>\begin{pmatrix}i & 0 \\ 0 & -i\end{pmatrix} \begin{pmatrix}0 & 1 \\ -1 & 0\end{pmatrix} = \begin{pmatrix}0 & i \\ i & 0\end{pmatrix}</math> Or, equivalently, &nbsp; <math>i\sigma_3 \ i\sigma_2 = i\sigma_1 .</math> All three of these matrices square to the negative of the identity matrix. If we take <math> 1=\sigma_0</math>, <math>i=i\sigma_3</math>, <math>j=i\sigma_2</math>, and <math>k=i\sigma_1</math>, it is easy to see that the span of the these four matrices is "the same as" (that is, isomorphic to) the set of quaternions <math>\mathbb{H}</math>. ==Exercises== # Using the presentation equations of Q<sub>8</sub>, write out the full product of two quaternions. In other words, given <math>q_1=a_1+b_1i+c_1j+d_1k</math> and <math>q_2=a_2+b_2i+c_2j+d_2k</math>, find the components of their product <math>q=q_1q_2 .</math> # Show the composition algebra property <math>(pq)(pq)^* = (p p^*) (q q^*) .</math> Hint: use [[w: Euler's four-square identity]]. ==Axial pencils== [[File:Sheaf_of_Planes.gif|thumb|right|250px|The axis of a pencil is the real axis in the 4-algebra]] Hamilton's quaternions provide a picture of a pencil of complex number planes that fill out his hyperspace. Another pair of pencils provide alternative descriptions of 4-space as made up of planar algebras: The hyperspace is <math>\reals^4</math> with the first coordinate taken as the real line, and as the axis of the various pencils. The Hamilton case uses the sphere of imaginary units :<math>S^2 = \{q \in H : q^2 = -1 \} = \{xi + yj + zk : x^2 + y^2 + z^2 = 1 \} .</math> Any pair of antipodal points on this sphere generates a plane isomorphic to the ordinary complex plane <math>\Complex .</math> The second and third pencils derive from the findings of James Cockle and Arthur Cayley. Cayley set up an arithmetic of matrix multiplication which has expedited modern science. For instance, the so-called imaginary units are represented by <math>\begin{pmatrix}0 & -1 \\ 1 & 0 \end{pmatrix}</math> which has multiplicative square equal to the negative of the identity matrix. But then there is also by <math>\begin{pmatrix}0 & 1 \\ 1 & 0 \end{pmatrix}</math> which generates an algebraic plane distinct from ordinary complex numbers. This algebra [[Associative Composition Algebra/Split-binarions|split-binarions]], has inverse proportion included as a structural feature, such as found in economics or spacetime. In fact, the Lorentz boost is exhibited by a split-binarion multiplication. The inherent relation was recognized in the 19th century by J. Cockle, W.K. Clifford, and A. Macfarlane in the English world and by some Serbians. The second pencil is an imaginary one without linear representation. As Hamilton had a sphere of imaginary units, Macfarlane would have a sphere of hyperbolic units ''u'' with ''u''<sup>2</sup> = +1. The full algebra of split-binarions is <math>A = \{ q = x + y u : x, y \in \reals \}</math> Any pair of elements that are polar opposite on this sphere generate a plane isomorphic to the split-binarions A. The 4-algebra containing this pencil is the '''hyperbolic quaternion''' algebra. As Oliver Heaviside and Willard Gibbs advocated a positive dot product for vectors, they have been associated with hyperbolic quaternions. When this algebra drew attention in the 1890s a "great vector debate" ensued in various publications including ''Nature''. When the failure of the algebra to satisfy the associative law of multiplication was noted, it was realized that no matrix representation would be found. Each plane of the pencil can represent a Lorentz boost. However, rotations of the vector subspace, an operation within the reach of Hamilton's structure, is beyond the means of hyperbolic quaternions, hence the Lorentz group cannot be represented with Macfarlane's algebra. The third pencil arises from both imaginary units and hyperbolic units as found in the ring of [[Abstract Algebra/2x2 real matrices|2x2 real matrices]]. In this figure there must be noted nilpotent matrices such as by <math>\begin{pmatrix}0 & 1 \\ 0 & 0 \end{pmatrix}</math> which correspond to [[Abstract Algebra/Shear and Slope|dual numbers]] in the matrix algebra. Such planes separate the complex and split-binarion planes, and are included in the pencil. The axis of the pencil is the line of matrices that are real multiples of the identity matrix. Over an alternate basis this ring is known as [[Associative Composition Algebra/Split-quaternions|split-quaternions]], and the pencil has three types of planar subrings. == Quaternion algebras == The real numbers are part of Hamilton's quaternions. An objective of abstract algebra is to show algebraic structures in their most general form. The real numbers satisfy the axioms of a field and they have other properties such as order and completeness. Given an arbitrary [[Abstract Algebra/Fields|field]] ''F'', it can be associated with an abstract algebra called a ''quaternion algebra'' as follows: The elements of a quaternion algebra are in the four-dimensional space over ''F'' : &nbsp;''V'' = ''F''<sup> 4</sup>. As in ''F'', there is a multiplicative identity 1 in ''V'', and hence a one-dimensional subspace <math>F \cdot 1.</math> The multiplication <math>\times</math> on ''V'' has the feature that basis vectors of the orthogonal complement of <math>F \cdot 1</math> in ''V'' are anticommutative. More particularly, with i and j perpendicular in this orthogonal complement of <math>F \cdot 1</math>, i j = &minus; j i. With k = i j, and perpendicular to the plane of i and j, associativity of multiplication implies jk = j i j = &minus; i j j = &minus;k j, and k i = i j i = &minus;i k, so k also anticommutes with i and j. The multiplication on ''V'' is determined by multiplication on its basis vectors. That multiplication is not commutative (due to anticommutivity) and includes the negative for each basis vector: <math>B = \{ 1, -1, i, -i, j, -j, k, -k \} \subset V .</math> There are only two non-commutative groups of order eight: the quaternion group Q<sub>8</sub> and the dihedral group of symmetries of a square figure D<sub>4</sub>. Thus, for any field ''F'', there are two quaternion algebras over ''F'' corresponding to the selection of multiplication on ''B'' according to Q<sub>8</sub> or D<sub>4</sub>. === Historic incidents === There was a glitch in an early presentation, with ''F'' being the field of real numbers, and the basis group confused. In 1878 [[w:W. K. Clifford]] nearly described representation of split-quaternions with matrices:<ref>[[w:W. K. Clifford]] (1878) [https://archive.org/details/elementsofdynami01clifiala/page/170/mode/2up ''Elements of Dynamic''], page 170 via Internet Archive</ref> He used ''K'' to express the imaginary unit <math>\begin{pmatrix}0 & 1 \\ -1 & 0 \end{pmatrix}</math>. The only flaw was a missing minus sign in the equation :<math>J K = \begin{pmatrix}0 & 1 \\ 1 & 0 \end{pmatrix} \begin{pmatrix}0 & 1 \\ -1 & 0 \end{pmatrix} = \begin{pmatrix}-1 & 0 \\ 0 & 1 \end{pmatrix} = -I .</math> The inexplicable mistake in a case of a finite subgroup of the general linear group hindered understanding. Some clarity followed from a letter to the editor from [[w:C. G. Knott]]<ref>{{cite journal |first=C.G. |last=Knott |title=Recent Innovations in Vector Theory |journal=Nature |volume=47 |issue=1225 |pages=590–3 |year=1893 |doi=10.1038/047590b0 |bibcode=1893Natur..47R.590. |doi-access=free }} read before the Royal Society of Edinburgh 19 December 1892 and published in ''Proceedings''</ref> 1892) He reaffirmed Hamilton's products in this proposition: :If a 4-algebra on basis <math>\{1,\,i,\,j,\,k\}</math> is associative and off-diagonal products are given by Hamilton's rules, then <math>i^2=-\!1=j^2=k^2</math>. '''Proof:''' :<math>j = ki = (-ji)i = -j(ii)</math>, so <math>i^2 = -1</math>. Cycle the letters <math>i</math>, <math>j</math>, <math>k</math> to obtain <math>i^2=-1=j^2=k^2</math>. An other hitch is the notion of isomorphism of algebras, which should include preserving the field ''F''. Here [[w:Leonard Dickson]] ventured to nullify the difference between the complex algebras ( ''F'' = '''C''' ) over the two basis groups Q<sub>8</sub> and D<sub>4</sub>. He wrote in ''Linear Algebras''<ref>Leonard Dickson (1915) [https://archive.org/details/cu31924001557515/page/n25/mode/2up?q=quaternion Equivalence of complex quaternion and matric algebras], ''Linear Algebras'', page 15</ref> that the complex quaternion and matric algebras were equivalent. There is a real isomorphism between them, but that is not a complex isomorphism preserving the field. Nevertheless, Dickson was one of the first to acknowledge the existence of a four-dimensional, real subalgebra of M(2,'''C''') other than quaternions. == References == {{Reflist}} {{Subject|Abstract Algebra}} 1up5vsd5sg7b12xtvsaaj4n4eajbmqs User:Jomegat/Sandbox/Knot 2 125983 4669005 904049 2026-09-05T19:21:30Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669005 wikitext text/x-wiki {| style="position:relative; margin: 0 0 0.5em 1em; border-collapse: collapse; float:right; background:white;{{text default color}}; clear:right; width:100%;" border="1" cellpadding="2" |- style="text-align:center;" ! style="background: tan;{{text default color}};"|{{{name}}} |- | {{#if:{{{image|}}}|[[image:{{{image}}}|thumb|{{{image_width|250px}}}|{{{image_caption|}}}]]}} {{#if:{{{image2|}}}|[[image:{{{image2}}}|thumb|{{{image2_width|250px}}}|{{{image2_caption|}}}]]}} {{#if:{{{use|}}}|<br><div style="text-align:left">'''Use:''' {{{use}}}</div>}} {{#if:{{{tying_instructions|}}}|<br><div style="text-align:left">'''How to tie:''' <br> {{{tying_instructions}}}</div>}} {{#if:{{{warnings|}}}|<br><div style="text-align:left"> '''WARNING:''' {{{warnings}}}</div>}} |} 5khd7kcm9t61udzt1jby7j7u7aeiq91 General Chemistry 0 129154 4668987 4666435 2026-09-05T18:53:25Z ~2026-48412-47 3625259 Undid revision [[Special:Diff/4666435|4666435]] by [[Special:Contributions/~2026-47545-99|~2026-47545-99]] ([[User talk:~2026-47545-99|discuss]]) 4668987 wikitext text/x-wiki {{DISPLAYTITLE:<span style="display:block;text-align:center;font-size:250%;font-style:italic;line-height:1em;">General Chemistry</span>}} Welcome to the '''''General Chemistry''''' wikibook. In this wikibook, you will be introduced to various aspects of general chemistry such as changes in matter and elements. == Contents == [[File:F4M0.png|300px|thumb|A three-dimensional representation of a 4f orbital]] {{Print version}} {{PDF version|GeneralChemistry}} {{Book Search|prefix=General Chemistry}} [[/Introduction/]] {{:General Chemistry/Properties of Matter}} {{:General Chemistry/Atomic Structure}} {{:General Chemistry/Compounds and Bonding}} {{:General Chemistry/Chemical Reactions}} {{:General Chemistry/Aqueous Solutions}} {{:General Chemistry/Phases of Matter}} {{:General Chemistry/Chemical Equilibria}} {{:General Chemistry/Chemical Kinetics}} {{:General Chemistry/Thermodynamics}} {{:General Chemistry/Chemistries of Various Elements}} === Appendices === # [[File:100%.svg]] [[/Periodic Table/]] # [[File:100%.svg]] [[/Units/]] # [[Image:75%.svg]] [[/Constants/]] # [[Image:50%.svg]] [[/Useful Equations/]] # [[File:100%.svg]] [[/Standard Reduction Potentials/]] # [[File:100%.svg]] [[/Table of the Chemical Elements and their Properties/]] # [[Image:25%.svg]] [[/Review Questions/]] == External Resources == *[http://www.chemmybear.com Chemmybear.com] Tons of info, pictures, and study flashcards. *[http://micvac.dichi.unina.it Chemistry Problems 1.0] Free educational software for General Chemistry *[http://www.freeuniv.com/lect/chempage.html Free University Project: General Chemistry] == Wikibook Administration == # [[/Book Structure/]] # [[/Book Cover/]] # [[/Orphaned Pages/]] __NOTOC__ __NOEDITSECTION__ {{Shelves|Chemistry}} {{alphabetical|G}} {{status|75%}} [[de:Allgemeine und Anorganische Chemie]] [[el:Γενική και Ανόργανη Χημεία]] [[fr:Chimie générale]] [[id:Kimia Dasar]] [[it:Chimica generale]] [[nl:Chemie Centraal]] [[pl:Chemia dla liceum/Okładka]] [[fi:Yleinen kemia]] o85png9wwz6zb2gofzae9vonckzkgdi User:MiszaBot 2 136191 4669009 3278453 2026-09-05T19:24:08Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669009 wikitext text/x-wiki {{bot|Misza13|status=approved}} {| style="text-align:center; background:yellowgreen;{{text default color}};border:1px solid gray; text-align:center; width:75%; font-size:150%; padding:5px;" | [[w:en:User:MiszaBot/Archive HowTo|<span style="color:darkslategray">Click here to read how to set up automated archiving of a page. Takes you to enwikipedia.</span>]] |} rutm4enou33vqzd6rh5tjlkna5lao82 User:Kriswarry 2 136798 4668992 4644387 2026-09-05T19:04:34Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668992 wikitext text/x-wiki {{{1|Welcome, {{PAGENAME}}!}}} {| style="background:white;{{Text default color}}; border:1px solid #abd5f5;; padding:0px; border-spacing:0px;" ! style="background:#d0e5f5;{{Text default color}};" | [[Wikibooks:Welcome, newcomers|Getting started]] with Wikibooks |- | style="padding:5px;" | * Wikibooks is a collection of open-source textbooks. Find out [[WB:WIW|what this means]]. * To sign your name (on talk pages), use four tildes, like this: &#126;&#126;&#126;&#126; * For help in using the wiki, see the [[Help:Editing|editing guide]]. * Explore, [[Wikibooks:Be bold|be bold]], and have fun! |} Come introduce yourself at the [[WB:SLN|new users]] page. If you have any questions, you can ask there or contact me personally. [[User:Urbane|<span style="color: black;"><b>Urbane</b></span>]] [[User talk:Urbane|<span style="color: green;"><small>(Talk)</small></span>]] [[Special:Contributions/Urbane|<span style="color: green;"><small>(Contributions)</small></span>]] 20:30, 13 October 2007 (UTC) j6k7glor2ozw5t4y9w4id4p1lgao2oj User:Aquillyne 2 139604 4669017 1026759 2026-09-05T19:32:12Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669017 wikitext text/x-wiki <div style="border: 2px solid #49f; background: #eefcff;{{Text default color}}; margin: auto 0em 1em 0em; padding: 0.8em; font-family: Verdana, Tahoma, Sans-Serif; font-size: 98%">'''[[wikipedia:User talk:Aquillyne|Please contact me via my talk page on the English Wikipedia]], where I usually contribute.<br />Messages left here will go unanswered for some time. Thanks.'''</div> enptfhscc8y0dl4rsy98mezbpdbu2qt Wikibooks:Reading room/Administrative Assistance 4 140081 4669059 4668705 2026-09-06T06:39:58Z MathXplore 3097823 Reporting Reazulkarim545456 4669059 wikitext text/x-wiki __NEWSECTIONLINK__ {{Discussion Rooms}} {{shortcut|WB:AN|WB:AA}} {{TOC left}} {{User:MiszaBot/config |archive = Wikibooks:Reading room/Administrative Assistance/Archives/%(year)d/%(monthname)s |algo = old(14d) |counter = 1 |minthreadstoarchive = 1 |minthreadsleft = 1 }} {{ombox|type=content|text='''To request a rename or usurpation''', go to the global request page at Meta [[meta:SRUC|here]].<br />''Please do not post those requests here!''}} {{Clear}} Welcome to the '''Administrative Assistance reading room'''. You can request assistance from [[WB:ADMIN|administrators]] for handling a variety of problems here and alert them about problems which may require special actions not normally used during regular content editing. Please be patient as administrators are often quite busy with either their own projects or trying to perform general maintenance and cleanup. You can deal with most vandalism yourself: [[Wikibooks:Dealing with vandalism|fix it]], then [[Wikibooks:Templates/User_notices|warn the user]]. If there is repeated vandalism by one user, lots of vandalism on a single page, or vandalism from many users, tell an admin here, or in [irc://irc.freenode.net/wikibooks #wikibooks] (say <code>!admin</code> to get attention). For more general questions and assistance that doesn't require an administrator, please use the [[WB:HELP|Assistance Reading Room]]. {{clear}} [[Category:Reading room]] == IntoAEC reported by MathXplore == * {{userlinks|IntoAEC}} Spam <!-- USERREPORTED:/IntoAEC/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:25, 19 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:27, 26 August 2026 (UTC) == CaribbeanMedicalSchools reported by MathXplore == * {{userlinks|CaribbeanMedicalSchools}} Spam <!-- USERREPORTED:/CaribbeanMedicalSchools/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:16, 26 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:27, 26 August 2026 (UTC) == Chzoraiz41 reported by MathXplore == * {{userlinks|Chzoraiz41}} Link spam, [[Special:AbuseLog/315229]] <!-- USERREPORTED:/Chzoraiz41/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:09, 27 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:17, 27 August 2026 (UTC) == Gloriagulshan reported by MathXplore == * {{userlinks|Gloriagulshan}} [[:w:Wikipedia:Sockpuppet investigations/Kagoz]] ([[Special:Contributions/Tikapara]], [[Wikibooks:Reading_room/Administrative_Assistance/Archives/2025/September#Tikapara_reported_by_MathXplore]]), created page [[Introduction to Filmmaking]] Contributed by Ali Zulfikar Zahedi ([[:w:Ali Zulfikar Zahedi]], [[:w:simple:Ali Zulfikar Zahedi]]) <!-- USERREPORTED:/Gloriagulshan/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 03:56, 29 August 2026 (UTC) :I believe this page is intended as instructional material for learning filmmaking rather than as an encyclopedic article. I will revise the page to focus on practical filmmaking concepts, methods, and processes in accordance with the purpose of Wikibooks. [[User:Gloriagulshan|Gloriagulshan]] ([[User talk:Gloriagulshan|discuss]] • [[Special:Contributions/Gloriagulshan|contribs]]) 04:20, 29 August 2026 (UTC) : Cc: {{ping|SHB2000|MarcGarver}} [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 04:41, 29 August 2026 (UTC) ::I see the account is glocked, and there are no sleepers that aren't already locked, so nothing more to do. [[User:MarcGarver|MarcGarver]] ([[User talk:MarcGarver|discuss]] • [[Special:Contributions/MarcGarver|contribs]]) 11:18, 3 September 2026 (UTC) == Atlanticgym reported by MathXplore == * {{userlinks|Atlanticgym}} Link spam, [[Special:AbuseLog/315249]] <!-- USERREPORTED:/Atlanticgym/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:32, 29 August 2026 (UTC) :{{done}} --[[User:SHB2000|SHB2000]] ([[User talk:SHB2000|discuss]] • [[Special:Contributions/SHB2000|contribs]]) 12:35, 29 August 2026 (UTC) == Makowe2026 reported by Veritas Sapientiae == * {{userlinks|Makowe2026}} Spam <!-- USERREPORTED:/Makowe2026/ --> [[User:Veritas Sapientiae|Veritas Sapientiae]] ([[User talk:Veritas Sapientiae|discuss]] • [[Special:Contributions/Veritas Sapientiae|contribs]]) 13:53, 29 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 19:20, 29 August 2026 (UTC) == Abir077 reported by MathXplore == * {{userlinks|Abir077}} Link spam, [[Special:AbuseLog/315272]] <!-- USERREPORTED:/Abir077/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:07, 31 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:46, 31 August 2026 (UTC) == Jeevandan26 reported by MathXplore == * {{userlinks|Jeevandan26}} Link spam, [[Special:AbuseLog/315288]] <!-- USERREPORTED:/Jeevandan26/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 13:14, 1 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 13:20, 1 September 2026 (UTC) == Mohansai00116 reported by MathXplore == * {{userlinks|Mohansai00116}} Link spam, [[Special:AbuseLog/315335]] <!-- USERREPORTED:/Mohansai00116/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:09, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:04, 3 September 2026 (UTC) == Fatemai6 reported by MathXplore == * {{userlinks|Fatemai6}} Link spam, [[Special:AbuseLog/315329]] <!-- USERREPORTED:/Fatemai6/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:10, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Kamrulhasan147 reported by MathXplore == * {{userlinks|Kamrulhasan147}} Link spam, [[Special:AbuseLog/315327]], [[Special:Contributions/Kamrulhasan142]] <!-- USERREPORTED:/Kamrulhasan147/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:12, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Kamrulhasan142 reported by MathXplore == * {{userlinks|Kamrulhasan142}} Link spam, [[Special:AbuseLog/315295]], [[Special:Contributions/Kamrulhasan147]] <!-- USERREPORTED:/Kamrulhasan142/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:13, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Twenty7incgs reported by MathXplore == * {{userlinks|Twenty7incgs}} Link spam, [[Special:AbuseLog/315323]] <!-- USERREPORTED:/Twenty7incgs/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:14, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Tailleash reported by MathXplore == * {{userlinks|Tailleash}} Link spam, [[Special:AbuseLog/315318]] <!-- USERREPORTED:/Tailleash/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:15, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Md Akash Mia12 reported by MathXplore == * {{userlinks|Md Akash Mia12}} Link spam, [[Special:AbuseLog/315299]], [[Special:AbuseLog/315298]] <!-- USERREPORTED:/Md Akash Mia12/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:17, 2 September 2026 (UTC) : {{done|Page deleted}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:03, 3 September 2026 (UTC) == Vapesitefiftybar reported by MathXplore == * {{userlinks|Vapesitefiftybar}} Link spam, [[Special:AbuseLog/315338]] <!-- USERREPORTED:/Vapesitefiftybar/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 13:40, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Myteethtime1 reported by MathXplore == * {{userlinks|Myteethtime1}} Spam <!-- USERREPORTED:/Myteethtime1/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:54, 4 September 2026 (UTC) : {{Done}} by MarcGarver. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 19:28, 4 September 2026 (UTC) == Rajstartupservices reported by MathXplore == * {{userlinks|Rajstartupservices}} Link spam, [[Special:AbuseLog/315363]] <!-- USERREPORTED:/Rajstartupservices/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 14:33, 4 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 19:28, 4 September 2026 (UTC) == Reazulkarim545456 reported by MathXplore == * {{userlinks|Reazulkarim545456}} Link spam, [[Special:AbuseLog/315377]] <!-- USERREPORTED:/Reazulkarim545456/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:39, 6 September 2026 (UTC) 0rdrzyvpvffmga9jfbx6j43stvdglh0 4669061 4669059 2026-09-06T06:40:58Z MathXplore 3097823 Reporting Fahmidafy 4669061 wikitext text/x-wiki __NEWSECTIONLINK__ {{Discussion Rooms}} {{shortcut|WB:AN|WB:AA}} {{TOC left}} {{User:MiszaBot/config |archive = Wikibooks:Reading room/Administrative Assistance/Archives/%(year)d/%(monthname)s |algo = old(14d) |counter = 1 |minthreadstoarchive = 1 |minthreadsleft = 1 }} {{ombox|type=content|text='''To request a rename or usurpation''', go to the global request page at Meta [[meta:SRUC|here]].<br />''Please do not post those requests here!''}} {{Clear}} Welcome to the '''Administrative Assistance reading room'''. You can request assistance from [[WB:ADMIN|administrators]] for handling a variety of problems here and alert them about problems which may require special actions not normally used during regular content editing. Please be patient as administrators are often quite busy with either their own projects or trying to perform general maintenance and cleanup. You can deal with most vandalism yourself: [[Wikibooks:Dealing with vandalism|fix it]], then [[Wikibooks:Templates/User_notices|warn the user]]. If there is repeated vandalism by one user, lots of vandalism on a single page, or vandalism from many users, tell an admin here, or in [irc://irc.freenode.net/wikibooks #wikibooks] (say <code>!admin</code> to get attention). For more general questions and assistance that doesn't require an administrator, please use the [[WB:HELP|Assistance Reading Room]]. {{clear}} [[Category:Reading room]] == IntoAEC reported by MathXplore == * {{userlinks|IntoAEC}} Spam <!-- USERREPORTED:/IntoAEC/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:25, 19 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:27, 26 August 2026 (UTC) == CaribbeanMedicalSchools reported by MathXplore == * {{userlinks|CaribbeanMedicalSchools}} Spam <!-- USERREPORTED:/CaribbeanMedicalSchools/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:16, 26 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:27, 26 August 2026 (UTC) == Chzoraiz41 reported by MathXplore == * {{userlinks|Chzoraiz41}} Link spam, [[Special:AbuseLog/315229]] <!-- USERREPORTED:/Chzoraiz41/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:09, 27 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:17, 27 August 2026 (UTC) == Gloriagulshan reported by MathXplore == * {{userlinks|Gloriagulshan}} [[:w:Wikipedia:Sockpuppet investigations/Kagoz]] ([[Special:Contributions/Tikapara]], [[Wikibooks:Reading_room/Administrative_Assistance/Archives/2025/September#Tikapara_reported_by_MathXplore]]), created page [[Introduction to Filmmaking]] Contributed by Ali Zulfikar Zahedi ([[:w:Ali Zulfikar Zahedi]], [[:w:simple:Ali Zulfikar Zahedi]]) <!-- USERREPORTED:/Gloriagulshan/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 03:56, 29 August 2026 (UTC) :I believe this page is intended as instructional material for learning filmmaking rather than as an encyclopedic article. I will revise the page to focus on practical filmmaking concepts, methods, and processes in accordance with the purpose of Wikibooks. [[User:Gloriagulshan|Gloriagulshan]] ([[User talk:Gloriagulshan|discuss]] • [[Special:Contributions/Gloriagulshan|contribs]]) 04:20, 29 August 2026 (UTC) : Cc: {{ping|SHB2000|MarcGarver}} [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 04:41, 29 August 2026 (UTC) ::I see the account is glocked, and there are no sleepers that aren't already locked, so nothing more to do. [[User:MarcGarver|MarcGarver]] ([[User talk:MarcGarver|discuss]] • [[Special:Contributions/MarcGarver|contribs]]) 11:18, 3 September 2026 (UTC) == Atlanticgym reported by MathXplore == * {{userlinks|Atlanticgym}} Link spam, [[Special:AbuseLog/315249]] <!-- USERREPORTED:/Atlanticgym/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:32, 29 August 2026 (UTC) :{{done}} --[[User:SHB2000|SHB2000]] ([[User talk:SHB2000|discuss]] • [[Special:Contributions/SHB2000|contribs]]) 12:35, 29 August 2026 (UTC) == Makowe2026 reported by Veritas Sapientiae == * {{userlinks|Makowe2026}} Spam <!-- USERREPORTED:/Makowe2026/ --> [[User:Veritas Sapientiae|Veritas Sapientiae]] ([[User talk:Veritas Sapientiae|discuss]] • [[Special:Contributions/Veritas Sapientiae|contribs]]) 13:53, 29 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 19:20, 29 August 2026 (UTC) == Abir077 reported by MathXplore == * {{userlinks|Abir077}} Link spam, [[Special:AbuseLog/315272]] <!-- USERREPORTED:/Abir077/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:07, 31 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:46, 31 August 2026 (UTC) == Jeevandan26 reported by MathXplore == * {{userlinks|Jeevandan26}} Link spam, [[Special:AbuseLog/315288]] <!-- USERREPORTED:/Jeevandan26/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 13:14, 1 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 13:20, 1 September 2026 (UTC) == Mohansai00116 reported by MathXplore == * {{userlinks|Mohansai00116}} Link spam, [[Special:AbuseLog/315335]] <!-- USERREPORTED:/Mohansai00116/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:09, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:04, 3 September 2026 (UTC) == Fatemai6 reported by MathXplore == * {{userlinks|Fatemai6}} Link spam, [[Special:AbuseLog/315329]] <!-- USERREPORTED:/Fatemai6/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:10, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Kamrulhasan147 reported by MathXplore == * {{userlinks|Kamrulhasan147}} Link spam, [[Special:AbuseLog/315327]], [[Special:Contributions/Kamrulhasan142]] <!-- USERREPORTED:/Kamrulhasan147/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:12, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Kamrulhasan142 reported by MathXplore == * {{userlinks|Kamrulhasan142}} Link spam, [[Special:AbuseLog/315295]], [[Special:Contributions/Kamrulhasan147]] <!-- USERREPORTED:/Kamrulhasan142/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:13, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Twenty7incgs reported by MathXplore == * {{userlinks|Twenty7incgs}} Link spam, [[Special:AbuseLog/315323]] <!-- USERREPORTED:/Twenty7incgs/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:14, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Tailleash reported by MathXplore == * {{userlinks|Tailleash}} Link spam, [[Special:AbuseLog/315318]] <!-- USERREPORTED:/Tailleash/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:15, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Md Akash Mia12 reported by MathXplore == * {{userlinks|Md Akash Mia12}} Link spam, [[Special:AbuseLog/315299]], [[Special:AbuseLog/315298]] <!-- USERREPORTED:/Md Akash Mia12/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:17, 2 September 2026 (UTC) : {{done|Page deleted}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:03, 3 September 2026 (UTC) == Vapesitefiftybar reported by MathXplore == * {{userlinks|Vapesitefiftybar}} Link spam, [[Special:AbuseLog/315338]] <!-- USERREPORTED:/Vapesitefiftybar/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 13:40, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Myteethtime1 reported by MathXplore == * {{userlinks|Myteethtime1}} Spam <!-- USERREPORTED:/Myteethtime1/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:54, 4 September 2026 (UTC) : {{Done}} by MarcGarver. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 19:28, 4 September 2026 (UTC) == Rajstartupservices reported by MathXplore == * {{userlinks|Rajstartupservices}} Link spam, [[Special:AbuseLog/315363]] <!-- USERREPORTED:/Rajstartupservices/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 14:33, 4 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 19:28, 4 September 2026 (UTC) == Reazulkarim545456 reported by MathXplore == * {{userlinks|Reazulkarim545456}} Link spam, [[Special:AbuseLog/315377]] <!-- USERREPORTED:/Reazulkarim545456/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:39, 6 September 2026 (UTC) == Fahmidafy reported by MathXplore == * {{userlinks|Fahmidafy}} Link spam, [[Special:AbuseLog/315378]] <!-- USERREPORTED:/Fahmidafy/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:40, 6 September 2026 (UTC) dto2sfehmexeb8jsach8tkz65jci25o 4669064 4669061 2026-09-06T06:42:07Z MathXplore 3097823 Reporting Grow spark digital 4669064 wikitext text/x-wiki __NEWSECTIONLINK__ {{Discussion Rooms}} {{shortcut|WB:AN|WB:AA}} {{TOC left}} {{User:MiszaBot/config |archive = Wikibooks:Reading room/Administrative Assistance/Archives/%(year)d/%(monthname)s |algo = old(14d) |counter = 1 |minthreadstoarchive = 1 |minthreadsleft = 1 }} {{ombox|type=content|text='''To request a rename or usurpation''', go to the global request page at Meta [[meta:SRUC|here]].<br />''Please do not post those requests here!''}} {{Clear}} Welcome to the '''Administrative Assistance reading room'''. You can request assistance from [[WB:ADMIN|administrators]] for handling a variety of problems here and alert them about problems which may require special actions not normally used during regular content editing. Please be patient as administrators are often quite busy with either their own projects or trying to perform general maintenance and cleanup. You can deal with most vandalism yourself: [[Wikibooks:Dealing with vandalism|fix it]], then [[Wikibooks:Templates/User_notices|warn the user]]. If there is repeated vandalism by one user, lots of vandalism on a single page, or vandalism from many users, tell an admin here, or in [irc://irc.freenode.net/wikibooks #wikibooks] (say <code>!admin</code> to get attention). For more general questions and assistance that doesn't require an administrator, please use the [[WB:HELP|Assistance Reading Room]]. {{clear}} [[Category:Reading room]] == IntoAEC reported by MathXplore == * {{userlinks|IntoAEC}} Spam <!-- USERREPORTED:/IntoAEC/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:25, 19 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:27, 26 August 2026 (UTC) == CaribbeanMedicalSchools reported by MathXplore == * {{userlinks|CaribbeanMedicalSchools}} Spam <!-- USERREPORTED:/CaribbeanMedicalSchools/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:16, 26 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:27, 26 August 2026 (UTC) == Chzoraiz41 reported by MathXplore == * {{userlinks|Chzoraiz41}} Link spam, [[Special:AbuseLog/315229]] <!-- USERREPORTED:/Chzoraiz41/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:09, 27 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:17, 27 August 2026 (UTC) == Gloriagulshan reported by MathXplore == * {{userlinks|Gloriagulshan}} [[:w:Wikipedia:Sockpuppet investigations/Kagoz]] ([[Special:Contributions/Tikapara]], [[Wikibooks:Reading_room/Administrative_Assistance/Archives/2025/September#Tikapara_reported_by_MathXplore]]), created page [[Introduction to Filmmaking]] Contributed by Ali Zulfikar Zahedi ([[:w:Ali Zulfikar Zahedi]], [[:w:simple:Ali Zulfikar Zahedi]]) <!-- USERREPORTED:/Gloriagulshan/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 03:56, 29 August 2026 (UTC) :I believe this page is intended as instructional material for learning filmmaking rather than as an encyclopedic article. I will revise the page to focus on practical filmmaking concepts, methods, and processes in accordance with the purpose of Wikibooks. [[User:Gloriagulshan|Gloriagulshan]] ([[User talk:Gloriagulshan|discuss]] • [[Special:Contributions/Gloriagulshan|contribs]]) 04:20, 29 August 2026 (UTC) : Cc: {{ping|SHB2000|MarcGarver}} [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 04:41, 29 August 2026 (UTC) ::I see the account is glocked, and there are no sleepers that aren't already locked, so nothing more to do. [[User:MarcGarver|MarcGarver]] ([[User talk:MarcGarver|discuss]] • [[Special:Contributions/MarcGarver|contribs]]) 11:18, 3 September 2026 (UTC) == Atlanticgym reported by MathXplore == * {{userlinks|Atlanticgym}} Link spam, [[Special:AbuseLog/315249]] <!-- USERREPORTED:/Atlanticgym/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:32, 29 August 2026 (UTC) :{{done}} --[[User:SHB2000|SHB2000]] ([[User talk:SHB2000|discuss]] • [[Special:Contributions/SHB2000|contribs]]) 12:35, 29 August 2026 (UTC) == Makowe2026 reported by Veritas Sapientiae == * {{userlinks|Makowe2026}} Spam <!-- USERREPORTED:/Makowe2026/ --> [[User:Veritas Sapientiae|Veritas Sapientiae]] ([[User talk:Veritas Sapientiae|discuss]] • [[Special:Contributions/Veritas Sapientiae|contribs]]) 13:53, 29 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 19:20, 29 August 2026 (UTC) == Abir077 reported by MathXplore == * {{userlinks|Abir077}} Link spam, [[Special:AbuseLog/315272]] <!-- USERREPORTED:/Abir077/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:07, 31 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:46, 31 August 2026 (UTC) == Jeevandan26 reported by MathXplore == * {{userlinks|Jeevandan26}} Link spam, [[Special:AbuseLog/315288]] <!-- USERREPORTED:/Jeevandan26/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 13:14, 1 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 13:20, 1 September 2026 (UTC) == Mohansai00116 reported by MathXplore == * {{userlinks|Mohansai00116}} Link spam, [[Special:AbuseLog/315335]] <!-- USERREPORTED:/Mohansai00116/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:09, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:04, 3 September 2026 (UTC) == Fatemai6 reported by MathXplore == * {{userlinks|Fatemai6}} Link spam, [[Special:AbuseLog/315329]] <!-- USERREPORTED:/Fatemai6/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:10, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Kamrulhasan147 reported by MathXplore == * {{userlinks|Kamrulhasan147}} Link spam, [[Special:AbuseLog/315327]], [[Special:Contributions/Kamrulhasan142]] <!-- USERREPORTED:/Kamrulhasan147/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:12, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Kamrulhasan142 reported by MathXplore == * {{userlinks|Kamrulhasan142}} Link spam, [[Special:AbuseLog/315295]], [[Special:Contributions/Kamrulhasan147]] <!-- USERREPORTED:/Kamrulhasan142/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:13, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Twenty7incgs reported by MathXplore == * {{userlinks|Twenty7incgs}} Link spam, [[Special:AbuseLog/315323]] <!-- USERREPORTED:/Twenty7incgs/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:14, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Tailleash reported by MathXplore == * {{userlinks|Tailleash}} Link spam, [[Special:AbuseLog/315318]] <!-- USERREPORTED:/Tailleash/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:15, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Md Akash Mia12 reported by MathXplore == * {{userlinks|Md Akash Mia12}} Link spam, [[Special:AbuseLog/315299]], [[Special:AbuseLog/315298]] <!-- USERREPORTED:/Md Akash Mia12/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:17, 2 September 2026 (UTC) : {{done|Page deleted}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:03, 3 September 2026 (UTC) == Vapesitefiftybar reported by MathXplore == * {{userlinks|Vapesitefiftybar}} Link spam, [[Special:AbuseLog/315338]] <!-- USERREPORTED:/Vapesitefiftybar/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 13:40, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Myteethtime1 reported by MathXplore == * {{userlinks|Myteethtime1}} Spam <!-- USERREPORTED:/Myteethtime1/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:54, 4 September 2026 (UTC) : {{Done}} by MarcGarver. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 19:28, 4 September 2026 (UTC) == Rajstartupservices reported by MathXplore == * {{userlinks|Rajstartupservices}} Link spam, [[Special:AbuseLog/315363]] <!-- USERREPORTED:/Rajstartupservices/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 14:33, 4 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 19:28, 4 September 2026 (UTC) == Reazulkarim545456 reported by MathXplore == * {{userlinks|Reazulkarim545456}} Link spam, [[Special:AbuseLog/315377]] <!-- USERREPORTED:/Reazulkarim545456/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:39, 6 September 2026 (UTC) == Fahmidafy reported by MathXplore == * {{userlinks|Fahmidafy}} Link spam, [[Special:AbuseLog/315378]] <!-- USERREPORTED:/Fahmidafy/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:40, 6 September 2026 (UTC) == Grow spark digital reported by MathXplore == * {{userlinks|Grow spark digital}} Link spam, [[Special:AbuseLog/315381]] <!-- USERREPORTED:/Grow spark digital/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:42, 6 September 2026 (UTC) 5j92ewrtt4xxnom7w8771e730coznju 4669095 4669064 2026-09-06T10:32:04Z MathXplore 3097823 Reporting Korigosnacks 4669095 wikitext text/x-wiki __NEWSECTIONLINK__ {{Discussion Rooms}} {{shortcut|WB:AN|WB:AA}} {{TOC left}} {{User:MiszaBot/config |archive = Wikibooks:Reading room/Administrative Assistance/Archives/%(year)d/%(monthname)s |algo = old(14d) |counter = 1 |minthreadstoarchive = 1 |minthreadsleft = 1 }} {{ombox|type=content|text='''To request a rename or usurpation''', go to the global request page at Meta [[meta:SRUC|here]].<br />''Please do not post those requests here!''}} {{Clear}} Welcome to the '''Administrative Assistance reading room'''. You can request assistance from [[WB:ADMIN|administrators]] for handling a variety of problems here and alert them about problems which may require special actions not normally used during regular content editing. Please be patient as administrators are often quite busy with either their own projects or trying to perform general maintenance and cleanup. You can deal with most vandalism yourself: [[Wikibooks:Dealing with vandalism|fix it]], then [[Wikibooks:Templates/User_notices|warn the user]]. If there is repeated vandalism by one user, lots of vandalism on a single page, or vandalism from many users, tell an admin here, or in [irc://irc.freenode.net/wikibooks #wikibooks] (say <code>!admin</code> to get attention). For more general questions and assistance that doesn't require an administrator, please use the [[WB:HELP|Assistance Reading Room]]. {{clear}} [[Category:Reading room]] == IntoAEC reported by MathXplore == * {{userlinks|IntoAEC}} Spam <!-- USERREPORTED:/IntoAEC/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:25, 19 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:27, 26 August 2026 (UTC) == CaribbeanMedicalSchools reported by MathXplore == * {{userlinks|CaribbeanMedicalSchools}} Spam <!-- USERREPORTED:/CaribbeanMedicalSchools/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:16, 26 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:27, 26 August 2026 (UTC) == Chzoraiz41 reported by MathXplore == * {{userlinks|Chzoraiz41}} Link spam, [[Special:AbuseLog/315229]] <!-- USERREPORTED:/Chzoraiz41/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:09, 27 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:17, 27 August 2026 (UTC) == Gloriagulshan reported by MathXplore == * {{userlinks|Gloriagulshan}} [[:w:Wikipedia:Sockpuppet investigations/Kagoz]] ([[Special:Contributions/Tikapara]], [[Wikibooks:Reading_room/Administrative_Assistance/Archives/2025/September#Tikapara_reported_by_MathXplore]]), created page [[Introduction to Filmmaking]] Contributed by Ali Zulfikar Zahedi ([[:w:Ali Zulfikar Zahedi]], [[:w:simple:Ali Zulfikar Zahedi]]) <!-- USERREPORTED:/Gloriagulshan/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 03:56, 29 August 2026 (UTC) :I believe this page is intended as instructional material for learning filmmaking rather than as an encyclopedic article. I will revise the page to focus on practical filmmaking concepts, methods, and processes in accordance with the purpose of Wikibooks. [[User:Gloriagulshan|Gloriagulshan]] ([[User talk:Gloriagulshan|discuss]] • [[Special:Contributions/Gloriagulshan|contribs]]) 04:20, 29 August 2026 (UTC) : Cc: {{ping|SHB2000|MarcGarver}} [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 04:41, 29 August 2026 (UTC) ::I see the account is glocked, and there are no sleepers that aren't already locked, so nothing more to do. [[User:MarcGarver|MarcGarver]] ([[User talk:MarcGarver|discuss]] • [[Special:Contributions/MarcGarver|contribs]]) 11:18, 3 September 2026 (UTC) == Atlanticgym reported by MathXplore == * {{userlinks|Atlanticgym}} Link spam, [[Special:AbuseLog/315249]] <!-- USERREPORTED:/Atlanticgym/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:32, 29 August 2026 (UTC) :{{done}} --[[User:SHB2000|SHB2000]] ([[User talk:SHB2000|discuss]] • [[Special:Contributions/SHB2000|contribs]]) 12:35, 29 August 2026 (UTC) == Makowe2026 reported by Veritas Sapientiae == * {{userlinks|Makowe2026}} Spam <!-- USERREPORTED:/Makowe2026/ --> [[User:Veritas Sapientiae|Veritas Sapientiae]] ([[User talk:Veritas Sapientiae|discuss]] • [[Special:Contributions/Veritas Sapientiae|contribs]]) 13:53, 29 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 19:20, 29 August 2026 (UTC) == Abir077 reported by MathXplore == * {{userlinks|Abir077}} Link spam, [[Special:AbuseLog/315272]] <!-- USERREPORTED:/Abir077/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:07, 31 August 2026 (UTC) :{{done}} ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 12:46, 31 August 2026 (UTC) == Jeevandan26 reported by MathXplore == * {{userlinks|Jeevandan26}} Link spam, [[Special:AbuseLog/315288]] <!-- USERREPORTED:/Jeevandan26/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 13:14, 1 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 13:20, 1 September 2026 (UTC) == Mohansai00116 reported by MathXplore == * {{userlinks|Mohansai00116}} Link spam, [[Special:AbuseLog/315335]] <!-- USERREPORTED:/Mohansai00116/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:09, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:04, 3 September 2026 (UTC) == Fatemai6 reported by MathXplore == * {{userlinks|Fatemai6}} Link spam, [[Special:AbuseLog/315329]] <!-- USERREPORTED:/Fatemai6/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:10, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Kamrulhasan147 reported by MathXplore == * {{userlinks|Kamrulhasan147}} Link spam, [[Special:AbuseLog/315327]], [[Special:Contributions/Kamrulhasan142]] <!-- USERREPORTED:/Kamrulhasan147/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:12, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Kamrulhasan142 reported by MathXplore == * {{userlinks|Kamrulhasan142}} Link spam, [[Special:AbuseLog/315295]], [[Special:Contributions/Kamrulhasan147]] <!-- USERREPORTED:/Kamrulhasan142/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:13, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Twenty7incgs reported by MathXplore == * {{userlinks|Twenty7incgs}} Link spam, [[Special:AbuseLog/315323]] <!-- USERREPORTED:/Twenty7incgs/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:14, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Tailleash reported by MathXplore == * {{userlinks|Tailleash}} Link spam, [[Special:AbuseLog/315318]] <!-- USERREPORTED:/Tailleash/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:15, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Md Akash Mia12 reported by MathXplore == * {{userlinks|Md Akash Mia12}} Link spam, [[Special:AbuseLog/315299]], [[Special:AbuseLog/315298]] <!-- USERREPORTED:/Md Akash Mia12/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:17, 2 September 2026 (UTC) : {{done|Page deleted}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:03, 3 September 2026 (UTC) == Vapesitefiftybar reported by MathXplore == * {{userlinks|Vapesitefiftybar}} Link spam, [[Special:AbuseLog/315338]] <!-- USERREPORTED:/Vapesitefiftybar/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 13:40, 2 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 14:05, 3 September 2026 (UTC) == Myteethtime1 reported by MathXplore == * {{userlinks|Myteethtime1}} Spam <!-- USERREPORTED:/Myteethtime1/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 12:54, 4 September 2026 (UTC) : {{Done}} by MarcGarver. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 19:28, 4 September 2026 (UTC) == Rajstartupservices reported by MathXplore == * {{userlinks|Rajstartupservices}} Link spam, [[Special:AbuseLog/315363]] <!-- USERREPORTED:/Rajstartupservices/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 14:33, 4 September 2026 (UTC) : {{done}}. [[User:Codename Noreste|<span style="color: blue">Codename Noreste</span>]] /// [[User talk:Codename Noreste|⭐️✨]] 19:28, 4 September 2026 (UTC) == Reazulkarim545456 reported by MathXplore == * {{userlinks|Reazulkarim545456}} Link spam, [[Special:AbuseLog/315377]] <!-- USERREPORTED:/Reazulkarim545456/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:39, 6 September 2026 (UTC) == Fahmidafy reported by MathXplore == * {{userlinks|Fahmidafy}} Link spam, [[Special:AbuseLog/315378]] <!-- USERREPORTED:/Fahmidafy/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:40, 6 September 2026 (UTC) == Grow spark digital reported by MathXplore == * {{userlinks|Grow spark digital}} Link spam, [[Special:AbuseLog/315381]] <!-- USERREPORTED:/Grow spark digital/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 06:42, 6 September 2026 (UTC) == Korigosnacks reported by MathXplore == * {{userlinks|Korigosnacks}} Link spam, [[Special:AbuseLog/315383]] <!-- USERREPORTED:/Korigosnacks/ --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 10:32, 6 September 2026 (UTC) id1f7jbu6b3zlc1e9i292rxv84xfsno User:Soul windsurfer 2 146738 4668923 4647736 2026-09-05T12:21:39Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668923 wikitext text/x-wiki This isn't what OP is asking for. In my opinion, the "best" solution is the one that can be read by another programmer (or the original programmer two years later) without copious comments. You may well want the fastest or cleverest solution which some have already provided but I prefer readability over cleverness any time.In my opinion, the "best" solution is the one that can be read by another programmer (or the original programmer two years later) without copious comments. You may well want the fastest or cleverest solution which some have already provided but I prefer readability over cleverness any time.<ref>[https://stackoverflow.com/questions/109023/count-the-number-of-set-bits-in-a-32-bit-integer?rq=1 stackoverflow question : count-the-number-of-set-bits-in-a-32-bit-integer]</ref> it was so easy that I am ashamed of having asked. [https://petapixel.com/2018/09/19/8-12-14-vs-16-bit-depth-what-do-you-really-need/ I’m not a big fan of speculating, so I’ve done a lot of testing. It is always important to validate your assumptions. I have heard many experts claim something to be true (in theory), only to find that real-world factors make the theory essentially irrelevant. A Ferrari is theoretically faster than a Ford truck, but maybe not on a dirt road. GREG BENZ] Sorry, I don't really understand this. I like mathematics but my knowledge is very limited. It is a great idea! Mindboggling, but I don't know how it would be done. faces two separate but interconnected problems. Benefits and drawbacks of each method = pros and cons = pro et contra ( latin) Julia Programming For Nervous Beginners The rabbit hole is deep with many paths to explore. ( 3DickUlus ) I don't think that this answers the OP's question in any way. ( Here OP's means probably Other People's ) "The answer is no, although it doesn't seem so easy to give a rigorous counter-example." Glougloubarbaki<ref>[https://math.stackexchange.com/questions/3546649/is-the-basin-of-attraction-of-a-p-starshaped-wrt-to-p math SE question: is-the-basin-of-attraction-of-a-p-starshaped-wrt-to-p]</ref> " Mathematics takes place at different time-scales. If you can solve a problem in 55 minutes that others need an hour to solve, you can probably get a good job. If you can solve a problem in a month that others might need a year to solve, you will probably do well as a graduate student. But if you can solve a problem in 10 years that nobody else can solve in a lifetime, you could be a great mathematician." Robert Israel " anyone who wishes to study this topic should earn a Ph.D. in number theory and spend several years researching the relevant topics in depth, with the guidance of a world class expert." Alon Amit, PhD in Mathematics; Mathcircler. "The author apologises wholeheartedly to those who dare read the source code." Freddie R. Exall A BELIEF IS NOT A PROOF. "Category theory is ... the most, abstract fields of mathematics" Robb Seaton<ref>[http://rs.io/why-category-theory-matters/ Why Category Theory Matters by Robb Seaton]</ref> For the sake of completeness, here is the entire code I used:" "That's quite a comprehensive analysis: It'll take me probably a week (or better a month) to understand it. " marcm200<ref>[https://fractalforums.org/fractal-mathematics-and-new-theories/28/line-segments-intersecting-msets-how-often/3181/msg17563 fractalforums.org : line-segments-intersecting-msets-how-often]</ref> I feel this is a very basic question, but I seem to be unable to find an answer for (neither by myself nor searching) marcm200 <gallery> Animated-GIFs-davidope-11.gif Artificial dendrites growth.gif Branchedgifsm.gif Fortunes-algorithm.gif </gallery> [http://fraktal.republika.pl My home page] - dead (:-( [[Image:Wikipedia-logo.png|20px]] Wikipedia - [[w:User:Adam majewski|Adam majewski]] [[Image:Commons-logo.svg|20px]] Commons - [[commons:User:Adam majewski|Adam majewski]] [https://www.dropbox.com/sh/o0txhw0ui3rbyam/oXlVzMWlJ6 My Dropbox public folders] [http://math.stackexchange.com/users/44654/adam Mathematics Stack Exchange] [https://gitlab.com/u/adammajewski gitlab repo] ='''wiki''' = <pre> == c source code== <syntaxhighlight lang="c"> </syntaxhighlight> == bash source code== <syntaxhighlight lang="bash"> </syntaxhighlight> ==make== <syntaxhighlight lang=makefile> all: chmod +x d.sh ./d.sh </syntaxhighlight> Tu run the program simply make ==text output== <pre> ==references== <references/> == References == {{Reflist}} <syntaxhighlight lang="python"> </syntaxhighlight> ==== Sections ==== Sections included inside a hidden block result in broken anchors in the table of contents at the top of the page. {{hidden begin|title=example}} ===== You can't get here from the table of contents ===== {{hidden end}} </pre> * [[:w:Special:SiteMatrix|SiteMatrix : List of Wikimedia wikis]] * [[:w:Wikipedia:Tools|Wikipedia tools]] * [[Template:Multiple_image|Multiple_image]] * [[Template:Gallery]] * [http://:m:Help:Images_and_other_uploaded_files#Gallery Help:Images_and_other_uploaded_files#Gallery] * [https://www.mathjax.org/ mathjax live demo ( mathjax render)] * [http://www.mediawiki.org/wiki/Extension:SyntaxHighlight_GeSHi SyntaxHighlight] * [[http://alexgorbatchev.com/SyntaxHighlighter/ SyntaxHighlighter]] * [[https://www.mediawiki.org/wiki/Extension:SyntaxHighlighter source]] * [[http://detectlanguage.com/ detect spoken language]] * [[Help:Variables]] * [[Help:Editing]] * [[Help:Editing#Inserting_references]] * {{Ping|username}} * [http://meta.wikimedia.org/wiki/List_of_Wikibooks List_of_Wikibooks languages] * [https://en.wikibooks.org/wiki/Help:Formulas formula ] * [[Special:SpecialPages | WIKIBOOKS SPECIAL]] * [https://www.mediawiki.org/wiki/Extension:RSS rss] * [https://en.wikipedia.org/wiki/Wikipedia:Manual_of_Style/Hidden_text | <code><nowiki><!-- Comment --></nowiki></code>] * http://meta.math.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference * https://en.wikibooks.org/wiki/Template:ISBN <pre> {{displaytitle|title=&nbsp;|tab=Print version}} {{print version notice}} {{print version cover}} {{PDF version}} {{Book title|{{BOOKNAME}}|A guide for the popular online role-playing game ''[[w:EverQuest II|EverQuest II]]''.}} == Table of Contents == {{Book search}} {{Print version}} {{wikipedia|Everquest II}} == How to write this book == Anyone who wishes to improve on this book is/are [[w:Wikipedia:Be bold in updating pages|highly encouraged to do so]]. Before you do, make sure you've read the [[Help:Editing|MediaWiki editing help page]]. {{status|0%}} {{Alphabetical|E}} {{shelves|Strategy guides}} </pre> If you want the stable and official version of Fractal zoomer documentation you can make pdf from wikibooks and put it in wikibooks or your repos. Then you will have full control of it's content ==table== Wikibooks help * [[Help:Tables]] * [[Editing_Wikitext/Tables]] * [[Editing_Wikitext/Tables_Ready_to_Use]] wikipedia help * [[:w:Wikipedia:Manual_of_Style/Tables]] * [[:w:Wikipedia:Table dos and don'ts]], a summary of the key points in this guideline * [[:w:Help:Table]], extensive help * [[:w:Help:Table/Introduction to tables]], a quick guide to using tables * [[:w:Help:Collapsing]] (show/hide button) * [[:w:Wikipedia:Conditional tables]] =Triangle groups= The triangle can be: * an ordinary Euclidean triangle * a triangle on the sphere * a hyperbolic triangle == Hyperbolic groups in H2== {{Further|Uniform tilings in hyperbolic plane}} Two-dimensional hyperbolic triangle groups exist as rank 3 Coxeter diagrams, defined by triangle (p q r) for: :<math>\frac{1}{p}+\frac{1}{q}+\frac{1}{r}<1.</math> {| class="wikitable" style="float:center;" |+ [[:w:Poincaré disk model|Poincaré disk model]] of fundamental domain [[:w:Triangle group|triangles]] |- !colspan=5|Example right triangles [p,q] |- align=center |[[File:H2checkers 237.png|80px]]<br>[3,7] |[[File:H2checkers 238.png|80px]]<br>[3,8] |[[File:Hyperbolic domains 932 black.png|80px]]<br>[3,9] |[[File:H2checkers 23i.png|80px]]<br>[3,&infin;] |- align=center |[[File:H2checkers 245.png|80px]]<br>[4,5] |[[File:H2checkers 246.png|80px]]<br>[4,6] |[[File:H2checkers 247.png|80px]]<br>[4,7] |[[File:H2checkers 248.png|80px]]<br>[4,8] |[[File:H2checkers 24i.png|80px]]<br>[&infin;,4] |- align=center |[[File:H2checkers 255.png|80px]]<br>[5,5] |[[File:H2checkers 256.png|80px]]<br>[5,6] |[[File:H2checkers 257.png|80px]]<br>[5,7] |[[File:H2checkers 266.png|80px]]<br>[6,6] |[[File:H2checkers 2ii.png|80px]]<br>[&infin;,&infin;] |- align=center !colspan=5|Example general triangles [(p,q,r)] |- align=center |[[File:H2checkers 334.png|80px]]<br>[(3,3,4)] |[[File:H2checkers 335.png|80px]]<br>[(3,3,5)] |[[File:H2checkers 336.png|80px]]<br>[(3,3,6)] |[[File:H2checkers 337.png|80px]]<br>[(3,3,7)] |[[File:H2checkers 33i.png|80px]]<br>[(3,3,&infin;)] |- align=center |[[File:H2checkers 344.png|80px]]<br>[(3,4,4)] |[[File:H2checkers 366.png|80px]]<br>[(3,6,6)] |[[File:H2checkers 3ii.png|80px]]<br>[(3,&infin;,&infin;)] |[[File:H2checkers 666.png|80px]]<br>[(6,6,6)] |[[File:Infinite-order triangular tiling.svg|80px]]<br>[(&infin;,&infin;,&infin;)] |} ==hyperbolic tilings== Shown in the [[:en:Poincaré disk model|conformal ('stereographic') disc model]]. In each, the origin is equidistant from the three defining mirrors. Made by [[User:Tamfang/programs|crude little Python programs]]. Full size is 2520 pixels (least common multiple of 1,2,3,4,5,6,7,8,9,10). Ranked by the area of the fundamental triangle. You will notice that many of the duals are missing; because, where an odd number of facets meet at a vertex, I have not thought of an algorithm to color them. (The black-and-white figures are made by counting mirror-flips from the pixel to the interior of the triangle that contains the centre.) {| class="wikitable" ! p q r !! xxx !! xox !! oox !! oxx !! oxo !! xxo !! xoo !! snub |- align=center | width=60|2 3 7 <br> area &pi;/42 |[[File:H2 tiling 237-7.png|90px]] [[File:H2checkers 237.png|90px]] |[[File:H2 tiling 237-5.png|90px]] |[[File:H2 tiling 237-1.png|90px]] |[[File:H2 tiling 237-3.png|90px]] |[[File:H2 tiling 237-2.png|90px]] |[[File:H2 tiling 237-6.png|90px]] |[[File:H2 tiling 237-4.png|90px]] |[[File:H2 snub 237a.png|90px]] [[File:H2 snub 237b.png|90px]] |- align=center | 2 4 5 <br> area &pi;/20 |[[File:H2 tiling 245-7.png|90px]] [[File:H2checkers 245.png|90px]] |[[File:H2 tiling 245-5.png|90px]] |[[File:H2 tiling 245-1.png|90px]] |[[File:H2 tiling 245-3.png|90px]] [[File:H2chess 245f.png|90px]] |[[File:H2 tiling 245-2.png|90px]] |[[File:H2 tiling 245-6.png|90px]] |[[File:H2 tiling 245-4.png|90px]] [[File:H2chess 245c.png|90px]] |[[File:H2 snub 245a.png|90px]] [[File:H2 snub 245b.png|90px]] |- align=center | 3 3 4 <br> area &pi;/12 |[[File:H2 tiling 334-7.png|90px]] [[File:H2checkers 334.png|90px]] |[[File:H2 tiling 334-5.png|90px]] |[[File:H2 tiling 334-1.png|90px]] |[[File:H2 tiling 334-3.png|90px]] |[[File:H2 tiling 334-2.png|90px]] |[[File:H2 tiling 334-6.png|90px]] |[[File:H2 tiling 334-4.png|90px]] |[[File:H2 snub 334a.png|90px]] [[File:H2 snub 334b.png|90px]] |- align=center | 2 3 &infin; <br> area &pi;/6 |[[File:H2 tiling 23i-7.png|90px]] [[File:H2checkers 23i.png|90px]] |[[File:H2 tiling 23i-5.png|90px]] |[[File:H2 tiling 23i-1.png|90px]] [[File:H2chess 23ib.png|90px]] |[[File:H2 tiling 23i-3.png|90px]] |[[File:H2 tiling 23i-2.png|90px]] |[[File:H2 tiling 23i-6.png|90px]] [[File:H2chess 23ie.png|90px]] |[[File:H2 tiling 23i-4.png|90px]] |[[File:H2 snub 23ia.png|90px]] [[File:H2 snub 23ib.png|90px]] |- align=center | 2 &infin; &infin; <br> area &pi;/2 |[[File:H2 tiling 2ii-7.png|90px]] [[File:H2checkers 2ii.png|90px]] |[[File:H2 tiling 2ii-5.png|90px]] [[File:H2chess 2iid.png|90px]] |[[File:H2 tiling 2ii-1.png|90px]] [[File:H2chess 2iib.png|90px]] |[[File:H2 tiling 2ii-3.png|90px]] [[File:H2chess 2iif.png|90px]] |[[File:H2 tiling 2ii-2.png|90px]] [[File:H2chess 2iia.png|90px]] |[[File:H2 tiling 2ii-6.png|90px]] [[File:H2chess 2iie.png|90px]] |[[File:H2 tiling 2ii-4.png|90px]] [[File:H2chess 2iic.png|90px]] |[[File:H2 snub 2iia.png|90px]] [[File:H2 snub 2iib.png|90px]] |- align=center | &infin; &infin; &infin; <br> area &pi; |[[File:H2 tiling iii-7.png|90px]] [[File:H2checkers iii.png|90px]] |[[File:H2 tiling iii-5.png|90px]] [[File:H2chess iiid.png|90px]] |[[File:H2 tiling iii-1.png|90px]] [[File:H2chess iiib.png|90px]] |[[File:H2 tiling iii-3.png|90px]] [[File:H2chess iiif.png|90px]] |[[File:H2 tiling iii-2.png|90px]] [[File:H2chess iiia.png|90px]] |[[File:H2 tiling iii-6.png|90px]] [[File:H2chess iiie.png|90px]] |[[File:H2 tiling iii-4.png|90px]] [[File:H2chess iiic.png|90px]] |[[File:H2 snub iiia.png|90px]] [[File:H2 snub iiib.png|90px]] |} The difference between the two snubs in each row is whether or not the central triangle contains a vertex. In my opinion the above six rows abundantly illustrate the principles; but, by popular demand, [[User:Tamfang/H2|I made a hundred more]]. (And it appears that each row now has at least one article in Wikipedia. I lament my role as enabler.) ==uniformn== {| class=wikitable align=right width=300 |+ Examples of uniform tilings |- !Spherical !Euclidean !colspan=4|Hyperbolic |- align=center |[[File:Uniform tiling 532-t0.png|100px]]<BR>[[dodecahedron|{5,3}]]<BR>5.5.5<BR>{{CDD|node_1|5|node|3|node}} |[[File:Uniform tiling 63-t0.png|100px]]<BR>[[hexagonal tiling|{6,3}]]<BR>6.6.6<BR>{{CDD|node_1|6|node|3|node}} |[[File:Heptagonal tiling.svg|100px]]<BR>[[heptagonal tiling|{7,3}]]<BR>7.7.7<BR>{{CDD|node_1|7|node|3|node}} |[[File:H2-I-3-dual.svg|100px]]<BR>[[Order-3 apeirogonal tiling|{∞,3}]]<BR>∞.∞.∞<BR>{{CDD|node_1|infin|node|3|node}} |- |colspan=4|''[[Regular tiling]]s'' {p,q} of the sphere, Euclidean plane, and hyperbolic plane using regular pentagonal, hexagonal and heptagonal and apeirogonal faces. |- align=center |[[File:Uniform tiling 532-t01.png|100px]]<BR>[[truncated dodecahedron|t{5,3}]]<BR>10.10.3<BR>{{CDD|node_1|5|node_1|3|node}} |[[File:Uniform tiling 63-t01.png|100px]]<BR>[[truncated hexagonal tiling|t{6,3}]]<BR>12.12.3<BR>{{CDD|node_1|6|node_1|3|node}} |[[File:Truncated heptagonal tiling.svg|100px]]<BR>[[Truncated heptagonal tiling|t{7,3}]]<BR>14.14.3<BR>{{CDD|node_1|7|node_1|3|node}} |[[File:H2 tiling 23i-3.png|100px]]<BR>[[Truncated apeirogonal tiling|t{∞,3}]]<BR>∞.∞.3<BR>{{CDD|node_1|infin|node_1|3|node}} |- |colspan=4|[[Truncation (geometry)|Truncated tilings]] have 2p.2p.q vertex figures from regular {p,q}. |- align=center |[[File:Uniform tiling 532-t1.png|100px]]<BR>[[icosidodecahedron|r{5,3}]]<BR>3.5.3.5<BR>{{CDD|node|5|node_1|3|node}} |[[File:Uniform tiling 63-t1.svg|100px]]<BR>[[trihexagonal tiling|r{6,3}]]<BR>3.6.3.6<BR>{{CDD|node|6|node_1|3|node}} |[[File:Triheptagonal tiling.svg|100px]]<BR>[[triheptagonal tiling|r{7,3}]]<BR>3.7.3.7<BR>{{CDD|node|7|node_1|3|node}} |[[File:H2 tiling 23i-2.png|100px]]<BR>[[triapeirogonal tiling|r{∞,3}]]<BR>3.∞.3.∞<BR>{{CDD|node|infin|node_1|3|node}} |- |colspan=4|''[[Quasiregular tiling]]s'' are similar to regular tilings but alternate two types of regular polygon around each vertex. |- align=center |[[File:Uniform tiling 532-t02.png|100px]]<BR>[[rhombicosidodecahedron|rr{5,3}]]<BR>3.4.5.4<BR>{{CDD|node_1|5|node|3|node_1}} |[[File:Uniform tiling 63-t02.png|100px]]<BR>[[Rhombitrihexagonal tiling|rr{6,3}]]<BR>3.4.6.4<BR>{{CDD|node_1|6|node|3|node_1}} |[[File:Rhombitriheptagonal tiling.svg|100px]]<BR>[[Rhombitriheptagonal tiling|rr{7,3}]]<BR>3.4.7.4<BR>{{CDD|node_1|7|node|3|node_1}} |[[File:H2 tiling 23i-5.png|100px]]<BR>[[Rhombitriapeirogonal tiling|rr{∞,3}]]<BR>3.4.∞.4<BR>{{CDD|node_1|infin|node|3|node_1}} |- |colspan=4|''[[Semiregular tiling]]s'' have more than one type of regular polygon. |- align=center |[[File:Uniform tiling 532-t012.png|100px]]<BR>[[truncated icosidodecahedron|tr{5,3}]]<BR>4.6.10<BR>{{CDD|node_1|5|node_1|3|node_1}} |[[File:Uniform tiling 63-t012.svg|100px]]<BR>[[truncated trihexagonal tiling|tr{6,3}]]<BR>4.6.12<BR>{{CDD|node_1|6|node_1|3|node_1}} |[[File:Truncated triheptagonal tiling.svg|100px]]<BR>[[truncated triheptagonal tiling|tr{7,3}]]<BR>4.6.14<BR>{{CDD|node_1|7|node_1|3|node_1}} |[[File:H2 tiling 23i-7.png|100px]]<BR>[[truncated triapeirogonal tiling|tr{∞,3}]]<BR>4.6.∞<BR>{{CDD|node_1|infin|node_1|3|node_1}} |- |colspan=4|''[[Omnitruncated tiling]]s'' have three or more even-sided regular polygons. |}<div style="font-size:75%;display:inline-block;float:right;clear:right;"> {| class="wikitable collapsible collapsed" align=right |+ Construction of Archimedean Solids and Tessellations !colspan=2|Symmetry !colspan=2|[[Dihedral symmetry in three dimensions|Triangular dihedral symmetry]]<br />[[File:Sphere symmetry group d3h.png|100px]] ![[Tetrahedral symmetry|Tetrahedral]]<br />[[File:Tetrahedral reflection domains.png|100px]] !colspan=2|[[Octahedral symmetry|Octahedral]]<br />[[File:Octahedral reflection domains.png|100px]] !colspan=2|[[Icosahedral symmetry|Icosahedral]]<br />[[File:Icosahedral reflection domains.png|100px]] !colspan=2|[[p6m symmetry]]<br />[[File:Tiling Dual Semiregular V4-6-12 Bisected Hexagonal.svg|100px]] !colspan=2|[[Coxeter–Dynkin diagram#Hyperbolic groups in H2|[3,7] symmetry]]<br />[[File:H2checkers 237.png|100px]] !colspan=2|[[Coxeter–Dynkin diagram#Hyperbolic groups in H2|[3,8] symmetry]]<br />[[File:H2checkers 238.png|100px]] |- ! Starting solid<br />Operation||Symbol<br />{p,q}<br />{{CDD|node_1|p|node|q|node}} ! [[Hosohedron|Triangular hosohedron]]<br />{2,3}<br />[[File:Spherical trigonal hosohedron.svg|50px]] || [[Dihedron|Triangular dihedron]]<br />{3,2}<br />[[File:Trigonal dihedron.svg|50px]] || [[Tetrahedron]]<br />{3,3}<br />[[File:Uniform polyhedron-33-t0.png|50px]] || [[Cube]]<br />{4,3}<br />[[File:Uniform polyhedron-43-t0.svg|50px]] || [[Octahedron]]<br />{3,4}<br />[[File:Uniform polyhedron-43-t2.svg|50px]] || [[Dodecahedron]]<br />{5,3}<br />[[File:Uniform polyhedron-53-t0.svg|50px]] || [[Regular icosahedron|Icosahedron]]<br />{3,5}<br />[[File:Uniform polyhedron-53-t2.svg|50px]] || [[Hexagonal tiling]]<br />{6,3}<br />[[File:Uniform tiling 63-t0.svg|50px]] || [[Triangular tiling]]<br />{3,6}<br />[[File:Uniform tiling 63-t2.svg|50px]] || [[Heptagonal tiling]]<br />{7,3}<br />[[File:Heptagonal tiling.svg|50px]] || [[Order-7 triangular tiling]]<br />{3,7}<br />[[File:Order-7 triangular tiling.svg|50px]] || [[Octagonal tiling]]<br />{8,3}<br />[[File:H2 tiling 238-1.png|50px]] || [[Order-8 triangular tiling]]<br />{3,8}<br />[[File:H2 tiling 238-4.png|50px]] |- align=center ! [[truncation (geometry)|Truncation]] (t)||t{p,q}<br />{{CDD|node_1|p|node_1|q|node}} | [[triangular prism]]<br />[[File:Spherical triangular prism.svg|50px]] || [[truncated triangular dihedron]]<br />[[File:Hexagonal_dihedron.svg|50px]]<span style="font-size:70%">(Half of the "edges" count as degenerate [[digon|digon faces]]. The other half are normal edges.)</span> || [[truncated tetrahedron]]<br />[[File:Uniform polyhedron-33-t01.png|50px]] || [[truncated cube]]<br />[[File:Uniform polyhedron-43-t01.svg|50px]] || [[truncated octahedron]]<br />[[File:Uniform polyhedron-43-t12.svg|50px]] || [[truncated dodecahedron]]<br />[[File:Uniform polyhedron-53-t01.svg|50px]] || [[truncated icosahedron]]<br />[[File:Uniform polyhedron-53-t12.svg|50px]] || [[Truncated hexagonal tiling]]<br />[[File:Uniform tiling 63-t01.svg|50px]] || [[Hexagonal_tiling|Truncated triangular tiling]]<br />[[File:Uniform tiling 63-t12.svg|50px]] || [[Truncated heptagonal tiling]]<br />[[File:Truncated heptagonal tiling.svg|50px]] || [[Truncated order-7 triangular tiling]]<br />[[File:Truncated order-7 triangular tiling.svg|50px]] || [[Truncated octagonal tiling]]<br />[[File:H2 tiling 238-3.png|50px]] || [[Truncated order-8 triangular tiling]]<br />[[File:H2 tiling 238-6.png|50px]] |- align=center ! [[Rectification (geometry)|Rectification]] (r)<br />Ambo (a)||r{p,q}<br />{{CDD|node|p|node_1|q|node}} |colspan=2| [[tridihedron]]<br />[[File:Trigonal_dihedron.svg|50px]]<span style="font-size:70%">(All of the "edges" count as degenerate [[digon|digon faces]].)</span> ||[[tetratetrahedron]]<br />[[File:Uniform polyhedron-33-t1.png|50px]] ||colspan=2| [[cuboctahedron]]<br />[[File:Uniform polyhedron-43-t1.svg|50px]] ||colspan=2| [[icosidodecahedron]]<br />[[File:Uniform polyhedron-53-t1.svg|50px]] ||colspan=2| [[Trihexagonal tiling]]<br />[[File:Uniform polyhedron-63-t1.png|50px]] ||colspan=2| [[Triheptagonal tiling]]<br />[[File:Triheptagonal tiling.svg|50px]] ||colspan=2| [[Trioctagonal tiling]]<br />[[File:H2 tiling 238-2.png|50px]] |- align=center ! [[Bitruncation]] (2t)<br />Dual kis (dk)||2t{p,q}<br />{{CDD|node|p|node_1|q|node_1}} | truncated triangular dihedron<br />[[File:Hexagonal_dihedron.svg|50px]]<span style="font-size:70%">(Half of the "edges" count as degenerate [[digon|digon faces]]. The other half are normal edges.)</span> || triangular prism<br />[[File:Spherical triangular prism.svg|50px]] || truncated tetrahedron<br />[[File:Uniform polyhedron-33-t12.png|50px]] || truncated octahedron<br />[[File:Uniform polyhedron-43-t12.svg|50px]] || truncated cube<br />[[File:Uniform polyhedron-43-t01.svg|50px]] || truncated icosahedron<br />[[File:Uniform polyhedron-53-t12.svg|50px]] || truncated dodecahedron<br />[[File:Uniform polyhedron-53-t01.svg|50px]] || truncated triangular tiling<br />[[File:Uniform tiling 63-t12.png|50px]] || truncated hexagonal tiling<br />[[File:Uniform tiling 63-t01.png|50px]] || Truncated order-7 triangular tiling<br />[[File:Truncated order-7 triangular tiling.svg|50px]] || Truncated heptagonal tiling<br />[[File:Truncated heptagonal tiling.svg|50px]] || Truncated order-8 triangular tiling<br />[[File:H2 tiling 238-6.png|50px]] || Truncated octagonal tiling<br />[[File:H2 tiling 238-3.png|50px]] |- align=center ! [[Birectification]] (2r)<br />[[Dual polyhedron|Dual]] (d)||2r{p,q}<br />{{CDD|node|p|node|q|node_1}} | triangular dihedron<br />{3,2}<br />[[File:Trigonal dihedron.svg|50px]] || triangular hosohedron<br />{2,3}<br />[[File:Spherical trigonal hosohedron.svg|50px]] || tetrahedron<br />[[File:Uniform polyhedron-33-t2.png|50px]]|| octahedron<br />[[File:Uniform polyhedron-43-t2.svg|50px]] || cube<br />[[File:Uniform polyhedron-43-t0.svg|50px]] || icosahedron<br />[[File:Uniform polyhedron-53-t2.svg|50px]] || dodecahedron<br />[[File:Uniform polyhedron-53-t0.svg|50px]] || triangular tiling<br />[[File:Uniform tiling 63-t2.svg|50px]] || hexagonal tiling<br />[[File:Uniform tiling 63-t0.svg|50px]] || Order-7 triangular tiling<br />[[File:Order-7 triangular tiling.svg|50px]] || Heptagonal tiling<br />[[File:Heptagonal tiling.svg|50px]] || Order-8 triangular tiling<br />[[File:H2 tiling 238-4.png|50px]] || Octagonal tiling<br />[[File:H2 tiling 238-1.png|50px]] |- align=center ! [[Cantellation]] (rr)<br />[[expansion (geometry)|Expansion]] (e)||rr{p,q}<br />{{CDD|node_1|p|node|q|node_1}} | colspan=2|[[triangular prism]]<br />[[File:Spherical triangular prism.svg|50px]]<span style="font-size:70%">(The "edge" between each pair of tetragons counts as a degenerate [[digon|digon face]]. The other edges (the ones between a trigon and a tetragon) are normal edges.)</span> || [[rhombitetratetrahedron]]<br />[[File:Uniform polyhedron-33-t02.png|50px]] ||colspan=2| [[rhombicuboctahedron]]<br />[[File:Uniform polyhedron-43-t02.png|50px]] || colspan=2|[[rhombicosidodecahedron]] <br />[[File:Uniform polyhedron-53-t02.png|50px]] || colspan=2|[[rhombitrihexagonal tiling]]<br />[[File:Uniform tiling 63-t02.svg|50px]] || colspan=2|[[Rhombitriheptagonal tiling]] <br />[[File:H2 tiling 237-5.png|50px]] || colspan=2|[[Rhombitrioctagonal tiling]] <br />[[File:H2 tiling 238-5.png|50px]] |- align=center ! Snub rectified (sr)<br />[[Snub (geometry)|Snub]] (s)||sr{p,q}<br />{{CDD|node_h|p|node_h|q|node_h}} |colspan=2| [[triangular antiprism]]<br />[[File:Trigonal antiprism.png|50px]]<span style="font-size:70%">(Three yellow-yellow "edges", no two of which share any vertices, count as degenerate [[digon|digon faces]]. The other edges are normal edges.)</span> || [[snub tetratetrahedron]]<br />[[File:Uniform polyhedron-33-s012.svg|50px]] ||colspan=2| [[snub cuboctahedron]]<br />[[File:Uniform polyhedron-43-s012.png|50px]] ||colspan=2| [[snub icosidodecahedron]]<br />[[File:Uniform polyhedron-53-s012.png|50px]] ||colspan=2| [[snub trihexagonal tiling]]<br />[[File:Uniform tiling 63-snub.svg|50px]] ||colspan=2| [[Snub triheptagonal tiling]]<br />[[File:Uniform tiling 73-snub.png|50px]] ||colspan=2| [[Snub trioctagonal tiling]]<br />[[File:Uniform tiling 83-snub.png|50px]] |- align=center ! [[Cantitruncation]] (tr)<br />Bevel (b)||tr{p,q}<br />{{CDD|node_1|p|node_1|q|node_1}} |colspan=2| [[hexagonal prism]]<br />[[File:Truncated triangle prism.png|50px]] || [[truncated tetratetrahedron]]<br />[[File:Uniform polyhedron-33-t012.png|50px]] ||colspan=2| [[truncated cuboctahedron]]<br />[[File:Uniform polyhedron-43-t012.png|50px]] ||colspan=2| [[truncated icosidodecahedron]]<br />[[File:Uniform polyhedron-53-t012.png|50px]] ||colspan=2| [[truncated trihexagonal tiling]]<br />[[File:Uniform tiling 63-t012.svg|50px]] ||colspan=2| [[Truncated triheptagonal tiling]]<br />[[File:H2 tiling 237-7.png|50px]] ||colspan=2| [[Truncated trioctagonal tiling]]<br />[[File:H2 tiling 238-7.png|50px]] |}</div> In [[Hyperbolic geometry|hyperbolic]] [[geometry]], a '''uniform hyperbolic tiling''' (or regular, quasiregular or semiregular hyperbolic tiling) is an edge-to-edge filling of the hyperbolic plane which has [[regular polygon]]s as [[Face (geometry)|faces]] and is [[vertex-transitive]] ([[Transitive group action|transitive]] on its [[vertex (geometry)|vertices]], isogonal, i.e. there is an [[isometry]] mapping any vertex onto any other). It follows that all vertices are [[Congruence (geometry)|congruent]], and the [[tessellation|tiling]] has a high degree of rotational and translational [[symmetry]]. Uniform tilings can be identified by their [[vertex configuration]], a sequence of numbers representing the number of sides of the polygons around each vertex. For example, 7.7.7 represents the [[heptagonal tiling]] which has 3 [[heptagon]]s around each vertex. It is also regular since all the polygons are the same size, so it can also be given the [[Schläfli symbol]] {7,3}. Uniform tilings may be [[Regular polyhedron|regular]] (if also face- and edge-transitive), quasi-regular (if edge-transitive but not face-transitive) or [[Semiregular polyhedron|semi-regular]] (if neither edge- nor face-transitive). For right triangles (''p''&nbsp;''q''&nbsp;2), there are two regular tilings, represented by [[Schläfli symbol]] {''p'',''q''} and {''q'',''p''}. ==see also== * [[:w:User:Tomruen/List of hyperbolic symmetry groups]] * [[:commons:User:Tomruen/gallery]] * [[:commons:User:Tamfang|User:Tamfang]] =github= * [https://github.com/nschloe/xhub nschloe: xhub ( Extend GitHub pages with support for LaTeX, graphs, etc.) math] * https://github.blog/2022-05-19-math-support-in-markdown/ * https://nschloe.github.io/2022/05/20/math-on-github.html * https://github.blog/2022-02-14-include-diagrams-markdown-files-mermaid/ * =table= [[Fractals/mandel#Misiurewicz_point|Misiurewicz_point]] {| class="wikitable" |+ Misiurewicz point of wake 1/q = <math>M_{q,1}</math> |- ! period !! p/q !! prep,period !! c !! [[Fractals/Iterations_in_the_complex_plane/wake|e_angles_of_the_wake]] !! [[Fractals/Iterations_in_the_complex_plane/p_misiurewicz|e_engles_of_Misiurewicz]] |- | 2 || 1/2 || 2,1 || -1.543689012692076 +0.000000000000000i || ( 1/3 = p01, 2/3 = p10 ) || |- | 3 || 1/3 || 3,1 || -0.101096363845622 +0.956286510809142i || ( 1/7 = p001, 2/7 = p010 ) || 9/56, 11/56, 15/56 |- | 4 || 1/4 || 4,1 || 0.366362983422764 +0.591533773261445i || Treść komórki || |- | 5 || 1/5 || 5,1 || 0.437924241359463 +0.341892084338116i || Treść komórki || |- | 6 || 1/6 || 6,1 || 0.424512719050040 +0.207530228166745i || || |- | 7 || 1/7 || 7,1 || 0.397391822296541 +0.133511204871878i || || |- | 8 || 1/8 || 8,1 || 0.372137705449577 +0.090398233158173i || || |- | 9 || 1/9 || 9,1 || 0.351423759052522 +0.063866559813293i || (1/511 = p000000001, 2/511 = p000000010 ) || |- | 10|| 1/10 || 10,1 || 0.334957506651529 +0.046732666062027i || (1/1023 = p0000000001, 2/1023 = p0000000010 )|| |- | 11|| || || || || |- | 12|| || || || || |- | 13|| || || || || |- | 14|| || || || || |- | 15|| || || || || |- | 16|| || || || || |- | 17|| || || || || |- | 18|| || || || || |- | 19|| || || || || |- | 20|| || || || || |- | 21|| || || || || |- | 22|| || || || || |- | 23|| || || || || |- | 24|| || || || || |- | 25|| || || || || |- | 26|| || || || || |- | 27|| || || || || |- | 28|| || || || || |- | 29|| || || || || |- | 30|| || || || || |- | q || 1/q || q,1 || ||<math>0.(0^{q-1}1,) , \ 0.(0^{q-2}10,) </math> || |} =comparison= {| cellspacing="0" cellpadding="15" style="width:100%; vertical-align:top; margin:0.8em 0; border: 1px solid SlateBlue; background:#F7F7FF;{{Text default color}};" |style="vertical-align:top; border-right:1px dashed SlateBlue"| <syntaxhighlight lang=txt> Math notation </syntaxhighlight> <math>square : \mathbb{C} \to \mathbb{C}</math> <math>c_e \leftarrow e^c+c_0</math> |style="vertical-align:top; border-right:1px dashed SlateBlue"| <syntaxhighlight lang=c> // c without complex type cx_e = exp(creal(c)) * cos(cimag(c)) + realpart(c0); // real part of c_e cy_e = exp(creal(c)) * sin(cimag(c)) + imagpart(c0); // imag part of c_e </syntaxhighlight> |style="vertical-align:top; border-right:1px dashed SlateBlue"| <syntaxhighlight lang=c> // c with complex type complex double map(complex double c) { return c = cexp(c) + c0; } </syntaxhighlight> |} =Sources of informations= * printed: ** books ** journals * (mostly) not printed ( online, but some online can also be printed) ** wikipedia ** google search ** [https://github.com/gleitz/howdoi CLI search: howdoi] ** OpenChet GPT ** [https://iq.opengenus.org/ iq.opengenus.org] See also * synthetic data generation (SDG) for AI training ** Computer-generated imagery (CGI) = technology or application of computer graphics for creating or improving images =AI= * [https://vanceai.com/image-enhancer/ vanceai image-enhancer] * [https://openai.com/dall-e-2 dall-e-2 = DALL-E image generation ] * midjourney ** [https://midjourney.gitbook.io/docs/ midjourney doc] ** [https://www.midjourney.com/home/?callbackUrl=%2Fapp%2F midjourney app] ** [https://www.aiphotomaker.art/home aiphotomaker] * [https://lexica.art/ lexica] * [https://playgroundai.com/ playground ai ] * [http://get3dfrom2d.com/ 3D from 2D] AI art engines: Midjourney (good control through text), Lexica (great at generating stylized beauty), PlaygroundAi (based on Stable Diffusion). Image-to-text engines (describe images in words): Midjourney's "describe" command, CLIP, Replicate. Visual libraries of artists: Midlibrary. Prompt marketplaces: Promptbase. Stock images: Unsplash. =SE= * [https://math.stackexchange.com/editing-help math.stackexchange : editing] * [https://math.meta.stackexchange.com/questions/1773/do-we-have-an-equation-editing-howto math.meta.SE question: do-we-have-an-equation-editing-howto ?] * [https://math.meta.stackexchange.com/questions/5020/mathjax-basic-tutorial-and-quick-reference math.meta.SE question: mathjax-basic-tutorial-and-quick-reference ] * [https://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers/8259 meta.stackexchange question: are-answers-that-just-contain-links-elsewhere-really-good-answers ?] console * [https://meta.stackoverflow.com/questions/273049/stack-snippets-console-output stack-snippets-console-output] * [https://meta.stackoverflow.com/questions/358992/ive-been-told-to-create-a-runnable-example-with-stack-snippets-how-do-i-do runnable-example-with-stack-snippets] * [https://meta.stackexchange.com/questions/239706/add-a-console-to-stack-snippets add-a-console-to-stack-snippets] =mapping= three methods for making a conformal mapping: * Using complicated Schwarz-Christoffel. See the work of Driscoll and Trefethen, for example, https://pdfs.semanticscholar.org/ec28/b851707a35630faf58fdb5690f31cc814b15.pdf , references thereto, and their subsequent work, e.g., https://arxiv.org/abs/1911.03696 . * Use Stephenson's circle packing method, for example, http://www.cs.jhu.edu/~misha/Fall09/Stephenson97.pdf , and references thereto. * Use Marshall's "ZIPPER" algorithm. Examples are visible here: http://sites.math.washington.edu/~marshall/zipper.html . More recent work on ZIPPER: https://arxiv.org/abs/math/0605532 . ==mandelbrot== https://www.youtube.com/watch?v=TJXwEIzyoq8 I use this formular: Z ← Zⁿ + F(C) where F(C) is a complex function of the screen coordinate C. If F does not depend on Z, it means that F(C) can be calculated before the starting of the iteration process. Which makes calculations faster. In this video F(C) = [Rot(C, u∙sin(v))]ᵐ Rot( ) is a complex function that rotates a complex number ( C ) by an angle ( u∙sin(v) ). v is the angle of the C vector with the x-axis. m, u and n are real numbers that I can change during the video. I make the following morphing: (n, m, u) = (2, 1, -10) → (2, 1, 0) → (3, 1, 10) → (3, 1, 0) → (4, 1, -10) → (4, 1, 0) → (5, 1, 5) → (5, 1, 0) → (6, 1, -5) → (6, 1, 0) → (6, 1, 5) → (2, -5, 0) → (2, -4, 10) → (2, -4, 0) → (2, -3, -10) → (2, -3, 0) → (2, -2, 6) → (2, -2, 0) → (2, -1, -6) → (2, -1, 0) → (2, 1, 6) → (2, 1, 0) → (2, 1, -10) ==viewer== * [https://www.falstad.com/complexviewer/ falstad : complex viewer] JS * [http://davidbau.com/conformal/ david bau : conformal/#z] ==examples== * [https://www.geogebra.org/m/mugcuvk7 Mappings of the circle to the upper/lower half plane] <math>z \to e^{i*3.14} \frac{z - z_0}{z - \bar{z_0}} </math> where <math> z_0 = 1*i</math> and <math> \bar{z_0} = -1*i</math> * [https://www.geogebra.org/m/xtueknna geometry of some complex functions Author:Walter Füchte] * [https://www.geogebra.org/m/kCxvMbHb Moebiusebene Author:Walter Füchte] * The map <math>t \to e^{it}</math> wraps the real axis around the unit circle (inf many times) * [https://www.geogebra.org/m/DgmYHpsy Complex mappings Author:Juan Carlos Ponce Campuzano] f(z) = u(x,y) + i v(x,y). * [https://mabotkin.github.io/complex/ complex mapper] * Images of a square grid of size [-pi,pi]x[-pi,pi] under the (conformal) map <math>z \to \cot(z)</math>. The image of the lines of constant real part accumuate round the points +-i. https://functions.wolfram.com/ElementaryFunctions/Cot/visualizations/4/ * You know that there is a conformal mapping from the unit disk to the upper half plane given by: <math>z \mapsto -i\frac{z-i}{z+i}</math>. But then you know that the transformation <math>z \mapsto \sqrt z</math> taking the principal value sends the upper half plane to the region you are desiring. Reversing these mappings gives: <math>w \mapsto \frac{iw^2+1}{-w^2-i}</math> Which you will see is a conformal mapping sending the first quadrant to the unit disk. <ref>[https://math.stackexchange.com/questions/298075/find-conformal-mapping-from-sector-to-unit-disc math.stackexchange question: find-conformal-mapping-from-sector-to-unit-disc]</ref> ** https://i.stack.imgur.com/r0Lno.jpg ** https://i.stack.imgur.com/YsIHj.jpg ** https://i.stack.imgur.com/a08mS.jpg ==area== https://math.stackexchange.com/questions/2063137/series-related-to-the-mandelbrot-set Despite expanding finite iterations, there's a series maps the exterior of a unit disk to the exterior of the $M$ set. <math> \begin{align} \psi(z) &= z+\sum_{m=0}^{\infty} \frac{\beta_{0,m+1}}{z^m} \\ z_{n} &= \sum_{m=0}^{\infty} \beta_{n,m} z^{2^n-m} \\ &= z^{2^{n}}+o(1) \end{align} </math> [http://gdz.sub.uni-goettingen.de/dms/load/img/?PID=GDZPPN001185500 John H. Ewing, Glenn Schober, The area of the Mandelbrot Set] Strictly speaking, we won't say the iteration converges when the final states are oscillating. Hence, **not all** the points on the Mandelbrot set converge to a limit. All points in $n$-periodic cycles $(n>1)$ or chaotic bands are **bounded**, so they belong to the Mandelbrot set but **do not converge**. If you insist for how interior of M is mapped to its final states. Please see derivation about period 1 cycle and its final state below: In conclusion, <math>c=\frac{re^{i\phi}}{2}-\frac{r^2e^{2i\phi}}{4}</math> maps to <math>z=\frac{re^{i\phi}}{2}</math> where * <math>(r,\phi) \in [0,1] \times [0,2\pi)</math> For period one cycle, z and c can be expressed in quadratic: <math>z^2-z+c=0</math> Taking the branch enclosing the super-attractive point c=0, <math>\begin{align} z &= \frac{1-\sqrt{1-4c}}{2} \\ &= \sum_{k=1}^{\infty} \frac{(-1)^{n-1}c^{n}}{2^{2n-1}} \binom{\frac{1}{2}}{n} \\ &= c+c^2+2c^4+5c^6+14c^8+42c^{10}+\ldots \end{align} </math> which has the radius convergence of <math>\dfrac{1}{4}</math>. The boundary of the mapping: $c=\frac{e^{i\theta}}{4} \mapsto z=\frac{1-\sqrt{|\sin \frac{\theta}{2}|+|\sin \frac{\theta}{2}|^2}}{2}- \frac{i\operatorname{sgn} (\sin \theta) \sqrt{|\sin \frac{\theta}{2}|-|\sin \frac{\theta}{2}|^2}}{2}$$ - The iteration and series agree only when $|c| \le \dfrac{1}{4}$. > Below is the comparison between the exact iterations (blue) and the series summation (red): [![enter image description here][6]][6] > The green boundaries refer pre-image and image enclosed for period two cycle. [![enter image description here][7]][7] - Animation of successive iterations of the Mandelbrot Set: [![enter image description here][8]][8] [1]: https://i.stack.imgur.com/cORV2.jpg [2]: [3]: https://i.stack.imgur.com/aZbQV.jpg [4]: https://i.stack.imgur.com/jE7kl.jpg [5]: https://i.stack.imgur.com/kBhwg.jpg [6]: https://i.stack.imgur.com/mgRaQ.jpg [7]: https://i.stack.imgur.com/ojdZL.jpg [8]: https://i.stack.imgur.com/5SsqA.gif ==Riemann mapping == * Construction of the Riemann mapping by steepest descent along Green's function ===ChatGPT=== Computing the Riemann mapping of a hyperbolic component of the Mandelbrot set can be a challenging task, as it involves solving a number of complex analytic problems. However, there are a few general steps that can be followed to compute a Riemann mapping of a given hyperbolic component: Identify the hyperbolic component: The first step is to identify the hyperbolic component that you wish to map. This typically involves finding the boundary of the component and determining its connectivity. Find a conformal map from the component to the unit disk: The next step is to find a conformal map from the hyperbolic component to the unit disk. A conformal map is a holomorphic function that preserves angles, which is necessary to maintain the topological properties of the component. There are various methods to find such a conformal map, like the method of the kernel function, or the method of the half-plane. Compute the Riemann mapping: Once a conformal map from the hyperbolic component to the unit disk has been found, the Riemann mapping can be computed by composing the conformal map with a suitable automorphism of the unit disk. Verify the Riemann mapping: The final step is to verify that the computed Riemann mapping is a bijection and that it preserves the topological properties of the hyperbolic component. It's worth noting that the above steps are very simplified and the actual process of finding the Riemann mapping can be quite involved and require a deep understanding of complex analysis. Also, in the case of the Mandelbrot set, the boundary of the hyperbolic component is fractal in nature and it's not clear cut, so it's not easy to identify it. It is also important to note that this process is generally not an explicit one, meaning that it may not be possible to write down an explicit formula for the Riemann mapping in closed form, it is usually obtained via numerical methods. ------------------------------------------------------ The method of the kernel function is a technique for finding a conformal map from a simply connected region in the complex plane to the unit disk. The method is based on the idea of finding a special function called the kernel function, which can be used to construct the desired conformal map. The basic idea behind the method is to find a function f(z) that satisfies the following conditions: f(z) is holomorphic and non-constant on the region of interest f(z) maps the region to the unit disk f(z) maps the boundary of the region to the unit circle The function that satisfies these conditions is called the kernel function. The conformal map from the region to the unit disk is then given by the function g(z) = f(z) / f'(z0), where z0 is an arbitrary point in the region. To find the kernel function, one typically starts by assuming that it has a certain form, such as f(z) = (z - z0)^k g(z) where k is a positive integer and g(z) is a holomorphic function on the region. Then one can use complex analysis techniques, such as the Schwarz reflection principle, to find the appropriate value of k and the function g(z) that make f(z) a kernel function. It's worth noting that this method can be quite involved and requires a deep understanding of complex analysis. Also, finding the kernel function may not be possible in all cases, and finding a good approximation of it may be challenging. ------------------ The method of the half-plane is another technique for finding a conformal map from a simply connected region in the complex plane to the unit disk. This method is based on the idea of mapping the region to a half-plane and then mapping the half-plane to the unit disk. The basic idea behind the method is to find a function f(z) that maps the region of interest to the upper half-plane and that satisfies the following properties: f(z) is holomorphic and non-constant on the region of interest f(z) maps the region to the upper half-plane f(z) maps the boundary of the region to the real axis Once we have this function, we can then use the well-known Moebius transformation that maps the upper half-plane to the unit disk, given by g(z) = (z-i)/(z+i) The final conformal map from the region of interest to the unit disk is the composition of f(z) and g(z) which is g(f(z)) As with the kernel function method, finding a good approximation of f(z) may be challenging and it may not be possible to find it in all cases. It's also worth noting that this method can be quite involved and requires a deep understanding of complex analysis. The method of the half-plane is often used to find conformal maps of regions that have some special symmetry, such as regions that are symmetric with respect to the real axis. ===basilica=== https://arxiv.org/abs/1201.4225 A Thompson Group for the Basilica by James Belk, Bradley Forrest A Riemann map on the central component. Basically, the answer is that I used inverse images to compute a very large number of points with known Bottcher coordinates, and then drew curves through the right sequences of points. Here is a summary of the procedure I used for drawing equipotentials and external rays for a quadratic Julia set: 1. Start with a large number (say 3 * 2^13) of equally spaced sample points on a circle of large radius (say R = 2^16) centered at the origin. Note that this circle is basically an equipotential for the Julia set, since the radius is so large. 2. Compute an equal number of points on the inverse image of this circle (which is again basically an equipotential whose radius is the square root of R). Note that each of the original points has two preimages, so it must be worked out in each case which preimage to use. 3. Iterate step 2 to produce sample points on a large number (say 50) of equipotentials that converge to the Julia set. This lets you draw '''the equipotentials''' with ease. If you want to draw '''the external rays''', it works to draw a piecewise-linear path between corresponding points on different equipotentials. Of course, the resulting external rays will be straight between the sample points, but you can fix this by using more than one orbit of equipotentials. '''The Riemann map for the central component for the Basilica''' was drawn in essentially the same way, except that instead of starting with points on a big circle, I started with sample points on a circle of small radius (e.g. 0.00001) around the origin. =analysis= Problem solving * brute-force analysis * Trial and error =2D computer graphic = * [https://www.falstad.com/matrix/ matrix viewer 2D transformatikon by Paul Falstad] * [[:w:Glossary_of_computer_graphics|Glossary_of_computer_graphics in wikipedia]] * [https://www.youtube.com/watch?v=HEFaRqI8TQw&t=869s Transformations of Functions MathWithMrsGA] * [https://itmedia.pl/kategoria-produktu/sprzet/komputery-i-laptopy/przeznaczenie-komputery-i-laptopy/ IT media] * tablica ( matrix) 2d i uzycie [[:en:w:Kernel_(image_processing)|kernel]] ==rendering== * raytracing * raymarching * rasterization ==csfml== <pre> sudo apt-get install libsfml-dev sudo apt-get install libcsfml-dev </pre> ==hdr== [[User:Soul_windsurfer#HDR_2|HDR description]] == printing== '''Poster''' * color mode = CMYK. Work in CMYK rather than RGB or convert to CMYK, icc profile : [https://color.org/fogra39.xalter Coated FOGRA 39] * Your poster should be easy to read from at least 5 feet (7.5 meters) away * The resolution: typical dpi for posters is 300 dpi ( at least 300 dpi for best results). 2400 dpi or more for large posters. * Standard poster sizes in inches are 11x17, 18x24, and 24x36. Big range is between 18 inches by 24 inches. * You have two choices for poster printing: digital or litho. Links * [[:w:Category:Quality issues in printing|Category:Quality issues in printing in wikipedia]] * [https://graphicdesign.stackexchange.com/questions/16512/how-to-prepare-a-design-for-cmyk-printing graphicdesign.stackexchange questions: how-to-prepare-a-design-for-cmyk-printing] * [https://graphicdesign.stackexchange.com/questions/2984/what-kind-of-black-should-i-use-when-designing-for-cmyk-print graphicdesign.stackexchange question: what-kind-of-black-should-i-use-when-designing-for-cmyk-print] * [https://graphicdesign.stackexchange.com/questions/24648/identifying-printing-quality-issues graphicdesign.stackexchange question: identifying-printing-quality-issues] * [https://fractalforums.org/discuss-fractalforums/5/printing-big-fractals/1731 fractalforums.org : printing-big-fractals] * [https://www.youtube.com/watch?v=PpmZjPljPvw printing big fractals by peter]: a rendered 170mb file I received to produce am image at 200 dpi 57 x 33 inches. The printer is an HP designjet 4500ps I rebuilt and its printing onto 180gsm coated paper. It will print up to 1067 mm x any length. ===poradnik=== https://forum.dobreprogramy.pl/t/inkscape-kolory-cmyk/510928/7 Teoretycznie się da ale ani to wygodne ani szybkie. Zakładam że w Inkscapie przygotowujesz rysunek wektorowy i tym wektorom chcesz nadać kolory cmykowe. Po pierwsze zainstaluj w systemie profile CMYK, oczywiście najlepiej te które dostaniesz od drukarni ale praktyka mówi że drukarnia nigdy nie wie jaki profil użyć więc jeśli jeszcze nie masz żadnych profili cmykowych to zainstaluj te z http://www.eci.org. 326 Ja używam ISOcoated_v2_eci.icc to jest profil o zafarbieniu 340 (o ile dobrze pamiętam), gdybyś ich tam nie znalazł to tutaj masz linka bezpośredniego z mojego serwera: ftp://ttmath.org/pub/color_management/profile_cmyk_dla_programow/ Taki profil instalujesz sobie w systemie, w moim przypadku kopiuje je do odpowiedniego katalogu: /home/tomek$ ls -1 .local/share/color/icc 27MP65.icm ISOcoated_v2_300_eci.icc ISOcoated_v2_eci.icc PSO_Uncoated_ISO12647_eci.icc eciRGB_v2.icc eciRGB_v2_ICCv4.icc Teraz konfigurujesz inkscape aby używał odpowiedniego profilu, screenshot: Następnie we właściwościach dokumentu Inkscepa w zakładce ‘kolor’ dodajesz odpowiedni profil: Teraz w Inkscapie przy ustawianiu kolorów dla obiektów uaktywni się zakładka CMS (nie CMYK), na zakładce CMS z listy rozwijanej wybierzesz nasz profil i wtedy pojawią się cztery suwaczki którymi ustawiasz jaki kolor ma być w wyeksportowanym pliku. Jak zauważysz będziesz mógł zmieniać także kolor przy pomocy zakładki RGB albo CMYK ale te ustawienia będą tylko poglądowe na ekranie to co ma się wyeksportować to ustawiamy na zakładce CMS. Zrobiłem prosty dokument w którym na górze są cztery kwadraty w pełnych cmykowych kolorach oraz na dole tekst w 100 procentowym czarnym: Nie ma jednak tak dobrze, to jeszcze nie koniec. Inkscape będzie używał naszego cmyka ale tylko w dokumentach SVG, w tej chwili nie potrafi jeszcze wyeksportować cmykowego dokumentu PDF. Z pomocą przyjdzie nam Scribus. W Inkscapie zapisujemy dokument *.svg, najlepiej wybrać opcję ‘czysty dokument svg’ aby Inkscape nie dodawał zbędnych atrybutów a następnie w Scribusie importujemy dokument SVG i eksportujemy cmykowego PDFa. Oczywiście na początku wstępna konfiguracja dokumentu: I po konfiguracji wybieramy opcję Plik -> Importuj -> Pobierz plik wektorowy… Tu jednak nastąpi problem, Scribus nie potrafi wczytać wszystkich właściwości obiektów (pędzle, wypełnienia itp) które ustawi Inkscape. Możemy to obejść otwierając dokument svg w edytorze tekstu bo to przecież jest zwykły xml i usuwając pare nadmiarowych styli które wstawił Inkscape: A tak wygląda dokument po usunięciu styli: Teraz ponownie próbujesz zaimportować plik do Scribusa i tym razem się udaje: I już możesz wyeksportować plik pdf: Zauważ że eksportuję jako PDFX, dlaczego to zakładam że wiesz. I tutaj końcowy efekt naszych prac: http://tmp.ttmath.org/inkscape_cmyk/rysunek_cmyk.pdf 123 Możesz ten plik otworzyć w programie graficznym obsługującym cmyka (przy imporcie uważaj aby była zaznaczona konwersja z cmyka) i po imporcie sprawdzić kolory, kwadraty będą miały czyste kolory cmykowe, odpowiednio pierwszy z lewej od góry: (100, 0, 0, 0), w środu u góry (0, 100, 0, 0) i tak dalej a tekst będzie miał tylko setke czarnego. Jeśli w swojej pracy masz bitmapy to je umieszczasz w Scribusie, Inkscape chyba nie da rady wyeksportować bitmapy cmykowej. Sam widzisz że dać się da ale ani to wygodne a i możliwość popełnienia błędu duża szczególnie przy poprawkach pliku w edytorze tekstu. ===dpi=== DPI * 300 dpi does the trick * 600 dpi looks great with graphics * 1200 dpi is ready to be sent to the company executives * 1440+ dpi is professional-level photographic print quality === Printing method=== * '''a litho print''' involves the printer making a set of 'plates' that are used to press the image to the paper. Creating these plates comes at a cost and doesn’t offer the immediacy of digital poster printing. The initial outlay can be expensive, but if you’re doing a large print run and want to output up to A1, it’s the process that offers a higher quality print and finish than digital printing. * '''Digital printing''' with inkjet or laser printers is the cheaper and quicker of the two and good for smaller print runs. If budget is an issue and you’re not being too exacting over the quality, go with digital printing. This is also fine if you're not going above A3. Links * [https://www.lifewire.com/4-6-8-color-process-printing-1077448 lifewire : 4-6-8-color-process-printing by Jacci Howard Bear Updated on November 25, 2019] === base === There are three main '''types of large posters''': * Paper posters are the most common type of large poster. They are usually printed on high-quality paper and are a great way to make a statement. you can print it out onto some paper and laminate it. * Vinyl posters are made of durable vinyl and are perfect for outdoor use. * Fabric posters are made of lightweight fabric and are perfect for indoor use. Paper * GSM stands for grams per square meter and determines how heavy the paper stock is Different paper types for posters include: * Gloss ( Gloss Art FSC or 150gsm ) – As the name suggests, this paper offers a glossy sheen to any poster. The shiny finish encourages an eye-catching look for your poster designs and is available in six different paper weights. * Bond – 100% recycled and high-quality, bond paper is an environmentally-friendly poster option. It’s durable and available in two different weights at Solopress. * Day Glo – For a fluorescent colour scheme, day glo posters are the go-to. With a luminous effect, this paper is perfect for making a huge impression. * Light Box – When you’re using a back light to illuminate a poster advert, print it on light box paper. It’s the ideal method for use in cinemas, theatres and on the street. * 170gsm Silk === size === There are five A poster sizes to choose from, each suiting a different purpose: * A4 – Small, but with enough room to make an impact, A4 posters are a great option. Available in a huge selection of paper types and weights, they’re a versatile choice. * A3 – If you’re looking for a little more room to play with, A3 can get your message across. It’s commonly seen indoors in bars or shop windows – the right mix of detail and white space make it especially eye-catching. * A2 – This is the perfect size for gig and event posters. A2 posters can display snippets of information and leave enough room for impressive artwork and imagery. * A1 – Our most popular choice at Solopress, A1 posters can super-size your message. Large fonts and grand designs are ideal for posters hanging in exhibition halls or museums. * A0 – Over one metre in width, A0 posters can make a big impression on viewers. This size allows for large, eye-catching artwork and has space for lots of information. A sizes (1.413 ratio): * A4 Paper Poster Size: 8.5” x 11” = (21 x 29.7 cm) = 2 550 x 3 300 points ( at 300 dpi ) = * A3 = 420 x 297 mm = 42 x 29.7 cm = 16.54 x 11.69 in = 4 962 x 3 507 points ( at 300 dpi) * A2 = 594 x 420 mm = 59.4 x 42 cm = 23.39 x 16.54 in = 7 017 x 4 962 points ( at 300 dpi ) * A1 = 841 x 594 mm = 84.1 x 59.4 cm = 33.11 x 23.39 in = 9 933 x 7 017 points ( at 300 dpi) * A0 = 1189 x 841 mm = 118.9 x 84.1 cm = 46.81 x 33.11 in = 14 043 x 9 933 points ( at 300 dpi) B sizes ( 1.4 ratio) * B2 = 707 x 500 mm = 70.7 x 50 cm = 27.83 x 19.69 in = 8 349 x 5 907 point ( at 300 dpi) * B1 = 1000 x 707 mm = 100 x 70.7 cm = 39.37 x 27.83 in = * B0 = 1400 x 1000 mm 140 x 100 cm = 55.12 x 39.37 in = https://www.canva.com/sizes/poster/ SIZE DIMENSION Smallest 8.5×11 in = 21.59 × 27.94 cm Small 11 × 17 in = 27.94 × 43.18 cm Medium 18 × 24 in = 45.72 × 60.96 cm Large 24 × 36 in = 60.96 × 91.44 cm Movie 27 × 40 in = 68.58 × 101.6 cm Bus Stop 40 × 60 in = 101.6 × 152.4 cm === unit system=== * The United States uses the Imperial system, which comes from the old British Imperial System. * The rest of the world uses the Metric system, developed in the late 18th century to unify all confusing measurements systems ===file=== * format pdf ver. 1.3. * https://profesjonalnydruk.pl/pliki-do-druku/ * https://wydrukujemy.to/pliki-do-druku/ * https://www.printworld.com/pl/plakat-a2-pion-1s.pdf * https://drukarniakursor.pl/przygotowanie-do-druku/ * https://www.walstead-ce.com/wp-content/uploads/2019/05/SPIN01_Przygotowanie-materia%C5%82%C3%B3w-do-druku.pdf * https://coloursfactory.pl/app/uploads/2021/04/cf-specyfikacja-techniczna-PL-A4_www.pdf * https://graphicdesign.stackexchange.com/questions/143024/how-to-check-if-a-pdf-file-is-in-rgb-or-cmyk Ubuntu: * GIMP - no CMYK * Krita ( CMYK) * Krita nie ma możliwości eksportu PDF, ani nie jest taka planowana. Aby utworzyć plik PDF z obrazami z Krity, należy użyć Scribus. * Scribus supports professional publishing features, such as CMYK colors, spot colors, ICC color management and versatile PDF creation ** [https://wiki.scribus.net/canvas/Your%20first%20PDF%20form%20with%20Scribus Your first PDF form with Scribus] ** [https://wiki.scribus.net/canvas/Color%20Management%20setup scribus: Color Management setup] ===TAC or TIC or TIL=== * https://www.prepressure.com/design/basics/tic * https://www.cummingsprinting.com/technotes/total-area-coverage/ * https://graphicdesign.stackexchange.com/questions/73233/total-ink-coverage-on-cmyk-digital-printing * https://callingcardbooks.com/whats-total-area-coverage-tac-and-why-does-ingramspark-care/ * https://creativepro.com/reducing-the-total-ink-limit-cmyk-images-using-photoshop/ * https://stackoverflow.com/questions/3092356/calculate-cmyk-coverage-on-pdf * https://stackoverflow.com/questions/6241282/converting-pdf-to-cmyk-with-identify-recognizing-cmyk?rq=1 * nafarbienie : https://grafmag.pl/artykuly/cmyk-i-rgb-roznice-w-wydruku When several colors are printed on top of each other, there is a limit to the amount of ink or toner that can be put on paper. This maximum total dot percentage is referred to as either * TIC (Total Ink Coverage) * TAC (ang. Total Area Coverage, pl. Suma wartości tonalnych) * [https://aldertech.com/what-is-the-right-total-ink-limit-setting/ TIL ( TOTAL INK LIMIT )] When a designer ignores this technical limitation, the ink that gets laid down last won’t attach properly to the previous layers, leading to muddy browns in neutral areas. The ink also won’t dry properly on the press sheets. This can cause set-off where the ink of a still wet sheet rubs off on whatever is stacked on top of it. technique * Under Color Removal (UCR) does indeed reduce the amount of ink used to print grayish colors. * Gray Component Replacement (GCR) that replaces equal portions of cyan, magenta and yellow by black in all colors. It can lead to even bigger ink savings. SWOP = [[:w:Specifications_for_Web_Offset_Publications|Specifications for Web Offset Publications]] ===color === * color separation = split color to 4 ( or more) inks * https://www.castleprint.co.uk/spot-and-process-colours-explained/ * RGB -> CMYK : * Color in printing ** spot color = colour chosen from a colour swatch, like standard Pantone© colours swatch ** Process Colour ( CMYK): *** Pantone 032 colour split to CMYK: Cyan = 0% – Magenta = 90% – Yellow = 86% – Black = 0% *** Pantone 247 is made up of 36% Cyan & 100% Magenta, with no yellow or black (K). industry standards in the classification of spot color systems * [[Pantone]], the dominant spot color printing system in the [[United States]] and [[Europe]]. PMS = Pantone Matching System * [[Toyo Ink|Toyo]], a common spot color system in [[Japan]]. * [[Dainippon Ink & Chemicals|DIC]] Color System Guide, another spot color system common in Japan – it is based on [[Munsell color system|Munsell color theory]].<ref>[http://www.theinformedillustrator.com/2012/09/process-versus-spot-color.html The Informed Illustrator: Digital Spot Color Systems]</ref> * [[ANPA color palette|ANPA]], a palette of 300 colors specified by the [[Newspaper Association of America|American Newspaper Publishers Association]] for spot color usage in [[newspapers]]. * [[GCMI]], a standard for color used in package printing developed by the Glass Packaging Institute (formerly known as the Glass Container Manufacturers Institute, hence the abbreviation). * [[HKS (colour system)|HKS]] is a color system which contains 120 spot colors and 3,250 tones for coated and uncoated paper. HKS is an abbreviation of three German color manufacturers: Hostmann-Steinberg Druckfarben, Kast + Ehinger Druckfarben and H. Schmincke & Co. * [[RAL (color space system)|RAL]] is a color matching system used in Europe. The so-called RAL CLASSIC system is mainly used for varnish and powder coating. Because each color system creates their own colors from scratch, spot colors from one system may be impossible to find within the library of another. [https://www.lifewire.com/use-spot-or-process-colors-1077446 When to Use]: * Spot Colors (Such as PMS Colors) * Process Colors (CMYK) * Process and Spot Colors Together * 6-Color or 8-Color Process Printing Black in cmyk * https://graphicdesign.stackexchange.com/questions/130388/where-does-black-come-from-in-cmyk-color-mode * https://graphicdesign.stackexchange.com/questions/2984/what-kind-of-black-should-i-use-when-designing-for-cmyk-print * https://graphicdesign.stackexchange.com/questions/668/whats-the-difference-between-cmyk-black-and-rgb-black?noredirect=1&lq=1 * https://graphicdesign.stackexchange.com/questions/12860/when-should-i-use-rich-black ====problems==== * https://www.clearprint.com/cmyk-printing-problems-solved/ ==color== * a '''web‑safe colors''': The web‑safe colors are the 216 colors used by browsers regardless of the platform. The browser changes all colors in the image to these colors when displaying the image on an 8‑bit screen. The 216 colors are a subset of the Mac OS 8‑bit color palettes. By working only with these colors, you can be sure that art you prepare for the web will not dither on a system set to display 256 colors.<ref>[https://helpx.adobe.com/photoshop/using/choosing-colors.html helpx.adobe photoshop: using/choosing-colors]</ref> * a '''non-printable color''': Some colors in the RGB, HSB, and Lab color models cannot be printed because they are out-of-gamut and have no equivalents in the CMYK model. * a '''spot color''': ===spot color libraries=== The Adobe Color Picker supports the following color systems ( libraries): * ANPA-COLOR: Commonly used for newspaper applications. The ANPA-COLOR ROP Newspaper Color Ink Book contains samples of the ANPA colors. * DIC Color Guide: Commonly used for printing projects in Japan. For more information, contact Dainippon Ink & Chemicals, Inc., in Tokyo, Japan. * FOCOLTONE: Consists of 763 CMYK colors. Focoltone colors help avoid prepress trapping and registration problems by showing the overprints that make up the colors. A swatch book with specifications for process and spot colors, overprint charts, and a chip book for marking up layouts are available from Focoltone. For more information, contact Focoltone International, Ltd., in Stafford, United Kingdom. * HKS swatches: Used for printing projects in Europe. Each color has a specified CMYK equivalent. You can select from HKS E (for continuous stationery), HKS K (for gloss art paper), HKS N (for natural paper), and HKS Z (for newsprint). Color samplers for each scale are available. HKS Process books and swatches have been added to the color system menu. * TRUMATCH: Provides predictable CMYK color matching with more than 2,000 achievable, computer-generated colors. Trumatch colors cover the visible spectrum of the CMYK gamut in even steps. The Trumatch Color displays up to 40 tints and shades of each hue, each originally created in four-color process and each reproducible in four colors on electronic imagesetters. In addition, four-color grays using different hues are included. For more information, contact Trumatch Inc., in New York City, New York. ===contrast ratio=== * https://github.com/adobe/leonardo ===black=== * czernią 100K ( ang. black), a tzw. bogatą czernią ( ang. rich black). Efekt jest taki, że w druku zwykła czerń (100K) jest ciemnoszara zamiast czarna. Po to właśnie używa się rich blacka. === profile kolorów === * [http://www.eci.org/doku.php?id=en:downloads European Color Initiative (ECI)] * https://www.colormanagement.org/index_en.html * print : Cmyku Coated FOGRA 39 dla profilu Print * RGB ** sRGB dla profilu Web ( został stworzony do wyświetlania kolorów m.in. w internecie i posiada najwęższy zakres możliwych barw, dzięki czemu kolory są wyświetlane w całej gamie bez względu na klasę monitora i karty graficznej użytkownika. Jeżeli przygotowujesz jakąkolwiek grafikę czy zdjęcie, które umieścisz w internecie — chcesz przypisać profil sRGB ) ** Adobe RGB (1998) został stworzony jako większy brat sRGB, a jego zakres kolorów jest szerszy i służy głównie do opisywania kolorów na fotografiach (ogólnie mówiąc wszelkich skomplikowanych obrazach rastrowych, które mają być drukowane i obrabiane). ** jest Lab (właściwie CIELAB D50). Posiada najszerszy gamut spośród wszystkich przestrzeni jakie istnieją. Opisywanie kolorów w tej przestrzeni oparte jest na postrzeganiu koloru przez ludzkie oko. I chociaż traktowany jest jako niezależny od urządzenia, można powiedzieć, że jest zależny od oka ludzkiego. Lab jest najtrudniejszy do zrozumienia, ponieważ nie posiada tradycyjnych kanałów z pojedynczymi kolorami. Skrót Lab to trzy kanały — luminancja (Lightness), a (tinta) i b (temperatura). Lightness zawiera informację jedynie o luminancji obrazu (jego naświetlenia, jasności i jaskrawości). Kanał ten przypomina z grubsza czarno białą wersję obrazu i przyjmuje wartości od zera (czerń) do 100 (biel). Kanał “a” to oś zieleń — czerwień (a właściwie karmazyn), natomiast kanał “b” to oś żółcień — ciemny niebieski (zbliżony do fioletu). Na pierwszy rzut oka te osie barw nie mają większego sensu, ale w rzeczywistości są odzwierciedleniem realnych barw powstających przy padaniu światła słonecznego na rzeczywiste obiekty. Z tego też powodu regulacja balansu bieli w module wywoływania negatywów cyfrowych w Photoshopie oparta jest na osiach Lab. Oś “b” odzwierciedla temperaturę barwową światła (od żółtej czyli ciepłej, do niebieskiej czyli zimnej), natomiast oś “a” to tinta, która reguluje zabarwianie sceny w zależności od światła odbitego od obiektów (np. ciasne podwórko wśród kamienic wydaje się być niebieskawo-fioletowe). Tryb Lab jest niezmiernie użyteczny, jeśli chcemy korygować jedynie tonację naszego zdjęcia, ponieważ pracujemy wtedy na kanale Lightness, podczas gdy w RGB proces ten jest niemożliwy, gdyż tony są połączone z informacją o barwie w poszczególnych kanałach. Wykonując np. polecenie poziomy (levels) w trybie RGB, zmieniamy także kolory. Lab znakomicie nadaje się też do nasycania kolorów — pracujemy przecież na odseparowanych kanałach barw. Kolory w Lab są żywsze i bardziej klarowne niż podczas obróbki w RGB. Niestety Lab nie jest trybem powszechnym, nie można zapisać pliku jpeg w trybie Lab i ogólnie mówiąc bardzo mało aplikacji obsługuje ten tryb. Jest to środowisko stricte edycyjne. Po dokonaniu potrzebnych korekt w Lab, musimy przekonwertować nasz plik z powrotem do RGB czy innego trybu. ** profilem jest ProPhoto RGB, który ma najszerszy zakres gamutu i potrafi opisać całe bogactwo barw jakie tylko może zarejestrować matryca aparatu (nie do końca), przez co jest doskonałym wyborem jeśli chodzi o profesjonalną postprodukcję zdjęć i ich wydruk na wysokiej klasy drukarkach fotograficznych. Zarówno Adobe RGB jak i ProPhoto lepiej nadają się do obróbki zdjęć niż sRGB. Szczerze mówiąc różnica nie jest kolosalna, ale jeśli zależy nam na najwyższej możliwej jakości i elastyczności, lepiej obrabiać zdjęcia z powyższymi profilami, na samym końcu zamieniając go ewentualnie na sRGB. [https://blog.psboy.pl/2009/05/wielka-trojka-rgb-cmyk-lab/ Wielka trójka — RGB, CMYK, Lab. Sebastian Kończak ] ===gray scale=== In computing image pixels are usually quantized to store them as unsigned integers, to reduce the required storage and computation. Some early grayscale monitors can only display up to sixteen different shades, which would be stored in binary form using '''4 bits'''. But today grayscale images intended for visual display are commonly stored with '''8 bits per sampled pixel'''. This pixel depth allows 256 different intensities (i.e., shades of gray) to be recorded, and also simplifies computation as each pixel sample can be accessed individually as one full byte. However, if these intensities were spaced equally in proportion to the amount of physical light they represent at that pixel (called a '''linear encoding or scale'''), the differences between adjacent dark shades could be quite noticeable as banding artifacts, while many of the lighter shades would be "wasted" by encoding a lot of perceptually-indistinguishable increments. Therefore, the shades are instead typically spread out evenly on a '''gamma-compressed nonlinear scale''', which better approximates uniform perceptual increments for both dark and light shades, usually making these 256 shades enough to avoid noticeable increments. ==transformation== * 2D * 3D ** OpneGL ===notation=== In [[linear algebra]], a '''column vector''' with m elements is an <math>m \times 1</math> [[Matrix_(mathematics)|matrix]] consisting of a single column of m entries, for example, <math display="block">\boldsymbol{x} = \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_m \end{bmatrix}.</math> Similarly, a '''row vector''' is a <math>1 \times n</math> matrix for some n, consisting of a single row of n entries, <math display="block">\boldsymbol a = \begin{bmatrix} a_1 & a_2 & \dots & a_n \end{bmatrix}. </math> {| class="wikitable" |- ! !! Row vector !! Column vector |- | '''Standard matrix notation'''<br/>(array spaces, no commas, transpose signs) | align=center| <math> \begin{bmatrix} x_1 \; x_2 \; \dots \; x_m \end{bmatrix} </math> | align=center| <math> \begin{bmatrix} x_1 \\ x_2 \\ \vdots \\ x_m \end{bmatrix} \text{ or } \begin{bmatrix} x_1 \; x_2 \; \dots \; x_m \end{bmatrix}^{\rm T} </math> |} <gallery> Row_and_column_major_order.svg|Illustration of difference between row- and column-major ordering </gallery> ===gallery=== <gallery> Lambert draw.png Gnomonic draw.png Scaled angle projection draw.png Fisheye-view projection.png Orthographic draw.png Stereographic draw.png Variable center projection draw.png </gallery> ===scaling or resizing=== * Resize a plane figure's linear dimensions by a scale factor s * When the size is changed, the object may also move * If the scaling factor S is less than 1, then we reduce the size of the object ( contraction or reduction). If the scaling factor S is greater than 1, then we increase size of the object ( dilation or enlargement ) * [https://www.geogebra.org/m/JhaRDXZP Geogebra : Enlarging to a Scale Factor and Centre by Jonathan Robinson] * [https://www.geogebra.org/m/hMNc4eES geogebra : Transformations by DavidA] * [[:w:Scaling_(geometry)|Scaling in geometry ( wikipedia)]] Scaling of object by by a scale factor s = sx+ sy*i x’ = x * sx y’ = y * sy. Scaling * Uniform (maintains the object’s proportions as it scales): sx = sy * non-uniform: sx != sy Resizing objects while maintaining a fixed centre point = Scaling object about their own center * width' = width * sx * height' = height * sy * compute coordinate of corners from the center ===rotation=== When we rotate a shape one should know: * a centre of rotation * the angle and units of the rotation * the direction of rotation ====point==== * a rotation about the origin O by an angle θ * a 2D clockwise theta degrees rotation of point (x, y) around point (a, b) About origin: float s = sin(angle); // angle is in radians float c = cos(angle); // angle is in radians For clockwise rotation : float xnew = p.x * c + p.y * s; float ynew = -p.x * s + p.y * c; For counter clockwise rotation : float xnew = p.x * c - p.y * s; float ynew = p.x * s + p.y * c; [https://gamedev.stackexchange.com/questions/111343/get-local-coords-from-global-coords Code in Java] * global coordinate ( before rotation) * local coordinate ( after rotation) * origin = (pointX, pointY) * <syntaxhighlight lang="java"> public static double[] getLocalFromGlobal(int pointX, int pointY, int localX, int localY, float angle) { float px = pointX - localX; float py = pointY - localY; double cos = Math.cos((Math.PI / 180) * angle); double sin = Math.sin((Math.PI / 180) * angle); double finalX = (px * cos) + (py * sin); double finalY = -(px * sin) + (py * cos); return new double[]{finalX, finalY}; } </syntaxhighlight> [https://stackoverflow.com/questions/2259476/rotating-a-point-about-another-point-2d First subtract the pivot point (cx,cy), then rotate it (counter clock-wise), then add the point again.] <syntaxhighlight lang="c"> POINT rotate_point(float cx,float cy, float angle, POINT p) { float s = sin(angle); float c = cos(angle); // translate point back to origin: p.x -= cx; p.y -= cy; // rotate point float xnew = p.x * c - p.y * s; float ynew = p.x * s + p.y * c; // translate point back: p.x = xnew + cx; p.y = ynew + cy; return p; } </syntaxhighlight> <syntaxhighlight lang="python"> def rotate(origin, point, angle): """ Rotate a point counter-clockwise by a given angle around a given origin. """ # Convert negative angles to positive angle = normalise_angle(angle) # Convert to radians angle = math.radians(angle) # Convert to radians ox, oy = origin px, py = point # Move point 'p' to origin (0,0) _px = px - ox _py = py - oy # Rotate the point 'p' qx = (math.cos(angle) * _px) - (math.sin(angle) * _py) qy = (math.sin(angle) * _px) + (math.cos(angle) * _py) # Move point 'p' back to origin (ox, oy) qx = ox + qx qy = oy + qy return [qx, qy] def normalise_angle(angle): """ If angle is negative then convert it to positive. """ if (angle != 0) & (abs(angle) == (angle * -1)): angle = 360 + angle return angle </syntaxhighlight> ====object==== * [https://www.geeksforgeeks.org/2d-transformation-rotation-objects/ geeksforgeeks : 2d-transformation-rotation-objects] * [https://stackoverflow.com/questions/20023209/function-for-rotating-2d-objects stackoverflow question: function-for-rotating-2d-objects] * [https://gamedev.stackexchange.com/questions/178555/why-are-rotations-in-2d-game-engines-often-counter-clockwise-positive-systems gamedev.stackexchange question: why-are-rotations-in-2d-game-engines-often-counter-clockwise-positive-systems] First, we need a function to rotate a point around origin. When we rotate a point (x,y) around origin by theta degrees, we get the coordinates: <math> (x*cos(\theta)-y*sin(\theta), x*sin(\theta)+y*cos(\theta))</math> If we want to rotate it around a point other than the origin, we just need to shift it so the center point becomes the origin. Now, we can write the following function: from math import sin, cos, radians def rotate_point(point, angle, center_point=(0, 0)): """Rotates a point around center_point(origin by default) Angle is in degrees. Rotation is counter-clockwise """ angle_rad = radians(angle % 360) # Shift the point so that center_point becomes the origin new_point = (point[0] - center_point[0], point[1] - center_point[1]) new_point = (new_point[0] * cos(angle_rad) - new_point[1] * sin(angle_rad), new_point[0] * sin(angle_rad) + new_point[1] * cos(angle_rad)) # Reverse the shifting we have done new_point = (new_point[0] + center_point[0], new_point[1] + center_point[1]) return new_point Some outputs: print(rotate_point((1, 1), 90, (2, 1))) # This prints (2.0, 0.0) print(rotate_point((1, 1), -90, (2, 1))) # This prints (2.0, 2.0) print(rotate_point((2, 2), 45, (1, 1))) # This prints (1.0, 2.4142) which is equal to (1,1+sqrt(2)) Now, we just need to rotate every corner of the polygon using our previous function: def rotate_polygon(polygon, angle, center_point=(0, 0)): """Rotates the given polygon which consists of corners represented as (x,y) around center_point (origin by default) Rotation is counter-clockwise Angle is in degrees """ rotated_polygon = [] for corner in polygon: rotated_corner = rotate_point(corner, angle, center_point) rotated_polygon.append(rotated_corner) return rotated_polygon Example output: my_polygon = [(0, 0), (1, 0), (0, 1)] print(rotate_polygon(my_polygon, 90)) # This gives [(0.0, 0.0), (0.0, 1.0), (-1.0, 0.0)] [https://gamedev.stackexchange.com/questions/86755/how-to-calculate-corner-positions-marks-of-a-rotated-tilted-rectangle In C by Aholio] X = x*cos(θ) - y*sin(θ) Y = x*sin(θ) + y*cos(θ) This will give you the location of a point rotated θ degrees around the origin. Since the corners of the square are rotated around the center of the square and not the origin, a couple of steps need to be added to be able to use this formula. First you need to set the point relative to the origin. Then you can use the rotation formula. After the rotation you need to move it back relative to the center of the square. <syntaxhighlight lang="c"> // cx, cy - center of square coordinates // x, y - coordinates of a corner point of the square // theta is the angle of rotation // translate point to origin float tempX = x - cx; float tempY = y - cy; // now apply rotation float rotatedX = tempX*cos(theta) - tempY*sin(theta); float rotatedY = tempX*sin(theta) + tempY*cos(theta); // translate back x = rotatedX + cx; y = rotatedY + cy; </syntaxhighlight> ===warp=== "A square is warped into a quarter-slice of a disk. The same transformation is again applied to the quarter-slice, and again to the resulting shape, repeatedly. A strange shape is created, with three spindly legs that appear to walk from corner to corner. This is the attractor of this particular transformation. [code]" matthen https://blog.matthen.com/ ===composition=== A sequence of transformations can be combined into single one (composition, concatenation). The resulting matrix is called as composite matrix. Advantage of composition : * It transformations become compact. * The number of operations is reduced. * Rules used for defining transformation in form of equations are complex as compared to matrix. the order in which the transforms are applied: * is important * transforms are applied to objects in the reverse of the order in which they are given in the code (because the first transform in the code is applied to an object that has already been affected by the second transform). == 2D normalized homogenous coordinate == Coordinate * finite point <math>z</math> on the complex plane <math>z \in \hat{\mathbb{C}}</math> with [[:w:Cartesian coordinate system|Cartesian coordinate]] <math>z = x + y * i</math> * point r on the extended complex plane (= [[:w:Riemann sphere|Riemann sphere]] ) ** 2D [[:w:homogenous coordinate|homogenous coordinate]] <math>r = [s,t,u] </math> ** normalized 2D homogenous coordinate <math>n = [v,w] </math> Special points * [[:w:Origin (mathematics)|origin]] <math>z = 0</math> * [[:w:point at infinity|point at infinity]] ** in homogenous coordinate : when last coordinate u is 1 <math> [s,t, 1] </math> then it is a point at infinity ** in normalized homogenous coordinate <math>[v, 1] </math> ===Conversions=== * from [[:w:Cartesian coordinate system|Cartesian coordinate]] to [[:w:homogenous coordinate|homogenous coordinate]] * from [[:w:homogenous coordinate|homogenous coordinate]] to normalized homogenous coordinate * from normalized homogenous coordinate to [[:w:homogenous coordinate|homogenous coordinate]] ==== from homogenous to Cartesian coordinate ==== The original Cartesian coordinates are recovered by dividing the first two positions by the third. Thus unlike Cartesian coordinates, a single point can be represented by infinitely many homogeneous coordinates. Note that here not u ( typical) but 1-u is used The mapping from the sphere to the finite plane is If <math> u < 1 </math> <math>x = \frac{s}{1 - u}</math> <math>y = \frac{t}{1 - u}</math> <math>z = \frac{x + y*i}{1 - u}</math> If <math> u = 1 </math> then z is [[:w:point at infinity|point at infinity]] <math> z = \infty </math> =deep= * deep” pixels – those containing multiple samples per pixel (and a potentially differing number of them in each pixel) * deep image = image with deep pixels * [[:w:Color_depth#Deep_color_(30-bit)|Deep color in wikipedia]] = 30-bit color depth and more =HDR= High dynamic range (HDR) is a dynamic range higher than usual, synonyms are wide dynamic range, extended dynamic range, expanded dynamic range. Types: * HDR TV / HDR Video ** HD *** UHD = 4K = Ultra High Definition = ultra HD ** HDR-TV = Wider color gamut and contrast range than Standard Dynamic Range (SDR). Minimum 10-bit color depth and output at least 540 nits of peak brightness *** four primary HDR formats are HDR10/10+, Dolby Vision, HLG, and Technicolor HDR *** one need compatible equipment down the line ( from source, cables and all devices) An internet speed of 15 to 25mbps is required for stable viewing. * HDR photo * HDR image [https://www.w3.org/Graphics/Color/Workshop/slides/talk/kunkel SDR is a retronym that was established over the past 15 years to identify traditional content that uses:] * gamma encoding * more limited luminance ranges * WCG = Wider color gamut = color gamuts such as Rec. 709 or sRGB. https://www.flatpanelshd.com/focus.php?subaction=showfull&id=1559638820 https://www.lenovo.com/in/en/faqs/monitors-faqs/hdr-displays/ What is HDR? Without getting too deep into the technical details, an HDR display produces greater luminance and color depth than screens built to meet older standards. Here are some HDR basics: HDR display luminance Display luminance describes the amount of light it emits, which in turn determines the gap between the brightest and darkest pixels on the screen. The increased light produced by an HDR display makes its brightest pixels far brighter than before, further differentiating them from the darkest ones. This increased contrast ratio enables more subtle pixel-to-pixel changes and better image reproduction. Luminance is measured in candelas/m2 or "nits" -- a term that's increasingly common in the technical specifications for both professional and consumer monitors and laptop displays. Several different standards have been published to define what can qualify as an HDR display, generally starting at 400 nits for laptops and rising to 1000 or even 10,000 nits for high-end professional monitors. HDR display color depth Color depth refers to how many bits of data each pixel of a display can utilize to produce the colors in an image or video. Before HDR, most displays topped out at 8-bit color. But the new HDR formats can process 10-bit (or even 12-bit) color, increasing the potential on-screen color variations exponentially. It's all in the math. Whether directly or through what's called dithering, 8-bit color depth allows for 256 different shades of each primary color, making it possible to generate about 16.5 million color variations. 10-bit color bumps the number of shade options from 256 to 1024 -- increasing the maximum color variations to more than 1 billion! [https://www.eizo.com/library/basics/pixel%20density%204k/ 4K resolution] * DCI 4K is twice the 2048 x 1080 pixel resolution of projectors (4096 x 2160/approx. 17:9) and is the 4K resolution of the film industry. * UHD 4K (also called UHDTV 4K), on the other hand, is the 4K resolution of the television industry defined by the International Telecommunication Union (ITU). It has twice the horizontal resolution of 1920 x 1080 pixel full HD (3840 x 2160/16:9). ==hdr video== HDR TV formats * HDR10: Most widely used open standard for HDR with 10-bit color and generalized meta data * Dolby Vision: Proprietary Dolby HDR technology promising 12-bit equivalent color and scene-by-scene meta data * HDR10+: A new, proprietary HDR format being developed reportedly with frame-by-frame meta data * HLG (Hybrid Log Gamma, from BBC and NHK) * Advanced HDR from Technicolor HDR monitor : VESA's HDR standards for monitors: * VESA DisplayHDR 400 * VESA DisplayHDR 1400 ===game=== You need four things to enable HDR on your PC: * A GPU that supports HDR * A display that supports HDR * A DisplayPort 1.4 or HDMI 2.0a (or newer) connection * HDR content, such as a game or streaming service https://displayhdr.org/ HDR on a PC. * A monitor that’s DisplayHDR 1000 certified or a quality HDR television. * A video card from the AMD RX 400, Nvidia GTX 900 series, or Intel integrated graphics found in Intel 7th-gen Core, or newer. * An HDMI 2.0a, DisplayPort 1.4, or Thunderbolt 4 connection, or newer. * Microsoft’s HEVC Extensions, which are sold on the Microsoft Store. * HDR content, such as an HDR-compatible game or streaming service. https://www.pcworld.com/article/394712/everything-you-need-to-know-about-hdr-on-your-pc.html ==image== HDRI stands for High Dynamic Range Imaging, and is basically an image format that contains from the deepest shadow up to the brightest highlight information. * the LDR an 'ordinary' digital image contains only 8 bits of information per color (red, green, blue) which gives you 256 gradations per color ( '''integers''' from 0 to 255 ) * the HDR image format stores the 3 colors with '''floating point accuracy'''. Thus the 'depth' from dark to light per color is virtually unlimited. Using HDR images in a 3D environment will result in very realistic and convincing shadows, highlights and reflections. This is very important for realistic emulation of chrome for example. High Dynamic Range (HDR) image was created by * merging LDR images ( photos) at different exposure ( multi-exposure HDR capture) = HDRI = High-dynamic-range imaging. In photography and videography, is a technique that creates extended or high dynamic range (HDR) images by taking and combining multiple exposures of the same subject matter at different exposure levels. Combining multiple images in this way results in an image with a greater dynamic range than what would be possible by taking one single imagage ( photo) * inverse tone mapping (ITM) a single exposure LDR image ( photo) * High-dynamic-range rendering (HDRR or HDR rendering), also known as high-dynamic-range lighting, is the rendering of computer graphics scenes by using lighting calculations done in high dynamic range (HDR) =computer graphic Image types * photography = photo * computer graphic HDR (high dynamic range) można krótko zdefiniować jako łączenie kilku zdjęć tej samej sceny, ale o różnym naświetleniu, w celu otrzymania jednego obrazu o powiększonym zakresie tonalnym (najciemniejszy punkt odpowiada takiemu punktowi na zdjęciu najciemniejszym, najjaśniejszy punkt odpowiada takiemu punktowi na zdjęciu najjaśniejszym). [https://blog.psboy.pl/2010/01/hdr-czy-tylko-tandetny-efekt/ hdr-czy-tylko-tandetny-efekt. Sebastian Kończak] głębia bitowa urządzeń * które obecnie używamy to osiem bitów na kanał, czyli 256 gradacji tonów. * Tymczasem HDR to 32 bity na kanał (ta wartość jest różna dla poszczególnych algorytmów i formatów zapisu) Urządzenia: * nasze oko widzi w HDR, czyli szerokim zakresie tonów * tymczasem aparaty fotograficzne (cyfrowe oczywiście też) „widzą” w mocno zawężonym zakresie LDR (low dynamic range) Etapy: * wykonać zdjęcia jednej sceny, najlepiej trzy i więcej klatek. * Przy fotografowaniu sceny korzystamy z opcji bracketingu w aparacie. Standardowe podejście to –2EV, 0 (domyślna ekspozycja zmierzona przez aparat), +2EV. Zatem mamy zdjęcie niedoświetlone, naświetlone prawidłowo i prześwietlone. Połączenie ich razem da nam zakres tonalny od najciemniejszych wartości zdjęcia niedoświetlonego, aż do najjaśniejszych obszarów zdjęcia prześwietlonego. * Proponuję także fotografować w formacie RAW, ponieważ dodatkowo zachowujemy potężny zakres tonów (16 bitowy) w porównaniu do 8 bitów w pliku JPEG, nie wspominając o braku kompresji stratnej i innych obróbek dokonywanych przez aparat. * wybrać 16 bits/channel, co pozwoli nam przekonwertować HDR’a na głębię 16 bitową, korzystając z którejś z dostępnych metod, a także przywrócić użyteczność wszystkich narzędzi i opcji Photoshopa. HDR Conversion, w którym mamy do wyboru cztery metody konwersji: * Exposure & Gamma (Ekspozycja i Kontrast Tonów Średnich) – pozwala na wybranie konkretnej ekspozycji (czyli po prostu jasności sceny) oraz jej kontrastu. Jest to metoda domyślna i produkuje najlepsze efekty, jeżeli naszym celem jest tylko poszerzony zakres tonalny, bez agresywnych efektów wizualnych, które możemy spotkać w internecie. * Highlight Compression (Kompresja Świateł) – jest metodą automatyczną, gdzie zakres tonalny zostaje skompresowany do 16 bitów od strony tonów jasnych. Pozwala to uniknąć prześwietleń w najjaśniejszych partiach sceny. * Equalize Histogram (Wyrównanie Histogramu) – metoda automatyczna, powoduje skompresowanie histogramu od strony cieni i świateł, zachowując przy tym średni, domyślny kontrast sceny. * Local Adaptation (Lokalne Dopasowanie) – jest to metoda produkująca tzw. „efekt” HDR, czyli charakterystyczne rozjaśnienia wokół konturów przedmiotów. Mamy tutaj dwa suwaki – Radius (Promień), w którym ustalamy wielkość lokalnego rozświetlenia, oraz Threshold (Próg) – w którym ustalamy jak bardzo mają się tonalnie różnić sąsiadujące piksele, by zakwalifikować je do jednego obszaru rozświetlenia. W tej metodzie mamy też do dyspozycji krzywą tonalną i histogram, dzięki którym możemy dopasować jasność i kontrast ogólny sceny. Ta metoda produkuje dobre „efekty” HDR, szczególnie w połączeniu z poleceniem Image – Adjustments – Shadow/Highlights (Obraz – Dopasowania – Cień/Światła). Tone mapping https://blog.psboy.pl/2016/11/photoshop-w-godzine-cz-4-gra-w-rawy/ ===photo=== https://www.adobe.com/creativecloud/photography/discover/hdr.html ==cgi== Computer-generated imagery, computer-graphic effects in films, television programs, and other visual media These images are * static (i.e. still images) * dynamic (i.e. moving images). The application of CGI for creating/improving animations is called computer animation, or CGI animation. CGI both refers to: * 2D computer graphics and (more frequently) * 3D computer graphics with the purpose of designing characters, virtual worlds, or scenes and special effects (in films, television programs, commercials, etc.). =RAW= * [[Python_Programming/Errors|raw_input in python]] * raw graphic image formats * raw disc image format : format is a plain binary image of the disc image, and is very portable. See [[QEMU/Images|QEMU Image formats]] * [[Haskell/Libraries/Data_structures_primer|in Haskell]] ** raw primitive values ** raw bytes ** raw performance with arrays * [[R Programming/Estimation utilities|in R programming language: raw function option]] * datbase : [[Oracle_and_DB2,_Comparison_and_Compatibility/Storage_Model/Data_Types/Oracle|Oracle RAW Data Types]]: Both RAW and LONG RAW are used for data that is not interpreted by the database binary data and byte strings, LONG RAW is (or rather was) for large binary objects – for the storage of Audio, Video. * C++ ** [[C++ Language/Preprocessing/PreprocessingStrings|raw-string-literal]] ** [[C++ Language/Indirection/SmartPointers/RiskFromRawPointers|Raw Pointers]] =PBURF= git clone https://github.com/luisjavierhernandez/PBURF.jl.git cd PBURF.jl cd src <syntaxhighlight lang="julia"> julia _ _ _ _(_)_ | Documentation: https://docs.julialang.org (_) | (_) (_) | _ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help. | | | | | | |/ _` | | | | |_| | | | (_| | | Version 1.5.3 _/ |\__'_|_|_|\__'_| | Ubuntu ⛬ julia/1.5.3+dfsg-3 |__/ | julia> pwd() "/home/a/PBURF.jl/src" julia> readdir() 1-element Array{String,1}: "PBURF.jl" julia> include("PBURF.jl") julia> import Pkg; Pkg.add("Polynomials") julia>import Pkg; Pkg.add("Polynomials") julia>import Pkg; Pkg.add("Colors") </syntaxhighlight> = function calculators = * [https://www.symbolab.com/solver/functions-calculator symbolab ] * [https://www.mathway.com/Algebra mathway - function algebra] * [https://wims.univ-cotedazur.fr/wims/en_tool~analysis~function.en.html Gang XIAO] * [https://www.emathhelp.net/calculators/calculus-1/function-calculator/ emathhelp] * [https://www.desmos.com/calculator/zzxbryrahc?lang=pl desmos] * [https://www.wolframalpha.com/calculators/domain-range-calculator/ wolframalpha: domain-range-calculator] * [https://www.mathworks.com/help/symbolic/find-asymptotes-critical-and-inflection-points.html mathworks:ind-asymptotes-critical-and-inflection-points ( online) ] =critical point = https://math.stackexchange.com/questions/502750/when-is-infty-a-critical-point-of-a-rational-function-on-the-sphere Just choose an appropriate pair of charts. Write <math>f(z) = p(z) / q(z)</math>, where <math>p</math> and <math>q</math> are polynomial functions with no common zeros. We may assume <math>f</math> is not a constant function – the constant case is trivial. There are a few cases: ==first case== * <math>f(\infty) = \infty</math> – look at the function <math>w \mapsto \frac{1}{f(1 / w)}</math>. The derivative is given by <math>\frac{f' (1/w)}{w^2 f(1/w)^2} = \frac{p'(1/w) q(1/w) - p(1/w) q'(1/w)}{w^2 p(1/w)^2}</math> but it's not immediate how to extract anything useful from this expression. Instead, suppose the leading term of <math>p(z)</math> is <math>a z^n</math> while the leading term of <math>q(z)</math> is <math>b z^m</math>. We must have <math>n > m</math> if <math>f(\infty) = \infty<math>, and the numerator is of degree <math>n + m - 1</math> (in terms of <math>1/w</math>) and the denominator is of degree <math>2 n - 2</math>. Now there are two subcases: * <math>m = n - 1</math> – then the value of the expression at <math>w = 0</math> is <math>\frac{b}{a}</math>; in particular, <math>\infty</math> is not a critical point of <math>f</math>. * <math>m < n - 1</math> – then the value of the expression at <math>w = 0</math> is <math>0</math>, so <math>\infty</math> is a critical point of <math>f</math>. ==second case== <math>f(\infty) \ne \infty</math> look at the function <math>w \mapsto f(1 / w)</math>. The derivative is given by <math>-\frac{f' (1/w)}{w^2} = -\frac{p'(1/w) q(1/w) - p(1/w) q'(1/w)}{w^2 q(1/w)^2}</math> but again it's not clear what we can say from this. Let <math>a z^n</math> be the leading term of <math>p(z)</math> and let <math>b z^m</math> be the leading term of <math>q(z)</math>. We must have <math>n \le m</math> if <math>f(\infty) \ne \infty</math>, and the numerator is of degree <math>n + m - 1<math> (if <math>n \ne m</math>) or <math>< n + m - 1</math> (if <math>n = m</math>) and the denominator is of degree <math>2 m - 2</math>. Now there are four subcases: * <math>n = m = 1</math> – then <math>f</math> is a Möbius transformation and the value of the expression is non-zero; in particular, <math>\infty</math> is not a critical point of <math>f</math>. * <math>n = m > 1</math> – if the numerator is of degree <math>2 m - 2</math> as well, then the value of the expression is non-zero; if the numerator is of degree <math>< 2 m - 2</math>, then the value of the expression is zero. (Both sub-subcases are possible, of course.) * <math>n = m - 1</math> – then the value of the expression at <math>w = 0</math> is <math>-\frac{a}{b}</math>; in particular, <math>\infty</math> is not a critical point of <math>f</math>. * <math>n < m - 1</math> – then the value of the expression at <math>w = 0</math> is <math>0</math>, so <math>\infty</math> is a critical point of <math>f</math>. At any rate, the point is that there is no _easy_ criterion purely in terms of the values of <math>f</math> and <math>f'</math>. =rigorous studies of nonlinear systems = * computing enclosures of trajectories * finding and proving the existence of symbolic dynamics * obtaining rigorous bounds for the topological entropy * methods for finding accurate enclosures of chaotic attractor * interval operators for proving the existence of fixed points and periodic orbits * methods for finding all short cycles https://rd.springer.com/chapter/10.1007/978-3-540-95972-4_2 ==methods== * [[:w:Trial_and_error|Trial_and_error in wiki]] * [[:w:Brute-force_search|Brute-force_search in wiki]] ==graphic software== * https://www.generic-mapping-tools.org/documentation/ * http://gwyddion.net/documentation/user-guide-en/color-map.html#color-gradient-editor* ==text color== * [[Template:Color|wikitext]] * [[Help:Tables#Color|tble]] * [[Help:Formulas#Color|math formula]] ==some notes== Some notes from [http://ca.wikipedia.org/wiki/Fractal | wikipedia ] <MATH> Z^2 </MATH> * <MATH> \operatorname{Re} = x^2 - y^2 </MATH> * <MATH> \operatorname{Im} = 2 * x * y </MATH> <MATH> Z^3 </MATH> * <MATH> \operatorname{Re} = x^3 - 3* y^2 * x </MATH> * <MATH> \operatorname{Im} = 3 * x^2 * y - y^3 </MATH> <MATH> Z^4 </MATH> * <MATH> \operatorname{Re} = x^4 - 6 * x^2 * y^2 + y^4 </MATH> * <MATH> \operatorname{Im} = 4*x^3 * y - 4 * x * y^3 </MATH> <MATH> Z^5 </MATH> * <MATH> \operatorname{Re} = x^5 - 10 * x^3 * y^2 + 5 * x * y^4 </MATH> * <MATH> \operatorname{Im} = 5*x^4 * y - 10 * x^2 * y^3 + y^5 </MATH> <MATH> Z^6 </MATH> * <MATH> \operatorname{Re} = x^6 - 15 * x^4 * y^2 +15 * x^2 * y^4 - y^6 </MATH> * <MATH> \operatorname{Im} = 6*x^5 * y - 20 * x^4 * y^2 + 6* x * y^5 </MATH> <MATH> Z^7 </MATH> * <MATH> \operatorname{Re} = x^7 - 21 * x^5 * y^2 + 35 * x^3 * y^4 - 7 * x * y^6 </MATH> * <MATH> \operatorname{Im} = 7*x^6 * y - 35 * x^4 * y^3 + 21* x^2 * y^5 - y^7 </MATH>, <MATH> \exp(Z) </MATH> * <MATH> \operatorname{Re} = \exp(x) * \cos(y) </MATH> * <MATH> \operatorname{Im} = \exp(x) * \sin(y) </MATH> <MATH> \ln(Z) </MATH> * <MATH> \operatorname{Re} = 0.5 * \ln(x^2 + y^2) </MATH> * <MATH> \operatorname{Im} = \arctan(y/x)</MATH> <MATH> \sin(Z) </MATH> * <MATH> \operatorname{Re} = \sin(x) * ((\exp(y) + \exp(-y))/2) </MATH> &nbsp; * <MATH> \operatorname{Im} = \cos(x) * ((\exp(y) - \exp(-y))/2) </MATH> <MATH> \cos(Z) </MATH> * <MATH> \operatorname{Re} = \cos(x) * ((\exp(y) + \exp(-y))/2) </MATH> * <MATH> \operatorname{Im} = -\sin(x) * ((\exp(y) - \exp(-y))/2) </MATH> <MATH> \sinh(Z) </MATH> * <MATH> \operatorname{Re} = \cos(y) * ((\exp(x) - \exp(-x))/2) </MATH> * <MATH> \operatorname{Im} = \sin(y) * ((\exp(x) + \exp(-x))/2) </MATH> <MATH> CosH(Z) </MATH> * <MATH> \operatorname{Re} = \cos(y) * ((\exp(x) + \exp(-x))/2) </MATH> * <MATH> \operatorname{Im} = \sin(y) * ((\exp(x) - \exp(-x))/2) </MATH> [https://people.math.carleton.ca/~kcheung/math/books/giam-ON/html/ A Gentle Introduction to the Art of Mathematics by Joe Fields,] =parabolic/hyperbolic/elliptic= The meaning of the terms "elliptic, hyperbolic, parabolic" in different disciplines in mathematics<ref>[https://www.quora.com/Where-is-the-best-summary-on-the-meaning-of-the-terms-elliptic-hyperbolic-parabolic-as-used-in-different-disciplines-in-mathematics quora : Where-is-the-best-summary-on-the-meaning-of-the-terms-elliptic-hyperbolic-parabolic-as-used-in-different-disciplines-in-mathematics]</ref> * PDE ( Linear Second Order PDE’s in two Independent Variables) : https://en.wikipedia.org/wiki/Partial_differential_equation * Moebius transformations = Classification of Isometries ( https://www.mathi.uni-heidelberg.de/~alessandrini/Arith_Reports/1-hyperbolic%20geometry.pdf) * dicrete local complex dynamics * Conic section * Quadratic form * probability distributions. <gallery caption="coordinate"> Elliptical coordinates grid.svg|elliptical </gallery> ===hyperbolic=== * hyperbolic". usually) means that |f′(t)|≠1| , https://math.stackexchange.com/questions/2172002/is-indeterminate-a-better-name-than-indifferent-for-neutral-fixed-points * http://www.scholarpedia.org/article/Hyperbolic_dynamics ===Moebius transformations=== Shadertoy * [https://www.shadertoy.com/view/msdGRj Elliptic Mobius Transform Created by Borthralla in 2023-02-28] * [https://www.shadertoy.com/view/Ddd3z2 Parabolic Mobius Transform Created by Borthralla in 2023-02-28] =curves= ==alg== * trace a curve * curve sampling = collect a list of points from curve * simplify curve * edge detection = ridge detection = line detection algorithm = Curve extraction * curve fitting ===sampling=== * uniform sampling of the function ( curve) * adaptive sampling of the function ( curve) ===simplify curve === * Polyline Simplification * to Reduce the Number of Nodes in Curve Object * reduce-the-number-of-points-in-a-curve-while-preserving-its-overall-shape * given a curve composed of line segments (= polyline ) find a similar curve with fewer points * decimate a curve composed of line segments to a similar curve with fewer points ** [https://stackoverflow.com/questions/7980586/how-to-reduce-the-number-of-points-in-a-curve-while-preserving-its-overall-shape stackoverflow question: how-to-reduce-the-number-of-points-in-a-curve-while-preserving-its-overall-shape] ** [http://Https://www.geometrictools.com/Documentation/PolylineReduction.pdf geometrictools : PolylineReduction] ** "removing the point whose angle between neighboring points is closest to 180 degrees, until some threshold, or until you've reached a desired number of points." aioobe ** https://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm ===smooth curve from points=== "curve fitting is a set of techniques used to fit a curve to data points " * https://www.quora.com/Whats-the-difference-between-curve-fitting-and-regression * https://www.codeproject.com/Articles/31859/Draw-a-Smooth-Curve-through-a-Set-of-2D-Points-wit * https://www.codeproject.com/Articles/25237/Bezier-Curves-Made-Simple * https://mycurvefit.com/ * https://www.particleincell.com/2012/bezier-splines/ * http://www.mvps.org/directx/articles/catmull/ * https://stackoverflow.com/questions/tagged/curve-fitting?sort=votes&pageSize=50 * https://web.cs.wpi.edu/~matt/courses/cs563/talks/curves.html * http://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/INT-APP/CURVE-INT-global.html * https://web.cs.wpi.edu/~matt/courses/cs563/talks/curves.html * https://gis.stackexchange.com/questions/138881/finding-the-center-line-from-a-set-of-3d-points Fit method * linear ** join points with segments = concatenated linear segments ** straight line using linear regression * nonlinear ** polynomial ** cubic spline *** Smooth Bézier Spline Through Prescribed Points ===trace a curve=== * To trace the curve we evaluate successive points on the curve * https://stackoverflow.com/questions/31464345/fitting-a-closed-curve-to-a-set-of-points * https://stackoverflow.com/questions/14631776/calculate-turning-points-pivot-points-in-trajectory-path * https://www.quora.com/Whats-the-difference-between-curve-fitting-and-regression * http://user.engineering.uiowa.edu/~dip/lecture/Segmentation2.html * http://alice.loria.fr/publications/papers/2014/STREAM/RobustStreamlines.pdf * https://link.springer.com/article/10.1007/s40819-015-0067-1 ** https://repository.kulib.kyoto-u.ac.jp/dspace/bitstream/2433/82596/1/0787-12.pdf ** ADAPTIVE MULTIPRECISION PATH TRACKING: https://www.semanticscholar.org/paper/Adaptive-Multiprecision-Path-Tracking-Bates-Hauenstein/6517744e4b68d3e648166448a88bda63e6a597e3 ** http://www.math.colostate.edu/~bates/preprints/BHS_ODE_21apr10.pdf ===sketch a curve=== * http://xaktly.com/DerivativesIII.html * ===boundary trace=== * http://paulbourke.net/papers/conrec/ * http://user.engineering.uiowa.edu/~dip/lecture/Segmentation2.html * http://sijoo.tistory.com/251 * http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/moore.html * https://www.ibiblio.org/e-notes/MSet/big_m.htm * ==types== * [[:w:Biarc|Biarc]] * folium ** [https://digilander.libero.it/roberto20129/matematica/curve2.html#Foliumd folium] ** [http://www.mathcurve.com/courbes2d/foliumsimple/foliumsimple.shtml folium simple] ** [http://www.mathcurve.com/courbes2d.gb/clairaut/clairaut.shtml clairaut curve] * trifolium ** [https://www.mathcurve.com/courbes2d.gb/trifoliumregulier/trifoliumregulier.shtml regular] https://www.mathcurve.com/courbes2d.gb/rosace/rosace.shtml rose curve = n-folium: The curve is composed of a n base patterns. The pattern is called : the petal or branch / leaf / lobe - symmetrical about Ox obtained for angle between -pi/(2n) and pi/(2n) osculating circle of a sufficiently smooth plane curve * https://www.geogebra.org/m/eemfktww ===level sets=== * https://scicomp.stackexchange.com/questions/1348/given-values-on-a-mesh-what-algorithm-can-i-use-to-construct-efficiently-level?rq=1 ==curve properities== ===curvature=== Interesting curves involning the curvature concept by [http://xahlee.info/SpecialPlaneCurves_dir/Curvature_dir/curvature.html Xah Lee]: * Evolute curve (the centers of osculating circles) * Radial curve (locus of osculating circle normals) * circle = curve with constant curvature everywhere * line = curve with curvature of 0 everywhere) * Clothoid = spiral cirve of linearly increasing curvature) =geometry= * https://www.ics.uci.edu/~eppstein/161/syl.html * https://www.cs.cmu.edu/~kmcrane/ * http://blancosilva.github.io/post/2014/10/28/Computational-Geometry-in-Python.html * digital ** https://dgtal.org/tools/ ** https://github.com/DGtal-team === Moore-Neighbor Tracing === * https://en.wikipedia.org/wiki/Moore_neighborhood * http://www.imageprocessingplace.com/downloads_V3/root_downloads/tutorials/contour_tracing_Abeer_George_Ghuneim/mmain.html * https://www.codeproject.com/Articles/1105045/Tracing-Boundary-in-D-Image-Using-Moore-Neighborho * https://stackoverflow.com/questions/26830697/moore-neighbourhood-in-python * https://py.checkio.org/en/mission/count-neighbours/ see also: * https://en.wikipedia.org/wiki/User:TerribleTadpole/sandbox * https://cs.wikibooks.org/wiki/Geometrie/Vypl%C5%88ov%C3%A1n%C3%AD * https://commons.wikimedia.org/wiki/Category:Pathfinding * https://en.wikipedia.org/wiki/Pathfinding ==chain code== * http://islab.ulsan.ac.kr/files/announcement/301/20091132.pdf * https://stackoverflow.com/questions/12885055/chain-code-infinite-loop?rq=1 * https://stackoverflow.com/questions/47001899/freeman-chain-code-infinite-loop-4-adjacency?rq=1 * https://stackoverflow.com/questions/6718525/understanding-freeman-chain-codes-for-ocr?rq=1 * https://www.e-olymp.com/en/problems/1803 * http://airccse.org/journal/ijcga/papers/4214ijcga02.pdf * http://appliedmaths.sun.ac.za/TW793/slides/slides_11_1.pdf * http://www.aass.oru.se/Research/Learning/courses/dip/2011/lectures/DIP_2011_L14.pdf ==test== <math>1 / 237142198758023568227473377297792835283496928595231875152809132048206089502588927 \approx 4.21687917729220928973942962050800760308398455294740302003110521004325771638790385468222014406044810316697454753662... *10^-81</math> <math> \frac{1}{2^{267}-1}= \frac{1}{237142198758023568227473377297792835283496928595231875152809132048206089502588927} \approx 4.216879177292209*10^{-81} </math>( land on the root point of period 267 component : c267 = 0.250137369683480-0.000003221184145 i with angled internal adress : <math>1 \xrightarrow{1/267} 267</math> ( land on the root point of period 268 component c268 = 0.250137369683480-0.000003221184145i period = 10000 i with angled internal adress : <math>1 \xrightarrow{267/268} 268</math> ==mandelbrot set == the Mandelbrot set for the function 1/z - z∙(1 + 0.001∙z)/(1 - 0.002∙z + 0.001∙z2) = "1 -0.002 - 0.999 -0.001 0 1 -0.002 0.001": <math>f(z) = \frac{1}{z} - \frac{z*(1 + 0.001*z)}{(1 - 0.002*z + 0.001*z^2)}</math> http://www.juliasets.dk/UFP.htm ==video== * https://www.college-de-france.fr/site/en-pierre-louis-lions/symposium-2017-05-30-15h30.htm * https://www.college-de-france.fr/site/en-pierre-louis-lions/symposium-2017-05-29-11h30.htm * https://www.math.stonybrook.edu/jackfest/Talks/ * http://www.math.vt.edu/netmaps/index.php ==programs== * http://jsxgraph.uni-bayreuth.de/wp/index.html * http://www.singsurf.org/index.php * http://www.javaview.de/index.html =gradient line of the 2D scalar field= * http://hplgit.github.io/ * https://www.khanacademy.org/math/multivariable-calculus/multivariable-derivatives/gradient-and-directional-derivatives/v/gradient * https://stackoverflow.com/questions/25342072/computing-and-drawing-vector-fields * https://stackoverflow.com/questions/33059710/how-to-plot-gradfx-y?noredirect=1&lq=1 * https://math.stackexchange.com/questions/462592/trouble-with-gradient-intuition * https://metacademy.org/graphs/concepts/finite_difference_approximations_to_derivatives * https://ocw.mit.edu/courses/mathematics/18-02sc-multivariable-calculus-fall-2010/2.-partial-derivatives/part-b-chain-rule-gradient-and-directional-derivatives/session-35-gradient-definition-perpendicular-to-level-curves/ * https://ocw.mit.edu/courses/mathematics/18-02sc-multivariable-calculus-fall-2010/2.-partial-derivatives/part-b-chain-rule-gradient-and-directional-derivatives/session-35-gradient-definition-perpendicular-to-level-curves/MIT18_02SC_notes_18.pdf * https://metacademy.org/browse * https://www.desmos.com/calculator/el5syd7ugj * http://freymanart.com/VectorFields/index.htm Key words: * "gradient line" 2d "scalar field" [http://people.reed.edu/~ormsbyk/projectproject/posts/level-sets.html flow] : * level curves and gradient vector * flow across continuously-spaced level curves * The flow’s derivative is the gradient – the flow will follow the gradient vectors * gradient is the direction of steepest ascent in the zz-direction, the reverse of the flow is the path of an object as it rolls on the surface, starting from a high place and rolling down to a lower place (in the exact opposite direction as the gradient vectors point). * def from [http://bora.uib.no/bitstream/handle/1956/1638/Masteroppgave-haegland.pdf?sequence=1&isAllowed=y Streamline Tracing on Irregular Grids by H˚akon Hægland] ** "The instantaneous curves that are at every point tangent to the direction of the velocity at that point are called '''streamlines''' of the flow" ** "A '''pathline''' of a fluid particle is the locus of its position in space as time passes. It is thus the trajectory of a particle of fixed identity" ==Khan== [https://www.khanacademy.org/math/multivariable-calculus/multivariable-derivatives/partial-derivative-and-gradient-articles/a/the-gradient the gradient] points in the direction which increases the value of f most quickly. There are two ways to think about this direction: * Choose a fixed step size, and find the direction such that a step of that size increases fff the most. Given steps of a constant size away from a particular point, the gradient is the one which increases f the most. * Choose a fixed increase in fff, and find the direction such that it takes the shortest step to increase fff by that amount. Given steps which increase f by a given size, the gradient direction is the shortest among these. Either way, you're trying to : * maximize the rise over run, * either by maximizing the rise, or minimizing the run. ==MathWorks== [https://uk.mathworks.com/help/matlab/ref/gradient.html Numerical Gradient] The numerical gradient of a function is a way to estimate the values of the partial derivatives in each dimension using the known values of the function at certain points. For a function of two variables, F(x,y), the gradient is ∇F=∂F/ ∂x ˆi + ∂F ∂y ˆ j  . The gradient can be thought of as a collection of vectors pointing in the direction of increasing values of F. In MATLAB®, you can compute numerical gradients for functions with any number of variables. Tips Use diff or a custom algorithm to compute multiple numerical derivatives, rather than calling gradient multiple times. Algorithms gradient calculates the central difference for interior data points. For example, consider a matrix with unit-spaced data, A, that has horizontal gradient G = gradient(A). The interior gradient values, G(:,j), are G(:,j) = 0.5*(A(:,j+1) - A(:,j-1)); The subscript j varies between 2 and N-1, with N = size(A,2). gradient calculates values along the edges of the matrix with single-sided differences: G(:,1) = A(:,2) - A(:,1); G(:,N) = A(:,N) - A(:,N-1); If you specify the point spacing, then gradient scales the differences appropriately. If you specify two or more outputs, then the function also calculates differences along other dimensions in a similar manner. Unlike the diff function, gradient returns an array with the same number of elements as the input. == so== https://stackoverflow.com/questions/263305/drawing-a-topographical-map The gradient is a mathematical operator that may help you. If you can turn your interpolation into a differentiable function, the gradient of the height will always point in the direction of steepest ascent. All curves of equal height are perpendicular to the gradient of height evaluated at that point. Your idea about starting from the highest point is sensible, but might miss features if there is more than one local maximum. I'd suggest 1. pick height values at which you will draw lines 2. create a bunch of points on a fine, regularly spaced grid, then walk each point in small steps in the gradient direction towards the nearest height at which you want to draw a line 3. create curves by stepping each point perpendicular to the gradient; eliminate excess points by killing a point when another curve comes too close to it-- but to avoid destroying the center of hourglass like figures, you might need to check the angle between the oriented vector perpendicular to the gradient for both of the points. (When I say oriented, I mean make sure that the angle between the gradient and the perpendicular value you calculate is always 90 degrees in the same direction.) In response to your comment to @erickson and to answer the point about calculating the gradient of your function. Instead of calculating the derivatives of your 300 term function you could do a numeric differentiation as follows. Given a point [x,y] in your image you could calculate the gradient (direction of steepest decent) g={ ( f(x+dx,y)-f(x-dx,y) )/(2*dx), ( f(x,y+dy)-f(x,y-dy) )/(2*dy) } where dx and dy could be the spacing in your grid. The contour line will run perpendicular to the gradient. So, to get the contour direction, c, we can multiply g=[v,w] by matrix, A=[0 -1, 1 0] giving c = [-w,v] https://stackoverflow.com/questions/68491888/how-tensorflow-knows-how-to-calculate-the-derivative numeric differentiation (aka finite differences) https://www.unioviedo.es/compnum/labs/lab07_der_int/lab07_der_int.html <pre> def numerical_derivative_2d(func, epsilon): def grad_func(x): return (func(x + np.array([epsilon, 0])) - func(x)) / epsilon, (func(x + np.array([0, epsilon])) - func(x)) / epsilon return grad_func </pre> =potential flow= * https://gregjavens.com/2016/03/12/laplace-equation-finite-element-method-3/ [[File:Construction of a potential flow.svg|thumb|right|Construction of a potential flow.svg]] =spiral= * https://math.stackexchange.com/questions/2254493/logarithmic-spiral-transform-function * https://math.stackexchange.com/questions/1232346/find-gradient-of-a-equi-angular-spiral-log-spiral * [https://www.ibiblio.org/e-notes/MSet/spiral.htm spiral in Julia set] * [https://www.geogebra.org/m/c982z9uw Pursuit Paths via Complex Numbers Author:Steve Phelps] ==The Golden Ratio and the Golden Angle== In disc [[phyllotaxis]], as in the [[sunflower]] and daisy, the mesh of spirals occurs in [[Fibonacci number]]s because divergence (angle of succession in a single spiral arrangement) approaches the [[golden ratio]]. The shape of the spirals depends on the growth of the elements generated sequentially. In mature-disc [[phyllotaxis]], when all the elements are the same size, the shape of the spirals is that of Fermat spirals&mdash;ideally. That is because Fermat's spiral traverses equal [[annulus (mathematics)|annuli]] in equal turns. The full model proposed by H Vogel in 1979<ref> {{Cite journal | last =Vogel | first =H | title =A better way to construct the sunflower head | journal =Mathematical Biosciences | issue =44 | pages =179–189 | year =1979 | doi =10.1016/0025-5564(79)90080-4 | volume =44 | postscript =<!--None--> }}</ref> is :<math>r = c \sqrt{n},</math> :<math>\theta = n \times 137.508^\circ,</math> where ''θ'' is the angle, ''r'' is the radius or distance from the center, and ''n'' is the index number of the floret and ''c'' is a constant scaling factor. The angle 137.508° is the [[golden angle]] which is approximated by ratios of [[Fibonacci number]]s.<ref>{{cite book | last =Prusinkiewicz | first =Przemyslaw | authorlink =Przemyslaw Prusinkiewicz |author2=Lindenmayer, Aristid |authorlink2=Aristid Lindenmayer | title =The Algorithmic Beauty of Plants | publisher =Springer-Verlag | date =1990 | location = | pages =101&ndash;107 | url =http://algorithmicbotany.org/papers/#webdocs | doi = | isbn = 978-0-387-97297-8 }}</ref> <gallery> Sunflower spiral.png|The pattern of florets produced by Vogel's model (central image). The other two images show the patterns for slightly different values of the angle. Dotswirl.gif Logarithmic floret simulation.svg </gallery> Illustration of Vogel's formula of the pattern of sunflower florets (see [[:en:Sunflower#Mathematical model of floret arrangement|article]]) for ''n'' from 1 to 500, using the polar coordinates equations <math>r = c \sqrt{n}</math> and <math>\theta = n \times \frac{2 \pi}{\phi + 1}</math>. Can be produced using the following MATLAB code: n=1:500; r=sqrt(n); t=2*pi/((sqrt(5)+1)/2+1)*n; plot(r.*cos(t),-r.*sin(t),'o') ===Links=== * [https://www.youtube.com/watch?v=EK32jo7i5LQ&list=PL53AB2CAE70F31F2A&index=34 Why do prime numbers make these spirals? | Dirichlet’s theorem, pi approximations, and more by 3Blue1Brown] * [https://www.shadertoy.com/view/4lGfDd best scrambling offset Created by FabriceNeyret2] pretends golden ratio gives the best Sunflower because it's the "most irrational" number. I find the argument a lot less convincing with linear offsets rather than circular. * [https://www.youtube.com/watch?v=sj8Sg8qnjOg The Golden Ratio (why it is so irrational) - Numberphile ] * [https://www.youtube.com/watch?v=OFI1FJcGLeM The Art of John Edmark Talk by Paul Dancstep from Exploratorium] * https://blog.matthen.com/tagged/fibonacci " Is it possible to find a pattern in the prime numbers? If you arrange them in what is called the Ulam spiral, you can see some clear patterns emerging. There are other spiral shapes which give nice patterns, such as stacking them into a triangle.... Is it possible to find a pattern in the prime numbers? If you arrange them in what is called the Ulam spiral, you can see some clear patterns emerging. There are other spiral shapes which give nice patterns, such as stacking them into a triangle. Here I have tried wrapping them into a Fibonacci spiral, where each dot is slightly further out than the last- and is rotated by a Golden ratio of a full turn (about 0.618034 * 360 = 222.49224 degrees). The red dots are the primes, the blacks the non-primes (composites). Unfortunately, there doesn’t seem to be any pattern. Does there? [code]" matthen " This spiral is rotated by the golden angle every frame. Though it looks like the circles are growing and changing colour, they are actually unchanging and the whole image is just rotating. [inspired by these amazing sculptures] [code] [related]" matthen ===Vogel's mode=== A model for the pattern of [[floret]]s in the head of a [[sunflower]] was proposed by [[:de:Helmut Vogel (Physiker)|Helmut Vogel]] in 1979.<ref>{{Citation | last =Vogel | first =Helmut | title =A better way to construct the sunflower head | journal = Mathematical Biosciences | issue =3–4 | pages = 179–89 | year = 1979 | doi = 10.1016/0025-5564(79)90080-4 | volume = 44}}</ref> This has the form <math> \theta = \frac{2\pi}{\varphi^2} n</math> <math>r = c \sqrt{n} </math> <math>z = r(\cos \theta + i\sin \theta ) </math> where: * {{math|''n''}} is the index number of the floret * {{math|''c''}} is a constant scaling factor The florets thus lie on [[Fermat's spiral]]. The divergence angle, approximately 137.51°, is the [[golden angle]], dividing the circle in the golden ratio. Because this ratio is irrational, no floret has a neighbor at exactly the same angle from the center, so the florets pack efficiently. Because the rational approximations to the golden ratio are of the form {{math|''F''(''j''):''F''(''j'' + 1)}}, the nearest neighbors of floret number {{math|''n''}} are those at {{math|''n'' ± ''F''(''j'')}} for some index {{math|''j''}}, which depends on {{math|''r''}}, the distance from the center. Sunflowers and similar flowers most commonly have spirals of florets in clockwise and counter-clockwise directions in the amount of adjacent Fibonacci numbers,{{sfn|Livio|2003|p=112}} typically counted by the outermost range of radii.<ref>{{Citation | last1 = Prusinkiewicz | first1 = Przemyslaw | author1-link = Przemyslaw Prusinkiewicz | author2-link = Aristid Lindenmayer | last2 = Lindenmayer | first2 = Aristid | title = The Algorithmic Beauty of Plants | publisher = Springer-Verlag | year = 1990 | pages = [https://archive.org/details/algorithmicbeaut0000prus/page/101 101–107] | chapter = 4 | chapter-url = http://algorithmicbotany.org/papers/#webdocs | isbn = 978-0-387-97297-8 | url = https://archive.org/details/algorithmicbeaut0000prus/page/101 }}</ref> ==Algorithm== * http://algorithmicbotany.org/papers/abop/abop-ch4.pdf * http://blog.marmakoide.org/?p=1 * https://www.codeproject.com/Articles/650821/Fractals-in-theory-and-practice * http://www.mathrecreation.com/2015/08/simple-fun-with-r.html * http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibnat2.html * http://demonstrations.wolfram.com/SpiralExplorer/ * http://demonstrations.wolfram.com/PhyllotaxisSpirals/ * http://demonstrations.wolfram.com/PhyllotaxisExplained/ * http://demonstrations.wolfram.com/NumericalFlowers/ * https://www.codeproject.com/Articles/1221341/The-Vogel-Spiral-Phenomenon * https://calculus7.org/2016/01/17/irrational-sunflowers/ * http://physics.nyu.edu/grierlab/fibonacci3b/node2.html * http://www.maths.surrey.ac.uk/hosted-sites/R.Knott/Fibonacci/fibnat2.html * http://www.mi.sanu.ac.rs/vismath/bridges2005/krawczyk/index.html * [https://maa.tandfonline.com/doi/abs/10.1080/0025570X.2002.11953126#.WuioS59fifY Golden, , and π Flowers: A Spiral Story Michael Naylor] ====code==== * https://www.desmos.com/calculator/risuha09iw R code <syntaxhighlight lang="R"> #http://www.mathrecreation.com/2015/08/simple-fun-with-r.html # https://github.com/dmackinnon1/r_examples/blob/master/simple/example2.r #example 2b phyllotaxis spiral t <- 1:500 p <- (1 + sqrt(5))*pi plot(sqrt(t)*cos(p*t), sqrt(t)*sin(p*t), type="p", axes=FALSE) </syntaxhighlight> Maple code <syntaxhighlight lang="Maple"> # code from : http://personal.maths.surrey.ac.uk/ext/R.Knott/Fibonacci/seedPlotMaple.txt # by Ron Knott > with(plots): #Growpts shows a single picture (plot) of n seeds (points) distributed at #TurnperSeed (a numberbetween 0 and 1) which is the fraction of 1 turn between #one seed and the next, > growpts:=(n,TpS)->growpts1(n,TpS,POINT): growpts1:=proc(n,TurnperSeed,symb) local i,a,r,s,phi2pi; s:=null; phi2pi:=TurnperSeed*2*Pi; listplot([seq([sqrt(n-i)*cos(phi2pi*i),sqrt(n-i)*sin(phi2pi*i)],i=1..n)], style=POINT,axes=NONE,scaling=CONSTRAINED,symbol=symb) end; #Here is a seed-head with Pi turns between each seed. #Since Pi=3.14159>1, it is the same as 0.14159 turns per seed. #Note how there are 7 radial arms (corresponding to 22/7 for Pi) near the centre #and the next set of radial arms are 113 arms with seeds placed 16 arms apart #(since the next best approximation to Pi is 3+16/113=355/113). > growpts(1000,Pi); #Here we take a single Turns-per-seed value and keep adding a new seed #(at the centre) showing the seed head growing up to n seeds finally. #The plots are animated to show the growing process: > seedplot := proc(n, ratio) display([seq(growpts1(i, ratio, CIRCLE), i = (1 .. n))], insequence = true, style = point, scaling = constrained, axes = NONE) end proc; #Here is 100 seeds at Phi =1.618.. turns per seed (which is the same as #Phi-1=0.618..=phi turns per seed): > seedplot(100,(sqrt(5)-1)/2); </syntaxhighlight> =intersection of polar curves= * https://math.stackexchange.com/questions/1221260/intersecting-polar-curves-r-1cos%CE%B8-and-r-1-cos%CE%B8 * https://math.stackexchange.com/questions/1064268/suppose-that-two-polar-curves-are-given-by-r-1-cos2-theta-and-r-2-si * https://math.stackexchange.com/questions/851190/finding-self-intersections-on-a-polar-curve * https://math.stackexchange.com/questions/2038456/intersection-points-of-two-polar-curves?rq=1 * https://math.stackexchange.com/questions/1281068/intersection-of-polar-curve-with-line?rq=1 * https://math.stackexchange.com/questions/2358269/points-of-intersection-for-two-logarithmic-spirals?rq=1 =iteration= * https://math.stackexchange.com/questions/2571345/iterating-quadratic-polynomials/2571349#2571349 * https://math.stackexchange.com/questions/140819/general-mandelbrot-iteration-formulas?rq=1 =atan2= [[File:Atan2 circle.svg|thumb|right]] * https://stackoverflow.com/questions/17574424/how-to-use-atan2-in-combination-with-other-radian-angle-systems * http://patrikstas.com/2015/11/05/what-is-difference-between-atan-and-atan2/ * https://mrl.nyu.edu/~perlin/courses/spring2012/texture.html * https://www.youtube.com/watch?v=mGEtMc20eeE * https://www.youtube.com/watch?v=Zh6cmQcT1YI * https://www.youtube.com/watch?v=LHzgW9aQUV8 * https://www.youtube.com/watch?v=Idxeo49szW0 =conformal= * " Conformal transformation: One can find solutions to the Dirichlet problem for a wider class of regions by conformal transformations. These are transformations which preserve the angles and have the property that the transplanted function is harmonic if the original function is harmonic. One can obtain conformal transformations using complex function (x,y) -> (u,v): if z=x+iy and F(z) is a polynomial in z and F(z)=u+i v, then the map is conformal. For example, to solve the Dirichlet problem outside a wing, one can transform the circle into the wing using a conformal transformation. Such methods are relevant in engeneering." http://www.math.harvard.edu/archive/21b_fall_03/laplace/index.html * https://www3.cs.stonybrook.edu/~gu/tutorial/RiemannMapping.html * https://www.chebfun.org/docs/guide/guide16.html * https://www.cs.cmu.edu/~kmcrane/Projects/Other/OverviewConformalGeometryProcessing.pdf * http://www-users.math.umn.edu/~olver/ln_/cml.pdf * The Euler conformal map, a special case of the M¨obius transformation, maps circles to circles * https://gregjavens.com/2016/05/11/conformal-map/ * https://gregjavens.com/2016/03/12/laplace-equation-finite-element-method-3/ * http://mathfaculty.fullerton.edu/mathews/c2003/ConformalMapDictionary.2.html * https://www3.cs.stonybrook.edu/~gu/ * https://arxiv.org/abs/1306.1162 * http://www.eng.biu.ac.il/weberof/publications/ * http://wwwf.imperial.ac.uk/~dgcrowdy/GuTalk.pdf ==numerical conformal mapping=== =Orthogonal= [[File:Apollonius hyperbolic.svg|thumb|right|Ancillary figure for van Roomen's solution to the problem of Apollonius.]] * https://www.mathcurve.com/courbes2d.gb/orthogonale/orthogonale.shtml * https://en.wikipedia.org/wiki/Orthogonal_trajectory * http://www.emathhelp.net/calculators/calculus-1/tangent-line-calculator/ * https://www.whitman.edu/mathematics/calculus_online/section10.02.html * http://tutorial.math.lamar.edu/Classes/CalcII/ParaTangent.aspx * http://www.emathhelp.net/calculators/calculus-1/online-graphing-calculator/ * https://www.math24.net/tangent-normal-lines/ * https://emathhelp.net/calculators/calculus-1/online-graphing-calculator/?uid=nwd4ldjtge * https://emathhelp.net/plot/nwd4ldjtge.png * https://math.stackexchange.com/questions/1919319/how-do-i-get-the-tangent-of-a-curve?rq=1 * https://math.stackexchange.com/questions/992847/finding-the-equation-of-a-tangent-line-to-a-polar-curve?rq=1 * tangent to circle in the polar form z= r(t) [http://www.emathhelp.net/calculators/calculus-1/online-graphing-calculator/ is line] : y = x*tan(t) <gallery> Kardioide.svg|Creating a cardioid by rolling a circle on a circle of the same radius File:Cardiod animation.gif|animation </gallery> Tangent to cardioid in polar form : z = 2a( 1 - cos(t)) is line : // y = (x*(-1+2*cos(t))*sin(t)+(-3+3*cos(t))*sin(t))/(-1+2*cos(t)^2-cos(t)) y = (x*(-1+2*cos(t))*sin(t)+(-2a+2a*cos(t))*sin(t))/(-1-cos(t)+2*cos(t)^2) where t is changing from 0 to 2*pi Compare : * [http://www.criced.tsukuba.ac.jp/grapes/image/fukuso1.html circle to cardioid mapping ( w = z^2)] * [http://www.criced.tsukuba.ac.jp/grapes/image/fukuso2.html The objects shown here are the inverse images of the map w = z4 where the point w is on the cricle and on the line in the complex plane.] ==ellipse== <math>(x,y)=(a \cos t, b \sin t),\ 0\le t<2\pi\ .</math> slope m <math> m = -\frac{b}{a}\cot t\quad </math> The equation of the tangent at point <math>\vec c_\pm(m)</math> has the form <math>y=mx+n</math> <math>y = m x \pm\sqrt{m^2a^2+b^2}\; .</math> https://www.math24.net/tangent-normal-lines-page-2/#example11 https://www.math24.net/implicit-differentiation/ Implicit * function * implicit differentiation = differentiation of the implicit function =sqare root= * http://mathlets.org/mathlets/complex-roots/ * https://flothesof.github.io/branch-cuts-with-square-roots.html * http://phantomgraphs.weebly.com/ * https://math.stackexchange.com/questions/1797223/graphically-solving-for-complex-roots-how-to-visualize?noredirect=1&lq=1 * Reciprocal Function as a Mapping ** http://functions.wolfram.com/ElementaryFunctions/Sqrt/visualizations/4/ ** http://functions.wolfram.com/ElementaryFunctions/Sqrt/visualizations/7/ ** http://mathfaculty.fullerton.edu/mathews/c2003/ComplexFunPowerRootMod.html ** https://sites.oxy.edu/ron/math/312/16/ws/08.pdf ** https://usamo.wordpress.com/2017/02/16/holomorphic-logarithms-and-roots/ ** http://laussy.org/wiki/MMII/Complex_functions_of_complex_numbers ** https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/_24769_figure12567.gif * branch cuts ** https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node129.html ** sqrt : The branch cut for square root lies along the negative real axis, continuous with quadrant II. The range consists of the right half-plane, including the non-negative imaginary axis and excluding the negative imaginary axis. ** https://math.stackexchange.com/questions/923931/problem-identifying-branch-cuts-of-a-square-root-function?noredirect=1&lq=1 ==repeated == * https://math.stackexchange.com/questions/3283/why-do-i-always-get-1-when-i-keep-hitting-the-square-root-button-on-my-calculat * https://www.geeksforgeeks.org/sqrt-square-root-decomposition-technique-set-1-introduction/ * http://edspi31415.blogspot.com/2015/08/repeated-presses-of-square-root-button.html * =tree= * https://www.youtube.com/watch?v=BEz-vGJvaik =People= [http://www.danca.rist.ro/index.htm Marius-F. Danca] [[pl:User:Adam_majewski]] =petal= "An attracting petal, P + , for a map M at zero is an open simply connected forward invariant region with 0 ∈ ∂P + , that shrinks down to the origin under iteration of M . More precisely, P + is an attracting petal if M (P + ) ⊂ P + ∪ {0} and n≥0 M n (P + ) = {0}. "<ref>NEWTON’S METHOD ON THE COMPLEX EXPONENTIAL FUNCTION MAKO E. HARUTA</ref> ==example== http://mathoverflow.net/questions/104482/parabolic-immediate-basins-always-simply-connected?rq=1 "An example is f(z)=z+1−1/zf(z)=z+1−1/z. There is one petal for the neutral point at infinity. Let AA be the dmain of attraction of ∞∞. Critical points are ±i±i. Everything is symmetric with respect to the real line, because the function is real. One critical point is in AA, so by symmetry the other one is also in AA. The map f:A→Af:A→A is 2-to-1 (because ff is of degree 22), so Riemann and Hurwitz tell us that AA is infinitely connected." shareciteeditflag answered Aug 12 '12 at 13:38 Alexandre Eremenko ==cylinder== What is the difference between the cylinder <math>\mathbb C \setminus 0</math> and cylinder <math>\mathbb C / \mathbb Z</math> ? =topology= * Topology is a branch of mathematics that deals with qualitative geometric information. This includes the classification of loops and higher-dimensional surfaces. * Topological data analysis and computational topology deal with the study of topology using a computer. * Persistent homology is an algebraic method for discerning topological features of data. * Connected component (or connected cluster of points) is a 0-dimensional feature and cycle (or loop) is a 1-dimensional feature. * Simplicial complex is a set composed of points, line segments, triangles, and their n-dimensional counterparts. * Filtration is the sequence of simplicial complexes, with an inclusion map from each simplicial complex to the next. * Barcode is a visual representation of the persistence of the topological features. Longer bars represent significant features of the data. Shorter bars are due to irregularities or noise. "A topologist is someone who doesn't know the difference between a cup of coffee and a donut." * [https://docs.gempy.org/tutorials/ch4-Topology/ch4-1-Topology.html Gempy] * [http://ronny.rest/tutorials/module/seg_01/segmentation_01_intro/ semantic segmentation] ==computational topology== * [https://www.youtube.com/@utahsoccomputationaltopolo4135 Utah SoC Computational Topology] * [https://markolalovic.github.io/blog/tda-digits tda-digits] ==set== * [[:w:dense set|dense set]] a subset A of a topological space X is said to be dense in X if every point of X either belongs to A or else is arbitrarily "close" to a member of A * [[:w:countable set|countable set]]: a set is countable if either it is finite or it can be made in one to one correspondence with the set of natural numbers. = ???= ''' El método de Mandelbrot ''': este método para desarrollar "objetos fractales" fue creado por [[Benoît Mandelbrot]] en la década de los años 70, mientras trabajaba en IBM. Consiste en construir, para cada punto '''c''' del plano complejo, una sucesión de números complejos '''z<sub>n</sub>'''. Partiendo del punto '''z<sub>0</sub> = 0''', se calcula la sucesión de forma iterativa mediante la fórmula '''z<sub>n+1</sub>=F(z<sub>n</sub>)+c''', donde '''F''' es una función arbitraria previamente elegida. Cuando la sucesión iterativa está acotada, se asigna al punto '''c''' del plano complejo un color sólido (por ejemplo, el color negro). Si la sucesión diverge entonces se asigna al punto '''c''' un color progresivamente distinto, dependiendo de cuántas iteraciones hayan sido necesarias para detectar la divergencia de la sucesión. El fractal derivado por este método cuando se toma la función '''F(z)=z<sup>2</sup>''' se llama [[conjunto de Mandelbrot]]. En lo que sigue, en lugar de '''z<sub>n+1</sub>=F(z<sub>n</sub>)+c''' se utilizará la notación '''Z=F(Z)+C''', como si se tratara de una asignación en algún lenguaje de programación. == Z = Z<sup>m</sup> + C == A continuación se muestra una serie de fractales iterando las diferentes potencias de '''Z = Z<sup>m</sup> + C''', según el método de '''Mandelbrot'''. <br><br> '''Ejemplos de fractales del tipo Mandelbrot: Z = Z<sup>m</sup> + C''' <gallery> MANDEL_Z2%2BC.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C'''</div>Conjunto de Mandelbrot Archivo:MANDEL_Z3%2BC.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> + C'''</div> Archivo:MANDEL_Z4%2BC.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup> + C'''</div> Archivo:MANDEL_Z5%2BC.jpg|<div style="text-align: center;">'''Z = Z<sup>5</sup> + C'''</div> Archivo:MANDEL_Z6%2BC.jpg|<div style="text-align: center;">'''Z = Z<sup>6</sup> + C'''</div> Archivo:MANDEL_Z7%2BC.jpg|<div style="text-align: center;">'''Z = Z<sup>7</sup> + C'''</div> Archivo:MANDEL_Z8%2BC_mediumB.jpg|<div style="text-align: center;">'''Z = Z<sup>8</sup> + C'''</div> Archivo:MANDEL_Z9%2BC_mediumB.jpg|<div style="text-align: center;">'''Z = Z<sup>9</sup> + C'''</div> Archivo:MANDEL_Z10%2BC_mediumB.jpg|<div style="text-align: center;">'''Z = Z<sup>10</sup> + C'''</div> Archivo:MANDEL_Z11%2BC_mediumB.jpg|<div style="text-align: center;">'''Z = Z<sup>11</sup> + C'''</div> Archivo:MANDEL_Z12%2BC_mediumB.jpg|<div style="text-align: center;">'''Z = Z<sup>12</sup> + C'''</div> Archivo:MANDEL_Z12%2BC_detall.jpg|<div style="text-align: center;">'''Z = Z<sup>12</sup> + C<br>x 8'''</div> Archivo:MANDEL_Z20%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>20</sup> + C'''</div> Archivo:MANDEL_Z20%2BC_detall.jpg|<div style="text-align: center;">'''Z = Z<sup>20</sup> + C<br>x 10'''</div> Archivo:MANDEL_Z48%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>48</sup> + C'''</div> Archivo:MANDEL_Z48%2BC_detall.jpg|<div style="text-align: center;">'''Z = Z<sup>48</sup> + C<br>x 20'''</div> Archivo:MANDEL_Z96%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>96</sup> + C'''</div> Archivo:MANDEL_Z96%2BC_detall.jpg|<div style="text-align: center;">'''Z = Z<sup>96</sup> + C<br>x 40'''</div> </gallery> Tal y como se puede ver en los ejemplos representados, el número de lóbulos es '''L = m - 1''' <br> === Un breve viaje a las profundidades del fractal de Mandelbrot Z = Z<sup>2</sup> + C === A continuación vamos a adentrarnos en el fractal clásico de Mandelbrot, utilizando el [[microscopio]] de altísima resolución que nos proporciona el [[cálculo iterativo]]. Todas las ampliaciones vienen precedidas de una imagen del fractal a escala 1:1 en donde podemos apreciar la zona ampliada.<ref>Barnsley, M. Fractals everywhere.Academic Press Inc, 1988. {{#isbn:0-12-079062-9}}. (Cap 5) </ref> ==== Ampliación zona 1 ==== Centro de coordenadas : '''Cx = 0.291811 , Cy = 0.0144686''' <br> <gallery> Archivo:MANDEL_Z2_X1_001.jpg|<div style="text-align: center;">''' x 1'''</div> Archivo:MANDEL_Z2_X732_0,291811_0,0144686.jpg|<div style="text-align: center;">''' x 732'''</div> </gallery> ==== Ampliación zona 2 ==== Centro de coordenadas : '''Cx = -0.165643411 , Cy = 0.656685704 ''' <br> <gallery> Archivo:MANDEL_Z2_X1_002.jpg|<div style="text-align: center;">''' x 1'''</div> Archivo:MANDEL_Z2_X3855_-0,165643411_0,656685704.jpg|<div style="text-align: center;">''' x 3855'''</div> </gallery> ==== Ampliación zona 3 ==== Centro de coordenadas : '''Cx = -0.755625 , Cy = 0.06328125 ''' <br> <gallery> Archivo:MANDEL_Z2_X1_003.jpg|<div style="text-align: center;">''' x 1'''</div> Archivo:MANDEL_Z2_X180_-0,755625_0,06328125.jpg|<div style="text-align: center;">''' x 180'''</div> </gallery> ==== Ampliación zona 4 ==== Centro de coordenadas : '''Cx = -0,1758752481899, Cy = 1,075392007''' <br> A continuación bajaremos a gran profundidad, con una ampliación de más de 2 millones y con un número máximo de 6000 iteraciones por pixel !<br> <gallery> Archivo:MANDEL_Z2_X1_004.jpg|<div style="text-align: center;">''' x 1'''</div> Archivo:MANDEL_Z2_X2369369_-0,1758752481899_1,075392007.jpg|<div style="text-align: center;">''' x 2,369,369'''</div> </gallery> ==== Ampliación zona XX ==== Centro de coordenadas : '''Cx = 0,02816835288421, Cy = 0,63790834667330 ''' <br> Ahora nos adentraremos en un sitio con extrañas formas y colores, pero donde pueden apreciarse perfectamente las formas del fractal de Mandelbrot... <br> <br> <gallery> Archivo:MANDEL_Z2_X5598_0,02816835288421_0,63790834667330.jpg|<div style="text-align: center;">''' x 5,598'''</div> </gallery> == Z = Z<sup>-m</sup> + C == '''Ejemplos de fractales del tipo Mandelbrot, con potencias negativas de Z.''' <gallery> Archivo:MANDEL_Z-2%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z <sup>-2</sup> + C'''</div> Archivo:MANDEL_Z-3%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z <sup>-3</sup> + C'''</div> Archivo:MANDEL_Z-4%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z <sup>-4</sup> + C'''</div> Archivo:MANDEL_Z-5%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z <sup>-5</sup> + C'''</div> </gallery> == Z = Z<sup>p</sup> / (1 + Z<sup>q</sup>) + C == <gallery> Archivo:MANDEL_Z2_(1+Z)+C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> / (1 + Z) + C''' <br></div> Archivo:MANDEL_Z3_(1%2BZ2)%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> / (1 + Z<sup>2</sup>) + C''' <br></div> Archivo:MANDEL_Z3_(1%2BZ)%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> / (1 + Z) + C''' <br></div> Archivo:MANDEL_Z3_(1%2BZ%2BZ2)%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> / (1 + Z + Z<sup>2</sup>) + C''' <br></div> Archivo:MANDEL_(1%2B2xZ)_Z2%2BC_medium.jpg|<div style="text-align: center;">'''Z = [(1 + Z) / Z<sup>2</sup>] + C''' <br></div> </gallery> == Z = Z<sup>m</sup> + C<sup>p</sup> == Pero, ¿ qué pasa cuando hacemos '''Z = Z<sup>m</sup> + C<sup>p</sup>''' ?. Tal y como se puede ver en los siguientes ejemplos, el número de lóbulos es '''L = (m - 1) * p''' <br> <gallery> Archivo:MANDEL_Z2_C2.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C<sup>2</sup>''' <br>L = (2 - 1)* 2 = '''2'''</div> Archivo:MANDEL_Z2_C3.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C<sup>3</sup>''' <br>L = (2 - 1)* 3 = '''3'''</div> Archivo:MANDEL_Z2%2BC6-1.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup>+C<sup>6</sup> - 1 ''' <br> L = (2 - 1)* 6 = '''6'''</div> Archivo:MANDEL_Z3_C2.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> + C<sup>2</sup>''' <br>L = (3 - 1)* 2 = '''4'''</div> Archivo:MANDEL_Z3_C3.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> + C<sup>3</sup>''' <br>L = (3 - 1)* 3 = '''6'''</div> Archivo:MANDEL_Z4_C4.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup> + C<sup>4</sup>''' <br>L = (4 - 1)* 4 = '''12'''</div> </gallery> == Z = Z<sup>m</sup> + Z + C == A continuación se muestra una serie de fractales iterando las diferentes potencias de '''Z = Z<sup>m</sup> + Z + C''', según el método de '''Mandelbrot'''. <br><br> <gallery> Archivo:MANDEL_Z2%2BZ%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + Z + C'''</div> Archivo:MANDEL_Z3%2BZ%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> + Z + C'''</div> Archivo:MANDEL_Z4%2BZ%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup> + Z + C'''</div> Archivo:MANDEL_Z9%2BZ%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>9</sup> + Z + C'''</div> </gallery> == Z = Z<sup>m</sup> - Z + C == A continuación se muestra una serie de fractales iterando las diferentes potencias de '''Z = Z<sup>m</sup> - Z + C''', según el método de '''Mandelbrot'''. <br><br> <gallery> Archivo:MANDEL_Z3-Z%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> - Z + C'''</div> Archivo:MANDEL_Z4-Z%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup> - Z + C'''</div> Archivo:MANDEL_Z5-Z%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>5</sup> - Z + C'''</div> Archivo:MANDEL_Z9-Z%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>9</sup> - Z + C'''</div> </gallery> == Z = Z<sup>m</sup> + 1 / C<sup>p</sup> == También se puede transformar cada punto del plano complejo, de acuerdo a una función arbitraria, antes de ser sumado a la función iterativa, según la siguiente ecuación '''Z = Z<sup>m</sup> + F(C) '''. Veamos que pasa cuando la transformación es del tipo:'''F(C) = 1 / C'''<br><br> '''Ejemplos de fractales del tipo Mandelbrot: Z = Z<sup>m</sup> + 1/C''', donde cada punto C del plano complejo se transforma en 1 / C, antes de entrar en la iteración de la potencia de Z. <br>Zo = (0,0i). El número de vértices es '''V = (m - 1)''' <gallery> Archivo:MANDEL_Z2_1_C.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + 1/C'''</div> Archivo:MANDEL_Z3%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> + 1/C'''</div> Archivo:MANDEL_Z4%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup> + 1/C'''</div> Archivo:MANDEL_Z5%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>5</sup> + 1/C'''</div> Archivo:MANDEL_Z6%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>6</sup> + 1/C'''</div> Archivo:MANDEL_Z7%2B1_C_mediumB.jpg|<div style="text-align: center;">'''Z = Z<sup>7</sup> + 1/C'''</div> </gallery> <br> Pero, qué pasa cuándo '''Z = Z<sup>m</sup> + (1 / C<sup>2</sup>)''' ?. Pues algo muy parecido a lo que veíamos antes, ahora el número de vértices es '''V = (m - 1) * p''' <br> <gallery> Archivo:MANDEL_Z2_iC2.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + 1 / C<sup>2</sup>''' <br>V = (2 - 1)* 2 = '''2'''</div> Archivo:MANDEL_Z3_iC2.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> + 1 / C<sup>2</sup>''' <br>V = (3 - 1)* 2 = '''4'''</div> Archivo:MANDEL_Z4_iC2.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup> + 1 / C<sup>2</sup>''' <br>V = (4 - 1)* 2 = '''6'''</div> Archivo:MANDEL_Z5_iC2.jpg|<div style="text-align: center;">'''Z = Z<sup>5</sup> + 1 / C<sup>2</sup>''' <br>V = (5 - 1)* 2 = '''8'''</div> Archivo:MANDEL_Z6_iC2.jpg|<div style="text-align: center;">'''Z = Z<sup>6</sup> + 1 / C<sup>2</sup>''' <br>V = (6 - 1)* 2 = '''10'''</div> Archivo:MANDEL_Z7_iC2.jpg|<div style="text-align: center;">'''Z = Z<sup>7</sup> + 1 / C<sup>2</sup>''' <br>V = (7 - 1)* 2 = '''12'''</div> </gallery> <br> <gallery> Archivo:MANDEL_Z2_iC3.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + 1 / C<sup>3</sup>''' <br>V = (2 - 1)* 3 = '''3'''</div> Archivo:MANDEL_Z2_iC3+1.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + 1 / (C<sup>3</sup>+1)''' <br>V = (2 - 1)* 3 = '''3'''</div> </gallery> <br> === Integrando en el mismo fractal una función de C y su inversa Z = Z<sup>m</sup> + C i Z = Z<sup>m</sup> + 1/C === La zona en color BLANCO intenso es el área de la intersección de los 2 sets.<br> <gallery> Archivo:MANDEL_Z2%2BC--Z2%2B1_C_mediumB.jpg|<div style="text-align: center;">Z = Z<sup>2</sup> + 1 / C <br>Z = Z<sup>2</sup> + C</div> Archivo:MANDEL_Z3%2BC--Z2%2B1_C_medium.jpg|<div style="text-align: center;">Z = Z<sup>2</sup> + 1 / C <br>Z = Z<sup>3</sup> + C</div> Archivo:MANDEL_Z2%2BC--Z3%2B1_C_medium.jpg|<div style="text-align: center;">Z = Z<sup>3</sup> + 1 / C <br>Z = Z<sup>2</sup> + C</div> Archivo:MANDEL_Z3%2BC--Z3%2B1_C_medium.jpg|<div style="text-align: center;">Z = Z<sup>3</sup> + 1 / C <br>Z = Z<sup>3</sup> + C</div> Archivo:MANDEL_Z4%2BC--Z4%2B1_C_medium.jpg|<div style="text-align: center;">Z = Z<sup>4</sup> + 1 / C <br>Z = Z<sup>4</sup> + C</div> Archivo:MANDEL_Z3%2BC--Z4%2B1_C_medium.jpg|<div style="text-align: center;">Z = Z<sup>4</sup> + 1 / C <br>Z = Z<sup>3</sup> + C</div> </gallery> == Z = ( Z<sup>m</sup> / C<sup>m</sup> ) + C == <gallery> Archivo:MANDEL_(Z4_C4)%2BC_medium.jpg|<div style="text-align: center;">'''Z = (Z<sup>4</sup> / C<sup>4</sup>) + C'''</div> Archivo:MANDEL_(Z8_C8)%2BC_medium.jpg|<div style="text-align: center;">'''Z = (Z<sup>8</sup> / C<sup>8</sup>) + C'''</div> </gallery> == Z = Z<sup>m</sup> + C + C<sup>p</sup> + 1/ C + 1/ C<sup>q</sup> == También podemos añadir más sumandos a la función Z<sup>m</sup>, combinando C, C<SUP>p</SUP>, 1/C y 1/C<SUP>q</SUP> en grupos de 2, 3 o 4, veamos que sucede si agrupamos C<SUP>2</SUP>, 1/C y 1/C<SUP>2</SUP> de 2,3 o 4 formas ..: <gallery> Archivo:MANDEL_Z2%2BC%2BC2_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C + C<sup>2</sup>''' <br></div> Archivo:MANDEL_Z2%2BC%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C + 1/C''' <br></div> Archivo:MANDEL_Z2%2BC%2B1_C2_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C + 1/C<sup>2</sup>''' <br></div> Archivo:MANDEL_Z2%2BC2%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C<sup>2</sup>+ 1/C'''</div> Archivo:MANDEL_Z2%2BC2%2B1_C2_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C<sup>2</sup> + 1/C<sup>2</sup>''' <br></div> Archivo:MANDEL_Z2%2B1_C%2B1_C2_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + 1/C + 1/ C<sup>2</sup> ''' <br></div> </gallery> <gallery> Archivo:MANDEL_Z2%2BC%2BC2%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C + C<SUP>2</SUP> + 1/C'''</div> Archivo:MANDEL_Z2%2BC%2BC2%2B1_C2_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C + C<SUP>2</SUP> + 1/C<sup>2</sup>'''</div> Archivo:MANDEL_Z2%2BC%2B1_C%2B1_C2_mediumB.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C + 1/C + 1/C<sup>2</sup>'''</div> Archivo:MANDEL_Z2%2BC2%2B1_C%2B1_C2_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C<SUP>2</SUP> + 1/C + 1/C<sup>2</sup>'''</div> Archivo:MANDEL_Z2%2BC%2BC2%2B1_C%2B1_C2_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C + C<sup>2</sup> + 1/C + 1/C<sup>2</sup>'''</div> </gallery> <br> A continuación más combinaciones con otros exponentes: <gallery> Archivo:MANDEL_Z2%2BC%2B1_C3_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + C + 1/ C<sup>3</sup>'''</div> </gallery> == Z = Z<sup>m</sup> + polinomios de C == Podemos combinar diferentes potencias de C y/o Z sumándolas a Z<sup>m</sup> , veamos qué sucede: <gallery> Archivo:MANDEL_Z2%2BC_(C2%2B1)%2BC_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C /(C<sup>2</sup>+1) + C'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BC_(C2-1)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C /(C<sup>2</sup>-1)'''<br> Zo = (0,0i)</div> Archivo:Z2_%2B_C2_(C4%2B_0,1).jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C<sup>2</sup> /(C<sup>4</sup> + 0.1)'''<br> Zo = (0,0i)</div> Archivo:Z2_%2B_C2_(C4-0,25).jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C<sup>2</sup> / (C<sup>4</sup> - 0.25)'''<br> Zo = (0,0i)</div> </gallery> === El caso de la función: Z=Z<sup>2</sup> + 1 /(C<sup>m</sup>-1) === <gallery> Archivo:MANDEL_Z2%2B1_(C2-1)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + 1 /(C<sup>2</sup>-1)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2B1_(C3-1)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + 1 /(C<sup>3</sup>-1)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2B1_(C4-1)_medium.jpg|<div style="text-align: center;">Z'''=Z<sup>2</sup> + 1 /(C<sup>4</sup>-1)'''<br> Zo = (0,0i)</div> </gallery> == Z = Z<sup>m</sup> + polinomios mixtos de C i Z == Podemos sumar a Z<sup>m</sup> polinomios mixtos de C i Z , veamos qué sucede: === Z = Z<sup>2</sup> + C/ (Z<sup>2</sup> + k) === <gallery> Archivo:MANDEL_Z2%2BC_(Z2-0,001)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C / (Z<sup>2</sup>- 0.001)'''<br> Zo = (0,0i)''' x 1000'''</div> Archivo:MANDEL_Z2%2BC_(Z2-0,01)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C / (Z<sup>2</sup>- 0.01)'''<br> Zo = (0,0i)''' x 100'''</div> Archivo:MANDEL_Z2%2BC_(Z2-0,1)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C / (Z<sup>2</sup>- 0.1)'''<br> Zo = (0,0i)''' x 10'''</div> Archivo:MANDEL_Z2%2BC_(Z2%2B0,1)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C / (Z<sup>2</sup>+ 0.1)'''<br> Zo = (0,0i)''' x 10'''</div> Archivo:MANDEL_Z2%2BC_(Z2%2B0,01)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C / (Z<sup>2</sup>+ 0.01)'''<br> Zo = (0,0i)''' x 100'''</div> Archivo:MANDEL_Z2%2BC_(Z2%2B0,001)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C / (Z<sup>2</sup>+ 0.001)'''<br> Zo = (0,0i)''' x 24,900'''</div> </gallery> === Z = Z<sup>m</sup> + C<sup>p</sup>/Z<sup>q</sup> + C === <gallery> Archivo:Mandel_Z2%2BC2_Z2%2BC_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + (C<sup>2</sup> /Z<sup>2</sup>) + C '''<br> Zo = (0,0i) m=2, p=2,q=2</div> Archivo:MANDEL_Z2+C4_Z2+C.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + (C<sup>4</sup> /Z<sup>2</sup>) + C '''<br> Zo = (0,0i) m=2,p=4,q=2</div> Archivo:Mandel_Z2%2BC4_Z4%2BC_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + (C<sup>4</sup> /Z<sup>4</sup>) + C '''<br> Zo = (0,0i) m=2, p=4,q=4</div> Archivo:Mandel_Z2%2BC6_Z6%2BC_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + (C<sup>6</sup> /Z<sup>6</sup>) + C '''<br> Zo = (0,0i) m=2, p=6,q=6</div> Archivo:Mandel_Z4%2BC2_Z4%2BC.jpg|<div style="text-align: center;">'''Z=Z<sup>4</sup> + (C<sup>2</sup> /Z<sup>4</sup>) + C '''<br> Zo = (0,0i) m=4, p=2,q=4</div> </gallery> === Z= [(Z<sup>m</sup>+C-1) / (m*Z<sup>m-1</sup>+C- m)]<sup>2</sup> === <gallery> Archivo:MANDEL_MAGNET_mediumB.jpg|<div style="text-align: center;">'''Z= [(Z<sup>2</sup>+C-1) / (2*Z+C-2)]<sup>2</sup>'''<br> Zo = (0,0i) '''MAGNET'''</div> Archivo:MANDEL_((Z2%2BC2-1)_(2XZ%2BC2-2))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z<sup>2</sup>+C<sup>2</sup>-1) / (2*Z+C<sup>2</sup> -2)]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z2%2BC3-1)_(2XZ%2BC3-2))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z<sup>2</sup>+C<sup>3</sup>-1) / (2*Z+C<sup>3</sup> -2)]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z3%2BC-1)_(3XZ2%2BC-3))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z<sup>3</sup>+C-1) / (3*Z<sup>2</sup>+C-3)]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z4%2BC-1)_(4XZ3%2BC-4))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z<sup>4</sup>+C-1) / (4*Z<sup>3</sup>+C-4)]<sup>2</sup>'''<br> Zo = (0,0i)</div> </gallery> === Z= [(Z + C<sup>m</sup>-1) / C<sup>m</sup>]<sup>2</sup> === <gallery> Archivo:MANDEL_((Z%2BC-1)_(C%2B0))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C -1) / C]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC2-1)_(C2%2B0))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>2</sup>-1) / C<sup>2</sup>]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC3-1)_(C3%2B0))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>3</sup>-1) / C<sup>3</sup>]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC4-1)_(C4%2B0))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>4</sup>-1) / C<sup>4</sup>]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC5-1)_(C5))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>5</sup>-1) / C<sup>5</sup>]<sup>2</sup>'''<br> Zo = (0,0i)</div> </gallery> === Z= [(Z + C<sup>m</sup>-1) / C<sup>m</sup>]<sup>3</sup> === <gallery> Archivo:MANDEL_((Z%2BC-1)_(C))3_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C-1) / C]<sup>3</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC2-1)_(C2))3_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>2</sup>-1) / C<sup>2</sup>]<sup>3</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC3-1)_(C3))3_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>3</sup>-1) / C<sup>3</sup>]<sup>3</sup>'''<br> Zo = (0,0i)</div> </gallery> === Z= [(Z + C<sup>m</sup>+1) / (C<sup>m</sup> - 1)]<sup>2</sup> === <gallery> Archivo:MANDEL_((Z%2BC%2B1)_(C-1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C +1) / (C -1]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC2%2B1)_(C2-1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>2</sup> +1) / (C<sup>2</sup> -1]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC3%2B1)_(C3-1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>3</sup> +1) / (C<sup>3</sup> -1]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC4%2B1)_(C4-1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>4</sup> +1) / (C<sup>4</sup> -1)]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC5%2B1)_(C5-1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>5</sup> +1) / (C<sup>5</sup> -1)]<sup>2</sup>'''<br> Zo = (0,0i)</div> </gallery> === Z= [(Z + C<sup>m</sup>-1) / (C<sup>m</sup> + 1)]<sup>2</sup> === <gallery> Archivo:MANDEL_((Z%2BC-1)_(C%2B1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C -1) / (C +1]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC2-1)_(C2%2B1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>2</sup> -1) / (C<sup>2</sup> +1]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC3-1)_(C3%2B1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>3</sup> -1) / (C<sup>3</sup> +1]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC4-1)_(C4%2B1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>4</sup> -1) / (C<sup>4</sup> +1)]<sup>2</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_((Z%2BC5-1)_(C5%2B1))2_medium.jpg|<div style="text-align: center;">'''Z= [(Z + C<sup>5</sup> -1) / (C<sup>5</sup> +1)]<sup>2</sup>'''<br> Zo = (0,0i)</div> </gallery> === Otras combinaciones de Z y C === <gallery> Archivo:mandel.jmb_001.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + C<sup>2</sup> /(Z<sup>2</sup>+C) + C'''<br> Zo = (0,0i)</div> </gallery> == Más funciones de variable compleja == Pero existe una amplia variedad de funciones, en el dominio de los [[Número complejo|números complejos]], que pueden ser iteradas según el método de Mandelbrot. <br> Voy a citar aquí algunos ejemplos, explicitando la parte real y la imaginaria:<br><br> ''' Exp(Z)''' = [ Exp(x) * Cos(x), Exp(x) * Sin(y)i ] <br> ''' Sin(Z)''' = [ Sin(x) * ((Exp(y) + Exp(-y)) / 2), Cos(x) * ((Exp(y) - Exp(-y)) / 2)i ] <br> ''' Cos(Z)''' = [ Cos(x) * ((Exp(y) + Exp(-y)) / 2) , -Sin(x) * ((Exp(y) - Exp(-y)) / 2)i ] <br> ''' SinH(Z)''' = [ Cos(y) * ((Exp(x) - Exp(-x)) / 2) , Sin(Y) * ((Exp(x) + Exp(-x)) / 2)i ] <br> ''' CosH(Z)''' = [ Cos(y) * ((Exp(x) + Exp(-x)) / 2) , Sin(y) * ((Exp(x) - Exp(-x)) / 2)i ] <br> ''' LN(Z)''' = [ 0.5 * Log(x * x + y * y) , Atn(y / x)i ] <br> ''' SQR(Z)''' = [ (x * x + y * y)^0.25 * Cos(0.5 * Atn(y/x)) , (x * x + y * y)^0.25 * Sin(0.5 * Atn(y/x)) i ] <br> ''' ATN(Z)''' = [PI / 4 - (1 / 2) * Atn((1 - x^2 - y^2) / (2 * x)), -(1 / 4) * Log((1 - x^2 - y^2) ^2 + 4 * x^2) + (1 / 2) * Log((1 + y) ^2 + x^2) i]<br> <br> === Z = Z<sup>m</sup> + F(C) === A continuación algunos ejemplos de fractales por iteración de '''Z<sup>2</SUP>''', pero transformando C según las funciones descritas anteriormente: <br> <gallery> Archivo:MANDEL_Z2+SIN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + Sin(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2B1_SIN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + 1/Sin(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2+SIN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + Cos(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2B1_SIN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + 1/Cos(C)'''<br> Zo = (0,0i)</div> </gallery> <gallery> Archivo:MANDEL_Z2+SINH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + SinH(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2B1_SINH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + 1/SinH(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2+COSH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + CosH(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2B1_COSH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + 1/CosH(C)'''<br> Zo = (0,0i)</div> </gallery> <gallery> Archivo:MANDEL_Z2%2BTAN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + Tan(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BCOTAN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + CoTan(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BTANH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + TanH(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BTANH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + CoTanH(C)'''<br> Zo = (0,0i)</div> </gallery> <gallery> Archivo:MANDEL_Z2%2BSIN(C)_COSH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + Sin(C)/CosH(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BCOSH(C)_SIN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + CosH(C)/Sin(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BCOS(C)_SINH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + Cos(C)/SinH(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BSINH(C)_COS(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + SinH(C)/Cos(C)'''<br> Zo = (0,0i)</div> </gallery> <gallery> Archivo:MANDEL_Z2%2BSIN(C)_SINH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + Sin(C)/SinH(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BSINH(C)_SIN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + SinH(C)/Sin(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BSIN(C)_SINH(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + Cos(C)/CosH(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z2%2BSINH(C)_SIN(C)_medium.jpg|<div style="text-align: center;">'''Z=Z<sup>2</sup> + CosH(C)/Cos(C)'''<br> Zo = (0,0i)</div> </gallery> <gallery> Archivo:MANDEL_Z2%2BATN(C)_medium.jpg|<div style="text-align: center;">'''Z= Z<sup>2</sup> + ATan(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_-0,5XZ2%2BSQR(C)_medium.jpg|<div style="text-align: center;">'''Z= -0.5*Z<sup>2</sup> + Sqr(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_-0,5XZ3%2BSQR(C)_medium.jpg|<div style="text-align: center;">'''Z= -0.5*Z<sup>3</sup> + Sqr(C)'''<br> Zo = (0,0i)</div> </gallery> == Fractales por iteración de Exp(Z) == Esta función se descompone en una parte real y otra imaginaria: ''' Exp(Z)''' = [ Exp(x) * Cos(y), Exp(x) * Sin(y)i ] <br> Puede ser utilizada como función iterativa o como función transformadora de C = (Cx,Cyi), o simultáneamente: === Como función iterativa === <gallery> Archivo:MANDEL_EXP(Z)%2BC.jpg|<div style="text-align: center;">'''Z = Exp(Z)+ C '''<br> Zo = (0,0i)</div> Archivo:MANDEL_ZxExp(Z)%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z * Exp(Z)+ C '''<br> Zo = (0,0i)</div> </gallery> === Como función transformadora de C === <gallery> Archivo:MANDEL_Z2%2BEXP(C).jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + Exp(C) '''<br> Zo = (0,0i)</div> </gallery> === Como función iterativa i transformadora de C, simultáneamente === <gallery> Archivo:EXP(C3_Z3).jpg|<div style="text-align: center;">'''Z = Exp(C<sup>3</sup>/Z<sup>3</sup>)'''<br> Zo = (0,0i)</div> Archivo:Mandel_Exp(_(Z%5E2%2Bk3xZ)_SQR(C%5E3)).jpg|<div style="text-align: center;">'''Z = Exp[(Z<sup>2</sup>-1.00001*Z)/Sqr(C<sup>3</sup>)]'''<br> Zo = (0,0i)</div> Archivo:Mandel_Exp(_(Z%5E2%2Bk3xZ)_C%5E3)_.jmb.jpg|<div style="text-align: center;">'''Z = Exp[(Z<sup>2</sup>- 1.00001*Z)/C<sup>3</sup>]'''<br> Zo = (0,0i)</div> </gallery> ==== El caso de la función Z = Exp[(Z<sup>2</sup> + k * Z) / F(C<sup>m</sup>)] ==== Esta función es muy sensible a Zo, y también al coeficiente ('''k''') que multiplica a Z. Veamos algunos ejemplos interesantes: <gallery> Archivo:Mandel Exp( (Z^2+k3xZ) Sqr(C^3) ).jmb.jpg|<div style="text-align: center;">'''Z = Exp[(Z<sup>2</sup>+ k*Z)/ Sqr(C<sup>3</sup>)]'''<br> Zo = (1,1i) ''' k = 1'''</div> Archivo:Mandel_Exp((Z2-0,8Z)_Sqr(C3))_medium.jpg|<div style="text-align: center;">'''Z = Exp[(Z<sup>2</sup>+ k*Z)/ Sqr(C<sup>3</sup>)]'''<br> Zo = (1,1i) ''' k = -0.8 '''</div> Archivo:MANDEL_EXP(Z2_SQR(C7))_medium.jpg|<div style="text-align: center;">'''Z = Exp[(Z<sup>2</sup>+ k*Z)/ Sqr(C<sup>7</sup>)]'''<br> Zo = (1,1i) ''' k = 0.0 '''</div> Archivo:MANDEL_EXP((Z2-0,8Z)_SQR(C7))_medium.jpg|<div style="text-align: center;">'''Z = Exp[(Z<sup>2</sup>+ k*Z)/ Sqr(C<sup>7</sup>)]'''<br> Zo = (1,1i) ''' k = -0.8 '''</div> Archivo:MANDEL_EXP((Z2%2B3Z)_LN(C9))_medium.jpg|<div style="text-align: center;">'''Z = Exp[(Z<sup>2</sup>+ k*Z)/ LN(C<sup>9</sup>)]'''<br> Zo = (1,1i) ''' k = 3.0 '''</div> </gallery> ==== El caso de la función Z<sub>n+1</sub> = Exp(Z<sub>n</sub> / C <sup>m</sup>) ==== <gallery> Archivo:MANDEL_EXP(Z_C)_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_EXP(Z_C2)_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C<sup>2</sup>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_EXP(Z_C3)_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C<sup>3</sup>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_EXP(Z_C4)_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C<sup>4</sup>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_EXP(Z_C5)_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C<sup>5</sup>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_EXP(Z_C6)_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C<sup>6</sup>)'''<br> Zo = (0,0i)</div> </gallery> <br> ==== El caso de la función Z<sub>n+1</sub> = Exp(Z<sub>n</sub> / C <sup>m</sup>) + C <sup>p</sup> ==== <gallery> Archivo:MANDEL_EXP(Z_C6)%2BC3_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C<sup>6</sup>) + C <sup>3</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_EXP(Z_C8)%2BC4_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C<sup>8</sup>) + C <sup>4</sup>'''<br> Zo = (0,0i)</div> Archivo:MANDEL_EXP(Z_C8)%2BC2_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z /C<sup>8</sup>) + C <sup>2</sup>'''<br> Zo = (0,0i)</div> </gallery> ==== El caso de la función Z<sub>n+1</sub> = Exp(Z<sub>n</sub><sup>p</sup> / C <sup>p</sup>) ==== <gallery> Archivo:Mandel_EXP(Z3_C3).jpg|<div style="text-align: center;">'''Z = Exp(Z<sup>3</sup>/C<sup>3</sup>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_EXP(Z4_C4).jpg|<div style="text-align: center;">'''Z = Exp(Z<sup>4</sup>/C<sup>4</sup>)'''<br> Zo = (0,0i)</div> </gallery> <br> ==== El caso de la función Z<sub>n+1</sub> = Z<sub>n</sub><sup>q</sup> * Exp(Z<sub>n</sub> / C <sup>p</sup>) + C ==== <gallery> Archivo:Mandel_Z2xEXP(Z_C)%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> * Exp(Z/C)+ C'''<br> Zo = (0,0i)</div> Archivo:Mandel_Z3xEXP(Z_C)%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup> * Exp(Z/C)+ C'''<br> Zo = (0,0i)</div> Archivo:Mandel_Z4xEXP(Z_C)%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup> * Exp(Z/C)+ C'''<br> Zo = (0,0i)</div> Archivo:Mandel_Z5xEXP(Z_C)%2BC_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>5</sup> * Exp(Z/C)+ C'''<br> Zo = (0,0i)</div> </gallery> ==== El caso de la función Z<sub>n+1</sub> = Exp[ Z<sub>n</sub><sup>2</sup> / (C <sup>m</sup> + C <sup>p</sup>) ] ==== Aparece un número de lóbulos centrales = '''m''', y un número de aristas exteriores = '''p''', siendo '''m<p'''. <gallery> Archivo:Exp(Z2 (C5 + C)).jpg|<div style="text-align: center;">'''Z = Exp[Z<sup>2</sup> / ( C<sup>5</sup> + C )]'''<br> Zo = (0,0i)</div> Archivo:Mandel_EXP(_Z2_(C6%2BC3)).jpg|<div style="text-align: center;">'''Z = Exp[Z<sup>2</sup> / ( C<sup>6</sup> + C<sup>3</sup> )]'''<br> Zo = (0,0i)</div> Archivo:Mandel_EXP(_Z2_(C8%2BC4)).jpg|<div style="text-align: center;">'''Z = Exp[Z<sup>2</sup> / ( C<sup>8</sup> + C<sup>4</sup> )]'''<br> Zo = (0,0i)</div> </gallery> <br> ==== El caso de la función Z<sub>n+1</sub> = Z<sub>n</sub><sup>m</sup> * Exp[ Cos(Z<sub>n</sub>)] + 1/C ==== Aparecen un número de aristas = '''m'''. <gallery> Archivo:MANDEL_Z2xExp(Cos(Z))%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup>* Exp[ Cos(Z)] + 1/C '''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z3xExp(Cos(Z))%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup>* Exp[ Cos(Z)] + 1/C '''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z4xExp(Cos(Z))%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup>* Exp[ Cos(Z)] + 1/C '''<br> Zo = (0,0i)</div> </gallery> == Fractales per iteración de Sin(Z) == Esta función se descompone en una parte real y otra imaginaria: ''' Sin(Z)''' = [ Sin(x) * ((Exp(y) + Exp(-y)) / 2), Cos(x) * ((Exp(y) - Exp(-y)) / 2)i ] <br> Puede ser utilizada como función iterativa o como función transformadora de los puntos C = (Cx,Cyi), simultáneamente: === Como función iterativa === === Como función transformadora de C === <gallery> Archivo:MANDEL_Z2+SIN(C)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup>+Sin(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z3+SIN(C)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup>+Sin(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z4+SIN(C)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup>+Sin(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z5+SIN(C)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>5</sup>+Sin(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z6+SIN(C)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>6</sup>+Sin(C)'''<br> Zo = (0,0i)</div> </gallery> <br> <gallery> Archivo:MANDEL_Z2+SIN(C2)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup>+Sin(C<sup>2</sup>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z3+SIN(C2)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>3</sup>+Sin(C<sup>2</sup>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_Z4+SIN(C2)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>4</sup>+Sin(C<sup>2</sup>)'''<br> Zo = (0,0i)</div> </gallery> === Como función iterativa y transformadora de C, simultáneamente === <gallery> Archivo:MANDEL_SIN(COSH(Z)xC3)_medium.jpg|<div style="text-align: center;">'''Z = Sin(CosH(Z)*C<sup>3</sup>)'''<br> Zo = (0,0i)</div> </gallery> ==== El caso de la función Z<sub>n+1</sub> = Sin(Z<sub>n</sub> * C <sup>m</sup>) ==== <gallery> Archivo:MANDEL_SIN(ZxSQR(C))_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z*C<sup>0.5</sup>)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(ZxC)_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z*C)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(ZxC2).jpg|<div style="text-align: center;">'''Z = Sin(Z*C<sup>2</sup>)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(ZxC3).jpg|<div style="text-align: center;">'''Z = Sin(Z*C<sup>3</sup>)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(ZxC10)_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z*C<sup>10</sup>)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(SQR(Z)xC3)_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z<sup>0.5</sup>*C<sup>3</sup>)'''<br> Zo = (1,0i)</div> </gallery> ==== El caso de la función Z<sub>n+1</sub> = Sin(Z<sub>n</sub> / C <sup>m</sup>) ==== <gallery> Archivo:MANDEL_SIN(Z_SQR(C))_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z/C<sup>0.5</sup>)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(Z_C)_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z/C)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(Z_C2)_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z/C<sup>2</sup>)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(Z_C3)_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z/C<sup>3</sup>)'''<br> Zo = (1,0i)</div> Archivo:MANDEL_SIN(Z_C10)_medium.jpg|<div style="text-align: center;">'''Z = Sin(Z/C<sup>10</sup>)'''<br> Zo = (1,0i)</div> </gallery> == Fractales por iteración de Cos(Z) == Esta función se descompone en una parte real y otra imaginaria: ''' ' Cos(Z)''' = [ Cos(x)*((Exp(y)+Exp(-y)) / 2), -Sin(x)*((Exp(y)-Exp(-y))/2)i ] <br> Puede ser utilizada como función iterativa o como función transformadora de C = (Cx,Cyi), o simultáneamente === Como función iterativa === <gallery> Archivo:MANDEL_COS(Z)%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z)+ 1/C'''<br> Zo = (0,0i)</div> Archivo:MANDEL_COS(Z)%2BLN(C)_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z)+ LN(C) '''<br> Zo = (0,0i)</div> Archivo:MANDEL_COS(Z3)%2B1_C.jpg|<div style="text-align: center;">'''Z = Cos(Z<SUP>3</SUP>)+ 1/C'''<br> Zo = (0.2,0.3i)</div> </gallery> === Como función transformadora de C === <gallery> Archivo:MANDEL_Z2%2BCOS(Z).jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + Cos( C)'''<br> Zo = (0,0i)</div> </gallery> === Como función iterativa y transformadora de C, simultáneamente === <gallery> Archivo:MANDEL_COS(Z)%2BCOS(C)_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z) + Cos(C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_COS(C_Z)_mediumB.jpg|<div style="text-align: center;">'''Z = Cos(C/Z)'''<br> Zo = (0,0i)</div> </gallery> ==== El caso de la función Z<sub>n+1</sub> = Cos(Z<sub>n</sub> * C <sup>m</sup>) ==== <gallery> Archivo:MANDEL_COS(ZxSQR(C))_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z*C<sup>0.5</sup>)'''<br> Zo = (0,0i)</div> Archivo:Mandel_Cos(ZxC).jpg|<div style="text-align: center;">'''Z = Cos(Z*C)'''<br> Zo = (0,0i)</div> Archivo:Mandel_Cos(ZxC2).jpg|<div style="text-align: center;">'''Z = Cos(Z*C<sup>2</sup>)'''<br> Zo = (0,0i)</div> Archivo:Mandel_Cos(ZxC3).jmb.jpg|<div style="text-align: center;">'''Z = Cos(Z*C<sup>3</sup>)'''<br> Zo = (0,0i)</div> </gallery> <br> ==== El caso de la función Z<sub>n+1</sub> = Cos(Z<sub>n</sub>/C <sup>m</sup>) ==== <gallery> Archivo:MANDEL_COS(Z_SQR(C))_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z/C<SUP>0.5</SUP>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_COS(Z_C)_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z/C)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_COS(Z_C2)_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z/C<SUP>2</SUP>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_COS(Z_C3)_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z/C<SUP>3</SUP>)'''<br> Zo = (0,0i)</div> Archivo:MANDEL_COS(Z_C4)_medium.jpg|<div style="text-align: center;">'''Z = Cos(Z/C<SUP>4</SUP>)'''<br> Zo = (0,0i)</div> </gallery> <br> == Fractales por iteración de SinH(Z) == Esta función se descompone en una parte real y otra imaginaria: ''' SinH(Z)''' = [ Cos(y) * ((Exp(x) - Exp(-x)) / 2) , Sin(Y) * ((Exp(x) + Exp(-x)) / 2)i ] <br> Puede ser utilizada como función iterativa o como función transformadora de C = (Cx,Cyi), o simultáneamente: === Como función iterativa === <gallery> MANDEL_SinH(Z)%2B1_C_BIG.jpg|<div style="text-align: center;">'''Z = SinH(Z) + 1/C'''<br> Zo = (0.91, -0.08i)</div> MANDEL_SinH(Z)%2B1_C_BIG2.jpg|<div style="text-align: center;">'''Z = SinH(Z) + 1/C'''<br> Zo = (0.90, -0.05i)</div> MANDEL_SinH(Z)%2B1_C2_BIG.jpg|<div style="text-align: center;">'''Z = SinH(Z) + 1/C<sup>2</sup>'''<br> Zo = (1, 0.1i)</div> MANDEL_SinH(Z2)%2B1_C_BIG.jpg|<div style="text-align: center;">'''Z = SinH(Z<sup>2</sup>) + 1/C'''<br> Zo = (1, -1i)</div> </gallery> === Como función transformadora de C === <gallery> MANDEL_Z2%2BSINH(C)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + SinH(C)'''<br> Zo = (0,0i)</div> MANDEL_Z2%2BSINH(1_C3)_medium.jpg|<div style="text-align: center;">'''Z = Z<sup>2</sup> + SinH(1/ C<sup>3</sup>)'''<br> Zo = (0,0i)</div> </gallery> <br> === Como función iterativa i transformadora de C, simultáneamente === <gallery> MANDEL_SinH(Z_C)_BIG.jpg|<div style="text-align: center;">'''Z = SinH(Z / C )'''<br> Zo = (0,1i)</div> MANDEL_SINH(Z)_C_mediumB.jpg|<div style="text-align: center;">'''Z = SinH(Z)/ C'''<br> Zo = (1,0i)</div> </gallery> <br><br> == Fractales por iteración de CosH(Z) == Esta función se descompone en una parte real y otra imaginaria: ''' CosH(Z)''' = [ Cos(y) * ((Exp(x) + Exp(-x)) / 2) , Sin(y) * ((Exp(x) - Exp(-x)) / 2)i ] <br> Puede ser utilizada como función iterativa o como función transformadora de C = (Cx,Cyi), o simultáneamente: === Como función iterativa === <gallery> MANDEL_COSH(Z)%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = CosH(Z) + 1/C'''<br> Zo = (0,0i)</div> MANDEL_COSH(Z2)%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = CosH(Z<sup>2</sup>) + 1/C'''<br> Zo = (0,0i)</div> MANDEL_COSH(Z3)%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = CosH(Z<sup>3</sup>) + 1/C'''<br> Zo = (0,0i)</div> MANDEL_COSH(Z4)%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = CosH(Z<sup>4</sup>) + 1/C'''<br> Zo = (0,0i)</div> MANDEL_COSH(Z5)%2B1_C_medium.jpg|<div style="text-align: center;">'''Z = CosH(Z<sup>5</sup>) + 1/C'''<br> Zo = (0,0i)</div> </gallery> == Fractales por iteración de combinaciones de diferentes funciones de Z == <gallery> MANDEL_SinH(Z)xSin(Z)%2BC_BIG.jpg|<div style="text-align: center;">'''Z = SinH(Z) * Sin(Z) + C '''<br> Zo = (0,0i)</div> MANDEL_CosH(Exp(Z2))%2BC_medium.jpg|<div style="text-align: center;">'''Z = CosH[Exp(Z<sup>2</sup>)]+ C '''<br> Zo = (0,0i)</div> MANDEL_EXP(Z_C5)%2BLN(Z)%2BZ_medium.jpg|<div style="text-align: center;">'''Z = Exp(Z/C<sup>5</sup>)+ Ln(Z) + Z '''<br> Zo = (0,0i)</div> </gallery> == Más fractales según el método de Mandelbrot == Aquí se muestra un ejemplo de iteración de dos funciones F(X) y F(Y), por adición de cada uno de los puntos del plano C(X,Y), y la introducción de una tercera función F(Z) que desequilibra el punto de convergencia.<br> '''Xn+1 = Xn - Sin(Yn) + C(X) .. Yn+1 = Yn - Sin( Xn) + C(Y) .. Zn+1 = Zn - Cos( Xn + Yn) ''' <br> <gallery> MANDEL_JMB01a_medium.jpg MANDEL_JMB01_medium.jpg </gallery> =references= *Computer Methods and Borel Summability Applied to Feigenbaum's Equation By Jean Pierre Eckmann Format Hardback | 297 pages, Publication date 01 May 1985, Publisher Springer , Publication City/Country United States , ISBN10 0387152156, ISBN13 9780387152158 * http://mathoverflow.net/questions/157309/power-series-expansion-of-the-koenigs-function?rq=1 * T. M. CHERRY, A singular case of iteration of analytic functions: A contribution to the small divisor problem. In: Nonlinear Problems of Engineering, W. F. AMES (Ed.), New York, 1964, 29–50. * Cherry, T. M., "A Singular Case of Iteration of Analytic Functions: A Contribution to the Small-Divisor Problem," in Nonlinear Problems of Engineering (edited by W. F. Ames), Academic Press, New York, 1964, 29-50. * MR178125 30.40 (57.48) Cherry, T. M. A singular case of iteration of analytic functions: A contribution to the small-divisor problem. 1964 Nonlinear Problems of Engineering pp. 29–50 Academic Press, New York {{user language|pl|N}} {{user language|en|2}}. qq5zip0a5bffwsvazgffvcmz8ygksgu Chess Opening Theory/1. d4/1...c6 0 148548 4668938 4668883 2026-09-05T13:32:15Z ~2026-48234-29 3625228 /* Theory table london is bad! */ 4668938 wikitext text/x-wiki {{Chess Opening Theory/Position |Queen's Pawn opening |moves=1.d4 c6 |eco=[[Chess/ECOA|A40]] |parent=[[../|Queens Pawn Opening]] }} == 1...c6 == '''1...c6''' is a transpositional tool. Black gives White the option of changing their mind and playing an e4 opening instead. After [[/2. c4|'''2. c4''']], Black can play 2...d5 and transpose into a [[Chess Opening Theory/1. d4/1...d5/2. c4/2...c6|Slav defence]], as if they had played 1. d4 d5 2. c4 c6. With this move order, White has the option of [[/2. e4|'''2. e4''']], where 2...d4 will transpose into a [[Chess Opening Theory/1. e4/1...c6/2. d4/2...d5|Caro-Kann]], as if they had played 1. e4 c6 2. d4 d5. However, if White plays something else, like '''2. Bf4''', going for a [[Chess Opening Theory/1. d4/1...d5/2. Bf4|Accelerated London]]-style set-up where Black might like to play ...c5 at some point, they may regret having given up a tempo on ...c6 now. miguel funk london is trash i love tomboy and femboy ==Theory table == {{Chess Opening Theory/Table}} '''1. d4 c6 ''' <table border="0" cellspacing="0" cellpadding="4"> <tr> <th></th> <th align="left">2</th> <th align="left">3</th> <th align="left">4</th> <th align="left">5</th> <th align="left">6</th> <th align="left">7</th> </tr> <tr> <th align="right">[[Chess/Slav Defence|Slav Defence]]</th> <td>[[/2. c4|c4]]<br>d5</td> <td>Nf3<br>Nf6</td> <td>Nc3<br>dxc4</td> <td>a4<br>Bf5</td> <td>e3<br>e6</td> <td>Bxc4<br>Bb4</td> <td>=</td> </tr> <tr> <th align="right">[[Chess/Caro-Kann Defence|Caro-Kann Defence]]</th> <td>[[/2. e4|e4]]<br>d5</td> <td>Nc3<br>dxe4</td> <td>Nxe4<br>Bf5</td> <td>Ng3<br>Bg6</td> <td>Nf3<br>Nd7</td> <td>h4<br>h6</td> <td>=</td> </tr> </table> {{ChessMid}} {{wikipedia|Queen's Pawn}} ==References== {{reflist}} ===See also=== {{BCO2}} {{NCO}} {{Chess Opening Theory/Footer}} 9apxefvi6b6hbrqlo7bx105hymp7f27 4668939 4668938 2026-09-05T13:35:39Z ~2026-48234-29 3625228 deleated the troll 4668939 wikitext text/x-wiki {{Chess Opening Theory/Position |Queen's Pawn opening |moves=1.d4 c6 |eco=[[Chess/ECOA|A40]] |parent=[[../|Queens Pawn Opening]] }} == 1...c6 == '''1...c6''' is a transpositional tool. Black gives White the option of changing their mind and playing an e4 opening instead. After [[/2. c4|'''2. c4''']], Black can play 2...d5 and transpose into a [[Chess Opening Theory/1. d4/1...d5/2. c4/2...c6|Slav defence]], as if they had played 1. d4 d5 2. c4 c6. With this move order, White has the option of [[/2. e4|'''2. e4''']], where 2...d4 will transpose into a [[Chess Opening Theory/1. e4/1...c6/2. d4/2...d5|Caro-Kann]], as if they had played 1. e4 c6 2. d4 d5. However, if White plays something else, like '''2. Bf4''', going for a [[Chess Opening Theory/1. d4/1...d5/2. Bf4|Accelerated London]]-style set-up where Black might like to play ...c5 at some point, they may regret having given up a tempo on ...c6 now. ==Theory table == {{Chess Opening Theory/Table}} '''1. d4 c6 ''' <table border="0" cellspacing="0" cellpadding="4"> <tr> <th></th> <th align="left">2</th> <th align="left">3</th> <th align="left">4</th> <th align="left">5</th> <th align="left">6</th> <th align="left">7</th> </tr> <tr> <th align="right">[[Chess/Slav Defence|Slav Defence]]</th> <td>[[/2. c4|c4]]<br>d5</td> <td>Nf3<br>Nf6</td> <td>Nc3<br>dxc4</td> <td>a4<br>Bf5</td> <td>e3<br>e6</td> <td>Bxc4<br>Bb4</td> <td>=</td> </tr> <tr> <th align="right">[[Chess/Caro-Kann Defence|Caro-Kann Defence]]</th> <td>[[/2. e4|e4]]<br>d5</td> <td>Nc3<br>dxe4</td> <td>Nxe4<br>Bf5</td> <td>Ng3<br>Bg6</td> <td>Nf3<br>Nd7</td> <td>h4<br>h6</td> <td>=</td> </tr> </table> {{ChessMid}} {{wikipedia|Queen's Pawn}} ==References== {{reflist}} ===See also=== {{BCO2}} {{NCO}} {{Chess Opening Theory/Footer}} 2ijw960vu406j4ulury012q2jy56sku User:Neoptolemus/Reading list 2 151245 4668929 3279564 2026-09-05T12:33:52Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668929 wikitext text/x-wiki The following is a list of existing books on topics I find interesting, created for my own use so that I can quickly find something fascinating to read and/or edit. [[User:Neoptolemus|'''Νεοπτόλεμος''']] ( [[User talk:Neoptolemus|talk]] &#124; [[Special:Emailuser/Neoptolemus|email]] &#124; [[Special:Contributions/Neoptolemus|contribs]] ) 01:13, 6 March 2008 (UTC) {|width="100%" align="center" cellpadding="4" style="text-align:left; background-color: transparent;color:inherit;" | style="text-align:center" | |style="width:33%" | *[[Chess]] *[[Chess Opening Theory]] *[[Astronomy]] *[[International Relations]] *[[American Politics]] *[[Introduction to Latin American Studies]] *[[Comparative Politics]] *[[Political Theory]] **[[Politicaltheory]] *[[United States Government]] *[[Introduction to Sociology]] *[[Mythology]] *[[Greek Mythology]] *[[Indian Mythology]] *[[Conlang]] *[[Buddhist Philosophy]] *[[Marxism, Communism, and Socialism]] | style="text-align:center" | |style="width:33%" | *[[Utopia]] *[[Political Philosophy: Ancient to Renaissance|Political Philosophy]] *[[Theology 1: Philosophy of Religion]] *[[Theology 2: Comparative Religion]] *[[Theology 3: Descriptive Religion]] *[[History of Islamic Civilization]] *[[History of Islam]] *[[Hinduism]] *[[Bahá'í Faith]] *[[Buddhism]] *[[Sikhism]] *[[Sufism]] *[[Islam]] *[[Ancient History]] *[[Modern History]] *[[World History]] *[[European History]] | style="text-align:center" | |style="width:33%" | *[[Latin-American History]] *[[The Seven Wonders of the World]] *[[New Zealand History]] *[[Australian History]] *[[Canadian History]] *[[English History]] *[[Ethiopian History]] *[[History of Greece]] *[[History of the United Kingdom]] *[[US History]] *[[Israeli History]] *[[Japanese History]] *[[Korean History]] *[[Iranian History]] *[[History of the Soviet Union]] *[[The Holocaust]] *[[COSTP World History Project]] |} j8ojhw4ngilw2q9vk67miyxd6nfbhuc User:Robbiemuffin/Templates/DT main/doc 2 158199 4668998 1186274 2026-09-05T19:12:25Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668998 wikitext text/x-wiki {{Documentation subpage}} <!-- PLEASE ADD CATEGORIES AND INTERWIKIS AT THE BOTTOM OF THIS PAGE. --> <div style="background-color:#abc;{{text default color}}; padding: 2px; border-top-right-radius: 2em; border-top-left-radius: 2em; -webkit-border-top-left-radius: 2em; -webkit-border-top-right-radius: 2em; -moz-border-radius-topleft: 2em; -moz-border-radius-topright: 2em;"> <div style="font-size: 5px; line-height: 5px">&nbsp;</div> <span style="margin-left: 1.1em; font-size: 1.5em; font-weight: bold; font-variant: small-caps"><nowiki>{{</nowiki><span style="font-size: 0.8em">User:Robbiemuffin/Templates/DT main</span><nowiki>}}</nowiki> — Documentation Template</span> <div style="margin-left: 5%; margin-right: 5%;"> {| | __TOC__ |} <br /> <!-- Add sections here --> == Purpose == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> The purpose of the documentation template is to make creating template or other documentation speedy and efficient. </div> == Specification == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> <pre><div style=" background-color:#abc; padding: 2px; border-top-right-radius: 2em; border-top-left-radius: 2em; -webkit-border-top-left-radius: 2em; -webkit-border-top-right-radius: 2em; -moz-border-radius-topleft: 2em; -moz-border-radius-topright: 2em;"> <div style="font-size: 5px; line-height: 5px">&nbsp;</div> {{{title|}}} <div style="margin-left: 5%; margin-right: 5%;"> {| | __TOC__ |} <br /> <!-- Add sections here --> {{{content|}}} <!-- end document --> </div> <div style="font-size:3em">&nbsp;</div> [[Image:Ajax-hacker.full.png|100px|center|]] <div style=" margin-left: auto; margin-right: auto; text-align: center; font-size:0.85em"> ''this page was brought to you by an Ajax hacker'' </div> </div></pre> </div> == Usage == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> <p> <span style="margin-left: 1.1em; font-size: 1.2em; font-weight: bold;"> <nowiki>{{</nowiki> <span style="font-variant: none">subst:</span>&nbsp; <span style="font-size: 0.8em; font-variant: small-caps">User:Robbiemuffin/Templates/DT main<nowiki> | </nowiki>title=</span><span style="font-size: 0.8em;">'''''doc_title'''''</span><span style="font-size: 0.8em; font-variant: small-caps"><nowiki> | </nowiki>content=</span><span style="font-size: 0.8em;">'''''doc_preinsertion_content'''''</span><nowiki> }}</nowiki> </span> </p> <div style="margin-left: 2%;"> {| style="padding: 0.25em; background-color: rgba(255, 255, 255, 0.25);{{text default color}};" |<span style="font-size: 1.8em; line-height: 2em">title</span> |Title text for the Documentation. |- |<span style="font-size: 1.8em; line-height: 2em">contents</span> |Convenience method, puts contents at the insertion point. |} </div> </div> == Example == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> Replacing the two sections that default with a new documentation page with: <pre>{{subst:User:Robbiemuffin/Templates/DT main|title=Some documentation|content= {{subst:User:Robbiemuffin/Templates/DT section|title=Purpose}} {{subst:User:Robbiemuffin/Templates/DT section|title=Specification}} {{subst:User:Robbiemuffin/Templates/DT section|title=Usage}} {{subst:User:Robbiemuffin/Templates/DT section|title=Example}} {{subst:User:Robbiemuffin/Templates/DT section|title=See Also}} }}</pre> -- generated this page. (Save and load the page, then come back and edit the documentation to fill it.) </div> == See Also == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> [[User:Robbiemuffin/Templates/DT section]] </div> <!-- end document --> </div> <div style="font-size:3em">&nbsp;</div> [[Image:Ajax-hacker.full.png|100px|center|]] <div style="margin-left: auto; margin-right: auto; text-align: center; font-size:0.85em">''this page was brought to you by an Ajax hacker''</div> </div> <includeonly><!-- ++++ PLEASE ADD CATEGORIES AND INTERWIKIS BELOW THIS LINE, THANK YOU. --> </includeonly> f7aldy8thfabxd3emiy4sd6v93n020s User:Robbiemuffin/Templates/DT section/doc 2 158200 4669014 1186256 2026-09-05T19:30:37Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669014 wikitext text/x-wiki {{Documentation subpage}} <!-- PLEASE ADD CATEGORIES AND INTERWIKIS AT THE BOTTOM OF THIS PAGE. --> <div style="background-color:#abc;{{Text default color}}; padding: 2px; border-top-right-radius: 2em; border-top-left-radius: 2em; -webkit-border-top-left-radius: 2em; -webkit-border-top-right-radius: 2em; -moz-border-radius-topleft: 2em; -moz-border-radius-topright: 2em;"> <div style="font-size: 5px; line-height: 5px">&nbsp;</div> <span style="margin-left: 1.1em; font-size: 1.5em; font-weight: bold; font-variant: small-caps"><nowiki>{{</nowiki><span style="font-size: 0.8em">User:Robbiemuffin/Templates/DT main</span><nowiki>}}</nowiki> — sections for Documentation Template</span> <div style="margin-left: 5%; margin-right: 5%;"> {| | __TOC__ |} <br /> <!-- Add sections here --> == Purpose == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> Convenience method for adding sections to a DT main-styled documentation page </div> == Specification == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> <pre>== {{{title|}}} == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> {{{content|}}} </div></pre> </div> == Usage == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> <p> <span style="margin-left: 1.1em; font-size: 1.2em; font-weight: bold;"> <nowiki>{{</nowiki> <span style="font-variant: none">subst:</span>&nbsp; <span style="font-size: 0.8em; font-variant: small-caps">User:Robbiemuffin/Templates/DT section<nowiki> | </nowiki>title=</span><span style="font-size: 0.8em;">'''''section_title'''''</span><span style="font-size: 0.8em; font-variant: small-caps"><nowiki> | </nowiki>content=</span><span style="font-size: 0.8em;">'''''section_preinsertion_content'''''</span><nowiki> }}</nowiki> </span> </p> <div style="margin-left: 2%;"> {| style="padding: 0.25em; background-color: rgba(255, 255, 255, 0.25);{{Text default color}};" |<span style="font-size: 1.8em; line-height: 2em">title</span> |Title text for the Section. |- |<span style="font-size: 1.8em; line-height: 2em">contents</span> |Convenience method, puts contents at the insertion point. |} </div> </div> == Example == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> Replacing the two sections that default with a new documentation page with: <pre>{{subst:User:Robbiemuffin/Templates/DT main|title=Some documentation|content= {{subst:User:Robbiemuffin/Templates/DT section|title=Purpose}} {{subst:User:Robbiemuffin/Templates/DT section|title=Specification}} {{subst:User:Robbiemuffin/Templates/DT section|title=Usage}} {{subst:User:Robbiemuffin/Templates/DT section|title=Example}} {{subst:User:Robbiemuffin/Templates/DT section|title=See Also}} }}</pre> -- generated this page. (Save and load the page, then come back and edit the documentation to fill it.) Since this works through substitution, you can use this method at any time to add new sections: If, later on, I want to add a new section after Usage, I could edit the USage section and add this code: <pre>{{subst:User:Robbiemuffin/Templates/DT section|title=My New Section}}</pre> Calling this template without substitutions (and preferably without options) gives a quick short hand to edit the actual template ... '''''which you should never do unless you will revert the changes afterwards.''''' This is a convenience method so you can tune your sections in a one-time-only fashion. </div> == See Also == <div style="margin-left: 2%; margin-right: 2%; text-align: justify; text-justify: newspaper"> [[User:Robbiemuffin/Templates/DT main]] </div> <!-- end document --> </div> <div style="font-size:3em">&nbsp;</div> [[Image:Ajax-hacker.full.png|100px|center|]] <div style="margin-left: auto; margin-right: auto; text-align: center; font-size:0.85em">''this page was brought to you by an Ajax hacker''</div> </div> <includeonly><!-- ++++ PLEASE ADD CATEGORIES AND INTERWIKIS BELOW THIS LINE, THANK YOU. --> </includeonly> bphxb34081pkhc5m81ezzq8eul7uozl User:PMarmottant/Physics at smaller scales 2 158236 4669004 1191516 2026-09-05T19:21:02Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669004 wikitext text/x-wiki == Microscopic scales found in fluids == * Distance between molecules in a liquid: <math> d \sim 0.1 \;\mathrm{nm}</math> * Distance between molecules in a gas: <math> d \sim (1/\rho)^{1/3}\sim(kT/P)^{1/3}\sim 3 \;\mathrm{nm}</math> * Free mean path between collisition in a gas, air at ambient pressure: <math> \lambda = k T/\sqrt{2}\pi \delta^2 P\simeq 61 \; \mathrm{nm}</math>, with <math>\pi\delta^2</math> the effective collision cross-section. == Size of objects of interest embedded in a liquids, example of biological elements == * Protein, lipid molecule of the membrane: 1 nm * Virus: 10 nm * Cell: 1-10 μm == Hierarchy of forces == * Size of the object: <math>l^1</math> * Surface: <math>l^2</math> * Volume and mass: <math>l^3</math> The surface to volume ratio increases when the size decreases. Importance of forces, as a function of distance <math>d</math> or object size <math>l</math> {| border="2" cellpadding="4" cellspacing="0" style="margin: 1em 1em 1em 0; background: #f9f9f9;{{text default color}}; border: 1px #aaa solid; border-collapse: collapse;" |- |- | Van des Waals between molecules | <math>d^{-7}\,</math> |- | Van des Waals between surfaces | <math>d^{-3}\,</math> |- | Capillary force | <math>l^1\,</math> |- | Capillary force | <math>l^1\,</math> |- | Muscular force | <math>l^2\,</math> |- | Gravity force | <math>l^3\,</math> |- | Magnetic force | <math>l^3\,</math> |- | Dielectrophoretic force | <math>l^3\,</math> |} The effects at the beginning of the table become increasingly present when down-sizing. == Examples in Nature of the hierarchy of forces == === Insects can walk on water === [[Image:WaterstriderEnWiki.jpg|thumb|200px|left|The [[w:water strider|Water strider]] uses surface tension to walk]] [[Image:PatteInsecte.svg|thumb|200px|right|Surface tension acts on the perimeter of legs]] A contact line occurs on the legs of these insects. The leg surface is hydrophobic, and therefore the surfaced is curved downwards, which creates an upward tension force. The typical leg diameter is l, and we can estimate the intensity of the forces: * Capillary force scales like <math> \sigma \pi l</math>, with <math>\sigma</math> the surface tension, a force per unit length whose value is <math>\sigma=70.10^{-3} \mathrm{N/m}</math> * Weight scales like <math> \rho g l^3</math> Therefore weight is comparable to the capillary force at the characteristic leghtscale: :<math>l^*=\sqrt{\frac{\sigma}{\rho g}}\simeq 3 \, \mathrm{mm}</math> Below this length capillary forces are preponderant. === Smaller but stronger === How many times can you lift people of your size? The structure of muscles is universal in the animal kingdom, with similar fibers of diameter <math>l_0</math>. Each fiber can exert a maximum force <math>f</math>. The number of fibers is <math>\scriptstyle l^2/l_0^2</math> * Muscular force exerted by a muscle therefore scales like :<math>F\sim P l^2\,</math> with <math>\scriptstyle P=f/l_0^2</math> the maximum stress exerted by a fiber. It is a "Natural" constant, independent of the size. It can be evaluated for human beings as <math>\scriptstyle P\sim F/l^2=100\; \mathrm{N}/10\;\mathrm{cm}^2\simeq 10^4 \;\mathrm{N}</math>, where we computed the typical force exerted by a muscle divided by its typical section area. * The weight scales like :<math>W \sim \rho g l^3\,</math> The number of people you can lift is therefore :<math>N=\frac{F}{W}=\frac{P}{\rho g l}=\frac{H}{l}</math> with <math>H\simeq 1 \; \mathrm{m}</math> a constant independent of size. Humans (l~1m) can lift 1 people Small ants (l~1mm) can lift 1000 people! Note, that this force is used by a particuliar species of ants to jump. These ants strike their mandibules on the ground with a force that is 300 times its own weight, and propell themselves up to 10cm in height <ref> Patek, S. N. and Baio, J. E. and Fisher, B. L. and Suarez, A. V. (2006) [http://www.pnas.org/cgi/content/abstract/103/34/12787 Multifunctionality and mechanical origins: Ballistic jaw propulsion in trap-jaw ants], Proceedings of the National Academy of Sciences, vol 103, page 12787 </ref>. ==References== {{reflist}} lju6wle6d2yl173exytt8gyrgjipmrq User talk:Mafutrct 3 162342 4669070 4668021 2026-09-06T06:46:08Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669070 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Mafutrct!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{Text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{Text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;{{!}}&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 22:03, 25 June 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} t8ip1ii7yl0gdmdfvw8upj00m1kf8rr User talk:Kpaul003 3 168378 4669074 4668064 2026-09-06T07:13:46Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669074 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Kpaul003!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{Text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}.</div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{Text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 03:19, 10 September 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} ==Hi== Katelyn, You have some really good points. I agree with you on your teaching philosophy. I also think that students should be active in their own learning. Students should be able to say things that they want to learn about too. Also, who said the teacher was the only one who could activate a learning environment. The students can also encourage learning to their fellow students. Good luck with your future 1st graders. I'm sure you will be a great teacher. You sound very passionate. Krista [[User:Kruss018|Kruss018]] ([[User talk:Kruss018|talk]]) 00:54, 15 September 2008 (UTC) Hi Katelyn, I really enjoyed reading your educational philosophy, and I believe we share a lot of the same ideas. I agree that too much pressure is put on standardized testing. I think teachers are having to rush through content and not have enough time for meaningful discussions with their students. I also feel that technology is very important to use in the classroom, and I definetly believe students need to take typing class at a much younger age. I thought that was a great point! Lastly, I agree that students of all abilities should be in one classroom. It sounds like you have some really great ideas about what you want to incorporate in your curriculum. Kelly Shepherd [[User:Kshep009|Kshep009]] ([[User talk:Kshep009|talk]]) 19:22, 13 September 2008 (UTC) Hey Katelyn! Thanks for commenting on my page! I also enjoyed reading your philosophy, and I agree with what you have written - especially the bit about group work and utilizing technology to the best advantage of the students and teacher. I also agree with your statement about students being exposed to other students with disabilities. When I was in middle school, I was taken to St. Mary's in downtown Norfolk (School for the handicapped) and it definitely had a positive impact on my life. Everyone, not just students, could benefit from stepping outside their world and seeing how people different from them live and persevere. Best wishes! [[User:Dbrod001|Dbrod001]] ([[User talk:Dbrod001|talk]]) 22:06, 13 September 2008 (UTC) [[User:Vlane02|Vlane02]] ([[User talk:Vlane02|talk]]) 00:11, 14 September 2008 (UTC) Katelyn, I agree with your idea about Teacher philosophies, but Standars of Learning testing is essential for the govermment, school boards, and the parents to find about how the students are doing in school, the knowledge they absorbed, and for the govermment to see the students standars. It is a great way to see how our education in the United States is doing. Students from others countries already come to compete in spelling Bees with the American students. Education is the foundation in any society and country; when we educate our children, we are educating the leaders of tomorrow. Hello Katelyn: Like many other teaching philosophies I have read there really appears to be an interest in helping to provide well rounded education to students. You brought up both technlogy and exposure to sports and the arts. I know that in my own adolesence the opportunity to play sports and to join a band were key steps in my youth. Many a happy moment were spent on the soccer field and in band concerts. I think your interest in very young children like first graders will be an excellent opportunity to teach children to accept challenges and to great opportunites for just that, opportunities. As you say, it is also important for children to be exposed to other's, especially their own age, who have conditions different then their own. Learning to cope with and overcome deficits such as physical, speech, mental or even emotional problems is something we all must face sometime in our lives. As a teacher, you will be in a position to demonstrate a true spirit of acceptance. One more thing. I really admire your spirit of nationalism. The rights our forefathers (and mothers) fought for and framed in the constitution are often taken for granted and insisting on saying the pledge of allegiance each day puts the focus or our civil responsibilities. By the way, I vote for a moment of prayer as well! God is our sovereign Lord and we would not even be alive save His providence. God bless you and these United States! [[User:Efari002|Ed Farinholt (efari002)]] ([[User talk:Efari002|talk]]) 13:55, 28 October 2008 (UTC) p6mstm714hyeqfo0opgusflijgos2x5 User talk:Hgibb005 3 168768 4669073 4668232 2026-09-06T07:13:09Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669073 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Hgibb005!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{Text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}.</div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{Text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 03:26, 10 September 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} ==Teaching philosophy== I enjoyed seeing your comment about spending time with students and finding out more about them. That would definitely go far with a student and help us when we are giving them positive feedback to reinforce and keep them on track toward our teaching goals. Finding time in a limited classroom period to effectively individualize education with each student is going to be a challenge for us. We often have so many students and so little time with them for individual communication in today's school environment. [[User:Phura001|Phura001]] ([[User talk:Phura001|talk]]) 18:29, 9 September 2008 (UTC) The concept of being able to have a one on one time with each student would be idle. [[User:Tfrat001|Tfrat001]] ([[User talk:Tfrat001|talk]]) 01:36, 12 September 2008 (UTC) First I want to say Congratulations on the new marriage! And I am very glad to hear you mother is better now! That is very impressive that you took a few years off of school to take care of her. I agree with your teaching philosophy. It is very important to have an environment where the student feels comfortable. I remember when I had a class where the teacher wasn't very welcoming, I never felt like going to that class and it made me not want to learn the subject. If a student doesn't feel comfortable in a class, they won't ask questions and that means they will most likely get lost or not learn the material. And even though it is very difficult for teachers to get to know each student on an individual basis, I agree that it is very important to have a positive relationship with all students. [[User:Cbrow103|Cbrow103]] ([[User talk:Cbrow103|talk]]) 18:19, 13 September 2008 (UTC) tpoiqtqvhlm4yc0zmxr9f1jmtuoksg5 User talk:Lpaul006 3 168811 4669075 4668034 2026-09-06T07:14:24Z ShakespeareFan00 46022 A 4669075 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Lpaul006!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{Text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{Text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 02:48, 10 September 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} kmsuz6quh9nfs8bbtm2s1tciihs36y0 User talk:Bzeig001 3 168823 4669068 4668462 2026-09-06T06:44:50Z ShakespeareFan00 46022 4669068 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Bzeig001!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{Text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}.</div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{Text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 02:55, 10 September 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} Well Bethany, welcome to the area. Hope your enjoying your move so far. And i see that you work for the YMCA; thats pretty cool, i did some comunity service at the mount trashmore location a little while back. I like your personal philosophy, "prepare for the worst and hope for the best", i'd say its a pretty good motto to have. You never know what this worlds going to throw atcha, best to be prepared! I also think you have a pretty good Educational Philosophy as well. Teaching is one of those things that deffinetly can influence the world. Hopefully you use your influence to arouse positive change and growth in your students! Good luck to you!! Gage[[Special:Contributions/70.161.55.43|70.161.55.43]] ([[User talk:70.161.55.43|talk]]) 15:22, 13 September 2008 (UTC)[[User:Gkapp001|Gkapp001]] ([[User talk:Gkapp001|talk]]) 15:27, 13 September 2008 (UTC) Hello Bethany. I was interested in your comment on how you prepare for the worst and hope for the best. I remember I used to think that way but have since revised my point of view. Now I hope for the best and realized that when life gives you lemons you simply make lemonade. Life has a lot to offer and I am sure depending on what type of YMCA you work for you see a wide variety of children and families. As teachers we will have many roles to play, Good luck on your journey and do not forget to stop and smell the roses sometime. [[User:Vguti001|Vguti001]] ([[User talk:Vguti001|talk]]) 22:43, 14 September 2008 (UTC) Hey Bethany. I have heard of Ben Lee, but can't say I'm a fan. Some of my favorite movies are A River Runs Through it, Garden State, Elizabethtown, and Into the Wild; movies that inspire. I love authentic mexican food, but I love taco bell as well. Your philosophy sounds like you'll make a good teacher someday. [[User:Pleex010|Pleex010]] ([[User talk:Pleex010|talk]]) 01:07, 15 September 2008 (UTC) == Copyright problems with [[:Image:Sidebar 2.jpg|Image:Sidebar 2.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Sidebar 2.jpg|Image:Sidebar 2.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Sidebar 2.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 03:08, 9 October 2008 (UTC)}} == Copyright problems with [[:Image:Me And Ma.jpg|Image:Me And Ma.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Me And Ma.jpg|Image:Me And Ma.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Me And Ma.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 03:21, 9 October 2008 (UTC)}} hp8tqeapnqjjpvcwxf01s0vlv8ilp98 User talk:Cwill122 3 168824 4669067 4668661 2026-09-06T06:44:25Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669067 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Cwill122!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 02:55, 10 September 2008 (UTC)</div> |- |style="text-align=right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} Hello, you posted your wiki article on a page for which you did not correctly sign up. This page is already taken, so I have removed your content. Please contact me so that we can work out a solution. [[User:PbakerODU|Pete]] ([[User talk:PbakerODU|talk]]) 14:24, 25 September 2008 (UTC) ltw382g8y8azzybvxkb4nnykb909wor User talk:Abake023 3 168846 4669072 4668254 2026-09-06T07:12:41Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669072 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Abake023!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{Text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}.</div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{Text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 03:06, 10 September 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} Hello Amy! I just wanted to say hi since I am the OTHER Amy Baker in the class...ABake028! Who knew I had a name double!! [[User:Abake028|Abake028]] ([[User talk:Abake028|talk]]) 14:45, 12 September 2008 (UTC) kican00kb2y5rpva4tvnquxly8e47le User talk:Bookaneer 3 168879 4669069 4668461 2026-09-06T06:45:14Z ShakespeareFan00 46022 4669069 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Bookaneer!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{Text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}.</div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{Text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{Text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 03:30, 10 September 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} nivq82hxyliw20kflgzwhunywwd2j8l User talk:Kolah001 3 168880 4669082 4667949 2026-09-06T07:20:06Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669082 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Kolah001!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything & it is really easy. Come say [[WB:HELP|hello]] to everyone! </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * You can always get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * If something you wrote was tagged with {{tlx|query}}, and you think this was done in error, just remove it & explain why on the talk page. * If your upload was tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] & source are always required; fair use images require a {{tlx|fair use rationale}}. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 03:32, 10 September 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} bw3n3x56skvh48f50efcqxjezpzswgp User:PoizonMyst/Australian Esoterica 2 169132 4668920 4409489 2026-09-05T12:12:27Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668920 wikitext text/x-wiki '''<small>[[Australian Esoterica]] • [[Talk:Australian_Esoterica|Discussion]] • [[Australian Esoterica/MOS|Manual of Style]] • [[User:PoizonMyst/Australian Esoterica Research|Resource Sandbox]]</small>'''<br /> This is my personal sandbox for the ''Australian Esoterica'' wikibook. ==Table of Contents== *[[Australian Esoterica|Introduction]] *[[Australian Esoterica/TOC|Table of Contents]] *[[Australian Esoterica/What is Neopaganism?|What is Neopaganism?]] *[[Australian Esoterica/World Nature Traditions|Nature Traditions of the World]] *[[Australian Esoterica/Neopaganism in Australia|Neopaganism in Australia]] *[[Australian Esoterica/Observances and Symmetries|Observances and Symmetries]] **[[Australian Esoterica/Seasonal Festivals|Seasonal Festivals]] **[[Australian Esoterica/Lunar Observances|Lunar Observances]] **[[Australian Esoterica/Elements|Elements]] **[[Australian Esoterica/Correspondence Tables|Correspondence Tables]] *[[Australian Esoterica/Botánica|Botánica]] **[[Australian Esoterica/Australian Herbs|Herbs]] **[[Australian Esoterica/Australian Essential Oils|Essential Oils]] **[[Australian Esoterica/Australian Carrier Oils|Carrier Oils]] *[[Australian Esoterica/Divination|Divination]] **[[Australian Esoterica/Astrology|Astrology]] **[[Australian Esoterica/Numerology|Numerology]] *[[Australian Esoterica/Glossary|Glossary of Terms]] *[[Australian Esoterica/Bibliography|Bibliography and Further Resources]] *[[Australian Esoterica/Authors|Contributing Authors]] *[[Australian Esoterica/MOS|Australian Esoterica Manual of Style]] *[[Australian Esoterica/Print Version|Print Version]] <small>''([[Australian Esoterica/Print Version|edit it]])''</small> ===Aboriginal Australian Culture=== These should be demonstrated by incorporation throughout the book chappters/pages. *[[Australian Esoterica/Aboriginal Australian Culture|Aboriginal Australian Culture]] **[[Australian Esoterica/Aboriginal Australian Mythology and Symbology|Mythology and Symbology]] **[[Australian Esoterica/Aboriginal Australian Spirit Guides|Spirit Guides]] **[[Australian Esoterica/Aboriginal Australian Ceremonies|Ceremonies]] **[[Australian Esoterica/Bush Tucker|Bush Tucker]] **[[Australian Esoterica/Bush Medicine|Bush Medicine]] **[[Australian Esoterica/Bush Craft|Bush Craft]] ===Equipment and Arts need to be changed around and sections better clarified=== *[[Australian Esoterica/Sacred Space|Sacred Space]] *[[Australian Esoterica/Equipment|Equipment]] **[[Australian Esoterica/Mystical Books|Mystical Books]] **[[Australian Esoterica/Lapidary|Lapidary]] **[[Australian Esoterica/Australian Symbology|Symbology]] <br>{{toplink}} ==Introduction== :<small>''Main article: [[Australian Esoterica|Introduction]]''</small> {{drop|F}}or Australian followers of Neopagan philosophies and customs, the traditional seasonal festivals, rituals, and practises taught by the European based disciplines, make it difficult for Australian witches to correctly synchronise with mother nature in the Southern Hemisphere. The '''Australian Esoterica''' aims to realign the traditional Northern Hemisphere Neopagan seasonal customs in accordance with Southern Hemisphere seasonal changes, while at the same time offering a comprehensive guide to Neopagan philosophies for Australian followers of the faith. Nevertheless, this book is not just a rehash of European spiritual practises turned upside down, but also aspires to become an internet [[Australian Esoterica/Mystical Books|Book of Shadows]] for all [[Australian Esoterica/Neopaganism in Australia|Australian Neopagans]] by describing culturally relevant mythologies, philosophies, and practises. <br>{{toplink}} ==What is Neopaganism?== :<small>''Main article: [[Australian Esoterica/What is Neopaganism?|What is Neopaganism?]]''</small> {{drop|A}}derivative of ''neo-'' (from the Ancient Greek prefix ''νεο-'', meaning "new") and ''pagan'' (from the Latin ''pāgānus'', meaning "country dweller, rustic"), '''Neopaganism''' is a broad term used to describe several modern spiritual movements that are influenced by ancient philosophies and cultures, in particular traditional nature-based customs and polytheistic or pantheistic beliefs of pre-Christian Europe. Neopaganism is distinguished as the modern revival or reconstruction of classical Paganism, although both terms are often used interchangeably. While early Christian missionaries first focused their efforts on establishing the Christian Church in major urban centres of the Roman Empire, people of the outlying rural regions continued to revere the cycles of nature and their associated spiritual deities. As such, "country dweller", or "pagan", soon pertained to someone who was simply "not a Christian." Ultimately, Christian political propaganda presented "paganism" as a derogatory expression pertaining to sinful hedonistic practises (from the Ancient Greek ''hēdonē'', meaning "pleasure"). Similarly, the Old Norse and Germanic Pagans, known as ''heathens'' (Old English translation of the Old High German ''heide'', meaning "heath, heathland"), became yet another term eventually distorted to be regarded as unfavourable. Today Neopagans worldwide are proudly reclaiming the original definitions of "Pagan" and "Heathen" to identify their nature-based spiritual practises and beliefs. *References for this page are located in the [[Australian_Esoterica/Bibliography#What_is_Neopaganism?|''Bibliography and Further Resources'']]. <br>{{toplink}} ==Nature Traditions of the World== :<small>''Main article: [[Australian Esoterica/World Nature Traditions|Nature Traditions of the World]]''</small> *References for this page are located in the [[Australian_Esoterica/Bibliography#Nature_Traditions_of_the_World|''Bibliography and Further Resources'']]. <br>{{toplink}} ==Neopaganism in Australia== :<small>''Main article: [[Australian Esoterica/Neopaganism in Australia|Neopaganism in Australia]]''</small> {{drop|S}}o how can a philosophical belief system originating in the Northern Hemisphere be relevant to a multicultural nation situated south of the equator? In answering this, the Australian Esoterica is not prepared to classify a cultural identity for Australian followers of Neopagan philosophies however there are a number of factors that southern followers of the craft may wish to contemplate. Modern Neopagan spiritual movements of the Northern Hemisphere describe themselves as influenced by ancient nature-based cultures and their philosophies. Seasonal festivals throughout the year commemorate these occasions. Certainly the dates of such observances can be adjusted in accordance with the southern seasons, yet Australian Neopagans may find it difficult to culturally relate to the relevant historical stories. But does that really matter? We are all of the same biological genus and reside on the same home planet. Ultimately, such narratives belong to all of us - they are the chronicles of human spirituality. Neopaganism is as much about what feels right for the individual as it is about traditional folklore and customs. With all this is mind Australian Neopagans might consider: *The traditional cultural practises and myths of Aboriginal Australians. *Other traditional cultures of the Southern Hemisphere such as the [[w:en:Austronesian peoples|Austronesian peoples]] of Oceania and Southeast Asia. *The [[w:en:Anglo-Celtic Australian|Anglo-Celtic]] colonial history of Australia. *The traditional nature-based practises of [[w:en:Eastern religion|Asiatic]] and [[w:en:Abrahamic religions|Abrahamic]] philosophies and customs who have prominent populations within Australia (such as ''[[w:en:Feng Shui|Feng Shui]]'' of China, the Islamic ''[[Koranic Law of Nature]]'', or ''[[Ayurveda]]'' of India). *Personal ancestry/geneology. *The natural landscape and local history of an Australian region with which they closely identify (such as their place of birth or residence). *The legality of Neopagan practises in Australia. *Their personal views on the cultural identity that is an [[w:en:Australian|Australian]] [[w:en:Neopagan|Neopagan]]. *References for this page are located in the [[Australian_Esoterica/Bibliography#Neopaganism_in_Australia|''Bibliography and Further Resources'']]. <br>{{toplink}} ==Seasonal Festivals== :<small>''Main article: [[Australian Esoterica/Seasonal Festivals|Seasonal Festivals]]''</small> {{drop|A}}s seasons in the Southern Hemisphere are reversed to those of the North, so too is the Neopagan festival calendar known as the Wheel of the Year. In Australia and New Zealand the long familiar "Christmas in July", though not an official holiday, is a popular celebration and compelling evidence of efforts to suitably inverse the Pagan festival of "Yule" for the Southern regions. ===Sabbat Festivals=== Neopagans and Wiccans observe eight festivals each year, known as '''Sabbats''', which commemorate the annual cycle of seasons or phases of the sun and moon. This cycle is referred to as the ''Wheel of the Year'', with festivities spaced at approximately even intervals throughout the calendar. Traditionally the festivals mark the solstices and equinoxes, and the times for planting and harvest of crops. The Wheel of the Year is a modern development of Wicca and Neopaganism originating from traditional holidays observed by Pagan cultures of ancient Europe. No pre-Christian European cultures celebrated all eight Sabbats of the calendar, so the Wheel of the Year comprises a modern merging of traditional festivals from all over ancient Europe, with similarities to the ancient rituals often ending at their shared names alone. Modern interpretations of ancient practices vary widely, as such different groups may conceptualize and celebrate the Sabbats in very different ways, but the themes and meanings are generally similar. For some, the Wheel of the Year not only describes the continuous cycles of nature and time, but also the human progression through birth, life, decline and death. For many Wiccans, it represents the cycle of life, death, and rebirth of the Horned God and fertility of the Goddess. Inspired by Gaelic fire festivals, the ''Cross-Quater Days'' (or ''Greater Sabbats'') mark the beginning of each [[w:en:Season#Traditional_season_divisions|traditional season]] (as opposed to [[w:en:Season#Astronomical|astronomical seasons]]) and fall approximately half-way between a solstice and an equinox. Generally, and mostly for convenience, the Greater Sabbats are celebrated on the first day of the season. In British and Irish traditions of the Middle Ages, ''Quarter Days'' (or ''Lesser Sabbats'') fell close to the two solstice and two equinox holidays. These were dates on which servants were hired, rents or rates were due, and magistrates would determine debts and resolve conflicts in outlying rural regions. In England today, leasehold payments and rents for business premises are often still due on the old English Quarter Days. The timing of these Lesser Sabbats are determined by the relationship of the Sun to the Earth so their dates deviate slightly each year. The Celtics recognised that a new day began in the darkness, so too the start of a new year. Thus Samhain, the Celtic Feast of the Dead and beginning of Winter, is generally recognised as the first Sabbat of the year. ===Southern Hemisphere Wheel of the Year=== Below, are the eight festivals and their dates, conveniently inversed for Southern Hemisphere practitioners of the craft. <br> {| style="width:100%" class="wikitable" |- ! style="width:20%; font-weight:bold; text-align:center;"|Season ! style="width:40%; font-weight:bold; text-align:center;"|Greater Sabbat ! style="width:40%; font-weight:bold; text-align:center;"|Lesser Sabbat |- | style="text-align:center; background-color:#F8F8FF;color:white;"|<big>Winter</big> Start: 1st June<br /> (SH Astronomical) | style="vertical-align:top; background-color:#F8F8FF;color:white;"|'''Samhain''' *'''1st May''' (alt. 4-10 May) *First day of ancient Winter. *Greater Sabbat. Lunar Festival. *A Cross Quarter celebration. *''Also known as Halloween.'' *Northern Hemisphere: 31 Oct/1 Nov | style="vertical-align:top; background-color:#F8F8FF;color:white;"|'''Yule''' *'''21st or 22nd June''' *June Solstice - Winter solstice. Shortest day of the year. *Lesser Sabbat. Solar Festival. *A Quarter Day celebration. *''Also known as Yuletide.'' *Northern Hemisphere: 21/22 Dec |- | style=" text-align:center; background-color:#E7FEFF;color:white;"|<big>Spring</big> 1st September<br /> (SH Astronomical) | style="vertical-align:top; background-color:#E7FEFF;color:white;"|'''Imbolc''' *'''1st August''' (alt. 3-10 August) *First day of ancient Spring. *Greater Sabbat. Lunar Festival. *A Cross Quarter celebration. *''Also known as Imbolg or Candlemas.'' *Northern Hemisphere: 1 Feb | style="vertical-align:top; background-color:#E7FEFF;color:white;"|'''Ostara''' *'''22nd or 23rd September''' *September Equinox - Spring (Vernal) Equinox. Equal day and night. *Lesser Sabbat. Solar Festival. *A Quarter Day celebration. *''Also known as Easter.'' *Northern Hemisphere: 21/22 Mar |- | style="text-align:center;background-color:#FFFFED;color:white;"|<big>Summer</big> 1st December<br /> (SH Astronomical) | style="vertical-align:top; background-color:#FFFFED;color:white;"|'''Beltane''' *'''1st November''' (alt. 5-10 Nov) *First day of ancient Summer. *Greater Sabbat. Lunar Festival. *A Cross Quarter celebration. *''Also known as Beltaine or May Day.'' *Northern Hemisphere: 1 May | style="vertical-align:top; background-color:#FFFFED;color:white;"|'''Litha''' *'''21st or 22nd December''' *December Solstice - Summer solstice. Longest day of the year. *Lesser Sabbat. Solar Festival. *A Quarter Day celebration. *''Also known as Midsummer.'' *Northern Hemisphere: 21/22 June |- | style=" text-align:center;background-color:#FAF0BE;color:white;"|<big>Autumn</big> 1st March<br /> (SH Astronomical) | style="vertical-align:top; background-color:#FAF0BE;color:white;"|'''Lughnasadh''' *'''1st February''' (alt. 2-7 Feb) *First day of ancient Autumn. *Greater Sabbat. Lunar Festival. *A Cross Quarter celebration. *''Also known as Lammas.'' *Northern Hemisphere: 1 Aug | style="vertical-align:top; background-color:#FAF0BE;color:white;"|'''Mabon''' *'''21st or 22nd March''' *March Equinox - Autumn Equinox. Equal day and night. *Lesser Sabbat. Solar Festival. *A Quarter Day celebration. *''Also known as the Autumnal Equinox.'' *Northern Hemisphere: 22/23 Sep |} ===Weather Observances of Australian Aboriginals=== Resource: http://en.wikipedia.org/wiki/Indigenous_Australian_seasons # {|style="border:1px solid gray;" | style="width:100% "|And more ... ''copied from:'' http://en.wikipedia.org/wiki/Season#Australia In Australia, the traditional Aboriginal people defined the seasons by what was happening to the plants, animals and weather around them. This led to each separate tribal group having different seasons, some with up to eight seasons each year. However, most modern Aboriginal Australians follow either four or six meteorological seasons, as do non-Aboriginal Australians. The commonly followed dates are as follows: 1st day of March, June, September and December for the start of Autumn, Winter, Spring and Summer, respectively. |} # ===Seasonal Observances around the world=== Interestingly, the Sabbats fall closely to, or on the same dates, as eight points of the [[w:en:Solar_term|24 Solar Terms]] in traditional lunisolar calendars that were developed independently in East Asia. *References for this page are located in the [[Australian_Esoterica/Bibliography#Seasonal_Festivals|''Bibliography and Further Resources'']]. <br>{{toplink}} ==Lunar Observances== :<small>''Main article: [[Australian Esoterica/Lunar Observances|Lunar Observances]]''</small> *References for this page are located in the [[Australian_Esoterica/Bibliography#Lunar_Observances|''Bibliography and Further Resources'']]. <br>{{toplink}} ==Glossary of Terms== :<small>''Main article: [[Australian Esoterica/Glossary|Glossary of Terms]]''</small> '''Neopaganism:''' Describes several modern spiritual movements that are influenced by ancient philosophies and cultures, in particular traditional nature-based customs and polytheistic or pantheistic beliefs of pre-Christian Europe. Neopaganism is distinguished as the modern revival or reconstruction of classical Paganism. '''Paganism:''' The traditional nature-based philosophies and polytheistic or pantheistic religions of classical pre-Christian Europe. '''Pantheisim:''' The belief that God and the universe are one and the same. '''Polytheistic:''' A belief in the existence of more than one god. <br>{{toplink}} ==Bibliography and Further Resources== :<small>''Main article: [[Australian Esoterica/Bibliography|Bibliography and Further Resources]]''</small> ===What is Neopaganism?=== * [[wikt:neo-|Wiktionary: Neo-]] * [[wikt:paganus|Wiktionary: Paganus]] * [http://www.websters-online-dictionary.org/definition/pagan Webster's Online Dictionary: Pagan] * [http://www.neopagan.net/PaganDefs.html neopagan.net: Defining Paganism] * [[w:en:Neopaganism|Wikipedia: Neopaganism]] * [[w:en:Paganism|Wikipedia: Paganism]] * [[wikt:hedonism|Wiktionary: Hedonism]] * [[wikt:Heide|Wiktionary: Heide]] * [[wikt:polytheism|Wiktionary: Polytheism]] ===Neopaganism in Australia=== * [http://www.abc.net.au/religion/stories/s796571.htm Paganism - Australian Broadcasting Corporation Religion and Ethics Library] * [http://resources.education.tas.gov.au/item/edres/87e0c394-5ef6-7cc8-376d-4d8d294f5cf3/1/ReligionAustralia.zip/index_religionsaus.htm Religious Identity of Australia - 2001 Census Results] ''(Tasmanian Government Educational Resource)'' * [http://www.paganawareness.net.au/laws.html Australian Witchcraft Laws - Pagan Awareness Network] * [http://www.abc.net.au/queensland/stories/s1097056.htm Ritual, magic and witchcraft in old Queensland houses] * [http://www.geocities.com/athens/2962/media/sunmail4_5_97.html Australian Media on Paganism] * [http://www.austlii.edu.au/au/legis/sa/consol_act/soa1953189/s40.html Summary Offences Act Section 40 - Austlii SA] * ''"Lost Worlds: The Rise of Man"'' documentary broadcast March 2009 on [[w:en:Special_Broadcasting_Service|SBS]] * [[w:en:Aboriginal_stone_arrangement|Wikipedia: Aboriginal stone arrangement]] ===Observances and Symmetries=== ====Seasonal Festivals==== * [[w:en:Archaeoastronomy|Wikipedia: Archaeoastronomy]] * [[w:en:Wheel of the Year|Wikipedia: Wheel of the Year]] * [[w:en:Sabbath|Wikipedia: Sabbath]] * [[w:en:Cross-quarter_day|Wikipedia: Cross-quarter day]] * [[w:en:Quarter_days|Wikipedia: Quarter days]] * [[w:en:Solar_term|Wikipedia: Solar Term]] * [[w:en:Season|Wikipedia: Season]] * [[w:en:Lunisolar_calendar|Wikipedia: Lunisolar Calendar]] * [http://paganwiccan.about.com/od/holidaysandcelebrations/u/Celebrations.htm Sabbats and Other Rituals - about.com] * [http://atheism.about.com/library/FAQs/religion/blrel_hol_equinox.htm Equinoxes, Solstices, and Calendars - about.com] * [http://www.unitedpaganchurch.org.au/sabbats.php Sabbats - United Pagan Church of Australia] * [http://www.shadowsofoz.net/calendar/wheel_of_the_year.html Southern Hemisphere Wheel of the Year - Shadows of Oz] * [http://www.magickaschool.com/forum/viewtopic.php?t=5018 The Wheel of the Year - Southern Hemisphere - Magic School Forum] <br>{{toplink}} <br>{{Userpage}} eu6kdw5gnnjiac271b3v70kk3lskuhg User:PoizonMyst/Template:MystBox 2 169531 4668999 1278776 2026-09-05T19:14:56Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668999 wikitext text/x-wiki <table style="background: {{{background|#DFE8FF}}}; color: {{{color|#000000}}}; border: {{{border|1px solid #1e90ff}}}; text-align: center; width:{{{width|80%}}}; margin:{{{margin|4px 10%}}};" align="{{{align|center}}}"><tr><td width="{{{imagewidth|50px}}};"> {{{1}}} </td><td>{{{2}}}</td></tr></table> <noinclude>[[User:PoizonMyst/Templates]]</noinclude> {|border="0" style="width:80%; text-align:center; background-color: #DFE8FF;{{text default color}}; border:1px solid #1e90ff;" |- |style="width:30%"|'''«''' |style="text-align:center" rowspan="2"|<big>'''''Australian Esoterica'''''</big><br>''{{{CurrentPage}}}'' |style="width:30%; text-align:right" | '''»''' |- |{{{PrevPage}}}<br><small>< [[/TOC|Table of Contents]]</small> |style="text-align:right" | {{{NextPage}}}<br><small>[[/Glossary|Glossary]] ></small> |- |} j4ycrqh6el4ifjyd5ixdlhgcz97r3b7 User talk:15lanea~enwikibooks 3 173443 4669076 4667958 2026-09-06T07:15:32Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669076 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, 15lanea!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[WB:HELP|introduce yourself]] to everyone, and let us know what interests you. </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * We tag pages with various [[WB:TM|message templates]], such as {{tlx|query}}, to let editors know what needs to be improved. To learn more about these, ask at [[WB:PROJECTS|the projects reading room]]. * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 01:49, 15 October 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} == Your account will be renamed == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> Hello, The developer team at Wikimedia is making some changes to how accounts work, as part of our on-going efforts to provide new and better tools for our users like cross-wiki notifications. These changes will mean you have the same account name everywhere. This will let us give you new features that will help you edit and discuss better, and allow more flexible user permissions for tools. One of the side-effects of this is that user accounts will now have to be unique across all 900 Wikimedia wikis. See [[m:Special:MyLanguage/Single User Login finalisation announcement|the announcement]] for more information. Unfortunately, your account clashes with another account also called 15lanea. To make sure that both of you can use all Wikimedia projects in future, we have reserved the name 15lanea~enwikibooks that only you will have. If you like it, you don't have to do anything. If you do not like it, you can [[Special:GlobalRenameRequest|pick out a different name]]. Your account will still work as before, and you will be credited for all your edits made so far, but you will have to use the new account name when you log in. Sorry for the inconvenience. Yours,<br />[[m:User:Keegan (WMF)|Keegan Peterzell]]<br />Community Liaison, Wikimedia Foundation </div> 22:54, 17 March 2015 (UTC) <!-- SUL finalisation notification --> == Renamed == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> This account has been renamed as part of [[m:Special:MyLanguage/Single User Login finalisation announcement|single-user login finalisation]]. If you own this account you can [[{{#special:userlogin}}|log in using your previous username and password]] for more information. If you do not like this account's new name, you can choose your own using this form after logging in: [[{{#special:GlobalRenameRequest}}]]. -- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) </div> 04:27, 19 April 2015 (UTC) <!-- SUL post-rename notification --> irnhelddvpu6f5184xfxj78ke7xhzkk 4669077 4669076 2026-09-06T07:15:56Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669077 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, 15lanea!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[WB:HELP|introduce yourself]] to everyone, and let us know what interests you. </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * We tag pages with various [[WB:TM|message templates]], such as {{tlx|query}}, to let editors know what needs to be improved. To learn more about these, ask at [[WB:PROJECTS|the projects reading room]]. * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 01:49, 15 October 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} == Your account will be renamed == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> Hello, The developer team at Wikimedia is making some changes to how accounts work, as part of our on-going efforts to provide new and better tools for our users like cross-wiki notifications. These changes will mean you have the same account name everywhere. This will let us give you new features that will help you edit and discuss better, and allow more flexible user permissions for tools. One of the side-effects of this is that user accounts will now have to be unique across all 900 Wikimedia wikis. See [[m:Special:MyLanguage/Single User Login finalisation announcement|the announcement]] for more information. Unfortunately, your account clashes with another account also called 15lanea. To make sure that both of you can use all Wikimedia projects in future, we have reserved the name 15lanea~enwikibooks that only you will have. If you like it, you don't have to do anything. If you do not like it, you can [[Special:GlobalRenameRequest|pick out a different name]]. Your account will still work as before, and you will be credited for all your edits made so far, but you will have to use the new account name when you log in. Sorry for the inconvenience. Yours,<br />[[m:User:Keegan (WMF)|Keegan Peterzell]]<br />Community Liaison, Wikimedia Foundation </div> 22:54, 17 March 2015 (UTC) <!-- SUL finalisation notification --> == Renamed == <div class="plainlinks mw-content-ltr" lang="en" dir="ltr"> This account has been renamed as part of [[m:Special:MyLanguage/Single User Login finalisation announcement|single-user login finalisation]]. If you own this account you can [[{{#special:userlogin}}|log in using your previous username and password]] for more information. If you do not like this account's new name, you can choose your own using this form after logging in: [[{{#special:GlobalRenameRequest}}]]. -- [[m:User:Keegan (WMF)|Keegan (WMF)]] ([[m:User talk:Keegan (WMF)|talk]]) </div> 04:27, 19 April 2015 (UTC) <!-- SUL post-rename notification --> a5xo0hvghvfffc5xmr94jgq6xwmt81u User talk:Poseurtech 3 175127 4669083 4667819 2026-09-06T07:21:18Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669083 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Poseurtech!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[WB:HELP|introduce yourself]] to everyone, and let us know what interests you. </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * We tag pages with various [[WB:TM|message templates]], such as {{tlx|query}}, to let editors know what needs to be improved. To learn more about these, ask at [[WB:PROJECTS|the projects reading room]]. * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 04:00, 7 November 2008 (UTC)</div> |- |style="text=align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} :Please note that Wikibooks is not for promotion, and neither are our other wikis. You're welcome to contribute constructively, however linking in the manner you have done cross-wiki is unwelcome. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 04:00, 7 November 2008 (UTC) 7bpfk4xe5toyzpfjjcmclfqzit5yo5c User talk:Kk.gnogi 3 175250 4669079 4667952 2026-09-06T07:17:57Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669079 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Kk.gnogi!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[WB:HELP|introduce yourself]] to everyone, and let us know what interests you. </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * We tag pages with various [[WB:TM|message templates]], such as {{tlx|query}}, to let editors know what needs to be improved. To learn more about these, ask at [[WB:PROJECTS|the projects reading room]]. * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 23:00, 8 November 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} ==[[:Orca manual]]== {{mbox|type=notice|msg= [[:Orca manual|This page]] appears to have been created in error (due to a test, or some kind of [[Help:Editing|misplaced edit]]). It might be a [[Help:Stub|stub]], if so, please use [[Talk:Orca manual|the discussion page]] as to explain what this page is about. If it evolves into a [[WB:WIW|legitimate Wikibooks module]], you may remove the tag. If not fixed, explained, or improved, it will automatically be considered a candidate for [[Wikibooks:Deletion policy#Speedy deletions|speedy deletion]] in 7 days. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 22:59, 8 November 2008 (UTC) }} lgo2kqf9sviq7b1hy46ofiryegc8yoo 4669080 4669079 2026-09-06T07:18:09Z ShakespeareFan00 46022 /* Orca manual */ 4669080 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Kk.gnogi!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[WB:HELP|introduce yourself]] to everyone, and let us know what interests you. </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * We tag pages with various [[WB:TM|message templates]], such as {{tlx|query}}, to let editors know what needs to be improved. To learn more about these, ask at [[WB:PROJECTS|the projects reading room]]. * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 23:00, 8 November 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} ==[[:Orca manual]]== {{mbox|type=notice|text= [[:Orca manual|This page]] appears to have been created in error (due to a test, or some kind of [[Help:Editing|misplaced edit]]). It might be a [[Help:Stub|stub]], if so, please use [[Talk:Orca manual|the discussion page]] as to explain what this page is about. If it evolves into a [[WB:WIW|legitimate Wikibooks module]], you may remove the tag. If not fixed, explained, or improved, it will automatically be considered a candidate for [[Wikibooks:Deletion policy#Speedy deletions|speedy deletion]] in 7 days. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 22:59, 8 November 2008 (UTC) }} 62vg6amrocuvow55gf4u46ecmbccnck User:Retropunk/Japanese Curriculum/Outline 2 176097 4668926 1354364 2026-09-05T12:30:35Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668926 wikitext text/x-wiki __NOTOC__ <table style="width: 100%;"> <tr> <td style="border: 3px solid #BB3E0C; background-color: #FAF4E6;{{Text default color}}; margin: .2em; padding: .5em" colspan="2"> {{wikiversity|Japanese}} * [[/Introduction/About|Introduction]] &mdash; About this wikibook * [[/Introduction/|The Japanese language]] * [[/Study methods/]] * [[/Using_This_Book | How to use this book ]] == Lesson plans == * [[/Beginner Lessons/]] * [[/Lower Intermediate Lessons/]] * [[/Upper Intermediate Lessons/]] * [[/Advanced Lessons/]] * [[/Near Native Lessons/]] * [[User:Retropunk/Japanese Curriculum]]</td> </tr> <tr> <td style="border: 1px solid #8B2500; background-color: #FAF4E6;{{Text default color}}; margin: .2em; padding: .5em; width: 50%; vertical-align: top"> == Reading and writing == [[Image:KanjiPractice.jpg|right|180px]] * [[/Kana Chart/]] * [[/Japanese writing system|Japanese scripts]] ** [[/Kana/]] ** [[/Kanji/]] * [[/Reader|Reading practice]] * [[/Writing Styles/ | Writing Styles]] </td> <td style="border: 1px solid #8B2500; background-color: #FAF4E6;{{Text default color}}; margin: .2em; padding: .5em; width: 50%; vertical-align: top"> == Linguistics == [[Image:Ja_da_ya.png|right|160px]] * [[/Pronunciation/]] * [[/Pitch accent/]] * [[/Dialects/]] * [[/Other Linguistics/ | Slang and other variations]] </td> </tr> <tr> <td style="border: 1px solid #8B2500; background-color: #FAF4E6;{{Text default color}}; margin: .2em; padding: .5em; vertical-align: top"> == Grammar == [[Image:Nihongo Bunpou b.100x400.svg|right]] :''Here will end the grammar points from the [[/Contents/]] once they develop into something solid.'' * [[/Nouns Reference/]] * [[/Adjectival Reference/]] * [[/Verb Reference/]] * [[/Particles/]] * [[/Expressions/]] * [[/Verb conjugation table/]] * http://www.guidetojapanese.org/ </td> <td style="border: 1px solid #8B2500; background-color: #FAF4E6;{{Text default color}}; margin: .2em; padding: .5em; vertical-align: top"> == Vocabulary == [[Image:言-red.png|right|160px]] :''See also the vocabulary [[/Vocabulary/|list]] and [[:Category:Japanese vocabulary|category]] for a more extensive list of available contents.'' * [[/Vocabulary/Academic Subjects/|Academic subjects]] * [[/Vocabulary/Animals/|Animals]] * [[/Vocabulary/Banking/|Banking]] * [[/Vocabulary/Body parts/|Body parts]] * [[/Vocabulary/Colors/|Colours]] * [[/Vocabulary/Computing/|Computing]] * [[/Vocabulary/Clothes and accessories/|Clothes and accessories]] * [[/Vocabulary/Country Names/|Countries and languages]] * [[/Vocabulary/Direction|Directions]] * [[/Vocabulary/Family and people/|Family and people]] * [[/Vocabulary/Food and Drink/|Food and drink]] * [[/Vocabulary/Health/|Health]] * [[/Vocabulary/Numbers/|Numbers]] * [[/Vocabulary/Time/|Time]] and [[/Vocabulary/Dates/|dates]] * [[/Vocabulary/Weather|Weather and seasons]] * The basic 1000 Japanese [[wikt:Appendix:1000_Japanese_basic_words|words]] </td> </tr> <tr> <td style="border: 3px solid #A5A77F; background-color: #FAF4F4;{{Text default color}};margin: .2em; padding: .5em" colspan="2"> == Related Wikibooks == {{Wikipedia|Japanese proverbs}} * [[East Asian Orthography]] * [[Japanese Phrasebook]] * [[JLPT Guide]] * [[Living in Japan]] * [[Cookbook:Cuisine of Japan]] * [[Japanese History]] </td> </tr> </table> 8kjyuj4956qv2xrtgnnv5qy8sd53upy User talk:Kmatusik 3 176191 4669081 4667951 2026-09-06T07:19:09Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669081 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Kmatusik!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[WB:HELP|introduce yourself]] to everyone, and let us know what interests you. </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * We tag pages with various [[WB:TM|message templates]], such as {{tlx|query}}, to let editors know what needs to be improved. To learn more about these, ask at [[WB:PROJECTS|the projects reading room]], or insert <nowiki>{{helpme|your reason here}}</nowiki> * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 21:08, 17 November 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} == Copyright problems with [[:Image:Transition-state analogs.png|Image:Transition-state analogs.png]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Transition-state analogs.png|Image:Transition-state analogs.png]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Transition-state analogs.png|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 13:37, 11 January 2009 (UTC)}} == Copyright problems with [[:Image:Pyrrole 2-carboxylic acid.png|Image:Pyrrole 2-carboxylic acid.png]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Pyrrole 2-carboxylic acid.png|Image:Pyrrole 2-carboxylic acid.png]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Pyrrole 2-carboxylic acid.png|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 13:37, 11 January 2009 (UTC)}} == Copyright problems with [[:Image:N-methylprotoporphyrin.png|Image:N-methylprotoporphyrin.png]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:N-methylprotoporphyrin.png|Image:N-methylprotoporphyrin.png]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:N-methylprotoporphyrin.png|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 13:38, 11 January 2009 (UTC)}} == Copyright problems with [[:Image:Racemization of Proline.png|Image:Racemization of Proline.png]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Racemization of Proline.png|Image:Racemization of Proline.png]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Racemization of Proline.png|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 13:38, 11 January 2009 (UTC)}} 5op9dgjeitjdzm1x70w8eb6oe393o4x User talk:KinkyBootBeast231 3 176192 4669078 4667953 2026-09-06T07:16:57Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669078 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, KinkyBootBeast231!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[WB:HELP|introduce yourself]] to everyone, and let us know what interests you. </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * We tag pages with various [[WB:TM|message templates]], such as {{tlx|query}}, to let editors know what needs to be improved. To learn more about these, ask at [[WB:PROJECTS|the projects reading room]], or insert <nowiki>{{helpme|your reason here}}</nowiki> * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 21:08, 17 November 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} == Copyright problems with [[:Image:Proteinsequencingchart.jpg|Image:Proteinsequencingchart.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Proteinsequencingchart.jpg|Image:Proteinsequencingchart.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Proteinsequencingchart.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 20:04, 26 November 2008 (UTC)}} == Copyright problems with [[:Image:Proteinsequencingexample.jpg|Image:Proteinsequencingexample.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Proteinsequencingexample.jpg|Image:Proteinsequencingexample.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Proteinsequencingexample.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 20:04, 26 November 2008 (UTC)}} == Copyright problems with [[:Image:Proteinsequencing.jpg|Image:Proteinsequencing.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Proteinsequencing.jpg|Image:Proteinsequencing.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Proteinsequencing.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 20:04, 26 November 2008 (UTC)}} == Copyright problems with [[:File:Proteinsequencingexample.jpg|File:Proteinsequencingexample.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:File:Proteinsequencingexample.jpg|File:Proteinsequencingexample.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:File:Proteinsequencingexample.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 04:05, 22 December 2008 (UTC)}} == Copyright problems with [[:Proteinsequencingchart.jpg|Proteinsequencingchart.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Proteinsequencingchart.jpg|Proteinsequencingchart.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Proteinsequencingchart.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. }} [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 20:34, 10 January 2009 (UTC) == Copyright problems with [[:Image:Free energy diagram.jpg|Image:Free energy diagram.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Free energy diagram.jpg|Image:Free energy diagram.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Free energy diagram.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 13:40, 11 January 2009 (UTC)}} == Copyright problems with [[:Image:Ping pong reaction.jpg|Image:Ping pong reaction.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Ping pong reaction.jpg|Image:Ping pong reaction.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Ping pong reaction.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 13:41, 11 January 2009 (UTC)}} == Copyright problems with [[:Image:Blood clotting.jpg|Image:Blood clotting.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Blood clotting.jpg|Image:Blood clotting.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Blood clotting.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 13:41, 11 January 2009 (UTC)}} == Copyright problems with [[:Image:Blood clot final path.jpg|Image:Blood clot final path.jpg]] == {{mbox|type=warning|msg= Thank you for uploading [[:Image:Blood clot final path.jpg|Image:Blood clot final path.jpg]]. However it is missing information needed for compliance with [[w:copyright|copyright law]] and Wikibooks' [[WB:MEDIA|media policy]]. This and other files you have uploaded may soon be deleted unless the '''copyright permissions''' and '''source''' can be determined. If you know this information, then please add the correct [[WB:ICT|templates]] to the [[:Image:Image:Blood clot final path.jpg|description page]] with the copyright and source information included; there is no need to upload it again. If you have any questions, feel free to contact me, or ask in the [[WB:HELP|assistance reading room]]. See {{UserImages}} for a complete list of your uploads which may get deleted soon.<br/>Thank you. [[User:Abigor|Abigor]] ([[User talk:Abigor|talk]]) 13:42, 11 January 2009 (UTC)}} 70m4qzi9kw2tbkn4weu0k2en4ymtnwh User talk:Kimberleelee 3 176213 4669084 4667948 2026-09-06T07:22:28Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669084 wikitext text/x-wiki <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Kimberleelee!</div> {| cellspacing="0" cellpadding="0" style="margin:0em 0em 1em 0em; width:100%" | style="width:45%; vertical-align:top; border:1px solid #fad67d; background-color:#faf6ed;{{text default color}};" | <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #fad67d; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/>You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing here and ''[[WB:AGF|assume good faith]]'' for the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[WB:HELP|introduce yourself]] to everyone, and let us know what interests you. </div> <div style="border-bottom:1px solid #fad67d; background-color:#faecc8;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * We tag pages with various [[WB:TM|message templates]], such as {{tlx|query}}, to let editors know what needs to be improved. To learn more about these, ask at [[WB:PROJECTS|the projects reading room]], or insert <nowiki>{{helpme|your reason here}}</nowiki> * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> | style="padding:0em 0.5em 0em 0.5em;" | | style="width:55%; vertical-align:top; border:1px solid #abd5f5; background-color:#f1f5fc;{{text default color}};" | <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Please [[:w:Wikipedia:Sign your posts on talk pages|sign your name]] on discussion pages by typing &#126;&#126;&#126;&#126; * If you're coming here from Wikipedia, you should read [[WB:WFW|our primer for Wikipedians]] to get up-to-speed quickly. * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #abd5f5; background-color:#d0e5f5;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #abd5f5; padding:0.4em 1em 0.3em 1em;"> * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]]. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks &nbsp;'''&mdash;&nbsp;[[User:Mike.lifeguard|<b style="color:#309;">Mike.lifeguard</b>]]'''&nbsp;&#124;&nbsp;<sup>[[User talk:Mike.lifeguard|<span style="color:#309;">talk</span>]]</sup> 23:26, 17 November 2008 (UTC)</div> |- |style="text-align:right" colspan=3|<small>(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</small> |} oczakriu1h2uoywdkftec06ljb3lnmx User:Renamed user wZdBmxEPfs/InkscapeTemplate 2 177128 4668930 3478772 2026-09-05T12:35:23Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668930 wikitext text/x-wiki {| style="align: center; float: bottom; border-spacing:8px; margin:0px -8px; width: 100%; border: 3px solid #cbcb98; background-color: #ffffcb; {{Text default color}}; vertical-align: center; -moz-border-radius:10px" |style="text-align: center"|[[Inkscape/About|About]] - [[Inkscape/Introduction|Introduction]] - [[Inkscape/Shape_Tools|Shape Tools]] - [[Inkscape/Path_Drawing_Tools|Path Drawing Tools]] - [[Inkscape/Other_Tools|Other Tools]] |style="text-align: right"| back to [[Inkscape|contents]] |} m7l1uf5twiub7cdet22n7js0x18sssg Aros/Developer/Porting software 0 179093 4668969 4492790 2026-09-05T17:35:26Z Jeff1138 301139 4668969 wikitext text/x-wiki {{ArosNav}} ==Introduction== Before you attempt to port a program, make sure it's API dependencies are met on AROS. (AmigaOS (TM) 3.x C API is considered AROS native) * Acceptable: ANSI-C/C++, [ SDL v1 but v2 wip], GTK via [http://sourceforge.net/projects/gtk-mui/ gtk-mui], [http://archives.aros-exec.org/index.php?function=browse&cat=development/library Cairo] (old port), OpenGL via Gallium3D acceleration, ... * Very difficult: PyGame, Boost, Allegro, no SDL, Gnome, KDE and/or QT4, Godot, etc. * Impossible: Java, C#, any Windows-only source, etc. ==Compilers and tools== Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w (or F12 and w) within the directory with the makefile. Type in sh to change the amiga shell into a unix shell. You can then type in ls (unix equivalent to amiga dir). Take a look [http://en.wikibooks.org/wiki/Linux_commands here] for commands. For a single file program-name.c or program-name.cpp gcc -o program-name program-name.c or g++ -o program-name program-name.cpp To close the shell, click on the top left-hand corner to close (twice). Other missing symbols are due to linker libraries being necessary for linking in functions that aren't in the standard C libraries. For example some source code would need added -lz -lm -lpng to compile or even -lmui switch to link a program with a MUI gui. use this in unix line command mode to search for 'search-item' in many .c files (*.cpp for c++, etc.) grep -l 'search-item' *.c ==Using CONFIGURE to create a Makefile== Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w within the directory with the configure and make files. Type in sh to change the amiga shell into a unix shell. configure—help to see the available options. You'll need time to examine the options and choose the right ones. Hints are available later on. When you configure GCC using the `configure' script, it will construct the file `Makefile' from the template file `Makefile.in'. When it does this, it will incorporate makefile fragment files from the `config' directory, named `t-TARGET' and `x-HOST'. If these files do not exist, it means nothing needs to be added for a given target or host. Examples... <pre> configure prefix=/PROGDIR --build=i686 --host=i686 --disable-nls configure prefix=/PROGDIR --build=i386 --host=i386 --disable-nls --without-opengl --without-star --disable-sdltest configure LDFLAGS="-nix" --prefix=/PROGDIR --build=i386 --disable-nls --without-x --without-pic --disable-shared GREP=bin: --enable-client=sdl --disable-server --disable-sdltest --with-sdl-prefix=development:include/SDL </pre> to create a Makefile but if it does not work, look at the Hints section below ==EDITING CONFIGURE to suit AROS== Take a look at Fishy's tutorial [http://web.archive.org/web/20111107002757/http://fishys-house-of-aros-fun.webs.com/apps/blog/show/2651598-aros-porting-guide first] dir ../ unix moving back a directory or two dir / amiga equivalent When the Makefile is created, whilst in the unix shell, type in make -f Makefile to create the program... ===CREATING MAKEFILE from a blank text file=== ====Generic template makefile (not to be used)==== which requires multiple copies of .c .o files <pre> CC = gcc #CC = g++ #AS = nasm -f coff #AR = ar LDFLAGS = -s FLAGS = -I. -Icpu -Iaros -Wall -march=pentium -fomit-frame-pointer LIBS = -lz -lm -LDevelopment:lib #LIBS = -lSDL_net lSDL_ttf -lSDL_mixer -lSDL_image -lpng -ljpeg -lz -lvorbisfile -logg -lSDL #LIBS = -lz -lm -LDevelopment:lib -lglu -lglut -lgl -lSDL_mixer -lSDL_image -lpng -ljpeg -lz -lSDL EXE = name OPTS = -O2 # @echo "Building source files..." $(CC) $(FLAGS) $(OPTS) -c src/.c -o obj/.o $(CC) $(FLAGS) $(OPTS) -c src/.c -o obj/.o #$(CC) $(FLAGS) $(OPTS) -c src/.cpp -o obj/.o #$(CC) $(FLAGS) $(OPTS) -c src/.cpp -o obj/.o @echo "Making executable..." $(CC) $(LDFLAGS) $(FLAGS) -o $(EXE) obj/.o $(LIBS) @echo "Done!" </pre> Remove # from CC = g++, if g++ compiler needed. Remember to put # it in front of CC = gcc. # at the start acts as a comment line and are not processed. Similarly, remove/add # in the LIBS part to activate simple command line compiling, simple SDL compiling or openGL compiling respectively. Replace name with the program title in EXE part. Then add various .c (compiling with gcc) or .cpp (compiling with g++) source code you want to compile and .o also <pre> $(CC) $(FLAGS) $(OPTS) -c src/main.c -o obj/main.o </pre> Finally, collect all the .o for the final line <pre> $(CC) $(LDFLAGS) $(FLAGS) -o $(EXE) obj/main.o main2.o etc.o $(LIBS) </pre> [http://archives.aros-exec.org/index.php?function=browse&cat=development/utility MakeTools] should be looked at also. <pre> CC = gcc CFLAGS = -O LDFLAGS = -lSDL_image -lpng -ljpeg -lSDL_ttf -lfreetype2 -lSDL_mixer -lvorbisfile -lvorbis -logg -lSDL -lgl -lglu -lz -lstdc++ -lm OBJS = part1.o part2.o main.o # $(OBJS) will look above for list of .o and then use the statements below to see what to do with them myprogram: ${OBJS} ${CC} -o myprogram ${CFLAGS} ${OBJS} $(LDFLAGS) #-------------------------------------------------------- part1.o: part1.c part1.h header.h ${CC} ${CFLAGS} -c part1.c part2.o: part2.c header.h ${CC} ${CFLAGS} -c part2.c main.o: main.c header.h ${CC} ${CFLAGS} -c main.c clean: rm -f myprogram ${OBJS} @echo "all cleaned up!" </pre> ====Better Makefiles==== Just use the one that suits you. <pre> #Simpler version suffices for most small-scale projects #DEPS is needed to recompile hellomake.c with changed hellomake.h CC=gcc CFLAGS=-I. DEPS = hellomake.h # gcc, $(CC) and rm need to be TABbed to work with make # macro DEPS, which is the set of .h files on which the .c files depend %.o: %.c $(DEPS) # -o $@ compiler output into file named on the left side of hellomake: below ie hellomake # the $< is the first item in the dependencies list #DEPS $(CC) -c -o $@ $< $(CFLAGS) #putting the object files--hellomake.o and hellofunc.o in dependency list #make knows it must first compile the .c versions individually, and then build the executable hellomake hellomake: hellomake.o hellofunc.o gcc -o hellomake hellomake.o hellofunc.o -I </pre> <pre> CC = gcc CFLAGS = -O2 -I/include LDFLAGS = -lSDL_image -lpng -ljpeg -lSDL_ttf -lfreetype2 -lSDL_mixer -lvorbisfile -lvorbis -logg -lSDL -lgl -lglu -lz -lstdc++ -lm #----------------------------------------------------------------------------- OBJS = part1.o main.o program: $(OBJS) $(CC) $(OBJS) -o $@ $(LDFLAGS) $(STRIP) --strip-unneeded --remove-section=.comment $@ #----------------------------------------------------------------------------- part1.o: part1.c part1.h @echo " Compiling $*..." @$(CC) $(CFLAGS) $*.c main.o: main.c header.h @echo " Compiling $*..." @${CC} ${CFLAGS} $*.c clean: rm -f myprogram ${OBJS} @echo "all cleaned up!" </pre> <pre> # Template for a simple generic Makefile # CC = i386-aros-gcc # CPP = i386-aros-gcc -E # CXX = # CPPFLAGS = # CXXFLAGS = CFLAGS = (cflags) LDFLAGS = (ldflags) TARGET = (final-file-name) OBJECTS = file1.o file2.o file3.o LINKS = file1.c file2.c file3.c # XTRAOBJ = # # rules # all: $(TARGET) $(TARGET): $(OBJECTS) $(XTRAOBJ) $(CC) $(OBJECTS) $(XTRAOBJ) $(LDFLAGS) -o $(TARGET) %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ # # eof # Cycloid Makefile Example # OBJ = window2.o # # w.exe: $(OBJ) # $(CC) $(CFLAGS) -o $@ $^ $(ARCHIVE) $(LIB) # # window.o: window2.c # # $(CC) $(INCL) -c window2.c </pre> <pre> # .h files in an include directory IDIR =../include CC=gcc CFLAGS=-I$(IDIR) # .o files into a obj subdirectory and some local libraries in lib directory ODIR=obj LDIR =../lib macro defined for any libraries you want to include, like mui library -lMUI LIBS=-lMUI _DEPS = hellomake.h DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) _OBJ = hellomake.o hellofunc.o OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) $(ODIR)/%.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) hellomake: $(OBJ) gcc -o $@ $^ $(CFLAGS) $(LIBS) # .PHONY rule keeps make from doing something with a file named clean .PHONY: clean # cleaning up your source and object directories clean: rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ </pre> <pre> #simple makefile CC=gcc CFLAGS=-O2 -s -DNO_INLINE_STDARG -I./api/ -I../api/ -I../modules/api/ -I../amide/modules/api/amide/ LDFLAGS=$(CFLAGS) -nostartfiles -nodefaultlibs -lamiga -lstdc.static -lgcc EXE=plugins/test.plugin # Objects OBJS = StartUp.o \ LibInit.o \ sasc_module.o all: $(EXE) clean: rm -f *.o $(EXE) $(EXE): $(OBJS) echo Making $@.. $(CC) -o $(EXE) $(OBJS) $(LDFLAGS) </pre> ==Hints for correcting errors== *undefs about std:: and operators mean that you need to use or g++ , or if you use gcc, then add to -lstdc++ *undefs about sdl_wav mean -lsdl_mixer, *undefs about AROSMesa mean -lgl, Link order is important, so you can't for example firstly do -lgl, and then -lsdl. As sdl wants gl, you will need to do -lsdl -lgl, and the same for all the other libs : include one after another when undefs happens. -lSDL_image -lpng -ljpeg -lSDL_ttf -lfreetype2 -lSDL_mixer -lvorbisfile -lvorbis -logg -lSDL -lgl -lglu -lz -lstdc++ -lm There are undefined symbols in 'sasc.module': __PROGRAM_ENTRIES__symbol_set_handler_missing __LIBS__symbol_set_handler_missing remove the -nostartfiles argument from command line the missing symbols are part of AROS automatic startup handling. Possibly manually adding -llibinit could fix the missing symbols. add -nodefaultlibs like this: LINK := $(OPTIMIZE) -s -nostartfiles -nodefaultlibs should remove all automatically added libraries and now you will have to add them manually $(CC) $(LINK) -o $@ $(O_FILES) -lamiga -lstdc.static -lgcc <pre> #simple makefile CC=gcc CFLAGS=-O2 -s -DNO_INLINE_STDARG -I./api/ -I../api/ -I../modules/api/ -I../amide/modules/api/amide/ LDFLAGS=$(CFLAGS) -nostartfiles -nodefaultlibs -lamiga -lstdc.static -lgcc EXE=plugins/test.plugin # Objects OBJS = StartUp.o \ LibInit.o \ sasc_module.o all: $(EXE) clean: rm -f *.o $(EXE) $(EXE): $(OBJS) echo Making $@.. $(CC) -o $(EXE) $(OBJS) $(LDFLAGS) </pre> and LoadModules function calls that function from main.c, case of AROS it is best to use portable macros to make these calls <pre> mod_class =AROS_LC0(void *, AmIDE_API_GetClass, struct Library *, (AmIDE_API_Base), 5, AmIDE_API ); </pre> #include <aros/libcall.h> Additionally, most AROS code depends on the library bases being opened automatically so you may need to add a link library, libauto (-lauto). Some systems (so it's down to the compiler to provide it) don't have working libauto in which case you need to open the library bases manually. AROS OS 64Bit GCC 10+ enforces strict checks on void variables so gcc output-> error: variable or field __ret declared void. AROS_LC0NR variant of macros to handle void return type (NR stands for No-Return) with more [http://www.aros.org/es/documentation/developers/app-dev/portable.html here] [http://aros.sourceforge.net/documentation/developers/porting.php Hints can be found here] Be warned that these links apply to using Linux to compile code and not native but may be useful. <pre> CONFIGURE ERRORS Error : no acceptable C compiler found in $PATH Solution : add CC=gcc or CC=g++ after configure Error : no acceptable grep could be found in /Development/bin: Solution : add GREP=bin: to configure line Error : gtk-mui library sequence Solution : gcc -o test addbutton.c\ -lglib-2.0 -lgtlayout -lgthread-2.0 -lgmodule-2.0 -lgobject-2.0 -lgtk-mui -lglib-2.o -liconv -lmui -lthread Error : VARIABLE not within scope Solution : add headers like... #include <libraries/mui.h> #include <proto/muimaster.h> or #include <string.h> etc Error : malloc.h no such file or directory Solution : malloc is contained within <aros/stdlib.h> Error : SDL.h no such file or directory Solution : #include SDL/SDL.h needed at top of .c file or -IDevelopment:include/SDL to the command line Error : Solution : Error : IMG_Load in -lSDL_image ... cannot find libSDL_image Solution : ?? Error : pow in -lm - 'case' unmatched - math.library (-lm) appears broken Solution : ?? Error : Solution : Error : Solution : MAKE ERRORS Error : *** missing separator. Stop. Solution : Make commands like gcc $(CC) or rm need to be TABbed in and not use spaces Error : Solution : Error : Solution : Error : Solution : COMPILING ERRORS Error : expected '=' ';' "asm" or '__attribute__' before '{' Solution : look at previous lines for missing/extra ; (like in defines) or missing } or forgot to #include something.h. Use gcc -E to check Error : request for member 'something' in function not a structure or union Solution : using b.x = 12 (usually arrays); when it should be b->x (usually structs) or (*b).x, .h needed, Error : 'something' undeclared (first use in this function) Solution : 'something' been declared at start of function, .h needed or link library needed -lmui etc., Error : there are undefined symbols in program Solution : /* around these symbols' */ until you work out if they are needed or can be deleted Error : there are undefined symbols in <program-name> or memcpy strndup first Solution : linker library not included -lz -lSDL or -lGL etc or <string.h> Error : expected specifier-qualifier list before 'USHORT' Solution : change all references of USHORT into UWORD (SHORT into WORD) Error : expected declaration specifiers or '...' before 'USHORT' Solution : replace USHORT with UWORD (SHORT into WORD) Error : field 'name' has incomplete type Solution : Error : expected ')' before 'type' Solution : Error : invalid conversion from 'ULONG*' to 'IPTR*' Solution : most amiga like OS's return ULONG values or use ULONG TAGS but 64bit AROS needs IPTR used for compatibility Error : dereferencing pointer to incomplete type Solution : Error : If crackly break-up noise found in SDL sound Solution : try to find where the number of samples for the buffer is set in the source and increase it (double it at least). This solves many sound issues with SDL programs. The buffer was set to 1024, now set it to 4096. Error : initializer element is not constant around TAG_DONE); Solution : header(s) <utility.h> and <proto/utility.h> need to be added Error : no i386-sdl-config Solution : use --build=i686 instead of --build=i386 Error : functions not found at final linking: SDL_CondWait, SDL_CondSignal, SDL_CreateCond Solution : find them in the SDL_cond_aros.c file in the cdxlplay-sdl source http://www.a500.org/downloads/video/ Error : crash glutGet((GLenum)GLUT_ELAPSED_TIME); Solution : The glutInit function is needed, replace with by SDL_GetTicks() Error : undefined symbols: recv, connect, inet_pton, socket, select, send, inet_ntoa Solution : LDFLAGS : -lSDL_net -lSDL with #include <proto/bsdsocket.h> (or <proto/socket.h>) in all files using SDL_net Error : SDL is not built with CDROM support. Solution : Look for SDL_INIT. It can look something like this: if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) change it to: if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK ) == -1 ) That includes all the init routines available in SDL, minus the CD one. Error : Video mode set failed: OpenGL support not configured Solution : 'sdl-config --libs' is fine for most SDL uses, but with GL it needs to be replaced with "-lgl" Error : Solution : Error : Solution : RUN TIME ERRORS Error : Solution : Error : Solution : Error : Solution : Error : Solution : Error : Solution : Delinting (removing warning messages) 64bit compatibility - MUIA_Application_Copyright, _(MSG_AppCopyright), + MUIA_Application_Copyright, (IPTR)_(MSG_AppCopyright), - io->io_Unit = (struct Unit *)unitnum; + io->io_Unit = (struct Unit *)(IPTR)unitnum; Clean up - ULONG signals; + ULONG signals = 0; - while((t = LibNextTagItem(&tagList))) + while((t = LibNextTagItem((struct TagItem **)&tagList))) - while ((tag = LibNextTagItem(&msg))) + while ((tag = LibNextTagItem((struct TagItem **)&msg))) - const struct TagItem *tstate = msg->ops_AttrList; - struct TagItem *tag; + struct TagItem *tag, *tstate = msg->ops_AttrList; - sprintf(buf, "SYS/printer%d.prefs", unit); + sprintf(buf, "SYS/printer%d.prefs", (int)unit); - STRPTR _return = NULL; + CONST_STRPTR _return = NULL; - return (CONST_STRPTR)_return; + return _return; </pre> ==Hints: Porting software from...== ===AmigaOS=== The right form of the main() function is <pre> int main(void) { ... return retval; } or int main(int argc, char **argv) { ... return retval; } </pre> (Old code has often "void main()" or no return type at all) For retval you can either use 0, EXIT_SUCCESS or EXIT_FAILURE (ANSI-C) or ADOS return codes which I don't know off-hand. First turn anything that ending in _proto.h <pre> #include <dos/dos_proto.h> to #include <proto/dos.h> </pre> and if you want it more portable, then try <pre> #ifdef AROS #include <proto/dos.h> #else #include <dos/dos_proto.h> #endif </pre> Include function prototypes for shared libraries from proto e.g. #include <proto/graphics.h> instead of #include <clib/graphics_protos.h> If the compiler complains about wrong type in a line like struct Library *GfxBase you have to look up the right type in the header, e.g. in includes/proto/graphics.h #include <proto/library_name.h> (replacing with correct name) should pull in the necessary info for automatic opening/closing of CORE libraries to work with basic applications which are written as DOS and Workbench/Wanderer launched processes. Others like mui have to be specified (-lmui in the gcc command line). It looks like you are still including from clib. You either have to include from proto or you have to link with -lexec -lgadtools, etc. There are undefined symbols in 'inctst': U AllocMem U FreeMem Adding -lexec removed the errors. <pre> There are undefined symbols in 'a.out': SetFont CloseFont OpenFont </pre> try -lgraphics or #include <proto/graphics.h> or #include <defines/graphics.h> or #include <clib/graphics_protos.h> <pre> Include sys/types.h before netinet/ip.h Include <netdb.h> first before rest of your network includes </pre> Most AROS C/C++ Compilers can open and close the libraries for you as part of the startup code. As long as you have the protos included in the headers and the appropriate compiler options specified, the compiler will take care of opening any used libraries for you. The library header source is in principle like AOS 68k too, with Resident struct, functable and so on. Except AROS has its own set of macros for functions which get parameters in registers. The AROS_LH#? and AROS_UFH#? stuff. You should be able to use contrib/mui/classes/nlist/commonaros/mccheader.c from AROS contrib sources as a hint. But always remember, that coding for AROS is not coding for m68k Amiga. Much is different here and coding AROS in C means searching hundreds of include files for macros. And AROS source code is partly useless for an external newbie developer, as AROS has a deeply integrated build system which hides important parts from the implementing developers, e.g. a shared library consists only of its methods, the rest (Romtag, Jumptable etc.) is hidden in the AROS build system. wbstart.library isn't ported indeed but its usage is depreciated and you are advised to convert its calls to use workbench.library/OpenWorkbenchObject() (which should be easy). A temporary quick trick is to use CLI callings on C:Open which will launch programs using Workbench (using this very function). It can even be used with arguments which are passed as workbench arguments (ie like multi-clicked files). ====Programming languages==== As long as no assembler code is being used in the program, compiling a C program written for plain AmigaOS up to version 3.1 should be possible on AROS without any changes to the source code. (That presumes your AROS is using a 32bit big-endian CPU, like the original Amiga computer.) (Please note that '''AROS is still beta and incomplete''', and might lack some functions from AmigaOS API. See [[Aros/Developer/Docs#Status of AROS implementation|Status of AROS implementation]] for more on this.) ====Data types and sizes / little endian / big endian==== Some of the first things to consider is the actual size of your C data types, and in your uses of binary files (IFF for example) paying attention to reading and writing with portability to 64bit and little-endian CPUs as well as the classic mc680x0 or powerpc cpus used by Amiga OS. * Warning signs is casting between char * and WORD/LONG/short/int etc., or any kind of pointer arithmetic, as well as any functions that read/write binary file formats (if they read character by character and/or does things similar to what I mentioned above, they are likely to be ok, if they read a chunk of memory in and treat it as a struct immediately then it will almost certainly fail). * Endianness issues need to be fixed and there are a lot of them (reading/writing binary files, writing data into graphics frame buffers). Also network stack, file system, hardware. Pretty much any time you have to deal with external data, you have to worry about endianness. There are C #define macros to handle writing/reading the correct endianness and flipping the ordering when necessary. * all LONG/ULONG/APTRs need to be checked if they need to be replaced by IPTR (e.g. relying on TagLists) [we should probably have a chart showing sizes/endian used by Manx/sas/dice C on a mc68000/68030 vs today's PPC/i386/x86_64 AROS options here along with some GCC source code to show how to read/write binary files correctly under AROS running on differing endian CPUs] ====Screens==== Amiga chipset-graphics-based screens were generally done in a planar format 16/32-colors max for ECS hires/lores modes respectively and 256-colors for AGA. [a chart of common amiga screen modes should go here] Methods that worked well for the relatively low-resolution planar Amiga displays may be suboptimal for chunky and true color screens that are common today. [pointer to examples should go here] Amiga screens could be of differing resolution, which could be dragged up and down to reveal another, so some applications were written with differing resolution screens, say for a control panel at one resolution and another for the "display" visible at the same time stacked vertically. This may not make sense with today's chip sets or wide-screen displays. Opening multiple screens that vary in scan rate can confuse displays (monitors or projectors) that might take several seconds "calibrating" every time the user decides to change which public or private application screen they want to view. Defaulting to the user's preference for Wanderer (workbench) for screen mode is probably better than having a predefined mode hard-coded into your application. ====Fonts==== AmigaOS 3.1 also shipped with some nice disk fonts that are not currently available under AROS, so you should be careful about having any diskfont hard-coded as a default into your program. The ROM font "topaz" should be ok. AROS fonts (as of 2010-03-10): *arial.font *dejavusansbold.font *dejavusansboldoblique.font *dejavusansbook.font *dejavusanscondensedbold.font *dejavusanscondensedboldobl.font *dejavusanscondensedcondens.font *dejavusanscondensedoblique.font *dejavusansextralight.font *dejavusansmonobold.font *dejavusansmonoboldoblique.font *dejavusansmonobook.font *dejavusansmonooblique.font *dejavusansoblique.font *dejavuserifbold.font *dejavuserifboldoblique.font *dejavuserifbook.font *dejavuserifcondensedbold.font *dejavuserifcondensedboldob.font *dejavuserifcondensedconden.font *dejavuserifcondensedobliqu.font *dejavuserifoblique.font *fixed.font *stop.font *ttcourier.font *Vera Mono Bold.font *Vera Mono Bold Italic.font *Vera Mono.font *Vera Mono Italic.font *Vera Sans Bold.font *Vera Sans Bold Italic.font *Vera Sans.font *Vera Sans Italic.font *Vera Serif Bold.font *Vera Serif.font *XEN.font ====GUI Toolkits==== =====Gadtools===== The order of the fields in struct Node which is currently different than on AOS (will be changed in ABI V1). struct Node has currently the following order: <pre> struct Node { struct Node * ln_Succ, * ln_Pred; char * ln_Name; UBYTE ln_Type; BYTE ln_Pri; }; </pre> =====MUI===== '''MUI''' - AROS' preferred GUI toolkit is Zune, a reimplementation of MUI 3.x, thus MUI 3.x code will work unchanged under AROS. MUI 4.x will need adapting or wait for the following [http://www.power2people.org/projects/profile/54 bounty] to be started. =====ClassAct===== '''ReAction/ClassAct''', a GUI toolkit for AmigaOS, is not available for AROS. It has been made part of AmigaOS 3.5 and higher. Programs that use ReAction might need considerable rework, preferably to use Zune (or: MUI), AROS' GUI toolkit. =====BGui===== '''bgui''' is available as part of the "contrib" archive, thus included in all current AROS binary distributions. [We could use a chart comparing gui options for developers here.] ====C/C++ Compilers==== GCC/G++ is the primary C compiler supplied with AROS. Amiga programs making use of other compilers' (SAS/C, Maxon C, ...) specific functionality might need some rework. You'll probably want to write makefiles that can run either hosted or native, so any AROS user can get them compiled and running on their machine. In a hosted environment the shell will most likely use UNIX semantics like cp==COPY ../==parent directory, and all file names will be case sensitive for your makefile and inside your C source code files (example: #include "myFile.h" != #include "MyFile.H"). Under AROS the makefile may use Amiga shell command semantics (copy #? progdir:prefs)or it may be using a UNIX shell ported to AROS, and the AROS environment, and like AmigaOS 3.1 may not care about case sensitivity of file names. We can't use the SLOWSTACKTAGS macros for getting ULONG values from a variadic list. ===== SAS Lattice C Compiler===== SAS/C was one of the more popular compiler packages back when AmigaOS 3.1 was released, it supported various keywords such as __chip for using chipram, and CPU-related register arguments that the current AROS GCC does not. The makefiles will have to be translated from SMAKE to GNU Make and some of the headers will have to be translated from SC to GCC. Pragmas were used on ancient C compilers like SASC. Include from "proto", e.g. #include <proto/workbench.h>. Look if there are headers which include from "clib". Change them to "proto", too. You can ignore warnings like "suggested parentheses..." or incompatible pointer types. Some types and names of defines have changed (SHORT/USHORT -> WORD/UWORD). -linput -lutility -lintuition -lrexxsyslib -lconsole -lgraphics -ldos -lexec strmfp, stcgfe, stcgfp, stcgfn and stci_d are SAS/C / Lattice function that do not exist under gcc. They have to be reimplemented. tolower and toupper was found once I've included ctype.h in the source code. Sometimes missing symbols come from missing include files. Those are macros like toupper—not real functions, and the C preprocessor needs the include definition for the macro. If you want your characters to be unsigned you need to put unsigned into the variable type. If you want them to be signed, put signed in the variable type. If you don't put either, you may get unexpected results. Sometimes you need wrappers for functions which aren't part of ANSI C. SAS/C allowed to use a type before it was defined => change the order or use forward declaration. Use AROS macros for Hook functions as explained here: http://aros.sourceforge.net/documentation/developers/app-dev/portable.php#hooks There might be more if you are porting system software (libraries, interrupts etc.) Just start and try to find the reason for warnings and errors. Generally when porting sources, if a header doesn't exist in AROS, wrap it with an #if or #ifndef statement and see what symbols, structure definitions, etc. aren't found. Then you can look through the AROS includes to see if the missing symbols, etc. are implemented in another place, or if you have to make your own compatible include file with those defined. For libraries you might want to look at the AROS source-tree to see how others have done it using things like [http://aminet.net/package/dev/gcc/sfdc sfdc], genmodule, etc. * SAS/C included a ton of non-standard functions in its C library. Alternative versions of these can generally be found online, and for example YAM includes some of them in their sources, depending on license working around this is easy (none of these functions are big/difficult to re-implement if needed). * SAS/C is very liberal in some of the things it accepts. This causes problems particularly for vbcc (not so relevant for AROS) but some things also for gcc, particularly in terms of type coercion and (lack) of forward declarations. * SAS/C has a multitude of extensions targeting AmigaOS, such as non-standard 68k focused register declarations. These must either be removed or worked around by defining preprocessor macros that expand to nothing or a suitable replacement. * The SAS/C smakefiles are a totally non-standard syntax. * The general caveats of AmigaOS vs. AROS include files apply - many paths can be expected to be different. * there might be endian issues * you'll get a lot of compiler warnings. Some of them are harmless (e.g. "parenthesis suggested ..."). Others are dangerous (e.g. "variable xxx may be undefined") * for some specials like callback hooks you'll have to use AROS macros. * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. * Fix (change IPTR/SIPTR back to ULONG/LONG) the few places which really rely on ULONG/LONG being exactly 32 bit. That's for things like pixel (ARGB) buffers, structs written/read to disk, colormaps, but probably little else. This is the [http://aros-exec.org/modules/newbb/viewtopic.php?start=30&topic_id=5705&viewmode=flat&order=ASC&type=&mode=0 code] that I use in diskimage.device for converting a BSTR to a CSTR <pre> LONG CopyStringBSTRToC (BSTR src, STRPTR dst, ULONG dst_size) { #ifdef __AROS__ STRPTR ptr = AROS_BSTR_ADDR(src); ULONG ln = AROS_BSTR_strlen(src); #else UBYTE *ptr = BADDR(src); ULONG ln = *ptr++; #endif if (ln > (dst_size-1)) ln = dst_size-1; memcpy(dst, ptr, ln); dst[ln] = 0; return ln; } </pre> Some blankers{{typo help inline|reason=similar to blinkers|date=October 2022}} are missing the symbol "custom". They have (as documented in the OS3.9 RKM) "extern struct Custom custom;". 'Custom' is a struct that maps the m68k Amiga AGA/OCS/ECS registers. Only build those for amiga-m68k, and you'll be fine. =====Maxon Hisoft C===== =====Dice C===== =====North C===== * RAWKEY: replaced with IDCMP_RAWKEY: * ModifyIDCMP(win,FLAGSON) replace with ? ===MorphOS=== ====Assemblers/ Disassemblers==== ADis, which reads binaries into memory hunk by hunk to disassemble them, and then just treats it as an array of short. The "right" way would be to treat it as a char *, and do (arr[0] << 8) + arr[1]. I wanted to use it to cross-disassemble M68k programs, but gave up and went with Ira instead because it was so pervasive. ===Linux Console Apps=== On AmigaOS this is done by libc on every I/O operation. Just AROS libs lacks this. Resources allocated by libc (malloc()ed memory, fopen() ed files, etc.) are safely reclaimed at exit(). libc tracks this internally. If your program additionally uses some AmigaOS API, it usually installs exit handler (I don't remebmer how), or disables Ctrl-C checking by redefining __chkabort() function. You have to explicitly check for it on AROS (and AmigaOS). The reason for this is that there's no safe way for the OS to kill an app and reclaim all resources on AmigaOS and derivatives (since an app can have "handed off" memory and other resources to other tasks). This is an example from the autodocs for SetSignal: <pre> #include <libraries/dos.h> /* Check & clear CTRL_C signal */ if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { printf("CTRL-C pressed!n"); } </pre> It is compiler dependent. It's safer to just do the SetSignal()-based check. If you want a shared library, recommend getting linux-hosted aros building (use the gimmearos.sh script) and then look at the other library sources found in AROS/workbench/libs for examples of how its done. If it were just a linker library, you can just compile the .c files with -fno-stack-protector (needed under aros-sdk cross compiler under linux, native aros gcc might not need that), etc. and join the .o files into a lib-yournamehere.a file with ar and ranlib them. ===SDL=== SDL_image may need -ljpeg -lpng -lz SDL_mixer needs -lSDL_mixer -lvorbisfile -lvorbis -logg (in this order) First thing to test with SDL sound under AROS is to increase the buffer. In all applications had needed this to obtain good sound output. In most cases it would certainly mean that you have to increase the value of SYSSND_MIXSAMPLES. Usually multiplying this value by 2 or 4 gives good results. You should also check the value of the obtained structure. It is not sure that AROS supports AUDIO_U8 and you might have reverted to AUDIO_U16. In this case sound will of course be distorted. from [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=2533&forum=2&post_id=45301#forumpost45301 here] Further tests with buffers using code from [http://www.kekkai.org/roger/sdl/mixer/ here], and this is the result I've noted: "a quick test compiling with 1024, 2048 or 4096 gave interesting results: 1024 - sounds are more responsive to key-events but if you quickly move the "game-window" around the screen you can hear sound glitches. 2048 - No big difference noticed in responsiveness and now no glitches moving the window around, anyway the fx-sound sample plays with some hiss-click glitches. 4096 - No hiss-click and no glitches moving the window BUT you can see that the responsiveness is decreased. Trying this code then with original xRick 8bit samples gives good sound results, and even using 1024 bytes buffer the sound doesn't glitch when moving window" Seems to me that buffer depends a lot on responsiveness you need, overall game load and also what kind of sound samples you're using (of course the lower is the bit-encoding and frequency, the smaller you can use as buffer). SDL_GetTicks just disable m_fLastTime = float(SDL_GetTicks())/1000; in 2 places of sdlapp.cpp and add your own code at the end: <pre> Ellapsed_Time = SDL_GetTicks() - Last_Time; if (Ellapsed_Time < 20) /* 20 ms target => 50FPS */ { SDL_Delay(20 - Ellapsed_Time); } </pre> Maybe SDL_GetTicks works a bit wrong by some reasons in aros's SDL, right ? (because if the same code works fast on os4/mos/win32/anything-else), then it mean that something wrong with SDL_GetTicks then .. PS : SDL_GetTicks() isn't causing any trouble, its a basic SDL function that is used in almost all SDL applications. int CSDLApplication::Run() in sdlapp.cpp and bool CMySDLApplication::FrameMove() in Armygaem.cpp In initial-code Render3DEnvironment is called continuously and only FrameMove is updated at 50fps, Render() and SDL_GL_SwapBuffers() are called even if nothing has moved. Calling the render() functions and SDL_GL_SwapBuffers(), too often is for me the root cause. A correction to OpenGL implementation would only be a safeguard to prevent stupid application from crashing or slowing down the system. crash on exit is certainly due to the application not freeing any resources before exiting. ===Writing ROM-able code=== Code in AROS modules should be written in a way that makes it suitable for embedding into a ROM, FlashRAM or other kinds read-only memory. The following coding style rules are meant to make it possible. Of course they apply to all Kickstart modules and to code that may be made resident, shared or linked to other modules. ROM modules must have no .data and .bss sections. Basically, we need to get rid of all non-const global data. The real Amiga Kickstart proves that it's both possible and easy to achieve this. If you encounter an external variable (static or not) that is modified by the code, try to get rid of it or move it into the base of the library/device (or in the device node of your handler or in the userdata of your class). The above applies to library bases as well. If you are writing a library, put the bases of other libraries into your own library base structure. Boopsi classes can store library bases in their class private data. Try to set the static and const attributes to all your global data. You can also use the CONST_STRPTR and CONST_APTR types defined in <exec/types.h>. Using static const allows the compiler to move data into the .text (AKA code) segment. If you need to pass these globals to another function, try to change its prototype to use const too. ===Hooks and SDI=== A hook is a custom function you write in order to be able to handle a specific situation that arises from intercepting the main code (like processing a message). The function must be designed to accept three arguments, whose order and type is given. * the first parameter (A0) contains the pointer to your hook, not to your window * the 2nd Parameter points to the Object which causes this action, this isn´t your window but it´s the Object which was pressed (it´s always the Object which was connected to the Hook (=1st Parameter of DoMethod) * then give 5 as number of Parameters for MUIM_CallHook, but´s 4 (=number of all Parameters in DoMethod after the Count Parameter) <pre> AROS_UFH3S ( void, MyHookFunction, AROS_UFHA(struct Hook * , hook, A0), AROS_UFHA(Object * , obj, A2), AROS_UFHA(ULONG * , params, A1) ) </pre> params is an array but IPTR should be correct. Then you can access your parameters... <pre> app = (Object *) *params++; window2 = (Object *) params++; </pre> <pre> The important thing about hook functions is that the parameters must be given in the order A0, A2, A1. And not to leave out parameters even if they are unused by the hook function. For initial quick&dirty ports one can even simply defines things like "__saveds", "__asm", "__regargs", "__stdargs", "register ..." to nothing. For library functions it's the same (with library base as last param). InitLib: libbase(d0), seglist(a0), sysbase(a6) OpenLib: version(d0), libbase(a6) CloseLib: libbase(a6) ExpungeLib: libbase(d0), libbase(a6) OpenDev: ioreq(A1), unitnum(d0), flags(d1), devbase(a6) CloseDev: ioreq(a1), devbase(a6) </pre> see [http://utilitybase.com/forum/index.php?action=vthread&forum=3&topic=1495 here] The AROS asm call and lib call macros require param type (like "struct Hook *") and param (like "myhook") to be passed in two different arguments. Not in a single one. Converting is easy. Adding some "AROS_" prefix plus some commas. Additionally in the hook functions and dispatcher functions "HOOK_INIT" / "HOOK_EXIT" / "DISPATCHER_INIT" / "DISPATCHER_EXIT" must be used (in case of AROS mapping to AROS_USERFUNC_INIT/AROS_USERFUNC_EXIT). To force procedure parameters to use registers (like a0) in GCC Since C calling convention on some machines (like 68k or x86) means params are passed on stack your C function must have params in correct order (Hook, object, msg) and not leave out params if they are unused by the function especially if it's the middle param (object). ULONG hook_function(REG(a0, struct Hook *hook), REG(a2, APTR object), REG(a1, APTR message)) In short when using HookEntry you initialize hooks like this: <pre> STATIC ULONG hookfunc(struct Hook *hook, APTR obj, APTR msg) { /* ... *// } #if defined(__amigaos4__) hook->h_Entry = hookfunc; #else hook->h_Entry = &HookEntry; hook->h_SubEntry = hookfunc #endif </pre> If you are not using SDI headers this is the most universal method which works on OS3, OS4, AROS and MorphOS with every compiler and architecture. Those dispatchers are usually taken as argument for MUI_CreateCustomClass(), which has: <pre> #if defined(__MAXON__) || defined(__amigaos4__) cl->cl_Dispatcher.h_Entry = (HOOKFUNC)dispatcher; #else cl->cl_Dispatcher.h_Entry = (HOOKFUNC)metaDispatcher; cl->cl_Dispatcher.h_SubEntry = (HOOKFUNC)dispatcher; #endif </pre> metaDispatcher: <pre> #ifdef __AROS__ AROS_UFH3(IPTR, metaDispatcher, AROS_UFHA(struct IClass *, cl, A0), AROS_UFHA(Object *, obj, A2), AROS_UFHA(Msg , msg, A1)) { AROS_USERFUNC_INIT return AROS_UFC4(IPTR, cl->cl_Dispatcher.h_SubEntry, AROS_UFPA(Class *, cl, A0), AROS_UFPA(Object *, obj, A2), AROS_UFPA(Msg , msg, A1), AROS_UFPA(APTR , cl->cl_Dispatcher.h_Data, A6) ); AROS_USERFUNC_EXIT } </pre> What confuses me is that our own macros have registers: <pre> #define BOOPSI_DISPATCHER(rettype,name,cl,obj,msg) \ AROS_UFH3(SAVEDS rettype, name,\ AROS_UFHA(Class *, cl, A0),\ AROS_UFHA(Object *, obj, A2),\ AROS_UFHA(Msg , msg, A1)) {AROS_USERFUNC_INIT </pre> Maybe there is a difference between MUI and BOOPSI when it comes to dispatchers and SDI DISPATCHER can only be used for MUI. AROS's MUI_CreateCustomClass() moves the dispatcher to h_SubEntry and uses something like HookEntry for h_Entry. There we don't have to care about registers. BTW: SDI's hook macros *are* wrong for AROS. <pre> HOOKPROTONHNO(TestFunc, void, int *param) { puts("Foobar"); } MakeHook(TestHook, TestFunc); </pre> expands to: <pre> static void TestFunc(__attribute__((unused)) struct Hook *_hook, __attribute__((unused)) APTR _obj, int *param) { puts("Foobar"); } struct Hook TestHook = {{0L, 0L}, (HOOKFUNC)TestFunc, NULL, 0L}; </pre> That works only by accident on i386-AROS (because of stack parameters). But there I *know* how to fix it and will soon send an update to you. <pre> #elif __AROS__ #define MakeHook(hookname, funcname) struct Hook hookname = {{NULL, NULL}, \ (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL} #define MakeHookWithData(hookname, funcname, data) struct Hook hookname = \ {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, (APTR)data} #define MakeStaticHook(hookname, funcname) static struct Hook hookname = \ {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL} #define ENTRY(func) (APTR)func #define DISPATCHERPROTO(name) SAVEDS ASM IPTR name(REG(a0, \ struct IClass * cl), REG(a2, Object * obj), REG(a1, Msg msg)) #define DISPATCHER(name) DISPATCHERPROTO(name) #define SDISPATCHER(name) static DISPATCHERPROTO(name) </pre> Difference is that funcname is moved to h_SubEntry. Problem are the dispatcher macros. They'll currently only work with MUI_CreateCustomClass(). If I define them like our BOOPSI macros I have a new problem: what happens if I define a function with register macros *AND* use HookEntry in h_Entry and the function in h_SubEntry? BTW: in SDI_compiler.h there is: <pre> /* we have to distinguish between AmigaOS4 and MorphOS */ #if defined(_M68000) || defined(__M68000) || defined(__mc68000) #define REG(reg,arg) arg __asm(#reg) #define LREG(reg,arg) register REG(reg,arg) #else #define REG(reg,arg) arg #define SAVEDS </pre> C++ is much more strict on types than C, this is the root of the problem. Absolutely everything should be casted, implicit conversions are not allowed at all. P.S. And casting is considered an extremely bad coding style IIRC... Those who want to develop AROS API in C++ should update their headers from a current SDK. HOOKFUNC looks now like this in include/utility/hooks.h: typedef IPTR (*HOOKFUNC)(); The prototypes have been included in "extern C" blocks, so that problems like this should be [http://aros-exec.org/modules/newbb/viewtopic.php?post_id=37123#forumpost37123 gone] ===Casts=== Casts simply put... casting through pointers, bad... casting through a union, [http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html good]*. (*exceptions apply) Hopefully someone can correct me if I'm wrong, but the main rule of thumb for avoiding these problems seems to be to not have two pointer variables in the same function that point to the same memory, but are of different type. It's actually a little more subtle than this. They can point to different types, but not when the types do not contain sub-sets of the others. i.e. <pre> struct Foo { struct MinNode Node; }; </pre> - any cast from struct Foo * to struct MinNode * is ok ... but: <pre> struct Foo { struct Foo *next; struct Foo *prev; }; </pre> - now casts from 'foo' to 'minnode' are not ok ... and worse, can be silently discarded (how that is considered polite behaviour I do not know). (and by extension, casting from List to Node are right out). I would argue that this is actually a different language - it is no longer 'C', as such, and although the spec (as far as I have been able to ascertain) actually specifies this it has never been implemented in such a way until now. It is there to provide additional optimisation opportunities ... although the whole 'we'll just silently drop code that is otherwise quite obvious' thing is rather nasty. The CellPerformance stuff really nails it all. Although I find it somewhat absurd you can cast pretty much anything through a union and it's 'ok', but using the language 'cast' exactly the same physical operation becomes 'illegal'. NEVER EVER touch buffers passed in by the user as an "input" parameter. The concept of input parameters is often implicit in the function description. For instance, the filename passed to Open() is clearly an input variable and Open() must not mess with it, even if it is going to fix it back later. Keep in mind that the buffer might be in read-only memory or shared among several instances of a resident or multithreaded program. Try to avoid host-OS calls such as malloc() and free() if you can do with AllocMem() and FreeMem(). This is because the pointer checking debug macros rely on finding the pointer within the Exec memory blocks with TypeOfMem(). SA_BackFill, (ULONG) &sbackfillhook, Please do not use ULONG's to store/cast pointers in your code. use APTR/IPTR where appropriate. ==Compiling small parts of AROS source without using Build system== [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=3475&forum=2&post_id=29123#forumpost29123 from] make stub make make install and need genmodule from [http://pagesperso-orange.fr/franck.charlet/temp/radeon.zip inside] here. Trying to build the support modules of [http://svn.berlios.de/wsvn/ignition/trunk/libs/scroller/ Ignition] with a normal Makefile: How can I get rid of these linker warnings? U __includelibrarieshandling and U __this_program_requires_symbol_sets_handling Is there something I have to care about when I create a module this way? (I have always used the build system in the past) Is there a function which must be the first in the generated module? Are you using ld directly? If so, don't do that, use the compiler's driver instead (gcc, that is) to do all the steps, final linking included. The problem arises because the linker needs to be invoked through a wrapper, which in our case is called collect-aros (it would be collect2 on other systems). You can either call collect-aros in place of ld (I wouldn't do that) or the compiler's driver (gcc, do that) as said above. Mh, hadn't noticed the makefile when I first replied and I had forgotten these symbols are actually produced by collect-aros itself. The problem arises because you are using -nostartfiles, which avoids linking with the startup file, but the startup file contains code that handles the automatic libraries opening/closing and the generic symbol sets handling. By using DFLAGS=-lgraphics -lintuition -lutility you are actually linking with stub libraries that require the automatic handling of shared libraries to be implemented. Either you avoid using these stubs or you implement the needed code yourself. You can take inspiration from the normal startup code. After re-enabling lines like #define UtilityBase cb->UtilityBase I was able to build the module without the stub libraries. ==Tutorials== See here for a [http://web.archive.org/web/20111107002757/http://fishys-house-of-aros-fun.webs.com/apps/blog/show/2651598-aros-porting-guide tutorial] SDL/MesaGL/OpenGL game frameworks. [http://msm.grumpybumpers.com/?p=64 Jumpcore Minimal] [http://lazyfoo.net/SDL_tutorials/index.php Tutorial] [http://www.monkeyfighter.com/tetris.html Amiga Tetris] [http://irrlicht.sourceforge.net/downloads.html Irrlicht 3D engine] {{BookCat}} euv6lzqz41mmnynx12kz0rh2gon6sla 4668970 4668969 2026-09-05T17:38:05Z Jeff1138 301139 4668970 wikitext text/x-wiki {{ArosNav}} ==Introduction== Before you attempt to port a program, make sure it's API dependencies are met on AROS. (AmigaOS (TM) 3.x C API is considered AROS native) * Acceptable: ANSI-C/C++, [ SDL v1 but v2 wip], GTK via [http://sourceforge.net/projects/gtk-mui/ gtk-mui], [http://archives.aros-exec.org/index.php?function=browse&cat=development/library Cairo] (old port), OpenGL via Gallium3D acceleration, ... * Abit of work: Dice C, SAS C, Aztec C, etc * Very difficult: PyGame, Boost, Allegro, no SDL, Gnome, KDE and/or QT4, Godot, etc. * Impossible: Java, C#, any Windows-only source, etc. ==Compilers and tools== Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w (or F12 and w) within the directory with the makefile. Type in sh to change the amiga shell into a unix shell. You can then type in ls (unix equivalent to amiga dir). Take a look [http://en.wikibooks.org/wiki/Linux_commands here] for commands. For a single file program-name.c or program-name.cpp gcc -o program-name program-name.c or g++ -o program-name program-name.cpp To close the shell, click on the top left-hand corner to close (twice). Other missing symbols are due to linker libraries being necessary for linking in functions that aren't in the standard C libraries. For example some source code would need added -lz -lm -lpng to compile or even -lmui switch to link a program with a MUI gui. use this in unix line command mode to search for 'search-item' in many .c files (*.cpp for c++, etc.) grep -l 'search-item' *.c ==Using CONFIGURE to create a Makefile== Open shell - its a menu option at the top left of Wanderer (desktop). Or by using the right Win key and w within the directory with the configure and make files. Type in sh to change the amiga shell into a unix shell. configure—help to see the available options. You'll need time to examine the options and choose the right ones. Hints are available later on. When you configure GCC using the `configure' script, it will construct the file `Makefile' from the template file `Makefile.in'. When it does this, it will incorporate makefile fragment files from the `config' directory, named `t-TARGET' and `x-HOST'. If these files do not exist, it means nothing needs to be added for a given target or host. Examples... <pre> configure prefix=/PROGDIR --build=i686 --host=i686 --disable-nls configure prefix=/PROGDIR --build=i386 --host=i386 --disable-nls --without-opengl --without-star --disable-sdltest configure LDFLAGS="-nix" --prefix=/PROGDIR --build=i386 --disable-nls --without-x --without-pic --disable-shared GREP=bin: --enable-client=sdl --disable-server --disable-sdltest --with-sdl-prefix=development:include/SDL </pre> to create a Makefile but if it does not work, look at the Hints section below ==EDITING CONFIGURE to suit AROS== Take a look at Fishy's tutorial [http://web.archive.org/web/20111107002757/http://fishys-house-of-aros-fun.webs.com/apps/blog/show/2651598-aros-porting-guide first] dir ../ unix moving back a directory or two dir / amiga equivalent When the Makefile is created, whilst in the unix shell, type in make -f Makefile to create the program... ===CREATING MAKEFILE from a blank text file=== ====Generic template makefile (not to be used)==== which requires multiple copies of .c .o files <pre> CC = gcc #CC = g++ #AS = nasm -f coff #AR = ar LDFLAGS = -s FLAGS = -I. -Icpu -Iaros -Wall -march=pentium -fomit-frame-pointer LIBS = -lz -lm -LDevelopment:lib #LIBS = -lSDL_net lSDL_ttf -lSDL_mixer -lSDL_image -lpng -ljpeg -lz -lvorbisfile -logg -lSDL #LIBS = -lz -lm -LDevelopment:lib -lglu -lglut -lgl -lSDL_mixer -lSDL_image -lpng -ljpeg -lz -lSDL EXE = name OPTS = -O2 # @echo "Building source files..." $(CC) $(FLAGS) $(OPTS) -c src/.c -o obj/.o $(CC) $(FLAGS) $(OPTS) -c src/.c -o obj/.o #$(CC) $(FLAGS) $(OPTS) -c src/.cpp -o obj/.o #$(CC) $(FLAGS) $(OPTS) -c src/.cpp -o obj/.o @echo "Making executable..." $(CC) $(LDFLAGS) $(FLAGS) -o $(EXE) obj/.o $(LIBS) @echo "Done!" </pre> Remove # from CC = g++, if g++ compiler needed. Remember to put # it in front of CC = gcc. # at the start acts as a comment line and are not processed. Similarly, remove/add # in the LIBS part to activate simple command line compiling, simple SDL compiling or openGL compiling respectively. Replace name with the program title in EXE part. Then add various .c (compiling with gcc) or .cpp (compiling with g++) source code you want to compile and .o also <pre> $(CC) $(FLAGS) $(OPTS) -c src/main.c -o obj/main.o </pre> Finally, collect all the .o for the final line <pre> $(CC) $(LDFLAGS) $(FLAGS) -o $(EXE) obj/main.o main2.o etc.o $(LIBS) </pre> [http://archives.aros-exec.org/index.php?function=browse&cat=development/utility MakeTools] should be looked at also. <pre> CC = gcc CFLAGS = -O LDFLAGS = -lSDL_image -lpng -ljpeg -lSDL_ttf -lfreetype2 -lSDL_mixer -lvorbisfile -lvorbis -logg -lSDL -lgl -lglu -lz -lstdc++ -lm OBJS = part1.o part2.o main.o # $(OBJS) will look above for list of .o and then use the statements below to see what to do with them myprogram: ${OBJS} ${CC} -o myprogram ${CFLAGS} ${OBJS} $(LDFLAGS) #-------------------------------------------------------- part1.o: part1.c part1.h header.h ${CC} ${CFLAGS} -c part1.c part2.o: part2.c header.h ${CC} ${CFLAGS} -c part2.c main.o: main.c header.h ${CC} ${CFLAGS} -c main.c clean: rm -f myprogram ${OBJS} @echo "all cleaned up!" </pre> ====Better Makefiles==== Just use the one that suits you. <pre> #Simpler version suffices for most small-scale projects #DEPS is needed to recompile hellomake.c with changed hellomake.h CC=gcc CFLAGS=-I. DEPS = hellomake.h # gcc, $(CC) and rm need to be TABbed to work with make # macro DEPS, which is the set of .h files on which the .c files depend %.o: %.c $(DEPS) # -o $@ compiler output into file named on the left side of hellomake: below ie hellomake # the $< is the first item in the dependencies list #DEPS $(CC) -c -o $@ $< $(CFLAGS) #putting the object files--hellomake.o and hellofunc.o in dependency list #make knows it must first compile the .c versions individually, and then build the executable hellomake hellomake: hellomake.o hellofunc.o gcc -o hellomake hellomake.o hellofunc.o -I </pre> <pre> CC = gcc CFLAGS = -O2 -I/include LDFLAGS = -lSDL_image -lpng -ljpeg -lSDL_ttf -lfreetype2 -lSDL_mixer -lvorbisfile -lvorbis -logg -lSDL -lgl -lglu -lz -lstdc++ -lm #----------------------------------------------------------------------------- OBJS = part1.o main.o program: $(OBJS) $(CC) $(OBJS) -o $@ $(LDFLAGS) $(STRIP) --strip-unneeded --remove-section=.comment $@ #----------------------------------------------------------------------------- part1.o: part1.c part1.h @echo " Compiling $*..." @$(CC) $(CFLAGS) $*.c main.o: main.c header.h @echo " Compiling $*..." @${CC} ${CFLAGS} $*.c clean: rm -f myprogram ${OBJS} @echo "all cleaned up!" </pre> <pre> # Template for a simple generic Makefile # CC = i386-aros-gcc # CPP = i386-aros-gcc -E # CXX = # CPPFLAGS = # CXXFLAGS = CFLAGS = (cflags) LDFLAGS = (ldflags) TARGET = (final-file-name) OBJECTS = file1.o file2.o file3.o LINKS = file1.c file2.c file3.c # XTRAOBJ = # # rules # all: $(TARGET) $(TARGET): $(OBJECTS) $(XTRAOBJ) $(CC) $(OBJECTS) $(XTRAOBJ) $(LDFLAGS) -o $(TARGET) %.o: %.c $(CC) $(CFLAGS) -c $< -o $@ # # eof # Cycloid Makefile Example # OBJ = window2.o # # w.exe: $(OBJ) # $(CC) $(CFLAGS) -o $@ $^ $(ARCHIVE) $(LIB) # # window.o: window2.c # # $(CC) $(INCL) -c window2.c </pre> <pre> # .h files in an include directory IDIR =../include CC=gcc CFLAGS=-I$(IDIR) # .o files into a obj subdirectory and some local libraries in lib directory ODIR=obj LDIR =../lib macro defined for any libraries you want to include, like mui library -lMUI LIBS=-lMUI _DEPS = hellomake.h DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS)) _OBJ = hellomake.o hellofunc.o OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ)) $(ODIR)/%.o: %.c $(DEPS) $(CC) -c -o $@ $< $(CFLAGS) hellomake: $(OBJ) gcc -o $@ $^ $(CFLAGS) $(LIBS) # .PHONY rule keeps make from doing something with a file named clean .PHONY: clean # cleaning up your source and object directories clean: rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ </pre> <pre> #simple makefile CC=gcc CFLAGS=-O2 -s -DNO_INLINE_STDARG -I./api/ -I../api/ -I../modules/api/ -I../amide/modules/api/amide/ LDFLAGS=$(CFLAGS) -nostartfiles -nodefaultlibs -lamiga -lstdc.static -lgcc EXE=plugins/test.plugin # Objects OBJS = StartUp.o \ LibInit.o \ sasc_module.o all: $(EXE) clean: rm -f *.o $(EXE) $(EXE): $(OBJS) echo Making $@.. $(CC) -o $(EXE) $(OBJS) $(LDFLAGS) </pre> ==Hints for correcting errors== *undefs about std:: and operators mean that you need to use or g++ , or if you use gcc, then add to -lstdc++ *undefs about sdl_wav mean -lsdl_mixer, *undefs about AROSMesa mean -lgl, Link order is important, so you can't for example firstly do -lgl, and then -lsdl. As sdl wants gl, you will need to do -lsdl -lgl, and the same for all the other libs : include one after another when undefs happens. -lSDL_image -lpng -ljpeg -lSDL_ttf -lfreetype2 -lSDL_mixer -lvorbisfile -lvorbis -logg -lSDL -lgl -lglu -lz -lstdc++ -lm There are undefined symbols in 'sasc.module': __PROGRAM_ENTRIES__symbol_set_handler_missing __LIBS__symbol_set_handler_missing remove the -nostartfiles argument from command line the missing symbols are part of AROS automatic startup handling. Possibly manually adding -llibinit could fix the missing symbols. add -nodefaultlibs like this: LINK := $(OPTIMIZE) -s -nostartfiles -nodefaultlibs should remove all automatically added libraries and now you will have to add them manually $(CC) $(LINK) -o $@ $(O_FILES) -lamiga -lstdc.static -lgcc <pre> #simple makefile CC=gcc CFLAGS=-O2 -s -DNO_INLINE_STDARG -I./api/ -I../api/ -I../modules/api/ -I../amide/modules/api/amide/ LDFLAGS=$(CFLAGS) -nostartfiles -nodefaultlibs -lamiga -lstdc.static -lgcc EXE=plugins/test.plugin # Objects OBJS = StartUp.o \ LibInit.o \ sasc_module.o all: $(EXE) clean: rm -f *.o $(EXE) $(EXE): $(OBJS) echo Making $@.. $(CC) -o $(EXE) $(OBJS) $(LDFLAGS) </pre> and LoadModules function calls that function from main.c, case of AROS it is best to use portable macros to make these calls <pre> mod_class =AROS_LC0(void *, AmIDE_API_GetClass, struct Library *, (AmIDE_API_Base), 5, AmIDE_API ); </pre> #include <aros/libcall.h> Additionally, most AROS code depends on the library bases being opened automatically so you may need to add a link library, libauto (-lauto). Some systems (so it's down to the compiler to provide it) don't have working libauto in which case you need to open the library bases manually. AROS OS 64Bit GCC 10+ enforces strict checks on void variables so gcc output-> error: variable or field __ret declared void. AROS_LC0NR variant of macros to handle void return type (NR stands for No-Return) with more [http://www.aros.org/es/documentation/developers/app-dev/portable.html here] [http://aros.sourceforge.net/documentation/developers/porting.php Hints can be found here] Be warned that these links apply to using Linux to compile code and not native but may be useful. <pre> CONFIGURE ERRORS Error : no acceptable C compiler found in $PATH Solution : add CC=gcc or CC=g++ after configure Error : no acceptable grep could be found in /Development/bin: Solution : add GREP=bin: to configure line Error : gtk-mui library sequence Solution : gcc -o test addbutton.c\ -lglib-2.0 -lgtlayout -lgthread-2.0 -lgmodule-2.0 -lgobject-2.0 -lgtk-mui -lglib-2.o -liconv -lmui -lthread Error : VARIABLE not within scope Solution : add headers like... #include <libraries/mui.h> #include <proto/muimaster.h> or #include <string.h> etc Error : malloc.h no such file or directory Solution : malloc is contained within <aros/stdlib.h> Error : SDL.h no such file or directory Solution : #include SDL/SDL.h needed at top of .c file or -IDevelopment:include/SDL to the command line Error : Solution : Error : IMG_Load in -lSDL_image ... cannot find libSDL_image Solution : ?? Error : pow in -lm - 'case' unmatched - math.library (-lm) appears broken Solution : ?? Error : Solution : Error : Solution : MAKE ERRORS Error : *** missing separator. Stop. Solution : Make commands like gcc $(CC) or rm need to be TABbed in and not use spaces Error : Solution : Error : Solution : Error : Solution : COMPILING ERRORS Error : expected '=' ';' "asm" or '__attribute__' before '{' Solution : look at previous lines for missing/extra ; (like in defines) or missing } or forgot to #include something.h. Use gcc -E to check Error : request for member 'something' in function not a structure or union Solution : using b.x = 12 (usually arrays); when it should be b->x (usually structs) or (*b).x, .h needed, Error : 'something' undeclared (first use in this function) Solution : 'something' been declared at start of function, .h needed or link library needed -lmui etc., Error : there are undefined symbols in program Solution : /* around these symbols' */ until you work out if they are needed or can be deleted Error : there are undefined symbols in <program-name> or memcpy strndup first Solution : linker library not included -lz -lSDL or -lGL etc or <string.h> Error : expected specifier-qualifier list before 'USHORT' Solution : change all references of USHORT into UWORD (SHORT into WORD) Error : expected declaration specifiers or '...' before 'USHORT' Solution : replace USHORT with UWORD (SHORT into WORD) Error : field 'name' has incomplete type Solution : Error : expected ')' before 'type' Solution : Error : invalid conversion from 'ULONG*' to 'IPTR*' Solution : most amiga like OS's return ULONG values or use ULONG TAGS but 64bit AROS needs IPTR used for compatibility Error : dereferencing pointer to incomplete type Solution : Error : If crackly break-up noise found in SDL sound Solution : try to find where the number of samples for the buffer is set in the source and increase it (double it at least). This solves many sound issues with SDL programs. The buffer was set to 1024, now set it to 4096. Error : initializer element is not constant around TAG_DONE); Solution : header(s) <utility.h> and <proto/utility.h> need to be added Error : no i386-sdl-config Solution : use --build=i686 instead of --build=i386 Error : functions not found at final linking: SDL_CondWait, SDL_CondSignal, SDL_CreateCond Solution : find them in the SDL_cond_aros.c file in the cdxlplay-sdl source http://www.a500.org/downloads/video/ Error : crash glutGet((GLenum)GLUT_ELAPSED_TIME); Solution : The glutInit function is needed, replace with by SDL_GetTicks() Error : undefined symbols: recv, connect, inet_pton, socket, select, send, inet_ntoa Solution : LDFLAGS : -lSDL_net -lSDL with #include <proto/bsdsocket.h> (or <proto/socket.h>) in all files using SDL_net Error : SDL is not built with CDROM support. Solution : Look for SDL_INIT. It can look something like this: if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 ) change it to: if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO|SDL_INIT_JOYSTICK ) == -1 ) That includes all the init routines available in SDL, minus the CD one. Error : Video mode set failed: OpenGL support not configured Solution : 'sdl-config --libs' is fine for most SDL uses, but with GL it needs to be replaced with "-lgl" Error : Solution : Error : Solution : RUN TIME ERRORS Error : Solution : Error : Solution : Error : Solution : Error : Solution : Error : Solution : Delinting (removing warning messages) 64bit compatibility - MUIA_Application_Copyright, _(MSG_AppCopyright), + MUIA_Application_Copyright, (IPTR)_(MSG_AppCopyright), - io->io_Unit = (struct Unit *)unitnum; + io->io_Unit = (struct Unit *)(IPTR)unitnum; Clean up - ULONG signals; + ULONG signals = 0; - while((t = LibNextTagItem(&tagList))) + while((t = LibNextTagItem((struct TagItem **)&tagList))) - while ((tag = LibNextTagItem(&msg))) + while ((tag = LibNextTagItem((struct TagItem **)&msg))) - const struct TagItem *tstate = msg->ops_AttrList; - struct TagItem *tag; + struct TagItem *tag, *tstate = msg->ops_AttrList; - sprintf(buf, "SYS/printer%d.prefs", unit); + sprintf(buf, "SYS/printer%d.prefs", (int)unit); - STRPTR _return = NULL; + CONST_STRPTR _return = NULL; - return (CONST_STRPTR)_return; + return _return; </pre> ==Hints: Porting software from...== ===AmigaOS=== The right form of the main() function is <pre> int main(void) { ... return retval; } or int main(int argc, char **argv) { ... return retval; } </pre> (Old code has often "void main()" or no return type at all) For retval you can either use 0, EXIT_SUCCESS or EXIT_FAILURE (ANSI-C) or ADOS return codes which I don't know off-hand. First turn anything that ending in _proto.h <pre> #include <dos/dos_proto.h> to #include <proto/dos.h> </pre> and if you want it more portable, then try <pre> #ifdef AROS #include <proto/dos.h> #else #include <dos/dos_proto.h> #endif </pre> Include function prototypes for shared libraries from proto e.g. #include <proto/graphics.h> instead of #include <clib/graphics_protos.h> If the compiler complains about wrong type in a line like struct Library *GfxBase you have to look up the right type in the header, e.g. in includes/proto/graphics.h #include <proto/library_name.h> (replacing with correct name) should pull in the necessary info for automatic opening/closing of CORE libraries to work with basic applications which are written as DOS and Workbench/Wanderer launched processes. Others like mui have to be specified (-lmui in the gcc command line). It looks like you are still including from clib. You either have to include from proto or you have to link with -lexec -lgadtools, etc. There are undefined symbols in 'inctst': U AllocMem U FreeMem Adding -lexec removed the errors. <pre> There are undefined symbols in 'a.out': SetFont CloseFont OpenFont </pre> try -lgraphics or #include <proto/graphics.h> or #include <defines/graphics.h> or #include <clib/graphics_protos.h> <pre> Include sys/types.h before netinet/ip.h Include <netdb.h> first before rest of your network includes </pre> Most AROS C/C++ Compilers can open and close the libraries for you as part of the startup code. As long as you have the protos included in the headers and the appropriate compiler options specified, the compiler will take care of opening any used libraries for you. The library header source is in principle like AOS 68k too, with Resident struct, functable and so on. Except AROS has its own set of macros for functions which get parameters in registers. The AROS_LH#? and AROS_UFH#? stuff. You should be able to use contrib/mui/classes/nlist/commonaros/mccheader.c from AROS contrib sources as a hint. But always remember, that coding for AROS is not coding for m68k Amiga. Much is different here and coding AROS in C means searching hundreds of include files for macros. And AROS source code is partly useless for an external newbie developer, as AROS has a deeply integrated build system which hides important parts from the implementing developers, e.g. a shared library consists only of its methods, the rest (Romtag, Jumptable etc.) is hidden in the AROS build system. wbstart.library isn't ported indeed but its usage is depreciated and you are advised to convert its calls to use workbench.library/OpenWorkbenchObject() (which should be easy). A temporary quick trick is to use CLI callings on C:Open which will launch programs using Workbench (using this very function). It can even be used with arguments which are passed as workbench arguments (ie like multi-clicked files). ====Programming languages==== As long as no assembler code is being used in the program, compiling a C program written for plain AmigaOS up to version 3.1 should be possible on AROS without any changes to the source code. (That presumes your AROS is using a 32bit big-endian CPU, like the original Amiga computer.) (Please note that '''AROS is still beta and incomplete''', and might lack some functions from AmigaOS API. See [[Aros/Developer/Docs#Status of AROS implementation|Status of AROS implementation]] for more on this.) ====Data types and sizes / little endian / big endian==== Some of the first things to consider is the actual size of your C data types, and in your uses of binary files (IFF for example) paying attention to reading and writing with portability to 64bit and little-endian CPUs as well as the classic mc680x0 or powerpc cpus used by Amiga OS. * Warning signs is casting between char * and WORD/LONG/short/int etc., or any kind of pointer arithmetic, as well as any functions that read/write binary file formats (if they read character by character and/or does things similar to what I mentioned above, they are likely to be ok, if they read a chunk of memory in and treat it as a struct immediately then it will almost certainly fail). * Endianness issues need to be fixed and there are a lot of them (reading/writing binary files, writing data into graphics frame buffers). Also network stack, file system, hardware. Pretty much any time you have to deal with external data, you have to worry about endianness. There are C #define macros to handle writing/reading the correct endianness and flipping the ordering when necessary. * all LONG/ULONG/APTRs need to be checked if they need to be replaced by IPTR (e.g. relying on TagLists) [we should probably have a chart showing sizes/endian used by Manx/sas/dice C on a mc68000/68030 vs today's PPC/i386/x86_64 AROS options here along with some GCC source code to show how to read/write binary files correctly under AROS running on differing endian CPUs] ====Screens==== Amiga chipset-graphics-based screens were generally done in a planar format 16/32-colors max for ECS hires/lores modes respectively and 256-colors for AGA. [a chart of common amiga screen modes should go here] Methods that worked well for the relatively low-resolution planar Amiga displays may be suboptimal for chunky and true color screens that are common today. [pointer to examples should go here] Amiga screens could be of differing resolution, which could be dragged up and down to reveal another, so some applications were written with differing resolution screens, say for a control panel at one resolution and another for the "display" visible at the same time stacked vertically. This may not make sense with today's chip sets or wide-screen displays. Opening multiple screens that vary in scan rate can confuse displays (monitors or projectors) that might take several seconds "calibrating" every time the user decides to change which public or private application screen they want to view. Defaulting to the user's preference for Wanderer (workbench) for screen mode is probably better than having a predefined mode hard-coded into your application. ====Fonts==== AmigaOS 3.1 also shipped with some nice disk fonts that are not currently available under AROS, so you should be careful about having any diskfont hard-coded as a default into your program. The ROM font "topaz" should be ok. AROS fonts (as of 2010-03-10): *arial.font *dejavusansbold.font *dejavusansboldoblique.font *dejavusansbook.font *dejavusanscondensedbold.font *dejavusanscondensedboldobl.font *dejavusanscondensedcondens.font *dejavusanscondensedoblique.font *dejavusansextralight.font *dejavusansmonobold.font *dejavusansmonoboldoblique.font *dejavusansmonobook.font *dejavusansmonooblique.font *dejavusansoblique.font *dejavuserifbold.font *dejavuserifboldoblique.font *dejavuserifbook.font *dejavuserifcondensedbold.font *dejavuserifcondensedboldob.font *dejavuserifcondensedconden.font *dejavuserifcondensedobliqu.font *dejavuserifoblique.font *fixed.font *stop.font *ttcourier.font *Vera Mono Bold.font *Vera Mono Bold Italic.font *Vera Mono.font *Vera Mono Italic.font *Vera Sans Bold.font *Vera Sans Bold Italic.font *Vera Sans.font *Vera Sans Italic.font *Vera Serif Bold.font *Vera Serif.font *XEN.font ====GUI Toolkits==== =====Gadtools===== The order of the fields in struct Node which is currently different than on AOS (will be changed in ABI V1). struct Node has currently the following order: <pre> struct Node { struct Node * ln_Succ, * ln_Pred; char * ln_Name; UBYTE ln_Type; BYTE ln_Pri; }; </pre> =====MUI===== '''MUI''' - AROS' preferred GUI toolkit is Zune, a reimplementation of MUI 3.x, thus MUI 3.x code will work unchanged under AROS. MUI 4.x will need adapting or wait for the following [http://www.power2people.org/projects/profile/54 bounty] to be started. =====ClassAct===== '''ReAction/ClassAct''', a GUI toolkit for AmigaOS, is not available for AROS. It has been made part of AmigaOS 3.5 and higher. Programs that use ReAction might need considerable rework, preferably to use Zune (or: MUI), AROS' GUI toolkit. =====BGui===== '''bgui''' is available as part of the "contrib" archive, thus included in all current AROS binary distributions. [We could use a chart comparing gui options for developers here.] ====C/C++ Compilers==== GCC/G++ is the primary C compiler supplied with AROS. Amiga programs making use of other compilers' (SAS/C, Maxon C, ...) specific functionality might need some rework. You'll probably want to write makefiles that can run either hosted or native, so any AROS user can get them compiled and running on their machine. In a hosted environment the shell will most likely use UNIX semantics like cp==COPY ../==parent directory, and all file names will be case sensitive for your makefile and inside your C source code files (example: #include "myFile.h" != #include "MyFile.H"). Under AROS the makefile may use Amiga shell command semantics (copy #? progdir:prefs)or it may be using a UNIX shell ported to AROS, and the AROS environment, and like AmigaOS 3.1 may not care about case sensitivity of file names. We can't use the SLOWSTACKTAGS macros for getting ULONG values from a variadic list. ===== SAS Lattice C Compiler===== SAS/C was one of the more popular compiler packages back when AmigaOS 3.1 was released, it supported various keywords such as __chip for using chipram, and CPU-related register arguments that the current AROS GCC does not. The makefiles will have to be translated from SMAKE to GNU Make and some of the headers will have to be translated from SC to GCC. Pragmas were used on ancient C compilers like SASC. Include from "proto", e.g. #include <proto/workbench.h>. Look if there are headers which include from "clib". Change them to "proto", too. You can ignore warnings like "suggested parentheses..." or incompatible pointer types. Some types and names of defines have changed (SHORT/USHORT -> WORD/UWORD). -linput -lutility -lintuition -lrexxsyslib -lconsole -lgraphics -ldos -lexec strmfp, stcgfe, stcgfp, stcgfn and stci_d are SAS/C / Lattice function that do not exist under gcc. They have to be reimplemented. tolower and toupper was found once I've included ctype.h in the source code. Sometimes missing symbols come from missing include files. Those are macros like toupper—not real functions, and the C preprocessor needs the include definition for the macro. If you want your characters to be unsigned you need to put unsigned into the variable type. If you want them to be signed, put signed in the variable type. If you don't put either, you may get unexpected results. Sometimes you need wrappers for functions which aren't part of ANSI C. SAS/C allowed to use a type before it was defined => change the order or use forward declaration. Use AROS macros for Hook functions as explained here: http://aros.sourceforge.net/documentation/developers/app-dev/portable.php#hooks There might be more if you are porting system software (libraries, interrupts etc.) Just start and try to find the reason for warnings and errors. Generally when porting sources, if a header doesn't exist in AROS, wrap it with an #if or #ifndef statement and see what symbols, structure definitions, etc. aren't found. Then you can look through the AROS includes to see if the missing symbols, etc. are implemented in another place, or if you have to make your own compatible include file with those defined. For libraries you might want to look at the AROS source-tree to see how others have done it using things like [http://aminet.net/package/dev/gcc/sfdc sfdc], genmodule, etc. * SAS/C included a ton of non-standard functions in its C library. Alternative versions of these can generally be found online, and for example YAM includes some of them in their sources, depending on license working around this is easy (none of these functions are big/difficult to re-implement if needed). * SAS/C is very liberal in some of the things it accepts. This causes problems particularly for vbcc (not so relevant for AROS) but some things also for gcc, particularly in terms of type coercion and (lack) of forward declarations. * SAS/C has a multitude of extensions targeting AmigaOS, such as non-standard 68k focused register declarations. These must either be removed or worked around by defining preprocessor macros that expand to nothing or a suitable replacement. * The SAS/C smakefiles are a totally non-standard syntax. * The general caveats of AmigaOS vs. AROS include files apply - many paths can be expected to be different. * there might be endian issues * you'll get a lot of compiler warnings. Some of them are harmless (e.g. "parenthesis suggested ..."). Others are dangerous (e.g. "variable xxx may be undefined") * for some specials like callback hooks you'll have to use AROS macros. * Use texteditor or some tool to replace all "ULONG" with "IPTR" and "LONG" with "SIPTR" in the sources. * Fix (change IPTR/SIPTR back to ULONG/LONG) the few places which really rely on ULONG/LONG being exactly 32 bit. That's for things like pixel (ARGB) buffers, structs written/read to disk, colormaps, but probably little else. This is the [http://aros-exec.org/modules/newbb/viewtopic.php?start=30&topic_id=5705&viewmode=flat&order=ASC&type=&mode=0 code] that I use in diskimage.device for converting a BSTR to a CSTR <pre> LONG CopyStringBSTRToC (BSTR src, STRPTR dst, ULONG dst_size) { #ifdef __AROS__ STRPTR ptr = AROS_BSTR_ADDR(src); ULONG ln = AROS_BSTR_strlen(src); #else UBYTE *ptr = BADDR(src); ULONG ln = *ptr++; #endif if (ln > (dst_size-1)) ln = dst_size-1; memcpy(dst, ptr, ln); dst[ln] = 0; return ln; } </pre> Some blankers{{typo help inline|reason=similar to blinkers|date=October 2022}} are missing the symbol "custom". They have (as documented in the OS3.9 RKM) "extern struct Custom custom;". 'Custom' is a struct that maps the m68k Amiga AGA/OCS/ECS registers. Only build those for amiga-m68k, and you'll be fine. =====Maxon Hisoft C===== =====Dice C===== =====North C===== * RAWKEY: replaced with IDCMP_RAWKEY: * ModifyIDCMP(win,FLAGSON) replace with ? ===MorphOS=== ====Assemblers/ Disassemblers==== ADis, which reads binaries into memory hunk by hunk to disassemble them, and then just treats it as an array of short. The "right" way would be to treat it as a char *, and do (arr[0] << 8) + arr[1]. I wanted to use it to cross-disassemble M68k programs, but gave up and went with Ira instead because it was so pervasive. ===Linux Console Apps=== On AmigaOS this is done by libc on every I/O operation. Just AROS libs lacks this. Resources allocated by libc (malloc()ed memory, fopen() ed files, etc.) are safely reclaimed at exit(). libc tracks this internally. If your program additionally uses some AmigaOS API, it usually installs exit handler (I don't remebmer how), or disables Ctrl-C checking by redefining __chkabort() function. You have to explicitly check for it on AROS (and AmigaOS). The reason for this is that there's no safe way for the OS to kill an app and reclaim all resources on AmigaOS and derivatives (since an app can have "handed off" memory and other resources to other tasks). This is an example from the autodocs for SetSignal: <pre> #include <libraries/dos.h> /* Check & clear CTRL_C signal */ if(SetSignal(0L,SIGBREAKF_CTRL_C) & SIGBREAKF_CTRL_C) { printf("CTRL-C pressed!n"); } </pre> It is compiler dependent. It's safer to just do the SetSignal()-based check. If you want a shared library, recommend getting linux-hosted aros building (use the gimmearos.sh script) and then look at the other library sources found in AROS/workbench/libs for examples of how its done. If it were just a linker library, you can just compile the .c files with -fno-stack-protector (needed under aros-sdk cross compiler under linux, native aros gcc might not need that), etc. and join the .o files into a lib-yournamehere.a file with ar and ranlib them. ===SDL=== SDL_image may need -ljpeg -lpng -lz SDL_mixer needs -lSDL_mixer -lvorbisfile -lvorbis -logg (in this order) First thing to test with SDL sound under AROS is to increase the buffer. In all applications had needed this to obtain good sound output. In most cases it would certainly mean that you have to increase the value of SYSSND_MIXSAMPLES. Usually multiplying this value by 2 or 4 gives good results. You should also check the value of the obtained structure. It is not sure that AROS supports AUDIO_U8 and you might have reverted to AUDIO_U16. In this case sound will of course be distorted. from [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=2533&forum=2&post_id=45301#forumpost45301 here] Further tests with buffers using code from [http://www.kekkai.org/roger/sdl/mixer/ here], and this is the result I've noted: "a quick test compiling with 1024, 2048 or 4096 gave interesting results: 1024 - sounds are more responsive to key-events but if you quickly move the "game-window" around the screen you can hear sound glitches. 2048 - No big difference noticed in responsiveness and now no glitches moving the window around, anyway the fx-sound sample plays with some hiss-click glitches. 4096 - No hiss-click and no glitches moving the window BUT you can see that the responsiveness is decreased. Trying this code then with original xRick 8bit samples gives good sound results, and even using 1024 bytes buffer the sound doesn't glitch when moving window" Seems to me that buffer depends a lot on responsiveness you need, overall game load and also what kind of sound samples you're using (of course the lower is the bit-encoding and frequency, the smaller you can use as buffer). SDL_GetTicks just disable m_fLastTime = float(SDL_GetTicks())/1000; in 2 places of sdlapp.cpp and add your own code at the end: <pre> Ellapsed_Time = SDL_GetTicks() - Last_Time; if (Ellapsed_Time < 20) /* 20 ms target => 50FPS */ { SDL_Delay(20 - Ellapsed_Time); } </pre> Maybe SDL_GetTicks works a bit wrong by some reasons in aros's SDL, right ? (because if the same code works fast on os4/mos/win32/anything-else), then it mean that something wrong with SDL_GetTicks then .. PS : SDL_GetTicks() isn't causing any trouble, its a basic SDL function that is used in almost all SDL applications. int CSDLApplication::Run() in sdlapp.cpp and bool CMySDLApplication::FrameMove() in Armygaem.cpp In initial-code Render3DEnvironment is called continuously and only FrameMove is updated at 50fps, Render() and SDL_GL_SwapBuffers() are called even if nothing has moved. Calling the render() functions and SDL_GL_SwapBuffers(), too often is for me the root cause. A correction to OpenGL implementation would only be a safeguard to prevent stupid application from crashing or slowing down the system. crash on exit is certainly due to the application not freeing any resources before exiting. ===Writing ROM-able code=== Code in AROS modules should be written in a way that makes it suitable for embedding into a ROM, FlashRAM or other kinds read-only memory. The following coding style rules are meant to make it possible. Of course they apply to all Kickstart modules and to code that may be made resident, shared or linked to other modules. ROM modules must have no .data and .bss sections. Basically, we need to get rid of all non-const global data. The real Amiga Kickstart proves that it's both possible and easy to achieve this. If you encounter an external variable (static or not) that is modified by the code, try to get rid of it or move it into the base of the library/device (or in the device node of your handler or in the userdata of your class). The above applies to library bases as well. If you are writing a library, put the bases of other libraries into your own library base structure. Boopsi classes can store library bases in their class private data. Try to set the static and const attributes to all your global data. You can also use the CONST_STRPTR and CONST_APTR types defined in <exec/types.h>. Using static const allows the compiler to move data into the .text (AKA code) segment. If you need to pass these globals to another function, try to change its prototype to use const too. ===Hooks and SDI=== A hook is a custom function you write in order to be able to handle a specific situation that arises from intercepting the main code (like processing a message). The function must be designed to accept three arguments, whose order and type is given. * the first parameter (A0) contains the pointer to your hook, not to your window * the 2nd Parameter points to the Object which causes this action, this isn´t your window but it´s the Object which was pressed (it´s always the Object which was connected to the Hook (=1st Parameter of DoMethod) * then give 5 as number of Parameters for MUIM_CallHook, but´s 4 (=number of all Parameters in DoMethod after the Count Parameter) <pre> AROS_UFH3S ( void, MyHookFunction, AROS_UFHA(struct Hook * , hook, A0), AROS_UFHA(Object * , obj, A2), AROS_UFHA(ULONG * , params, A1) ) </pre> params is an array but IPTR should be correct. Then you can access your parameters... <pre> app = (Object *) *params++; window2 = (Object *) params++; </pre> <pre> The important thing about hook functions is that the parameters must be given in the order A0, A2, A1. And not to leave out parameters even if they are unused by the hook function. For initial quick&dirty ports one can even simply defines things like "__saveds", "__asm", "__regargs", "__stdargs", "register ..." to nothing. For library functions it's the same (with library base as last param). InitLib: libbase(d0), seglist(a0), sysbase(a6) OpenLib: version(d0), libbase(a6) CloseLib: libbase(a6) ExpungeLib: libbase(d0), libbase(a6) OpenDev: ioreq(A1), unitnum(d0), flags(d1), devbase(a6) CloseDev: ioreq(a1), devbase(a6) </pre> see [http://utilitybase.com/forum/index.php?action=vthread&forum=3&topic=1495 here] The AROS asm call and lib call macros require param type (like "struct Hook *") and param (like "myhook") to be passed in two different arguments. Not in a single one. Converting is easy. Adding some "AROS_" prefix plus some commas. Additionally in the hook functions and dispatcher functions "HOOK_INIT" / "HOOK_EXIT" / "DISPATCHER_INIT" / "DISPATCHER_EXIT" must be used (in case of AROS mapping to AROS_USERFUNC_INIT/AROS_USERFUNC_EXIT). To force procedure parameters to use registers (like a0) in GCC Since C calling convention on some machines (like 68k or x86) means params are passed on stack your C function must have params in correct order (Hook, object, msg) and not leave out params if they are unused by the function especially if it's the middle param (object). ULONG hook_function(REG(a0, struct Hook *hook), REG(a2, APTR object), REG(a1, APTR message)) In short when using HookEntry you initialize hooks like this: <pre> STATIC ULONG hookfunc(struct Hook *hook, APTR obj, APTR msg) { /* ... *// } #if defined(__amigaos4__) hook->h_Entry = hookfunc; #else hook->h_Entry = &HookEntry; hook->h_SubEntry = hookfunc #endif </pre> If you are not using SDI headers this is the most universal method which works on OS3, OS4, AROS and MorphOS with every compiler and architecture. Those dispatchers are usually taken as argument for MUI_CreateCustomClass(), which has: <pre> #if defined(__MAXON__) || defined(__amigaos4__) cl->cl_Dispatcher.h_Entry = (HOOKFUNC)dispatcher; #else cl->cl_Dispatcher.h_Entry = (HOOKFUNC)metaDispatcher; cl->cl_Dispatcher.h_SubEntry = (HOOKFUNC)dispatcher; #endif </pre> metaDispatcher: <pre> #ifdef __AROS__ AROS_UFH3(IPTR, metaDispatcher, AROS_UFHA(struct IClass *, cl, A0), AROS_UFHA(Object *, obj, A2), AROS_UFHA(Msg , msg, A1)) { AROS_USERFUNC_INIT return AROS_UFC4(IPTR, cl->cl_Dispatcher.h_SubEntry, AROS_UFPA(Class *, cl, A0), AROS_UFPA(Object *, obj, A2), AROS_UFPA(Msg , msg, A1), AROS_UFPA(APTR , cl->cl_Dispatcher.h_Data, A6) ); AROS_USERFUNC_EXIT } </pre> What confuses me is that our own macros have registers: <pre> #define BOOPSI_DISPATCHER(rettype,name,cl,obj,msg) \ AROS_UFH3(SAVEDS rettype, name,\ AROS_UFHA(Class *, cl, A0),\ AROS_UFHA(Object *, obj, A2),\ AROS_UFHA(Msg , msg, A1)) {AROS_USERFUNC_INIT </pre> Maybe there is a difference between MUI and BOOPSI when it comes to dispatchers and SDI DISPATCHER can only be used for MUI. AROS's MUI_CreateCustomClass() moves the dispatcher to h_SubEntry and uses something like HookEntry for h_Entry. There we don't have to care about registers. BTW: SDI's hook macros *are* wrong for AROS. <pre> HOOKPROTONHNO(TestFunc, void, int *param) { puts("Foobar"); } MakeHook(TestHook, TestFunc); </pre> expands to: <pre> static void TestFunc(__attribute__((unused)) struct Hook *_hook, __attribute__((unused)) APTR _obj, int *param) { puts("Foobar"); } struct Hook TestHook = {{0L, 0L}, (HOOKFUNC)TestFunc, NULL, 0L}; </pre> That works only by accident on i386-AROS (because of stack parameters). But there I *know* how to fix it and will soon send an update to you. <pre> #elif __AROS__ #define MakeHook(hookname, funcname) struct Hook hookname = {{NULL, NULL}, \ (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL} #define MakeHookWithData(hookname, funcname, data) struct Hook hookname = \ {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, (APTR)data} #define MakeStaticHook(hookname, funcname) static struct Hook hookname = \ {{NULL, NULL}, (HOOKFUNC)HookEntry, (HOOKFUNC)funcname, NULL} #define ENTRY(func) (APTR)func #define DISPATCHERPROTO(name) SAVEDS ASM IPTR name(REG(a0, \ struct IClass * cl), REG(a2, Object * obj), REG(a1, Msg msg)) #define DISPATCHER(name) DISPATCHERPROTO(name) #define SDISPATCHER(name) static DISPATCHERPROTO(name) </pre> Difference is that funcname is moved to h_SubEntry. Problem are the dispatcher macros. They'll currently only work with MUI_CreateCustomClass(). If I define them like our BOOPSI macros I have a new problem: what happens if I define a function with register macros *AND* use HookEntry in h_Entry and the function in h_SubEntry? BTW: in SDI_compiler.h there is: <pre> /* we have to distinguish between AmigaOS4 and MorphOS */ #if defined(_M68000) || defined(__M68000) || defined(__mc68000) #define REG(reg,arg) arg __asm(#reg) #define LREG(reg,arg) register REG(reg,arg) #else #define REG(reg,arg) arg #define SAVEDS </pre> C++ is much more strict on types than C, this is the root of the problem. Absolutely everything should be casted, implicit conversions are not allowed at all. P.S. And casting is considered an extremely bad coding style IIRC... Those who want to develop AROS API in C++ should update their headers from a current SDK. HOOKFUNC looks now like this in include/utility/hooks.h: typedef IPTR (*HOOKFUNC)(); The prototypes have been included in "extern C" blocks, so that problems like this should be [http://aros-exec.org/modules/newbb/viewtopic.php?post_id=37123#forumpost37123 gone] ===Casts=== Casts simply put... casting through pointers, bad... casting through a union, [http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html good]*. (*exceptions apply) Hopefully someone can correct me if I'm wrong, but the main rule of thumb for avoiding these problems seems to be to not have two pointer variables in the same function that point to the same memory, but are of different type. It's actually a little more subtle than this. They can point to different types, but not when the types do not contain sub-sets of the others. i.e. <pre> struct Foo { struct MinNode Node; }; </pre> - any cast from struct Foo * to struct MinNode * is ok ... but: <pre> struct Foo { struct Foo *next; struct Foo *prev; }; </pre> - now casts from 'foo' to 'minnode' are not ok ... and worse, can be silently discarded (how that is considered polite behaviour I do not know). (and by extension, casting from List to Node are right out). I would argue that this is actually a different language - it is no longer 'C', as such, and although the spec (as far as I have been able to ascertain) actually specifies this it has never been implemented in such a way until now. It is there to provide additional optimisation opportunities ... although the whole 'we'll just silently drop code that is otherwise quite obvious' thing is rather nasty. The CellPerformance stuff really nails it all. Although I find it somewhat absurd you can cast pretty much anything through a union and it's 'ok', but using the language 'cast' exactly the same physical operation becomes 'illegal'. NEVER EVER touch buffers passed in by the user as an "input" parameter. The concept of input parameters is often implicit in the function description. For instance, the filename passed to Open() is clearly an input variable and Open() must not mess with it, even if it is going to fix it back later. Keep in mind that the buffer might be in read-only memory or shared among several instances of a resident or multithreaded program. Try to avoid host-OS calls such as malloc() and free() if you can do with AllocMem() and FreeMem(). This is because the pointer checking debug macros rely on finding the pointer within the Exec memory blocks with TypeOfMem(). SA_BackFill, (ULONG) &sbackfillhook, Please do not use ULONG's to store/cast pointers in your code. use APTR/IPTR where appropriate. ==Compiling small parts of AROS source without using Build system== [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=3475&forum=2&post_id=29123#forumpost29123 from] make stub make make install and need genmodule from [http://pagesperso-orange.fr/franck.charlet/temp/radeon.zip inside] here. Trying to build the support modules of [http://svn.berlios.de/wsvn/ignition/trunk/libs/scroller/ Ignition] with a normal Makefile: How can I get rid of these linker warnings? U __includelibrarieshandling and U __this_program_requires_symbol_sets_handling Is there something I have to care about when I create a module this way? (I have always used the build system in the past) Is there a function which must be the first in the generated module? Are you using ld directly? If so, don't do that, use the compiler's driver instead (gcc, that is) to do all the steps, final linking included. The problem arises because the linker needs to be invoked through a wrapper, which in our case is called collect-aros (it would be collect2 on other systems). You can either call collect-aros in place of ld (I wouldn't do that) or the compiler's driver (gcc, do that) as said above. Mh, hadn't noticed the makefile when I first replied and I had forgotten these symbols are actually produced by collect-aros itself. The problem arises because you are using -nostartfiles, which avoids linking with the startup file, but the startup file contains code that handles the automatic libraries opening/closing and the generic symbol sets handling. By using DFLAGS=-lgraphics -lintuition -lutility you are actually linking with stub libraries that require the automatic handling of shared libraries to be implemented. Either you avoid using these stubs or you implement the needed code yourself. You can take inspiration from the normal startup code. After re-enabling lines like #define UtilityBase cb->UtilityBase I was able to build the module without the stub libraries. ==Tutorials== See here for a [http://web.archive.org/web/20111107002757/http://fishys-house-of-aros-fun.webs.com/apps/blog/show/2651598-aros-porting-guide tutorial] SDL/MesaGL/OpenGL game frameworks. [http://msm.grumpybumpers.com/?p=64 Jumpcore Minimal] [http://lazyfoo.net/SDL_tutorials/index.php Tutorial] [http://www.monkeyfighter.com/tetris.html Amiga Tetris] [http://irrlicht.sourceforge.net/downloads.html Irrlicht 3D engine] {{BookCat}} bzg2nl2i7y1y693v8zkwuvsuojos3eo User:Sjorskingma 2 200244 4668997 4586173 2026-09-05T19:11:46Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668997 wikitext text/x-wiki <div style="background-color:#aaffff;{{text default color}}; line-height:1.5; border-width : 6px; border-style:solid;border-color:#88CCFF;"> <div style="background-color:#aaffff;{{text default color}}; line-height:1.5; border-width : 5px; border-style:solid;border-color:#00CCCC;"> <div style="background-color:#eeffff;{{text default color}}; line-height:1.5; border-width : 2px; border-style:solid;border-color:#3399AA;"> <div style="background-color:#eeffff;{{text default color}}; line-height:1.5; border-width : 2px; border-style:solid;border-color:#666677;"> <div style="background-color:#eeffff;{{text default color}}; line-height:1.5; border-width : 5px; border-style:solid;border-color:#BBBBBB;"> <div style="background-color:#eeffff;{{text default color}}; line-height:1.5; border-width : 5px; border-style:solid;border-color:#BBDDBB;"> <div style="background-color:#aaffff;{{text default color}}; line-height:1.5; border-width : 6px; border-style:solid;border-color:#88CCFF;"> <div style="background-color:#aaffff;{{text default color}}; line-height:1.5; border-width : 5px; border-style:solid;border-color:#00CCCC;"> <div style="background-color:#eeffff;{{text default color}}; line-height:1.5; border-width : 2px; border-style:solid;border-color:#3399AA;"> <div style="background-color:#eeffff;{{text default color}}; line-height:1.5; border-width : 2px; border-style:solid;border-color:#666677;"> <div style="background-color:#eeffff;{{text default color}}; line-height:1.5; border-width : 5px; border-style:solid;border-color:#BBBBBB;"> <div style="background-color:#eeffff;{{text default color}}; line-height:1.5; border-width : 5px; border-style:solid;border-color:#BBDDBB;"> Link to my Dutch wikipedia userpage ---> [http://nl.wikipedia.org/wiki/Gebruiker:Sjorskingma] </div> </div></div></div></div></div></div></div></div></div></div></div> r89w1lczw1fa7kc7c1w37ghwhdmeafd USMLE Step 1 Review/Pathology 0 203476 4669071 3328983 2026-09-06T06:48:56Z ~2026-48319-29 3625295 4669071 wikitext text/x-wiki ===5 SIGNS OF INFLAMMATION (as described by Celsus)=== *Redness/Erythema (''Rubor'') *Raised temperature (''Calor'') *Swelling (''Tumor'') *Pain (''Dolor'') *Loss of Function (''Functio Laesa'') ====HYPERSENSITIVITY REACTIONS==== Goombs classification: "'''A'''nna '''C'''ycled '''I'''mmediately '''D'''ownhill--Gell & Goombs" or "'''ACID'''". * Type I '''A'''naphylaxis * Type II Cytotoxic-mediated * Type III '''I'''mmune-complex * Type IV '''D'''elayed hypersensitivity Coal workers pneumoconiosis is due to the presence of anthracosis. Basically a carbon pigment from coal mining accumulates in macrophages along the pleural lymphatics and interstitium. Usually advances through various stages. Clinical stages (Anthracosis) 1. Asymptomatic 2. Simple CWP(Coal workers pneumoconiosis. Cx(characterized) by coal-dust macules and nodules in upper lobes that produce little pulmonary dysfunction. 3. Complicated CWP. Cx progressive massive fibrosis accompanied by increasing respiratory distress, secondary pulmonary hypertension, and cor pulmonale. 4. Caplan syndrome is CWP accompanied by rheumatoid arthritis. Terms: Pneumoconiosis, anthracosis, macrophages, pleural lymphatics, interstitium, asymptomatic, pulmonary dysfunction, fibrosis, Secondary pulmonary hypertension, cor pulmonale, rheumatoid arthritis, caplan syndrome. {{BookCat}} npxtx6467zu0xfloz8zosqf8fonfh4r User talk:Malosh 3 204488 4669065 4594366 2026-09-06T06:42:32Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669065 wikitext text/x-wiki == Welcome! == <div style="font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Malosh!</div> <div style="width:55%; float:left; margin: .2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#15304f;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold; color:#f4eed7;">[[Image:Crystal Clear app korganizer.png|20px]] '''First steps tutorial'''</div> <div style="border-bottom:1px solid #15304f; padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for freely-licensed collaboratively-developed [[WB:WIW|textbooks]].'''<br/> You don't need technical skills in order to contribute here. '''[[WB:BOLD|Be bold]]''' contributing and ''[[WB:AGF|assume good faith]]'' about the intentions of others. Remember, this is a ''[[w:wiki|wiki]]'', so you're allowed to change just about anything, and changes can be made easily. Come [[Wikibooks:Reading room/General|introduce yourself]] to everyone, and let us know what [[Wikibooks:Reading room/Projects|interests you]]. If you're coming here from other Wikimedia projects, you should read [[Help:Wikibooks for Wikimedians|our primer for Wikimedians]] to get quickly up-to-speed. </div> <div style="border-bottom:1px solid #15304f; background-color:#2a62a1;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold; color:#e9deaf;">[[Image:Icon apps query.svg|20px]] '''Getting help'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> * See the '''Wikibooks [[Help:Contents|help pages]]''' for common issues. * Remember, every edit is saved, so if you make mistakes, you can [[Wikibooks:Reverting|revert]] to an earlier version if needed. * Get help from the community in the [[Wikibooks:Reading room|Reading room]] or in our [[irc:wikibooks|IRC channel]]. * You cannot upload an image until you have been a member for at least '''4 days'''. If your upload is tagged with {{tlx|nld}}, {{tlx|bfu}}, or {{tlx|nfur}}, please read the template message as it explains the violation of [[WB:MEDIA|our media policy]]. Please be sure to provide the required {{tlx|information}}: a [[WB:ICT|license tag]] and source citation are always required; fair use images require a {{tlx|fair use rationale}}. Get help in the [[WB:HELP|user assistance room]]. </div> </div> <div style="width:43%; float:left; margin: .2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#5f96d3;{{text default color}}; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold; color:#15304f;">[[Image:Transmission icon.png|20px]] '''Goodies, tips and tricks'''</div> <div style="border-bottom:1px solid #15304f; padding:0.4em 1em 0.3em 1em;"> * Please fill in [[:w:Help:Edit summary|the edit summary]] and [[Help:Show preview|preview]] your edits before saving. * Sign your name on [[Help:Talk page|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> <div style="border-bottom:1px solid #15304f; background-color:#5f96d3; padding:0.2em 0.5em 0.2em 0.5em; font-size:110%; font-weight:bold; color:#15304f;">[[Image:Nuvola filesystems trashcan full.png|20px]] '''Made a mistake?'''</div> <div style="border-bottom:1px solid #15304f; padding:0.4em 1em 0.3em 1em;"> * '''Please make sure you follow our [[WB:NP|naming policy]]''' - modules should be named like <code>Book Title/Chapter Title</code>. * Need to rename a page? Use the ''move'' tab (only become available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To get a page deleted, add {{tlx|delete|''your reason for requesting deletion''}} to the top of the page. * If something you wrote was deleted, please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:VFD|VFD]] archives if applicable. You can request undeletion at [[WB:VFU]], or ask the administrator who deleted the page. </div> <div style="background-color:#transparent;color:inherit; padding:0.2em 0.5em 0.2em 0.5em;">Thanks, --[[User:Adrignola|Adrignola]] <sup>[[User talk:Adrignola|talk]] [[Special:Contributions/Adrignola|contribs]]</sup> 13:17, 21 July 2009 (UTC)</div> </div> <div style="clear: both; text-align:right; font-size:smaller">(P.S. Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> ==Just a tip== When you create new pages, please place {{tlx|BookCat}} at the bottom of them so they will be added to the category that contains all of the book's pages. That will save us time categorizing in the future. Thanks! Happy editing. -- [[User:Adrignola|Adrignola]] <sup>[[User talk:Adrignola|talk]] [[Special:Contributions/Adrignola|contribs]]</sup> 13:19, 21 July 2009 (UTC) byyugaeikqr809ncl5kqss8bvdl0isk User:Tiicoo:AFSKRB/KrbInstall 2 210660 4669008 4104606 2026-09-05T19:23:25Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669008 wikitext text/x-wiki {{:User:Tiicoo:AFSKRB/Draft:Nav | User:Tiicoo:AFSKRB/Overview | Overview on OpenAFS and Kerberos | User:Tiicoo:AFSKRB/AFSInstall | Installation Of OpenAFS}} __TOC__ ==What is Kerberos?== [[w:Kerberos|Kerberos]] is a Software developed at the [[w:MIT|MIT]] which can be used for network authentication. It uses a trusted third party (which we will call [[w:Key_distribution_center|key distribution center]] or KDC) in case two entities are trying to communicate safely. That third party consists of an authentication server one one side and on the other side of a Ticket Granting Server. For each entity the third party knows the secret key. In case two entities try secret communication the [[w:Key_distribution_center|key distribution center]] the KDC generates a session key. The tickets you get from the KDC, specifically the AFS tokens you can make from those tickets will be the passport in the AFS network. ==Where to get?== ===Installing packages provided by your distribution=== Most distributions provide an OpenAFS/Kerberos environment themselves. For Gentoo an ebuild is provided. In case you are using Slackware64 you may get packages from http://ossy86.bplaced.net/dev/afskrb/ ===Building it from source=== You can download Kerberos packages from http://web.mit.edu/kerberos/www/ or download a current development release via svn co svn://anonsvn.mit.edu/krb5/trunk/ . into the your current working directory. After you have got the sources we will do a util/reconf in order to update the necessary configuration files. After we have done that we tell the build system to compile modules we are relying on via ./configure \ --prefix=/usr \ --enable-dns-for-realm \ --enable-athena \ --enable-kdc-replay-cache \ --with-ldap \ --libdir=/usr/lib64 The following table describes necessary options. {| class="prettytable" ! style="background:#FFDEAD;{{text default color}};" colspan=7 | Description of configuration parameters |- ! style="background:#efefef;{{text default color}};" | Switch ! style="background:#efefef;{{text default color}};" | Description |- | style="text-align:center;" | --prefix=/usr | style="text-align:center;" | We are going to install Kerberos into the directory /usr |- | style="text-align:center;" | --enable-dns-for-realm | style="text-align:center;" | If this option is enabled we can use the Domain Name System for finding Kerberos Servers |- | style="text-align:center;" | --enable-athena | style="text-align:center;" | Enable if you wish support for athena-like systems (distributed administration of thin clients and/or small computers with training software) |- | style="text-align:center;" | --enable-kdc-replay-cache | style="text-align:center;" | Enable detection of retransmitted and/or replayed requests to the [[w:Key_distribution_center|key distribution center]] |- | style="text-align:center;" | --with-ldap | style="text-align:center;" | Enable the [[w:LDAP|LDAP]] Backend |- | style="text-align:center;" | --libdir=/usr/lib64 | style="text-align:center;" | We would like to install libraries into this directory in case we are running on a x86_64 machine. |} {{:User:Tiicoo:AFSKRB/Draft:Nav | User:Tiicoo:AFSKRB/Overview | Overview on OpenAFS and Kerberos | User:Tiicoo:AFSKRB/AFSInstall | Installation Of OpenAFS}} 6aigdgxj5lddcsnlo4io4n1yax8itw8 User:RussellNash 2 211630 4668928 1634447 2026-09-05T12:32:15Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668928 wikitext text/x-wiki == About Russell Nash == {| align="right" border="1" cellspacing="0" cellpadding="2" width="350px" ! style="background:#efefef;{{Text default color}};text-align:right; vertical-align:top"| Name: | Russell Nash |} I am an Applied Economics Major at the University of Minnesota. My interests range from water polo and soccer to learning to bartend, cook, and play pool. For the first five months of 2009 I studied in Barcelona, Spain. This was one of the greatest experiences of my life. My interests beyond school are unknown. I have looked into furthering my education in either economics or law. n0kskc7al252l34fu5thpsaf8fu5mbb User:Karmine2010 2 219879 4669013 1707971 2026-09-05T19:29:44Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669013 wikitext text/x-wiki =About Karmine2010= {| style="text-align:right;width:350px" border="1" cellspacing="0" cellpadding="2" ! style="background:#efefef;{{Text default color}}; text-align:right; vertical-align:top"| Name: | Karmine2010 |- ! style="background:#efefef;{{Text default color}}; text-align:right; vertical-align:top"| Current Home: | Minneapolis, MN |} I am currently a multifaceted student studying many topics in the medical field. I am a part of writing the online Wiki book for the ''U of M'' course '''Writ 3562W''' with my colleagues. I enjoy many activities including playing lacrosse, playing in my band, and reading books which are relevant to my professional goals. ==Goals as a Student== I plan on applying to medical school and specializing in cardiology. Currently I am pursuing a B.S. in Nutrition, where I plan on becoming a Registered Dietitian (RD) after graduation. I also enjoy networking with like-mined individuals to discover and create solutions to current dietary and medical problems that our present in today's world. ==Favorite Music== I enjoy most types of music, but I prefer artists such as John Mayer, Dave Matthews Band, and bands with similar musical styles. I also enjoy some alternative rock music from bands such as Blink 182, Third Eye Blind, Goo Goo Dolls, Eve 6, '''The Strokes are by far my favorite band.''' http://www.blink182.com/ ==Favorite TV Shows== My favorite TV shows include The Office, 30 Rock, Entourage, Arrested Development, Friday Night Stand Up, Weeds, Flight of the Conchords, The First 48, Family Guy, Family Matters, Full House, Home Improvement, Best Week Ever, Anything on ESPN ==Favorite Movies== My favorite movies include '''Baseketball, Super Bad, Pineapple Express, The Dark Knight, Rudy, A Lot Like Love, Remember The Titans, The Sting, Oceans 11, 12, 13, Knocked Up, Heavyweights, Wedding Crashers, Dazed And Confused, The Professional, The Pelican Brief, Goldeneye, The Truman Show, Liar Liar, We Are Marshall, Dead Poets Society, Rules Of Attraction, American History X, American Psycho, American Gangster, American Pie, Boondock Saints, Billy Madison, Happy Gilmore, Big Daddy''' ==Favorite Books== My favorite books ''American Psycho, Less than Zero, The Pelican Brief, Harry Potter, Pitching the Black, Heart of a Champion, The Rookie, Scar Tissue, I Hope They Serve Beer In Hell, Soldier Boys, Runaway Jury, The Thief, Lord of the Rings, Hamlet, Midsummer's Night Dream, Lunar Park, The Informers, A Million Little Pieces'' io42lxqz50zjdans83dxo058h9g04pt User:Zoomdesign 2 219891 4669011 1771011 2026-09-05T19:26:03Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669011 wikitext text/x-wiki =About zoomdesign= {| align="right" border="1" cellspacing="0" cellpadding="2" width="350px" ! style="background:#efefef;{{text default color}};text-align:right;vertical-align:top"| Nickname: | Calor |- ! style="background:#efefef;{{text default color}};text-align:right;vertical-align:top"| Hometown: | Wisconsin |- ! style="background:#efefef;{{text default color}};text-align:right;vertical-align:top"| Current Home: | Minneapolis, MN |- ! style="background:#efefef;{{text default color}};text-align:right;vertical-align:top"| Education: | College of Design<br>University of Minnesota<br> |- ! style="background:#efefef;{{text default color}};text-align:right;vertical-align:top"| Websites: | [http://www.sporcle.com/ Mentally Stimulating Diversions]<br> [http://www.tetris.com/ Tetris Game]<br> |} I am a student at the '''University of Minnesota''', taking the Professional and Technical Writing Class 3562W. I enjoy every second I spend in the '''University of Minnesota Marching Band'''. I love watching old cartoons like ''Darkwig Duck'', ''Talespin'', and ''Ducktales''. In my downtime I love to watch movies, listen to music, and create art. Buying movies is my Achilles heal, almost every time I go into Target I end up with a new movie. =Professional= I am in my Junior year at the '''U of M''' and will be graduating next spring 2011. I have very little professional experience in my graduating field, but am very determined to not move back home once I have graduated. My hope is to get involved in Housing Development or Historic Preservation. I am also considering Graduate School in a variety of places, but have not decided anything yet. =Favorites= My all time favorite movie is ''The Sound of Music''. I have loved it ever since I was young and watched it with my grandmother. Currently, my favorite music comes from ''The Fray'', ''Cascada'', ''Kelly Clarkson'', ''Paramore'', and ''Jason Derulo''. When I find time to read non-school books, I find the ''Harry Potter'' Series, ''The Voyage of the Jerlie Shannara'' Series, and ''The Chronicles of Narnia'' Series to be some of my favorites. Fantasy books are probably my favorite genre for books because they stimulate your imagination and really make you picture the places they have created. =Interests= Being from '''Wisconsin''', I have to love '''Packer''' Football. It is the one sports team from '''Wisconsin''' that I will never let my allegiance change. I also enjoy going shopping with my friends and spending money that I shouldn't, it's always a good time. Photographing every fun and exciting event is both awesome and a curse. A lot of times I end up missing things because I'm off somewhere taking pictures of everything. 56edmfewdhjfwfq46oe740kat2dwrm0 Aros/Developer/Zune/Classes 0 223648 4668971 4603745 2026-09-05T17:47:47Z Jeff1138 301139 4668971 wikitext text/x-wiki {{ArosNav}} ==Introduction== Mui original classes are identified by the trailing .mui like List, String, etc MUI (Zune) replacement classes MCCs came later which include Nlist, BetterString, etc which some developers frown upon. Please read autodocs/MUI_Application.doc/MUIM_Application_NewInput it has a proper example for a '''complete''' main loop. A MUI program has a main loop, but in an ideal application the loop is empty. Main loops as well as hooks are a thing of the past but backwards compatibility is still there. '''New method''' So nowadays, in order to handle notifications from buttons, sliders, etc. - you [http://guidetoamigacompatibleprogramming.googlecode.com/svn-history/r4/trunk/english/CAP_4.txt subclass Application.mui], Window.mui or <one of the groups>.mui of your choice, define your own private methods there and set up notifications on your buttons to call these methods. This lets you keep a neat internal structure rather than having everything in a one huge switch statement of return ids. Methods have no TRUE or FALSE states nor anything other defined states, they are just function calls (well, sort of). The only approach is subclassing technique and overload the method. You can then do anything you wish. The custom class is your way. To define your own private method and attribute ids you could start with TAG_USER. ;Read more [https://github.com/chfhhd/guidetoamigacompatibleprogramming here] '''Old Method''' With MUI you can also call hooks to avoid creating subclasses, but only the change of an attribute can cause an action. * First set Application and Window classes information. * Use Horizontal Groups (HGroup) or Vertical Groups (VGroup) to stuff objects (buttons, sliders, directory listers, etc) into them. Objects are not placed directly to some fixed locations but are instead grouped in special containers which are then dynamically displayed and positioned. * Use [http://www.pcguru.plus.com/tutorial/mui_methods.html Notification] to do something when object changes (pressed, slide, etc) * Release them when finished or when ending app Macros play a part in programming Zune interfaces. Get and Xget can replace GetAttrs and Set and Xset similarly with SetAttrs. When you read the mui autodocs there is a field after the function name with [ISG] and sometimes also [ISGN] And that indicates what to can do with the tag. <pre> I = Init S = SetAttr can be used G = GetAttr can be used N = Supports Notify </pre> So if you see [I.G] that means that you can use the Tag at Init and use GetAttr on it. ==MUI Zune Base Classes== {| class="wikitable" |- |+ BOOPSI rootclass connected to Zune NOTIFY.mui class ! [http://amiga.sourceforge.net/amigadevhelp/MUI_Application.html Application.mui] ! [http://amiga.sourceforge.net/amigadevhelp/MUI_Window.html Window.mui] ! [http://amiga.sourceforge.net/amigadevhelp/MUI_Family.html Family.mui] ! [http://amiga.sourceforge.net/amigadevhelp/MUI_Area.html Area.mui] |- | | Aboutmui | Menustrip | Rectangle |- | | | Menu | Balance |- | | | Menulist | Image |- | | | | Menubar |- | | | | Bitmap |- | | | | Text |- | | | | Gadget |- | | | | Gauge |- | | | | Scale |- | | | | Colorfield |- | | | | List |- | | | | Numeric |- | | | | Pendisplay |- | | | | Group |- |} encapsulation is what you have with all the MUI classes. For example to use a listview you have a well defined interface for this gadget, and all implementation details are encapsulated into the class (like private variables etc.) You would do similar with an advanced application. Locate all sub-systems and implement these as "isolated" modules with interfaces and implementation details encapsulated into the modules, not visible from the outside. inheritance via subclassing polymorphism ===Subclasses=== ;[http://library.morphzone.org/General_Rules_and_Purpose_of_Subclassing Subclassing Classes] Good source examples [http://www.onyxsoft.se/snakee.html Snakee], [http://www.bluemind.org/amiga-lister-dopus-magellan-lister-system-amigaos/ List], ====Application==== ; [http://www.pcguru.plus.com/tutorial/mui_howitworks.html Read more here] and [http://library.morphzone.org/Subclassing_Application_Class Application Class here] Instead of MUI_NewObject(MUIC_Application, ,etc) is often replaced by the macro ApplicationObject, etc, etc... When subclassing window or application class there aren't MUIM_Setup/Cleanup methods at all. If you want to make a gui where everything is made of custom classes (at least the outer stuff, ie application and windows), you define all your classes as usual, and then instantiate your application with a single newobject() call. It's no problem to add elements to a group/window/application when it is being allocated (inside OM_NEW). ====Window==== ; [http://library.morphzone.org/MUI_Subclassing_Tutorial:_SciMark2_Port#GUI_Design Gui Design] Instead of MUI_NewObject(MUIC_Window, ,etc) is often shortened to the macro WindowObject,etc,etc but can be still used in Child Windows... The way to do this would be to implement a method in one of your subclasses (MUIC_Window or the window's Root MUIC_Group are always safe picks) and have a MUIA_Window_? notification call it. For the positions to be remembered, you have to close the windows (set MUIA_Window_Open to false) before disposing the Zune Application object ====Classes==== ;[http://library.morphzone.org/Subclassing_List_Class Morphos List SubClass] Instead of MUI_NewObject(MUIC_Group, ,etc) is often rewritten as the macro <Group>GroupObject,etc,etc... Then class creation: TheClass = MUI_CreateCustomClass (NULL, supername, NULL, sizeof (MyObjectData), dispatcher); <pre> if (!(mcc = MUI_CreateCustomClass(NULL,MUIC_Area,NULL,sizeof(struct NewClass_Data),NewClass_Dispatcher))) { printf("Cannot create custom class.\n"); return(0); } </pre> Is it ok to inherit from other types of object? Yes, to subclass slider class to overload MUIM_Numeric_Stringify method. How to check for a minimum version of a MUI MCC when building a GUI? [...] Your best chance is that the custom class writer has overloaded MUIA_Version/Revision. ===Doing Stuff=== And here is a way to access this inside a method: <pre> LONG AnyMethod (Class *cl, Object *obj, Msg msg) { struct MyObjectData *data = INST_DATA(cl,obj); /*...*/ if (!strcmp ("Amiga", data->Pointer)) DoSomething(); /*...*/ } </pre> Memory allocated for object data structure is freed automatically by MUI in object destructor, you have to do nothing. struct MyObjectData *data = (MyObjectData *)INST_DATA(cl, obj); ====Dispatcher==== Then, in your dispatcher subprogram, you write something like case MUIM_NList_ContextMenuBuild then MyOwnContextMenuBuild(cl,obj,msg); then you write a subprogram MyOwnContextMenuBuild that does what you want your class to do when this method is called. Every object in your subclass gets its own data area added to the object "structure". Also known as a data instantation. It is your own var area privately for the object with the given size in the MUI_CreateCustomClass() call but do not use the obsolete MUI_GetClass() and MakeClass() pairing. See the [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=2765 Class2.c] example in the MUI:Developer/C/Examples dir. ====Overloading==== '''Overloading''' class methods is the main and best design to use when you need to add some class features or use some specials behaviours. In MUI C version this is done by creating a new MCC (MUI Custom Class) and a dispatcher routine catching incoming BOOPSI messages when DoMethod() is called on instance of this MCC. To find out when a superclass's attribute changes without using a Notify? Yes, just overload OM_SET. Most (if not all) calls to OM_SET are done with a temporary tag list allocated on the stack, so it'll be lost anyway... If you need this pointer separate for every object, you should place it in object data structure. <pre> struct MyObjectData { char *Pointer; }; </pre> Tag list or method structures should be untouched in any way if it's not documented. If MUI or 3rd party mcc's do this they're broken... Example of documented method structures touched by MUI are MUIM_Draw and MUIM_AskMinMax... MUI will call MUIM_Hide, MUIM_Show on your object if the dimension change. So no need to check this in MUIM_Draw. MUIM_Draw is btw always called for a reason, so see no reason for you to omit a redraw here. <pre> ULONG NewList_New(struct IClass *cl , Object *obj, Msg msg) { return 0; } ULONG NewList_Set(struct IClass *cl , Object *obj, Msg msg) { return(DoSuperMethodA(cl, obj, msg)); } ULONG NewList_Get(struct IClass *cl, Object *obj, Msg msg) { return(DoSuperMethodA(cl, obj, msg)); } </pre> ===Application and Window=== How can you get a pointer to an active window object at any time? Normally you should search for MUIA_Window_Active in Application window list. Can create MUIC_Window subclass and intercept MUIA_Window_Active, and create your API for this. On the other hand, you can set up notification on this tag and if window receives it you will know about it and set some field in memory to window pointer or so. MUIA_Window_Screen for your own screen and trying to have window size completely under control. Setting MUIA_Window_Width and MUIA_Window_Height always works when you don't specify window ID (MUIA_Window_ID) for WindowObject. In case you specify this ID, height and width are set automatically by system and are remembered for next time you run application. <pre> app = ApplicationObject, MUIA_Application_Title, (IPTR)"KeyShow", MUIA_Application_Version, (IPTR)"$VER: KeyShow 1.0 (24.02.2012)", MUIA_Application_Copyright, (IPTR)_(MSG_AppCopyright), MUIA_Application_Author, (IPTR)"The AROS Development Team", MUIA_Application_Description, (IPTR)_(MSG_AppDescription), MUIA_Application_Base, (IPTR)"KEYSHOW", SubWindow, (IPTR)(win = WindowObject, MUIA_Window_Title, (IPTR)_(MSG_WI_TITLE), MUIA_Window_ID, MAKE_ID('K','S','W','N'), WindowContents, (IPTR)KeyboardGroupObject, End, End), End; if (app == NULL) </pre> <syntaxhighlight lang="c"> /* Copyright © 2002, The AROS Development Team. All rights reserved. $Id: dtpic.c 30792 2009-03-07 22:40:04Z neil $ */ #include <dos/dos.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <libraries/mui.h> struct Library *MUIMasterBase; Object *app; int main(void) { Object *wnd; MUIMasterBase = (struct Library*)OpenLibrary("muimaster.library",0); app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "dtpic test", MUIA_Window_Activate, TRUE, WindowContents, VGroup, Child, MUI_NewObject("Dtpic.mui",MUIA_Dtpic_Name,"SYS:System/Images/AROS.png",TAG_DONE), End, End, End; if (app) { ULONG sigs = 0; DoMethod ( wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit ); set(wnd,MUIA_Window_Open,TRUE); while (DoMethod(app, MUIM_Application_NewInput, (IPTR) &sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D); if (sigs & SIGBREAKF_CTRL_C) break; if (sigs & SIGBREAKF_CTRL_D) break; } } MUI_Object(app); } CloseLibrary(MUIMasterBase); return 0; } </syntaxhighlight> You must OM_ADDMEMBER a window to an application before opening it and you must OM_ADDMEMBER an area object to a group object (in a MUIM_Group_InitChange/ExitCHange pair) if you want to show it in a window (be part of your GUI). Mui Dev docs have a section on Dynamic Windows (Dynamic Object Linking/Windows) which are detailed documentation for dynamic window creation. But you can create a custom class and get notified just by looking for incoming methods. Overloading MUIM_Setup is probably the best idea. You can subclass your window and put screen change detection in MUIM_Setup. E.g. in every MUIM_Setup you can remember screen pointer somewhere in object data, compare it with the previous value and do some things if screen has changed. use _app(obj) after MUIM_Setup. You could have subclass of MUIC_Group where the all objects are placed... When you detect in MUIM_Setup that _screen() changed, you set MUIA_Window_CloseRequest to TRUE... If you app runs on WB screen user can change WB screen resolution/depth at any time. User can change your screen from the custom screen database at any time. Other thing to consider is iconify from the Exchange or ARexx. You _must_ react for screen changes. Then you should place MUIM_Application_Save after your main loop. Overloading MUIM_Window_Snapshot with some code which saves the prefs would do a save whenever the user selects the Snapshot icon on the window border, it would not do that only at program end. If you really want to save on Snapshot, you have to create a new class with CreateCustomClass() which must be a subclass of MUIC_Window. In the dispatcher of this sub class you have to call your own code whenever the dispatcher receives the MUIM_Window_Snapshot method. Then you have to change the application creation code: You have to replace every window creation with creation of an object of your window sub class (Intuition.NewObject()). There seems to be a general problem when disposing windows: You must *not* reference the application object in a windows dispose method! Why? Because before disposing a window, you unlink it from the application (OM_REMMEMBER). After that, the window does no longer belong to an application and using _app(obj) is illegal. You don't have _app(obj) available during OM_NEW, the same is true for OM_DISPOSE. Using _app(obj) anywhere in setup/cleanup methods (either before or after the DoSuperMethod) is fine. In fact, there is another layer between new/dispose and setup/cleanup where an object learns about its application context. However, this layer has not been made publically available through methods yet. MUIA_Window_IsSubWindow does exactly this (skipping OM_REMMEMBER and OM_DISPOSE). However, this is not the solution to all problems which arise from the "global" window list in the application object. Window class should probably be able to have more window children itself. How do we get the actual Window from my MUI-object ??? <pre> struct Window *win; DoMethod(obj,MUIA_Window,&win); </pre> MUIA_Window is an attribute. You can read attributes by calling GetAttr() from Intuition: GetAttr(MUIA_Window, obj, &x); And few warnings: * MUIA_Window is only valid when the window is opened * MUIA_Window is an area class tag. Use MUIA_Window_Window for window objects. To call ChangeWindowBox on MUI windows. Just take care that the window is currently open (MUIA_Window_Window!=NULL) need the screen, you can always get MUIA_Window_Window and use window->WScreen etc. like with other intuition windows. '''MUIM_Application_PushMethod''' So you want to get out of the object context first, and this is easily done with MUIM_Application_PushMethod. <pre> /* From your mail window */ DoMethod(_app(obj), MUIM_Application_PushMethod, _app(obj), 2, MUIM_MyApplication_RemoveObject, obj); /* From your application subclass */ case MUIM_MyApplication_RemoveObject: { DoMethod(obj, OM_REMMEMBER, msg->Obj); MUI_DisposeObject(msg->Obj); } break; </pre> Basically have a rendering task that does a heap of computation and renders into an offscreen rastport. When it's finished a frame, it sets a flag (Drawn) to FALSE, releases a semaphore, and does a PushMethod. The main program, waiting patiently in its event loop, at some point will be awakened by the PushMethod, which triggers the custom class to do a MUI_Redraw() internally, which in turn obtains the semaphore, copies the offscreen bitmap to the window, sets Drawn to TRUE, and releases the semaphore. Then it goes back to sleep. The rendering subtask, in the meantime, has done an ObtainSemaphore. When it gets it, it checks to see if Drawn is TRUE. If so, it can continue because it means the main task successfully copied the bitmap. Otherwise it releases it, does a little Delay, and tries again, to try and give the main task time to snatch the semaphore and do its work. So, the semaphore is, in effect, protecting the offscreen rastport (and the Drawn flag) - neither task can access or change it without obtaining the semaphore first, and the flag is used to tell the draw task whether the main task has had a chance to do its job or not. Most of the time (i.e. almost always) the main task does, in fact, manage to grab the semaphore immediately so the draw task doesn't manage to steal it back again too quickly. If the main task finishes quickly, then when the draw task tries to obtain the semaphore it succeeds immediately, so there's no penalty. PushMethod should not be too heavily overloaded, however, for inter-process communication recommends using private messageports for more intensive stuff. Use it as a signalling mechanism to wake up the main task and get it to send a MUI_Redraw to the custom class, and only ever send one at once (although there are 30-60 of them per second). Never had any problems with it in those circumstances. <pre> struct SignalSemaphore lock_AddEntry_Sem; ... InitSemaphore(&lock_AddEntry_Sem); ... while(something){ ... ObtainSemaphore(lock_AddEntry_Sem); // Grab the semaphore while (lock_AddEntry){ // Main task completed its job? ReleaseSemaphore(lock_AddEntry_Sem); // No, release semaphore Delay(1); // Wait a bit ObtainSemaphore(lock_AddEntry_Sem); // Try again } ... lock_AddEntry = TRUE; // Set flag ReleaseSemaphore(lock_AddEntry_Sem); // Give CPU back to main task ... } </pre> MsgPorts are slower. Semaphores are better to use under any AmigaOS like. MUIM_HandleEvent is called for each event handler node unless MUI_EventHandlerRC_Eat is returned. MUIM_HandleInput is called for an active object if it was not eaten by MUIM_HandleEvent. Should use EventHandler and not request? To avoid getting events even if my object is not the active one ? Yes - eventhandlers respect properties such as the active and default object, priorites etc. HotkeyString is a subclass of BetterString. It adds a new eventhandler with a higher priority, thus get the events before its superclass, which wouldn't be the case for the other approach (one could override MUIM_HandleInput, but this was just *one* example...) Eventhandlers also allow you to swallow input, another thing which isn't possible with IDCMP-requesting. This means many objects (which use the old way) will only interpret input when they are the active or default object, which is bad e.g. in IProbe where I want HTMLview to react on arrow up/down, even when the URL-string is active - and this is AFAIK only possible with eventhandlers. the proper way to know the current active window (IDCMP_ACTIVEWINDOW/IDCMP_INACTIVEWINDOW was what I tracked before). What is the proper MUI way to know a window has become active? You can attempt a setup dispatcher that add the required actions to the event handler. <pre> struct your_data { struct MUI_EventHandlerNode ehnode; }; ULONG yoursetup(struct IClass *cl, Object *obj, Msg msg) { struct your_data *data = (struct your_data *)INST_DATA(cl, obj); if (!DoSuperMethodA(cl, obj, msg)) return(FALSE); data->ehnode.ehn_Object = obj; data->ehnode.ehn_Class = cl; data->ehnode.ehn_Events = IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW; DoMethod(_win(obj), MUIM_Window_AddEventHandler, &data->ehnode); return(TRUE); } </pre> add a cleanup dispatcher that looks like : <pre> ULONG yourcleanup(struct IClass *cl, Object *obj, struct MUIP_HandleInput *msg) { struct your_data *data = (struct your_data *)INST_DATA(cl, obj); DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehnode); return(DoSuperMethodA(cl,obj,msg)); } </pre> Add a dispatcher for MUIM_HandleEvent and take care of your wanted event like : <pre> ULONG yourhandler(struct IClass *cl, Object *obj, struct MUIP_HandleInput *msg) { struct your_data *data = (struct your_data *)INST_DATA(cl, obj); if (msg->imsg) { case IDCMP_ACTIVEWINDOW: // Do what you want here break; case IDCMP_INACTIVEWINDOW: // Do what you want... break; } return(DoSuperMethodA(cl, obj, (Msg)msg)); } </pre> or You could try to install an event listener that triggers every time MUIA_Window_Activate gets changed. Be able to receive mouse co-ordinates and keypresses into my application, even when the window is not active. You can poll intuition base and read mouse coords at any time. An interrupt routine would be the best solution if your app wants keep an eye on it all the time... (might be possible with other libraries) Everything is single threaded unless you specifically use MUIM_Application_InputBuffered. No functions are interrupted in order to handle a signal. Would a better method be to offload the MUI interface handling onto a separate task, and communicate with the network task through signals? This would at least solve the problem mentioned above. STRICQ uses MUI and is setup to handle any number of simultaneous sockets, both TCP and UDP. First create another window, then call MUIM_Application_InputBuffered (even though you should really try to avoid this) and then do the PushMethod. What should I do if the InputBuffered had to be used to handle other actions? Come up with a design pattern that avoids this nasty input probing in the middle of your program Creating a subclass of application class for this purpose where you could call one method with the object to be deleted as an argument and the application sub-class then stored a pointer to this object and deleted it after MUIM_Application_Input returned (and a nested counter tells me that there is no other recursive call to MUIM_Application_Method). Remember that the MUIM_PushMethod is not safe in the sense that it can fail (e.g. out of memory) and then your object doesn't get deleted (i.e. memory leak). The solution using a sub class of application class is safe as there is no need to allocate memory for the pointer to the object by adding it to an 'internal' Group class. ====Iconify==== <pre> #ifdef __amigaos4__ MUIA_Application_DiskObject , diskobject = GetDiskObject(_ProgramName), #endif </pre> MUIA_Application_DiskObject,GetDiskObject("PROGDIR:mp3player"), where PROGDIR:mp3player is the name of your app. Be aware, that you are leaking the disk object this way. Be sure to assign it to pointer and FreeDiskObject after your application has ended.. <pre> struct DiskObject *my_app_icon; MUIA_Application_DiskObject,my_app_icon=GetDiskObject("PROGDIR:zamp"), ULONG iconified=0; get(application, MUIA_Application_Iconified, &iconified); if( !iconified) </pre> How to execute an arexx script from your own program as though it was run from your program's arexx port. An application subclass that adds one method called MUIM_Application_RunScript, just call this method with the scriptname and its arguments then it will be launched with your (MUI) port as host and it will make sure your program doesn't quit before the script has completed. <pre> ULONG ListWindows( Object *application ) { ULONG windows = 0; struct MinList *windowlist; windowlist = (struct MinList *) xget( application, MUIA_Application_WindowList ); if( windowlist && !IsListEmpty( (struct List *) windowlist ) ) { Object *object, *objectstate = (Object *) windowlist->mlh_Head; while( object = NextObject( &objectstate ) ) { Printf( "Object 0x%08lx is %swindow.\n", object, IsWindow( object ) ? "" : "not " ); windows++; } } return( windows ); } </pre> You can check whether object class is class or subclass of MUIC_Window, using similar code to below: <pre> BOOL IsWindow( Object *object ) { struct IClass *windowclass = MUI_GetClass( MUIC_Window ); struct IClass *class; for( class = OCLASS( object ); class; class = class->cl_Super ) if( class == windowclass ) return( TRUE ); return( FALSE ); } </pre> ====External input====  MUIM_Application_AddInputHandler(struct( MUI_InputHandlerNode ) in the MUIM_Setup and MUIM_Cleanup methods of your class (not subclass?). Remove with MUIM_Application_RemInputHandler '''Obsolete Hooks''' Is it safe to call the MUI_DisposeObject() inside a hook which is called by a notification if it frees the object the notification is attached to? This is not safe. The hook contents are not freed because after returning from the hook, there is still some return code from the calling class which has to be executed. <pre> MUIM_Application_AboutMUI MUIM_Application_AddInputHandler MUIM_Application_CheckRefresh MUIM_Application_InputBuffered MUIM_Application_Load MUIM_Application_NewInput (replaces old Input) MUIM_Application_OpenConfigWindow MUIM_Application_PushMethod MUIM_Application_RemInputHandler MUIM_Application_ReturnID MUIM_Application_Save MUIM_Application_SetConfigItem MUIM_Application_ShowHelp </pre> <pre> MUIA_Application_Active MUIA_Application_Author MUIA_Application_Base MUIA_Application_Broker MUIA_Application_BrokerHook MUIA_Application_BrokerPort MUIA_Application_BrokerPri MUIA_Application_Commands MUIA_Application_Copyright MUIA_Application_Description MUIA_Application_DiskObject MUIA_Application_DoubleStart MUIA_Application_DropObject MUIA_Application_ForceQuit MUIA_Application_HelpFile MUIA_Application_Iconified MUIA_Application_MenuAction MUIA_Application_MenuHelp MUIA_Application_Menustrip MUIA_Application_RexxHook MUIA_Application_RexxMsg MUIA_Application_RexxString MUIA_Application_SingleTask MUIA_Application_Sleep MUIA_Application_Title MUIA_Application_UseCommodities MUIA_Application_UsedClasses MUIA_Application_UseRexx MUIA_Application_Version MUIA_Application_Window MUIA_Application_WindowList </pre> <pre> MUIM_Window_AddEventHandler MUIM_Window_Cleanup MUIM_Window_RemEventHandler MUIM_Window_ScreenToBack MUIM_Window_ScreenToFront MUIM_Window_Setup MUIM_Window_Snapshot MUIM_Window_ToBack MUIM_Window_ToFront </pre> <pre> MUIA_Window_Activate MUIA_Window_ActiveObject MUIA_Window_AltHeight MUIA_Window_AltLeftEdge MUIA_Window_AltTopEdge MUIA_Window_AltWidth MUIA_Window_AppWindow MUIA_Window_Backdrop MUIA_Window_Borderless MUIA_Window_CloseGadget MUIA_Window_CloseRequest MUIA_Window_DefaultObject MUIA_Window_DepthGadget MUIA_Window_DisableKeys MUIA_Window_DragBar MUIA_Window_FancyDrawing MUIA_Window_Height MUIA_Window_ID MUIA_Window_InputEvent MUIA_Window_IsSubWindow MUIA_Window_LeftEdge MUIA_Window_MenuAction MUIA_Window_Menustrip MUIA_Window_MouseObject MUIA_Window_NeedsMouseObject MUIA_Window_NoMenus MUIA_Window_Open MUIA_Window_PublicScreen MUIA_Window_RefWindow MUIA_Window_RootObject MUIA_Window_Screen MUIA_Window_ScreenTitle MUIA_Window_SizeGadget MUIA_Window_SizeRight MUIA_Window_Sleep MUIA_Window_Title MUIA_Window_TopEdge MUIA_Window_UseBottomBorderScroller MUIA_Window_UseLeftBorderScroller MUIA_Window_UseRightBorderScroller MUIA_Window_Width MUIA_Window_Window </pre> ===Objects=== DoMethod( object1, method, attribute, value, object2, parameter_number, method2, attribute2, value2 [,...]) * MUIM_Application_NewInput * MUIM_Window_ * MUIM_CallHook MUIM_FindUData MUIM_GetUData MUIM_SetUData * MUIM_KillNotify MUIM_NoNotifySet MUIM_Notify * MUIM_Set MUIM_MultiSet MUIM_SetAsString * MUIM_List_InsertSingle When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. If you want to manage a set of invisible objects the class MUIC_Family may be of help. Need to know size of object while program is between MUIM_GroupInitChange and MUIM_GroupExitChange. Simple asking about MUIA_Width a MUIA_Height returns 0. Anyone have any idea? Width/height is not valid until you call ExitChange again. But if you need to know object dimensions subclassing is probably the best way to do so. You can get object dimensions by using _width()/_height() macros. The object can't tell the difference of whether OM_SET was invoked through SetAttr() or through MUIM_MultiSet. Some standard MUI classes do indeed modify the taglist passed to them. A good example is Group class; it sets certain tags to TAG_IGNORE, because they either cannot be forwarded to the children, or shouldn't be handled by its superclass (Area). How do you add a selected image to an app to use a different image for normal and selected states ? Most people are using a Group with PageMode set, so that the group simply toggle the displayed page, when pressed, and each page has the desired image shown on it. ====Notifications==== ;[http://library.morphzone.org/Event_Driven_Programming,_Notifications Morphos Notify] Basically, MUI doesn't use BOOPSI's notification system. Notification happens transparently; the only thing you need to do is pass the method up to your superclass, and you should be doing that anyway—you don't need to use the approach that non-MUI BOOPSI classes use. You can put notification on every attribute of your custom class. That's assuming your class is derived from MUIC_Notify. Then MUI will automagically execute the notification whenever you set an attribute. You can place a notification on any (public) attribute of any class (or its ancestors) using the MUIM_Notify method. These notifications can be placed at any time from anywhere. All you have to do is only change attributes of your object using set(), and in your set method handler add return (DoSuperMethodA(cl, obj, msg)); at the end. This will pass on the OM_SET up the class hierarchy to Notify.mui, which will then perform the notifications. The other thing, of course, is to always use set() whenever you want to change a value, rather than just assigning it directly. Only within the OM_SET method should you assign it directly. When some other class puts a notification on one of your attributes, and your attribute gets changed using set() (or OM_SET), then when it does the DoSuperMethod() call the OM_SET will eventually reach the root class of all MUI classes—Notify.mui. This keeps a list of notifications to be performed. <pre> /* This is setting up a notification on the MUIA_Robot_FrameRate * attribute */ DoMethod(MyObj, MUIM_Notify, MUIA_Robot_FrameRate, MUIV_EveryTime, FrameCntObj, 4, MUIM_SetAsString, MUIA_Text_Contents, MUIX_R"%ld", MUIV_TriggerValue ); ... /* This is setting the frame rate (actually done within the class * itself -- ie. I use set() rather than just changing the value * directly in case there are notifications on it. */ set(obj, MUIA_Robot_FrameRate, data->framecnt - data->lastframecnt); ... /* This is the relevant part of my custom class's OM_SET method * handler. */ static ULONG mSet(struct IClass * cl, Object * obj, Msg msg) { struct MyData *data = INST_DATA(cl, obj); struct TagItem *tags, *tag; for (tags = ((struct opSet *) msg)->ops_AttrList; tag = NextTagItem(&tags);) { switch (tag->ti_Tag) { ... case MUIA_Robot_FrameRate: data->framerate = (ULONG) tag->ti_Data; break; ... } } return(DoSuperMethodA(cl, obj, msg)); } </pre> If you have an attribute MUIA_Xxx_Yyy that is readable and notifiable, and recognized by mGet() (your OM_GET method). Internally it reads from data->Yyy. Further, let's say you have a private attribute MUIA_Xxx_YyyP (probably best to give it a numeric value quite different to the rest in your class) that is recognized by mSet() and writes to data->Yyy. mSet(), however, does *not* recognize MUIA_Xxx_Yyy. The code in the mSet() switch statement that recognizes MUIA_Xxx_YyyP, in addition to writing to data->Yyy, changes tag->ti_Tag to MUIA_Xxx_Yyy. Then, when the DoSuperMethodA() call is made, Notify class recognizes the attribute that was changed as MUIA_Xxx_Yyy and correctly performs the notification. Suppose your class use the custom attribute MUIA_HHH_MyAttr. Other objects can ask MUI to be notified whenever this attribute is set()ted to a given value,for example you can have something like this: DoMethod(obj1,MUIM_Notify,MUIA_HHH_MyAttr,32,obj2,1,MUIM_MyObj_Changed); Here object obj2 asks to be notified with method MUIM_MyObj_Changed whenever the attribute MUIA_HHH_MyAttr of obj1 is set()ted to 32. Child, Label2("Allow duplicates:"), Child, ck6 = CheckMark(TRUE), DoMethod(ck6, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ACT_CK6); The confusing thing about this bug is that it only affects CheckMark(TRUE) objects (or if you use MUIM_Application_Load to restore the state of checkmarks then those that become set to TRUE will exhibit the same problem). The autodocs state you 'simply' add your checkmarks and strings (paired together) even in 'invisible' space. You need the string because the autostring for a checkmark is only place-able at the left side (which would be unintuitive). <pre> Object *MakeCheck(BYTE state, char *label) { return ImageObject, ImageButtonFrame, MUIA_Text_Contents, label, MUIA_InputMode , MUIV_InputMode_Toggle, MUIA_Image_Spec , MUII_CheckMark, MUIA_Background , MUII_ButtonBack, MUIA_ShowSelState, state, MUIA_CycleChain , TRUE, End; } </pre> DoMethod(timerobj,MUIM_Notify,MA_Timer_Seconds,MUIV_EveryTime,obj,2,MM_Clock_Seconds,MUIV_TriggerValue); This should call MM_Clock_Seconds everytime MA_Timer_Seconds changes. <pre> WaitIO(data->req); CurrentTime(&raw,&micros); today = raw%86400; SetAttrs(obj,MA_Timer_Seconds,today%60,TAG_DONE); </pre> Notify does not happen <pre> data->seconds = today%60+30; data->minutes = (today%3600)/60; data->hours = today/3600; data->req->tr_node.io_Command = TR_ADDREQUEST; data->req->tr_time.tv_secs = 1; data->req->tr_time.tv_micro = 0; SendIO((struct IORequest *)data->req); </pre> timerobj's OM_GET: <pre> case MA_Timer_Seconds: *msg->opg_Storage = data->seconds; return TRUE; </pre> Class has no OM_SET but you '''must implement OM_SET''' to notify. I would not use MUI notifications for this kind of events because due to BOOPSI latency. The timer does work (tested by getting MA_Timer_Seconds in every MUIM_Draw for the clock class, but MM_Clock_Seconds never gets called. SetAttrs(NULL, ... In theory you do not have to because SetAttrsA() is only a wrapper call to DoMethodA() which accepts NULL object pointer but this is not documented behaviour either in SetAttrsA() nor DoMethodA(). So do not rely on it but use macro instead to save you from typing if statements. Restore a button frame - D&D lately but it seems it clashes with MUI's own D&D drawing. You could look into Ambient D&D for ideas. It uses its own dropmarks. <pre> MUI_DISPATCH(NewList_Dispatcher) { switch (msg->MethodID) { case OM_NEW : return(NewList_New (cl,obj,(APTR)msg)); case OM_SET : return(NewList_Set (cl,obj,(APTR)msg)); case OM_GET : return(NewList_Get (cl,obj,(APTR)msg)); case MUIM_DragQuery : return(NewList_DragQuery(cl,obj,(APTR)msg)); case MUIM_DragDrop : return(MyList_DragDrop (cl,obj,(APTR)msg)); case MUIM_ExternDrop :return(MyList_ExternDrop(obj,(APTR)msg)); } return(DoSuperMethodA(cl,obj,msg)); } </pre> added an internal notification method to each checkmark (checkbox) and added the method to the dispatcher, <pre> DISPATCHERPROTO(MCC_BIA_dispatcher) { struct mydata *mydata = INST_DATA(cl,obj); switch (msg->MethodID) { case OM_NEW: return( MCC_BIA_New (cl, obj, (APTR) msg)); case OM_SET: return( MCC_BIA_Set (cl, obj, (APTR) msg)); case OM_GET: return( MCC_BIA_Get (cl, obj, (APTR) msg)); case OM_DISPOSE: return( MCC_BIA_Dispose (cl, obj, (APTR) msg)); case MUIM_AskMinMax: return( MCC_BIA_AskMinMax (cl, obj, (APTR) msg)); case MUIM_BIA_Changed: return( MCC_BIA_Changed (cl, obj, (APTR) msg)); default: return( DoSuperMethodA (cl, obj, msg)); } } </pre> Each time click on one of the checkboxes you get an MUIM_BIA_changed and the function get's called. Within the function readout the checkboxes and rebuild the bit array which can be read and set by using the MUIA_BIA_Array tag. Now a notification for MUIA_BIA_Array is required. Do I need to call the class itself by using set(MUIA_BIA_Array) to cause a notification to take place, or is there a more simple way. Calling the class from inside would cause the checkboxes to change and this would result in another MUIM_BIA_changed and we have an endless loop. The problem is that setting would cause an update of the class internal gadgets. These would cause a notify and the notify would cause another set(). <pre> //The best way to handle it is to filter out tag list.. struct TagItem *tagitem; tagitem = FindTagItem( MUIA_xxx_name, taglist ); if( tagitem != NULL ) { tagitem->ti_Tag = TAG_IGNORE; } </pre> do-notify set might still causing infinite loop in some circumstances that vary on super class attributes implementation, and therefore in one class version working fine, in second crashing system... <pre> MUIA_ApplicationObject MUIA_AppMessage MUIA_HelpLine MUIA_HelpNode MUIA_NoNotify MUIA_ObjectID MUIA_Parent MUIA_Revision MUIA_UserData MUIA_Version MUIM_CallHook MUIM_Export MUIM_FindUData MUIM_GetConfigItem MUIM_GetUData MUIM_Import MUIM_KillNotify MUIM_KillNotifyObj MUIM_MultiSet MUIM_NoNotifySet MUIM_Notify MUIM_Set MUIM_SetAsString MUIM_SetUData MUIM_SetUDataOnce MUIM_WriteLong MUIM_WriteString </pre> ====Layouts==== <pre> // Create your GUI app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, (IPTR) "Title", MUIA_Window_CloseGadget, FALSE, WindowContents, (IPTR) VGroup, MUIA_Group_SameWidth, TRUE, Child, (IPTR) HGroup, Child, (IPTR) VGroup, Child, TextObject, MUIA_Text_Contents, "33cText1", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText2", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText3", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText4", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText5", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText6", End, [...] End, End, Child, HGroup, Child, Scan_button = SimpleButton("Button"), Child, Quit_button = SimpleButton("Quit"), End, End, End, End; </pre> <pre> Object *exampleWinObj, *exampleVirtGObj, *exampleContainerObj; Object *exampleChildObj; exampleWinObj = (Object *)WindowObject, MUIA_Window_CloseGadget, FALSE, MUIA_Window_Title, (IPTR)"Example Window", WindowContents, (IPTR) (exampleVirtGObj= (Object *)GroupObject, MUIA_Group_Virtual, TRUE, Child, (exampleContainerObj = (Object *)VGroup, End), End), End; if (exampleWinObj) { int i; for (i = 0; i < 10; i++) { exampleChildObj = HVSpace; if (DoMethod(exampleContainerObj, MUIM_Group_InitChange)) { DoMethod(exampleContainerObj, OM_ADDMEMBER, exampleChildObj); DoMethod(exampleContainerObj, MUIM_Group_ExitChange); } } } </pre> Change the HVSpace for whatever object (group, etc) you want to add.. '''Obsolete Hooks.''' MUI does not allow own position of Components, only automatic positions available (group concept) but by setting and Layout Hook and add and Left, Top, Width and Height to every Object, you can disable this behaviour Your notify should preferably invoke a method on the class responsible for the action you want to have executed. Tend to gather more general stuff in window or application subclasses. If there's really no place it belongs then you can have it call a hook instead. You must add your own layout hook which reports the size. Then simply invoke MUIM_Group_Init/ExitChange on your virtgroup object, as that will cause a re-layout == invocation of your layout hook, which can report new sizes for the contents. If your family tree needs any layout (before rendering) then the layout hook is also the ideal place for this. Take a look at 2b_VRastPort sources on Aminet. <pre> /* gcc syntax */ ULONG __attribute__((regparm(3))) Genealo_Layout(struct Hook *hook, struct MUI_LayoutMsg *lmsg, Object *obj ) { ULONG result = 0; int longueur=500, haut=500; switch(lmsg->lm_Type) { case MUILM_MINMAX: { printf("MinMax\n"); lmsg->lm_MinMax.MinWidth = 500; lmsg->lm_MinMax.MinHeight = 500; lmsg->lm_MinMax.MaxWidth = 500; lmsg->lm_MinMax.MaxHeight = 500; lmsg->lm_MinMax.DefWidth = 500; lmsg->lm_MinMax.DefHeight = 500; } break; case MUILM_LAYOUT: { printf("Layout...\n"); lmsg->lm_Layout.Width = longueur; lmsg->lm_Layout.Height = haut; result = TRUE; } break; } return result; } </pre> <pre> ULONG __attribute__((regparm(3))) Genealo_Dispatcher(struct IClass *cl , void *msg,Object *obj ) { Msg msg2 = ( Msg ) msg; struct Genealo_Data *data; ULONG result; switch (msg2->MethodID) { case OM_NEW: { result = DoSuperMethodA(cl,obj,msg); if(obj = (Object *)(result)) { data = (struct Genealo_Data *)INST_DATA(cl,obj); data->LayoutHook.h_Entry = (ULONG(*) ())Genealo_Layout; data->LayoutHook.h_Data = data; SetAttrs(obj,MUIA_Group_LayoutHook, &data->LayoutHook,TAG_DONE); } printf("%p\n",result); return( result ); } break; /* ..... */ </pre> How to do multithreading in MUI, where the same thread to be running several times simultaneously? Your application tree may only be accessed by one task, as no MUI object is re-entrant nor thread-safe (the classes are, not the objects). Using DoMethod(app,MUIM_CallHook,&hook) works fine for running different threads at the same time but when calling the same hook a second time, the first one pauses. It is because both threads are running on the same OS task. If you want to have them running simultaneously, you have to create a separate task for each thread, e.g. by CreateProc() from dos.library. That method is the same as CallHookA(&hook, app, NULL) which again is the same as just calling the hook-function directly, with 'app' and '&hook' as parameters. Not sure why you think this equals 'multi-threading'. If the second event then terminates, the first one continues, but it seems all the local variables have been altered by the second event. Because your code is not reentrant. ====Finding==== there is also a user field in IClass and you can access to this through MUI_CreateCustomClass() as in the Dispatcher. <pre> mcc = MUI_CreateCust..() mcc->mcc_Class->cl_UserData = data; </pre> in the Dispatcher: <pre> data = cl->cl_UserData; </pre> [http://library.morphzone.org/Locating_Objects_in_the_Object_Tree Locating objects in a tree using MUIA_UserData and MUIM_FindUData] use MUIA_UserData, to store a pointer to a private struct where IT store information that object/related code might need ... e.g pointers to paths/filenames, whatever you like really. the MUIA_UserData of the object contains the given udata\ and returns the object pointer in this case. ====Area (dragging, RMB etc)==== Let the program know if the user clicks anywhere on the map, the answer is yes: Group class is a child of area class, thus you can use any attribute of area class, for example MUIA_Pressed. Let the program know, if and where the user clicked on the map, the answer is no. That's exactly what custom classes are for. If any drawing will be manipulated by the user (e.g. an area for painting with the mouse), you write a subclass of Area class. Bitmap is just for displaying rastered images. If you want to have a (resizeable) area for application specific drawings, sub-classing Area is still the right thing to do. If you want to create a bitmap of them tiled, which would then be displayed inside the application. For this application it is certainly simpler to use a Column group with Bitmap objects as children, or even a group with a custom LayoutHook that adapts the number of columns to the size of the area. <pre> // want the image to be the same size as the picture or if the object has to be bigger then the picture, // it should be centered (horiz and vertically). TextAttr ta = { "topaz", 8, 0, 0 }; TextFont *Topaz8Font = OpenFont(&ta); Object *guiobject = ImageObject, MUIA_Image_Spec, "5:<path>", MUIA_Image_FreeHoriz, FALSE, MUIA_Image_FreeVert, FALSE, MUIA_Image_FontMatch, TRUE, MUIA_Font, Topaz8Font, End; </pre> the Image class is a subclass of Area class, and the Area class can handle input, thus it should be possible to create an Image object that behaves like an ordinary button. Simply try to create an Image object, init the attribute MUIA_Image_Spec as "5:picture_filename" (to load the image via datatypes) and try to init the Area class attribute MUIA_InputMode as MUIV_InputMode_RelVerify. Then set up a notification for that object, so you will hear from it, open the window... It might help to have a look at the "default macros" for images and buttons in mui.h to initialize the other attributes (frame type etc.) properly. # Call MUIM_Group_InitChange on a parent group of your object. # OM_REMMEMBER it from the group. # Change the size ie you should modify the data used in MUIM_AskMinMax to fill the structure. # OM_ADDMEMBER it back. # Call MUIM_Group_ExitChange on the group. =====MUIM_DRAW===== If you want to code yourself what your class will display (eg the wireframe drawing with the mui class1 demoprogram), you implement this overriding the MUIM_Draw method. (have a look at the three examples of custom classes class1 (ok), class2 (ok), class3 (obsolete). Is it possible to draw on objects outside of MUIM_Draw? MUIM_Draw adds some overhead compared to direct draw (like in gadtools) but overhead is very minimal and you can't notice any slow down either... Is there a safe way to do draw into a window/MUI-object outside a Draw-event? You can draw only inside MUIM_Draw because: * your object may belong to virtual group and needs clipping (MUI installs this automatically for MUIM_Draw) * your application can be hidden (in the iconified state) at anytime and thus _rp(obj) is not always valid. * your object could be hidden for some reason (page and register groups) If you just want draw new parts of your objects without full redraw? Then you could do something like this: <pre> data->DrawCommand = MY_OWN_DRAW_COMMAND; MUI_Redraw(obj, MADF_DRAWUPDATE); </pre> And then in your MUIM_Draw method: <pre> MyDraw() { DoSuperMethod(); if (msg->flags & MADF_DRAWUPDATE) { switch (data->DrawCommand) { /* UPDATE PARTS YOU WANT TO */ } } else { /* FULL REDRAW */ } } </pre> In MUIM_Draw simply call BltBitMapRastPort() to display stuff in screen: BltBitMapRastPort(data->RastPort.BitMap, 0, 0, rp, mleft, mtop , mwidth, mheight, 0xc0); create a bitmap, embed it in a rastport and set this rastport in your MUI renderinfo - then simply call MUIM_DrawBackground, and the background is drawn into your off-screen bitmap. Remember to set back the rastport within your objects area you ae absolutely free to render whatever you want. And about the rastport: You *should* attach an own rastport to the object, if you use any graphics.library functions: Mui expects to find the objects own rastport in the same state after MUIM_Draw is executed. If MUIM_Draw not being called (blank area with a frame) then check that you are not calling DoSuperMethodA() first in your MUIM_Draw method and that the MUIM_Draw Method only checks for msg->flags == MADF_DRAWOBJECT. <pre> switch( msg->MethodID ) { [...] case MUIM_Draw: return( draw( class, object, msg ) ); [...] } </pre> solved the problem, replaced them in the draw method <pre> if(!DoSuperMethodA(cl,obj,(APTR)msg)) DoSuperMethodA(cl,obj,(APTR)msg); </pre> Typically your object should have an internal buffer where you store the objects state after the last MUIM_Draw. This allows you to draw only those parts of your map, that need to be updated. Stuff the parameters into you instance data and call MUI_Redraw() with MADF_DRAWUPDATE. That's what it is for. Basically, all rendering is done inside MUIM_Draw. If another method wants to render, it sets up parameters and calls MUI_Redraw(). MUI_Redraw() will then call MUIM_Draw for you. However, you must be aware that MUIM_Draw might _not_ be called, e.g. when your object is currently hidden. So, MUIM_Draw should only draw; your other methods should do all the other stuff (if you draw an ellipse, you have to store that information somewhere in case a refresh comes in, the application is iconified etc. So, you MUIM_xxx_DrawEllipse will store all that information somewhere (adding the ellipse to a list or drawing it into an offscreen bitmap), then it will call MUI_Redraw(TheObject,MADF_DRAWUPDATE) to update the display). What about a 3ds viewer with mui buttons ? Titler display opengl and mui on the same window, so what class/methods can use to display/redirect opengl output onto mui win? You need an area subclass to display your GL stuff in MUI window. You only need an offscreen bitmap which is blitted to the window in your MUIM_Draw method. InitRastPort(&data->RastPort) is done in other part of code! Once opengl context is initialized you can render to your offscreen bitmap using GL calls. Have a look to aminet/wazp3d in soft3d_opengl.c. Inside there is code to start mesa for aros (seek ifdef aros...) But aros mesa cant render in a bitmap: You will need to use your mui window + glscissor [http://aminet.net/package/dev/mui/GLArea_src AreaGL] may be helpful. <pre> MUIA_Image_FontMatch MUIA_Image_FontMatchHeight MUIA_Image_FontMatchWidth MUIA_Image_FreeHoriz MUIA_Image_FreeVert MUIA_Image_OldImage MUIA_Image_Spec MUIA_Image_State </pre> =====MUI_Redraw===== With MUI_Redraw(), an object tells itself to refresh, e.g. when some internal attributes were changed. Calling MUI_Redraw() is only legal within a custom class dispatcher, "using this function within an applications main part is invalid!". To solve the same problem with my GUI for the UAE port of AROS, and simply wrapped the MUI_Redraw inside a custom method. <pre> MUIM_UAEDisplay_Update, struct MUIP_UAEDisplay_Update *, ({ if (message->top >= data->height || message->bottom <= 0) return TRUE; if (message->top <= 0) message->top = 0; data->update_top = message->top; data->update_bottom = message->bottom; MUI_Redraw(self, MADF_DRAWUPDATE); return TRUE; }) case OM_SET: { struct TagItem *tagitem, *tagstate = msg->ops_AttrList; while( tagitem = NextTagItem( &tagstate ) ) { case MUIA_[classname]_Update: { MUI_Redraw( obj, MADF_DRAWUPDATE); break; } } return( DoSuperMethodA( cl, obj, msg ) ); } </pre> But better might be making just attribute to passing array of vectors.. When it's passed redraw is called.. or custom method: <pre> case MUIM_[classname]_Update: { MUI_Redraw( obj, MADF_DRAWUPDATE); return( 0 ); } </pre> You must not completely intercept OM_SET. Program sub-class some MUI class like Area.mui or Group.mui and they have their own attributes that might be set during program running.. Intercepting them or redrawing window might cause illegal actions.. =====Groups===== The group class was designed to contain other groups and gadgets not to be a gadget by self. It's a side effect because it's a subclass of area class (making it a subclass of notify class and copying part of methods would be senseless). Well... if you want create an image button (button with text and gfx), apart from the group class it could be done by creating subclass of MUIC_Area which in MUIM_Setup load necessary picture(s) using datatypes.library, draw it in MUIM_Draw and dispose in MUIM_Cleanup. Btw. the group class isn't a subclass of area class by mistake. Only group objects can have children. To get children there's MUIA_Group_ChildList. Walking through list is done with NextObject(). Example: <syntaxhighlight lang="c"> Object *obj1; struct List *children = (struct List *)XGET(_maingrp, MUIA_Group_ChildList); APTR pObj = GetHead(children); // Parse the children while(NULL != (obj1 = NextObject((Object **)&pObj))) { printf("ID is: %ld\n", XGET(obj1,MUIA_ObjectID)); } </syntaxhighlight> To get parent there's MUIA_Parent. If you don't know number of children or it's variable you would have to alloc some memory for the method struct ( sizeof(struct MUIP_Group_Sort) + sizeof(Object *) * num_children) and then call it with DoMethodA(obj, alloc'd_method). Then free the method struct again. num_children = number of successful NextObject() calls on child list. There's MUIM_Group_Sort method allowing you to tell the group object the exact order of the childs. NListview.mcc uses this and the group_initchange/group_exitchange stuff to dynamically show/hide scrollbars. Almost all attributes you set on a group will be forwarded to its children. You can set MUIA_Group_Forward to FALSE to prevent this (while setting the tag in question). a MUIM_Group_Insert method for inserting a child into a group in specified place, just like MUIM_Family_Insert. Currently move the child list from the group to my private family, insert the new child into my family with MUIM_Family_Insert and move all children from the family to the group again. on groups just like MUIM_Family_Sort on families. <pre> #define MUIM_Group_Sort 0x80427417 /* V4 */ DoMethod(parent, MUIM_Group_InitChange); DoMethod(parent, REMMEMBER, obj); set(obj, MUIA_FixWidth, 100); // just some changing beyond the object borders DoMethod(parent, ADDMEMBER, obj); DoMethod(parent, MUIM_Group_ExitChange); </pre> InitChange/ExitChange during setup/cleanup is not a good idea. You should add your childs in MUIM_Setup *before* the DoSuperMethod() and remove your childs in MUIM_Cleanup *after* the DoSuperMethod(). should not disable groups anyway just to disable its children. Better disable each child for itself, since this will indeed look nicer. You can do this with one DoMethod, e.g. MUIM_MultiSet or MUIM_SetUData Group is intended for objects having visual representation. For a text editor, if you group Buffer and Display objects it will be a bit tricky since Buffer isn't really a gadget. Editor should be a subclass of Display, and Buffer should be attached via pointer in object data structure. It better shows relations between Buffer and Display, they are not just a gadgets in a group. Basically you have to call MUIM_InitChange before removing or adding objects and then call MUIM_ExitChange: <pre> DoMethod(yourgroup,MUIM_InitChange) DoMethod(OM_ADDMEMBER,newobject) DoMethod(yourgroup,MUIM_ExitChange) </pre> to trigger a relayout by doing a MUIM_Group̠InitChange and MUIM_Group_Exitchange on the _parent(obj) Every object should be responsible for passing the new settings on to its children. Like when you have a subclass of group that contains a numeric and a string gadget, it will have some attribute that holds a structure of the gadgets' respective values, and the group object has to know which value goes to which of its children and set them accordingly when itself it receives an OM_SET. Then you'd ideally do a set(mywindow,PREFS_ATTRIBUTE,&some_structure) and the object tree would handle the rest by itself. Then there's no other way than to remember each object that needs to be updated in some structure and set() it "by hand". virtgroup.mui are internal part of MUI (they're "inside" muimaster.library). The virtual group it's like a container that can scroll if the content exceeds its boundaries. A Virtual group makes sense inside a ScrollGroup. you should not use MUIA_Pressed for notifying toggle gadgets (only for RelVerify ones like buttons). Use MUIA_Selected. <pre> window ---> group (<--- set MaxWidth/MaxHeight here, works) ------> scrollgroup ---------> virtgroup ------------> text ------> rectangle (<--- or here, works, too) </pre> How to get a virtgroup which is only in the horiz direction virtual w/o using scrollgroup (use MUIA_Scrollgroup_FreeVert, FALSE) or is there a way to have the scrollbar hidden all the time? You need a [http://morphosambient.cvs.sourceforge.net/morphosambient/ambient/virtgroupclass.c?revision=1.5&view=markup custom class] which uses fixed height or width thus locking virtgroup vertically or horizontally. Adding objects to a group on the fly. First you have to '''init''' the changes you want to do, then '''perform''' them and then declare you have '''finished'''. Example of code to add or remove a group from another group: <syntaxhighlight lang="c"> Object *_maingrp = .... // the container Object *_subgrp = .... // the content // add the subgroup if(DoMethod(_maingrp, MUIM_Group_InitChange)) { DoMethod(_maingrp, OM_ADDMEMBER, _subgrp); DoMethod(_maingrp, MUIM_Group_ExitChange); } // remove the subgroup if(DoMethod(_maingrp, MUIM_Group_InitChange)) { DoMethod(_maingrp, OM_REMMEMBER, _subgrp); DoMethod(_maingrp, MUIM_Group_ExitChange); } </syntaxhighlight> <pre> LONG sigs; DoMethod(app,MUIM_Application_NewInput,&sigs); </pre> This seems to be a general pitfall for MUI programmers, but 'sigs' really has to be initialized to zero! It's worse: sigs is the result of Wait(), i.e. the signals received by the process. So if you give a random value, MUI will think random signals were received, and act on these. Normally the effect of this is not noticeable, as a message-port signal will just cause a "while(GetMsg(port))", which will immediately terminate, but in theory serious problems could arise Want to reproduce the Workbench way of dealing with icons. Want to be able to move images from a point to another. Derive a Group (virtual or otherwise) with its own custom layout hook and make the objects of that group Draggable; when you get a drop event, re-layout the group (force this using MUIM_Group_InitChange = followed by ExitChange) [http://www.henning-thielemann.de/ProgramsE.html TableGroup] <pre> MUIM_Group_ExitChange MUIM_Group_InitChange MUIM_Group_Sort MUIA_Group_ActivePage MUIA_Group_Child MUIA_Group_ChildList MUIA_Group_Columns MUIA_Group_Horiz MUIA_Group_HorizSpacing MUIA_Group_LayoutHook MUIA_Group_PageMode MUIA_Group_Rows MUIA_Group_SameHeight MUIA_Group_SameSize MUIA_Group_SameWidth MUIA_Group_Spacing MUIA_Group_VertSpacing </pre> =====RMB and LMB===== RMB menus to gadgets. Context menus are a feature of the Area class, and can be set with MUIA_ContextMenu, or dynamically created by overloading MUIM_ContextMenuBuild. Is it possible to use rmb as lmb in MUI? Yes, you should override MUIM_ContextMenuBuild for your object. Create fake Menu object (just with one menu and no items), give it to MUIA_ContextMenu attribute and do your job in MUIM_ContextMenuBuild, returning NULL from there (it means no context menu will be drawn). Well, its not easy, because there is no simple method to get informed about RMB _release_. You have to sub-class Text class and write own MUIM_HandleInput, which is mentioned in docs as obsolete. But unfortunately MUI event handlers don't react to RMB (bug in MUI?). can look at the MUIMine source (on Aminet). It does something like that and mentions problems with the RMB. It's also using MUIM_HandleInput. =====Dragging===== <pre> ULONG MyList_DragQuery(struct IClass *cl,Object *obj,struct MUIP_DragDrop *msg) { if (msg->obj==obj) { //return(MUIV_DragQuery_Accept); return(DoSuperMethodA(cl,obj,(Msg)msg)); } else { if (msg->obj==(Object *)muiUserData(obj)) return(MUIV_DragQuery_Accept); else return(MUIV_DragQuery_Refuse); } } </pre> Whenever there are no conflicting inputs, MUI starts the drag operation immediately. If the LMB is needed for anything else (ie on a button), MUI starts dragging like specified in the prefs. set MUI_Draggable, TRUE to an object of a MUI_Area subclass <pre> get(obj,MUIA_List_DropMark,&dropmark); DoMethod(obj,MUIM_List_InsertSingle,entry,dropmark); </pre> Note that you must get the dropmark from the destination object, *not* from the source. One mode allows you to enter the data in the string gadget. The other allows dragging. In the dragging mode you make the StringObject a TextObject. That way you have no problems dragging the objects around. You could also try making a Custom string class. How to get MUI to report the dropped position relative to the object that is accepting the drop? Also is there some way to get mui to report based on the top, left of the object that was grabbed and not report from where you grabbed the object at? If the position is screen based, just substract from it _mleft(obj) and _window(obj)->LeftEdge, _mtop(obj and _window(obj)->TopEdge. Is there a way to react to a dragging of a workbench icon into an appwindow created with MUI. The desktop manager sends message to an application only when user stopped dragging so it is not possible. MUI has its way to handle d&d with MUIM_DragBegin/DragFinish for its MUI object.... MUIM_DragBegin/Finish are for internal MUI D&D. AppWindow messages are externally generated and MUI can not control it. This is typically a method that you usually won't call yourself (like the drag'n'drop methods of area.mui) <pre> MUIM_AskMinMax MUIM_Cleanup MUIM_ContextMenuBuild MUIM_ContextMenuChoice MUIM_CreateBubble MUIM_CreateShortHelp MUIM_DeleteBubble MUIM_DeleteShortHelp MUIM_DragBegin MUIM_DragDrop MUIM_DragFinish MUIM_DragQuery MUIM_DragReport MUIM_Draw MUIM_DrawBackground MUIM_HandleEvent MUIM_HandleInput MUIM_Hide MUIM_Setup MUIM_Show MUIA_Background MUIA_BottomEdge MUIA_ContextMenu MUIA_ContextMenuTrigger MUIA_ControlChar MUIA_CycleChain MUIA_Disabled MUIA_Draggable MUIA_Dropable MUIA_ExportID MUIA_FillArea MUIA_FixHeight MUIA_FixHeightTxt MUIA_FixWidth MUIA_FixWidthTxt MUIA_Font MUIA_Frame MUIA_FramePhantomHoriz MUIA_FrameTitle MUIA_Height MUIA_HorizDisappear MUIA_HorizWeight MUIA_InnerBottom MUIA_InnerLeft MUIA_InnerRight MUIA_InnerTop MUIA_InputMode MUIA_LeftEdge MUIA_MaxHeight MUIA_MaxWidth MUIA_Pressed MUIA_RightEdge MUIA_Selected MUIA_ShortHelp MUIA_ShowMe MUIA_ShowSelState MUIA_Timer MUIA_TopEdge MUIA_VertDisappear MUIA_VertWeight MUIA_Weight MUIA_Width MUIA_Window MUIA_WindowObject </pre> ====register (TABS)==== how can a child (a tab) of a register (Tab) know that he is currently visible w/o knowing in which tab it is? Have a .mcc which is a subclass of group and creates a row of cycletitle-objects (like cycle gadget, but with a fixed title string within the cyclegadget) where each button represents a window. The group gets notified (by notifyintuition.library) when a new window is opened or one win gets closed. or create a subclass of group which has a new attribute of something like MUIA_XGroup_PageIndex. You could then compare this to the "main groups" objects active page. You should know the "main group" object as it gets this from reading MUIA_Parent of the "tab page". if tabpage.pageindex = tabpage.parent.activepage then (simple pseudo code) Or create a subclass of register which as well as MUIA_Group_ActivePage has say MUIA_Group_ActivePageObj which is set on a change of MUA_Group_ActivePage. You could then compare this to the "tab page". if tabpage = tabpage.parent.activepageobj then (simple pseudo code) Or create a new method of register that returns the current obj (similar to your above idea) but as a method it will be usable for all your register groups. <pre> MUIA_Register_Frame MUIA_Register_Titles </pre> ====Lists==== ;[http://library.morphzone.org/Subclassing_List_Class good examples of lists] * The list class is a class which can hold and manipulate (to some extent) a linked list of data. * The listview class is a group subclass which handles the layout and interconnection of a list and the required sliders. Listtree which uses images for the branches, but afaik doesn't allow you to change the image. At startup the list is empty and add entries with MUIM_List_InsertSingle. MUIA_List_SourceArray to assign an strarray then use the MUIA_List_Active result as the index for that array. MUIM_List_Remove listview to have the width of the text inside and no more and no less. MUIA_List_Format - MAXWIDTH/MINWIDTH MUIA_List_AdjustWidth, TRUE to insert strings in a ListView: DoMethod(projectfiles,MUIM_List_InsertSingle,(long unsigned int)TXT.sfilename.c_str(),(IPTR)MUIV_List_Insert_Bottom); COPYING you will need to define Construct & Destruct hooks as List object does NOT copy your string (just takes a pointer) until you order otherwise. If you got simple one column list and you will be satisfied storing just strings in it, MUI offers builtin construct hooks for this. Refer autodocs for construct & destructs (must set both!). MUIA_List_ConstructHook, MUIV_List_ConstructHook_String MUIA_List_DestructHook, MUIV_List_DestructHook_String MUIV_List_Remove_Selected You can call MUIM_List_CreateImage as soon as the list class completed its setup method. You must call MUIM_List_DeleteImage before the list completes its cleanup method. MUIM_Insert_xyz inserts an Object to a List, this meant that the List class can handle any Object and so you can not add only Strings to it. only a Pointer is stored and not the content of it. Note the List is not responsible for Displaying its' content, this was done by the Listview and by default it´s Displayhook expects pointers to a Text in the list. how to add a small image next to a string in the list? game/think/MUIMastermind.lha might have a simple approach without CreateImage() and so on. Reading MUIA_List_Active gives me the entry number, but if the order's changed, it doesn't mean anything? GetEntry returns pointer to your entry and you can access any column you wish. It's your private pointer anyway. If you want a page background for an app, simply use MUIA_Background, MUII_PageBack for your group object. '''Obsolete Hooks.''' If hooks are being used, multicolumn List object to display the result but want to add title to columns <pre> HOOKPROTO(ResultList_Display, ULONG, char **array, struct ReqData *reqdata) { if (reqdata) { int n; for (n=0; n<reqdata->nb ; n++) { *array++ = reqdata->columns[n]; } } else { reqdata = (struct ReqData *)hook->h_Data; // list titles int n; for (n=0; n<reqdata->nb ; n++) { *array++ = reqdata->columns[n]; } } return 0; } MakeStaticHook(hook_ResultList_Display, ResultList_Display); Somewhere in your code you set h_Data: hook_ResultList_Display.h_Data = (APTR)reqdata_titles; </pre> You can either build a hook object that h_entry part is your function and use MUIM_CallHook or subclass the object id_main_add so that it handles a particular method, and in the case of your method is received call your add some function (it's the recommended way).. the callhook stuff would be something like struct Hook h = { addsome, NULL, NULL }; DoMethod(id_main_add, MUIM_Notify, MUIA_Pressed, FALSE, id_main_add,2, MUIM_CallHook, &h ); for AROS you have to change <pre> #define MUI_LIST_DISP(x,y) ULONG SAVEDS ASM x (REG(a2,char **array), REG(a1, y )) to #define MUI_LIST_DISP(x,y) ULONG SAVEDS ASM x (REG(a0,struct Hook *h), REG(a2,char **array), REG(a1, y )) </pre> so that a pointer to the Hook is the 1st argument. Same for other [hook macros http://aros.sourceforge.net/documentation/developers/headerfiles/aros/asmcall.h]. We have some hints about hooks in our [documentation http://aros.sourceforge.net/documentation/developers/app-dev/portable.php#hooks] <pre> MUIM_List_Clear MUIM_List_CreateImage MUIM_List_DeleteImage MUIM_List_Exchange MUIM_List_GetEntry MUIM_List_Insert MUIM_List_InsertSingle MUIM_List_Jump MUIM_List_Move MUIM_List_NextSelected MUIM_List_Redraw MUIM_List_Remove MUIM_List_Select MUIM_List_Sort MUIM_List_TestPos MUIA_List_Active MUIA_List_AdjustHeight MUIA_List_AdjustWidth MUIA_List_AutoVisible MUIA_List_CompareHook MUIA_List_ConstructHook MUIA_List_DestructHook MUIA_List_DisplayHook MUIA_List_DragSortable MUIA_List_DropMark MUIA_List_Entries MUIA_List_First MUIA_List_Format MUIA_List_InsertPosition MUIA_List_MinLineHeight MUIA_List_MultiTestHook MUIA_List_Pool MUIA_List_PoolPuddleSize MUIA_List_PoolThreshSize MUIA_List_Quiet MUIA_List_ShowDropMarks MUIA_List_SourceArray MUIA_List_Title MUIA_List_Visible </pre> ====Strings==== How to get notification of when an MUI string gadget is made active? So I know when the user has clicked on the gadget and activated the cursor, but before they start typing anything? I've tried setting MUIA_InputMode to MUIV_InputMode_RelVerify and MUIV_InputMode_Immediate, but neither work with either the MUIA_Pressed or MUIA_Selected notifications. Build a subclass of String.mui and do what ever you need to do in the MUIM_GoActive and MUIM_GoInactive methods. Converts input from a 'text box' (using Zune/MUI) to a floating point number. <pre> get(my-string-object, MUIA_String_Contents, &str); stcd_l(str, &num); </pre> Subclass the gadget and overload MUIM_GoInactive. Just be sure you've considered every situation the user may be in, e.g. leaving the gadget temporarily to copy the rest of the value from some other place or similar. Needed to subclass string gadget and add own event handler. As a workaround (imho), return DoSuperMethodA(cl,obj,(Msg)msg); when you return 0. You can notify MUIA_String_Contents, which will be triggered each time the content change. You can probably also use MUIA_Window_ActiveObject, which should be set to everything but the string gadget when it goes inactive. And if you use one of the string gadget replacements then there's also the possibility of overloading MUIM_GoInactive for the string class (Textinput, Newstring or Betterstring). But keep in mind that inactivating the gadget (using tab, the mouse, opening a new window or similar) should never have a confirming effect! <pre> MUIA_String_Accept MUIA_String_Acknowledge MUIA_String_AdvanceOnCR MUIA_String_AttachedList MUIA_String_BufferPos MUIA_String_Contents MUIA_String_DisplayPos MUIA_String_EditHook MUIA_String_Format MUIA_String_Integer MUIA_String_LonelyEditHook MUIA_String_MaxLen MUIA_String_Reject MUIA_String_Secret </pre> ====Numeric (slider, knobs, levelmeters etc)==== Releasing the button when NOT over the gadget is well regarded to be a "cancel" action. Like "whoops! I accidentally pressed the button, but now I don't want to exit, so I'll move my mouse away" Sliders also keep the value you dragged them to if you release the mouse outside the gadget. How about getting a notification on a slider when the slider is released only? I tried MUIA_Pressed but that didn't work. If you also use Area.mui/MUIA_InputMode. Also, I noted that MUIA_Slider_Level says (OBSOLETE). Use MUIA_Numeric_Value instead. If pressing TAB key cycles options. How can I implement that ? You just set MUIA_CycleChain (area class) as TRUE in all the objects you want to be part of the cycle-chain. Cycle object <pre> STRPTR colors[] = { "Red", "Green", "Blue", NULL }; ULONG colorsV; STRPTR ch; // then in the program... get(cy1, MUIA_Cycle_Active, &colorsV); ch = (char *)colorsV; </pre> Cycle_active contains the NUMBER of the selected item. To get the string you need to do something like this: ch = colors[ colorsv ]; Since MUIA_Cycle_Entries is [I..] the only way is to create a new cycle every time you want to change the entries. To do this you do MUIM_Group_InitChange on the group containing the cycle, then OM_REMMEMBER the old one, OM_ADDMEMBER the new one and do MUIM_Group_ExitChange. You may have to use MUIM_Group_Sort to get the cycle to the right place or put it into a separate group. Can anyone tell me if it is possible to create a dynamic cycle gadger You can "emulate" it by removing the gadget and creating a new one with MUIA_Cycle_Entries changed. Use MUIM_Group_InitChange/ExitChange for this. <pre> MUIA_Cycle_Active MUIA_Cycle_Entries </pre> a slider with gradient background. You can set gradient by MUIA_Background (but attribute string is undocumented) or maybe overloading MUIM_DrawBackground... Sliders that look like a regular button when not pressed, but when pressed, they pop up and become a slider. They save a lot of space. It's a NumericbuttonObject - it's used in the demo program Slidorama. <pre> MUIM_Numeric_Decrease MUIM_Numeric_Increase MUIM_Numeric_ScaleToValue MUIM_Numeric_SetDefault MUIM_Numeric_Stringify MUIM_Numeric_ValueToScale MUIA_Numeric_CheckAllSizes MUIA_Numeric_Default MUIA_Numeric_Format MUIA_Numeric_Max MUIA_Numeric_Min MUIA_Numeric_Reverse MUIA_Numeric_RevLeftRight MUIA_Numeric_RevUpDown MUIA_Numeric_Value </pre> ====Menus==== Mui has its own methods for menus but the old NewMenu calls can still be used. The best way is maybe to create&dispose the context menus you need in a subclass of window class. Menu items are set for currently active window? In the case you can set up different menu for each of window, preferably inside window subclass, and with notification which will call method or attribute or your's window class and it'll be able to react. <syntaxhighlight lang="c"> </syntaxhighlight> How to notify on pressing shortcut combination with shift, control and alt keys? I tried such code: DoMethod(win, MUIM_Notify,MUIA_Window_InputEvent, "-control x",app, 2,MUIM_Application_ReturnID,MEN_RUN); but I get notification each time X button is pressed (no matter whether control is pressed). You need a normal eventhandler in your class for that. Please do not use returned stuff? So I see the only way is to use rawkey hook. Want such shortcuts for menu items, there are too many of them so I can't use combinations with Amiga for each one. menu item "MUI Settings...". To set a notify to the menu item that calls MUIM_Application_OpenConfigWindow The way to do this would be to implement a MenuTrigger method in one of your subclasses (MUIC_Window or the window's Root MUIC_Group are always safe picks) and have a MUIA_Window_MenuAction notification call it. There you could either have a switch with all the IDs, or simply use methodIDs instead of menu IDs and just do it like: <pre> ULONG mMenuTrigger(struct IClass *cl, Object *obj, struct mpMenuTrigger *msg) { DoMethod(obj, msg->menutriggercommand); } </pre> Once all menu triggers are nicely done as methods (say MUIM_MyClass_Open, MUIM_MyClass_DoSomething) and you've built a menu using those IDs, you could also implement an eventhandler in the Group subclass I mentioned and simply map raw keys into methods again. This could be done nicely using something like: <pre> struct MenuKey { ULONG methodForQualifierShift; ULONG methodForQualifierControl; ULONG methodForQualifierAlt; ULONG methodForQualifierAltShift; }; </pre> and then have these mapped like <pre> struct MenuKey hotkeys[256] = { {0, MUIM_MyClass_Jump}, // RAWKEY_TILDE {MUIM_MyClass_First}, // RAWKEY_1 .... }; </pre> so you can easily map every key combo into a method. Well... just one of the many possible approaches to this problem, but one that will leave you with a nice OO structure in the source. Added a check for msg->imsg->Code==MENUDOWN which reatcs the RMB being pressed and stops the timer. I also did the reverse msg->imsg->Code==MENUUP which would start the timer again. BUT - once the Menu is open the mouse button presses are attached to the menu and not my window/object so the MENUUP button event is never seen so my timer remains stopped and does not start again after using a menu. You could use MUIA_Window_MenuAction to be notified when a menuitem was chosen, DoMethod (win, MUIM_Notify, MUIA_Window_MenuAction, MUIV_EveryTime, obj, 2, MM_Main_MenuAction, MUIV_TriggerValue); Not sure if the attribute gets triggered when no item was selected... Checking window activation does not help either as the window remains active when a menu is opened so nothing changes. You could add a global input handler for checking of RMB pressing and releasing and then also check if the mouse pointer is over your window... '''Redundant''' MUIA_Application_Menu and MUIA_Window_Menu (old New Menus system) '''Redundant''' MUIM_Application_GetMenuCheck, MUIM_Application_GetMenuState, MUIM_Application_SetMenuCheck, MUIM_Application_SetMenuState '''Redundant''' MUIM_Window_SetMenuCheck, MUIM_Window_SetMenuState, MUIM_Window_GetMenuCheck, MUIM_Window_GetMenuState <pre> MUIA_Menu_Enabled MUIA_Menu_Title </pre> =====MenuStrip===== Menustrip class is the base class for MUI's object oriented menus. Its children are objects of Menu class, each of them describes exactly one menu. A Menustrip object doesn't feature many options itself, but as a subclass of Family class, it simply acts as father for multiple Menu objects. The Menustrip object is usually specified as a child of either Application class or window class with the attributes MUIA_Application_Menustrip or MUIA_Window_Menustrip. Have you tried using MenustripObject and MenuObject instead of MenuitemObject, and MUIA_Menu_Title instead of MUIA_Menitem_Title? Though to be honest, I'm not sure if all of those macros exist in AROS. the hierarchy is: MenustripObject -> MenuObject -> MenuitemObject Using Menuitems everywhere worked before, but it was not compatible with MUI and was changed. With family objects (from Wanderer/Info): DoMethod(_win(obj), MUIM_Notify, MUIA_Window_MenuAction, MUIV_EveryTime, obj, 2, MUIM_MySubClass_MenuThingy, MUIV_TriggerValue); Read more about Menus in MUIA_Window_MenuAction section of muidevs. See also DiskSpeed.c in DiskSpeed drawer of the contrib-source of AROS. In one MenuItem tag there wasn`t a "MUIA_UserData" tag identifier in front of the ID of that menuitem and so on a dispose gcc somehow freed an area in memory that caused the crash where sas/c didn`t somehow. <pre> entry = MUI_MakeObject(MUIO_Menuitem,advance_name_translation(i),NULL,0,0); set(entry,MUIA_UserData,i); DoMethod(entry,MUIM_Notify,MUIA_Menuitem_Trigger, MUIV_EveryTime, entry,6, MUIM_CallHook, &civstandard_hook, diplomacy_tech, pdialog, plr0->player_no,entry); DoMethod(menu_title,MUIM_Family_AddTail, entry); </pre> <pre> MUIA_Menustrip_Enabled </pre> ====Requesters==== MUI_Request(app, mainwnd, 0L, "Sorry...", "Close", "...but this feature is not yet implemented", NULL); Either create your new objects outside this huge MUI constructions, and in there use just a pointer, or get rid of the "End" macro and exchange it with "TAG_DONE)". On MOS and AmigaOS, the NewObject variadic function is kept in the static library. It takes most of the parameters on the stack - thanks to that the implementation of NewObject calls the NewObjectA function. Everything works perfect, and the typical MUI macros may be easily used. This, however, is not the case when you compile for AROS. Here, NewObject is a variadic macro, not a function. Thanks such approach we do not need any custom compiler in case of systems, where the arguments of variadic functions are passed partially through registers and partially through the stack (This is the case of PPC and x86_64, this is also the reason why both OS4 and MOS require specially patched compilers). Since NewObject is a macro, the gcc's preprocessor expects the list of macros arguments enclosed within parentheses. In MUI macros it is not the case. =====ASL requester===== this should [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=1430&forum=2&post_id=11642#forumpost11642 help]: <syntaxhighlight lang="c"> struct FileRequester *req; if ((req=MUI_AllocAslRequestTags(ASL_FileRequest, ASLFR_Window,win , ASLFR_TitleText, "A requester for AmiDevCpp", ASLFR_InitialDrawer , "T:", ASLFR_InitialFile, "foo.txt", ASLFR_InitialPattern , "#?.txt", ASLFR_DoPatterns , TRUE, ASLFR_RejectIcons , TRUE, TAG_DONE))) { if (MUI_AslRequestTags(req,TAG_DONE)) { /* you can find the drawer in req->fr_Drawer and the file in req->fr_File */ } } </syntaxhighlight> MUI_AslRequest() functions and MUI takes care of window refresh for you. <pre> MUIA_Popasl_Active MUIA_Popasl_StartHook MUIA_Popasl_StopHook MUIA_Popasl_Type </pre> ====Pop Up Pen etc==== MUIA_Window or MUIA_WindowObject? MUIA_Window should refer to struct Window * but MUIA_WindowObject to Object * Both are always NULL for a popup list, whether open or not. An interesting point is that the window object pointer supplied to the MUIA_Popobject_WindowHook is non-NULL. checking for whether popup is open such work around anyway? Popup object is open only a while, when user clicked popup button and popup object appeared on screen- any clicking causes popup object to disappear. So, I can't even imagine where and why are you checking this.. From 2nd parallel running task? If popup object is made by you, you always can subclass any MUI class. And this way you will get all methods and attributes like f.e. OM_SET/OM_GET and MUIM_Setup/MUIM_Cleanup/MUIM_Show/MUIM_Hide. Probably listening on show/hide might help checking whether popup is currently open. This method probably should work also for other MUI applications, if you're not owner of app, but making monitor software- but instead subclassing get and store dispatcher address, then put your own, and listen methods/attrs like above, then call original dispatcher to return control to original application. It looks like [http://www.sasg.com/mui/autodocs/MUI_Popstring.html Popstring] has special hooks for this task * MUIA_Popstring_OpenHook * MUIA_Popstring_CloseHook Shift up/down is (normally) bound to page up/down, and if the listview hasn't been drawn once, then there are no page dimensions. DoMethod(PP_String, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, App_p, 2, MUIM_Application_ReturnID, RID_EXECUTE); A notify watch if a tag changes (for the given object) - MUIA_String_Acknowledge is a tag of the string class (not the Popph-string) and is set (and therefor changed) for the string object. So the notify must be on this object, rather than the container (which is Popph) Either get the pointer to the internal string-object, and setup a notify on this (and do try to avoid ReturnID's ;-) ) Should just be to forward MUIM_Notify to the child objects, preferably only if OM_GET returns TRUE for the tag in question. I.e. if OM_GET returns TRUE for the Popph object itself (an Area class tag probably) then keep the notify, otherwise try to see which of the children supports it. Or maybe it'd be better if Popph introduced two new methods a la MUIM_Popph_NotifyString & List. Then one could use either of these to setup a notify on an internal object. nothing wrong with ObtainBestPenA() if you don't want the user to configure the pen values (which you often do want) - though avoid placing the pen-stuff in MUIM_Show/Hide, it should be MUIM_Setup/Cleanup, otherwise it'll re-allocate pens each time you resize the window If you want the user to be able to configure the pens then you do so by using the Poppen-object together with MUI_ObtainPen() - here's a snip from MUI_PopPen.Doc: Anyway, you do not have to care about the internals of this class. Just create it like obj = MUI_NewObject(MUIC_Poppen, MUIA_CycleChain , 1, MUIA_Window_Title, "Followed Links Color", TAG_DONE); somewhere in your prefs window and everything will be fine. You can get/set the current color from a Poppen object by using the MUIA_Pendisplay_Spec attribute. The resulting struct MUI_SpenSpec may then be saved somewhere in your preferences and used as parameter for MUI_ObtainPen() and MUI_ReleasePen(). comes back in the format of: "rxxxxxxgxxxxxxbxxxxxx". There are 3 parameters in MUI_ObtainPen() *mri , *spec & flags.l look in libraries/mui.h and you will fin a macro like this muiRenderInfo() just do this mymri = muiRenderInfo(myobj); and should have a valid MUI_RenderInfo but this macro should only be used between MUIM_Setup/MUIM_Cleanup A popobject which is connected to a string gadget. The popobject is a listview. So that pressing up/down in the string gadget will scroll the listview updown (even when the listview is hidden) ? MUIA_String_AttachedList -- (V4 ) [ISG], Object * <pre> MUIA_Popobject_Follow MUIA_Popobject_Light MUIA_Popobject_Object MUIA_Popobject_ObjStrHook MUIA_Popobject_StrObjHook MUIA_Popobject_Volatile MUIA_Popobject_WindowHook </pre> <pre> MUIA_Poplist_Array </pre> <pre> MUIM_Popstring_Close MUIM_Popstring_Open MUIA_Popstring_Button MUIA_Popstring_CloseHook MUIA_Popstring_OpenHook MUIA_Popstring_String MUIA_Popstring_Toggle </pre> ====Text==== * (N)Floattext already does exactly the same as you did using the list. It splits a long text into separate lines, inserts some spaces to produce an aligned text and displays them. * The TextEditor class in read-only does more or less the same like Floattext, but with the ability to apply different styles and coloring apart from the standard MUI text engine. Furthermore it allows to let the user edit the text in read-write mode. YAM makes heavy use of it in both modes to show and edit the mails. Where ony Text() is done. So the size of the area depends on the size of the actual default font. Using rp(obj)->Font, but in AskMinMax it seems that when it is first called, the Font is not yet initialized. You can use _font(obj) to obtain the font. If you also need a rastport then you can setup one temporarily to do your calculations. <pre> struct RastPort rp; InitRastPort(&rp); SetFont(&rp, _font(obj)); WORD size = TextLength(&rp, "The Text", 8); </pre> The problem is that text will not stay the right size. They are either spread all over the window, or cramped into one edge, when all I want them to do is to stay on the right and just as big to display 6 chars (as long as possible). MUIA_String_Maxlen seems to have no effect, and just forcing one width doesn't seem right as you never know wether the user may prefer to use a font 50 pixels wide. Use tag MUIA_FixWidthTxt. For example str = StringObject, MUIA_FixWidthTxt, "0000000", End; Note 7 characters there: one is for cursor. And use characters which are wide by nature (read MUI_Area.doc and you understand why). It could also be solved by using MUIA_Weight, weight. Try a combination of "MUIA_Weight, weight" for the string(s) and Put RectangleObjects before/and/or/after the stringobject. For example, to align a gadget to the right <pre> HGroup, Child, RectangleObject, MUIA_Weight, 75, End, Child, StringObject,...,MUIA_Weight, 25, End, End, </pre> Which means that if you want to change the label and the key shortcut using one attr, you should subclass text, and handle a specific tag for changing the label and the shortcut, parsing yourself the string. Examples of subclassing a mui class can be found in mui dev kit (especially psi contains many subclasses...) and some tools can help you to have a skeleton class using a meta definition of the class you want (mui2c or bcc do such things). If you create a subgroup something like: <pre> mygroup=Group ( MUIA_Group_PageMode,True Child,SimpleButton("_Download"), Child,SimpleButton("_Resume"), TAG_DONE) </pre> you get much better result. The "Download" button is now visible, but if you set (mygroup, MUIA_Group_ActivePage, 1) "Download" disappears and "Resume" becomes visible. This is very common trick in MUI applications. Buttons are simply text objects, which have the following tag: MUIA_Text_SetVMax, TRUE Setting this to FALSE makes a TextObjects y-size unlimited. Defaults to TRUE which means the objects height is fixed. A plain text object cannot be higher than its text, unless you set MUIA_Text_SetVMax to FALSE (default is TRUE). This will give your object unrestricted height, but the text will be displayed vertically centered, unless you set MUIA_Text_VCenter to FALSE. MUIA_Text_Contents is ISG so: SetAttrs(text, MUIA_Text_Contents, "NewContent", TAG_DONE); set (object->STR_text, MUIA_Text_Contents, myText); object->STR_Text ? Looks like MUIBuilder generated code :) If your 'text-edit-box' is a String object, you'd rather use set( object->STR_text, MUIA_String_Contents, myText ); How to calculate the x/y coords to use with the Move() function so that when using Text() to draw the label it appears centred. There is bunch of macros in mui.h: <pre> _mleft() = starting x coordinate of your drawing area _mtop() = starting y coord etc. _mwidth() = width of your drawing area _mheight() = obvious =) </pre> <pre> text_height=GetItSomeHow(); text_len=TextLength("heipparallaa"); Move(rp, _mleft(obj) + ((_mwidth(obj) - text_len) / 2), _mtop(obj) + ((_mheight(obj) - text_height) / 2) ); </pre> (TextObject) If you really need to change the text, then you must set() it again after the modification. If using a TextObject, then it has the FULL initial size... but if appending extra lines then these are not visible (although a bug causes it to write outside of itself!). The only way to get it to enlarge for the new text is to iconise & then uniconise the MUI window. Also, the text is not word-wrapped. You must not modify the text as long as it is "in use" by the object. MUI will calculate the required dimensions on basis of the given text and expects it to be constant. If you really need to change the text, then you must set() it again after the modification. This will let MUI do a relayout to display all of the new text. But this will work to a certain extend only, namely when the complete text's height becomes larger than the window's maximum height. If you need to display larger texts, then the object should be placed into a Scrollgroup object (some of which is MUI4 compatible) like this: <pre> ScrollgroupObject, MUIA_Scrollgroup_AutoBars, TRUE, MUIA_Scrollgroup_Contents, VGroupV, Child, TextObject, MUIA_Text_Contents, "insert your text here", MUIA_Text_Copy, TRUE, End, End, End, </pre> The attribute MUIA_Scrollgroup_AutoBars will let the scrollgroup show the scrollbars only if they are really needed, i.e. the contents' dimensions are larger than the scrollgroup's dimensions. This attribute is available in MUI4 only like MUIA_Text_Copy, MUI3 will silently ignore it and always show the scrollbars. Second, the attribute MUIA_Text_Copy instructs Text.mui to keep a copy of your text. This makes it possible to free() the text given to MUIA_Text_Contents after object creation of after set() and it also allows you to modify the text without risking any graphical glitches due to redraw operations while the text is still modified. However, your text will always be displayed exactly as you specify it. This means that you need to insert line breaks yourself. If using FloattextObject or TextEditorObject, then no matter the initial contents, the initial size is always three lines of text (which is the minimum space needed by the scrollbar + arrows), but it is at least vertically scrollable. Also, the text is word-wrapped. Since Floattext.mui inserts line breaks itself you cannot expect a variable height, because the text's height depends on the object's width. You can enforce a certain object height by using something like MUIA_FixHeightTxt, "\n\n\n\n". This will give you a fixed height of four lines while respecting the object's font. Floattext.mui is a subclass of List.mui and as such has no restrictions on its dimensions, except you enforce them, i.e. by using MUIA_FixHeightTxt or by subclassing Floattext.mui yourself with a restricting implementation of MUIM_AskMinMax. MUI cannot just resize an object to display the entire initial content, because the content is arbitrary. It may be zero lines, but it may be a million lines. What should the initial size be in this case? Of course you can override MUIM_AskMinMax and return the dimensions which fit you best, but you must be prepared and accept that MUI will adapt the actual dimensions of the object within the limits that your (or the default) MUIM_AskMinMax method returns. If want to the Floattext object to be resizeable then you must make the label resizeable as well by adding at least one space object above or below the label object like this: Child, VGroup, Child, Label2("FloattextObject"), Child, VSpace(0), End, This will give you a top aligned label. Placing the label after the VSpace(0) object will make it bottom aligned. Using VCenter() will give you a vertically centered label. Choose the solution which fits your needs best. Have a look at MUI's demo application MUI-Demo. It uses Floattext objects in every single window. <pre> MUIA_Text_Contents MUIA_Text_PreParse MUIA_Text_SetMax MUIA_Text_SetMin MUIA_Text_SetVMax </pre> ====Fonts==== try putting SetFont(_font(obj)); in your MUIM_Draw. In OM_NEW you should set MUIA_Font to one of the predefined values (the MUIV_Font_XXXXXX values) and mui will open the font for you and make it accessible using _font(obj) In MUIM_Draw, SetFont() to my fonts opened in MUIM_Setup. If SetFont(_font(obj)) otally lose user-settable-fonts. You are not allowed to change settings of _rp( obj ) directly! So make sure you are working on a copy of original rastport and then set fonts, colours or whatever. <pre> struct RastPort rp1 = *_rp( obj ); struct RastPort *rp = &rp1; SetAPen( rp, 0 ); </pre> The same applies to normal gadgetclass BOOPSI objects, where before drawing anything you have to ObtainGIRPort(), draw and then ReleaseGIRPort()... MUICFG_Font_Fixed ====Gadgets==== MUIM_Import/Export and handle the loading and saving yourself. The advantages are that you don't need to create, and call MUIM_Export for the pages that the user doesn't visit, as you'll export the settings (from the created/visited pages) into an already filled dataspace object (loaded during program startup) - which should save both time, memory and complexity. Another advantage is that it makes it very easy to add options such as "Reset to defaults", "Restore" etc. Two functions which should make it easier to save/read IFF files into dataspace objects. <syntaxhighlight lang="c"> VOID LoadDataspace (STRPTR file, Object *dataspace) { BPTR fh; if(fh = Open(file, MODE_OLDFILE)) { struct IFFHandle *iff; if(iff = AllocIFF()) { InitIFFasDOS(iff); iff->iff_Stream = (ULONG)fh; if(!OpenIFF(iff, IFFF_READ)) { if(!StopChunk(iff, 'PREF', 'IPRB')) { if(!ParseIFF(iff, IFFPARSE_SCAN)) DoMethod(dataspace, MUIM_Dataspace_ReadIFF, iff); } CloseIFF(iff); } FreeIFF(iff); } Close(fh); } } </syntaxhighlight> <syntaxhighlight lang="c"> VOID SaveDataspace (STRPTR file, Object *dataspace, Object *app) { BOOL retry; do { retry = FALSE; BPTR fh; if(fh = Open(file, MODE_NEWFILE)) { struct IFFHandle *iff; if(iff = AllocIFF()) { InitIFFasDOS(iff); iff->iff_Stream = (ULONG)fh; if(!OpenIFF(iff, IFFF_WRITE)) { if(!PushChunk(iff, 'PREF', 'FORM', IFFSIZE_UNKNOWN)) DoMethod(dataspace, MUIM_Dataspace_WriteIFF, iff, 0, 'IPRB'); CloseIFF(iff); } FreeIFF(iff); } Close(fh); } else { UBYTE buf[84]; Fault(IoErr(), "DOS", buf, 84); retry = MUI_Request(app, NULL, 0L, "Error", "_Retry|_Cancel", "\33cError saving:\n%s\n\n%s", file, buf); } } while(retry); } </syntaxhighlight> One object can't belong to two parents. How does one insure free pens being allocated? I am running most applications on 16 bit screens. Not sure what is required but I would think there should be some way to have some free. What/how does on "free" pens? On True/Hi color screens You may expect to have unlimited number of free pens (or at least 65536/16777216 pens), because you can change the color of every single pixel without affecting the rest. But unfortunately all RastPort rendering functions rely on pen scheme and pen fields in RastPort are only 8-bit wide. It gives you only 256 pens. Tried to use the MUIA_Bitmap_SourceColors and the MUIA_Bitmap_Precision but all I get is a big black rectangle in place of the discoloured image. Did you set MUIA_Bodychunk_Depth to 5 and MUIA_Bodychunk_Masking to 0 (but check if you save the brush *without* mask plane)? And remember that you should repeat R, G, B values in every byte of a longword, so for example some colour like R=$A5, G=$32, B=$0A, in palette data it looks like $A5A5A5A5,$32323232,$0A0A0A0A. So every palette entry takes 12 bytes. You need to set the MUIA_Window_UseBottomBorderScroller (or whatever side you want) on the window. Then create a Prop Object and set the MUIA_Prop_UseWinBorder to the corresponding side(s) that you did in the window. Then just set up a notification on the prop object to listen for changes in MUIA_Prop_First. When you place the one on the right and open the window, MUI opens the window the smallest possible and doesn't draw any of the other objects that should be in the window. ====dtpic Datatypes==== If you would like to get a pointer to the bitmap that holds the data of the picture or a way to copy it to your own bitmap but all Zune attributes did not work. In that case you will want to use datatypes.library directly. Dtpic AFAIK is just for easily including datatype images into MUI/Zune GUIs (as button imagery, in listviews and so on...). If AROS supports the superbitmap window refresh method then you can. For a non-borderless window you will probably want to make it gimmezerozero (gzz) as well so that the borders and window contents have separate layers (uses slightly more memory). That being said just blitting the bitmap into the window is probably a simpler and more portable solution. How to "convert" e.g. a png image to a bitmap structure (datatypes?). DTpic.mui is your friend. Using picture.datatype and then blitting bitmap to object rastport in MUIM_Draw. <syntaxhighlight lang="c"> Child, image_button = MakeButton("PROGDIR:Imagesg/test_but.png", 't',"\33uT\33nest Button"), static APTR MakeButton(UBYTE *Image, UBYTE Key, UBYTE *Help) { return(MUI_NewObject("Dtpic.mui", MUIA_Dtpic_Name,Image, MUIA_InputMode, MUIV_InputMode_RelVerify, MUIA_ControlChar, Key, MUIA_Background, MUII_ButtonBack, MUIA_ShortHelp, Help, PropFrame,TRUE, ImageButtonFrame, TAG_DONE)); } </syntaxhighlight> <syntaxhighlight lang="c"> if(app) { struct BitMapHeader *bmhd; struct BitMap *bitmap; Object *datatype_obj; /* pointer to the Datatype Object */ Object *bitmap_obj; /* a mui BitmapObject */ Object *list_obj; /* the one that should be used in the list */ if(datatype_obj = NewDTObject("Images/www.iff", DTA_SourceType , DTST_FILE, DTA_GroupID , GID_PICTURE, TAG_DONE)) { if(DoMethod(datatype_obj, DTM_PROCLAYOUT, NULL, 1)) { get(datatype_obj, PDTA_BitMapHeader, &bmhd); GetDTAttrs(datatype_obj, PDTA_DestBitMap, &bitmap, TAG_DONE); if(!bitmap) GetDTAttrs(datatype_obj, PDTA_BitMap, &bitmap, TAG_DONE); if(bitmap_obj = BitmapObject, MUIA_Bitmap_SourceColors , xget(datatype_obj, PDTA_CRegs), MUIA_Bitmap_Width , bmhd->bmh_Width, MUIA_Bitmap_Height , bmhd->bmh_Height, MUIA_FixWidth , bmhd->bmh_Width, MUIA_FixHeight , bmhd->bmh_Height, MUIA_Bitmap_Transparent , 0, MUIA_Bitmap_Bitmap , bitmap, End) { list_obj = (Object *)DoMethod(LV_ButtonBank, MUIM_List_CreateImage, bitmap_obj, NULL); } } } } </syntaxhighlight> in MUI4.0 <syntaxhighlight lang="c"> Child, zoneimage = (Object *) MUI_NewObject(MUIC_Dtpic, MUIA_Dtpic_Name, "PROGDIR:resource/zone_local.png", TAG_DONE), DEFSMETHOD(OWBWindow_UpdateZone) { GETDATA; char *image; switch(msg->zone) { default: case MV_OWBBrowser_Zone_Local: image = "PROGDIR:resource/zone_local.png"; break; case MV_OWBBrowser_Zone_Internet: image = "PROGDIR:resource/zone_internet.png"; break; } set(data->zoneimage, MUIA_Dtpic_Name, image); return 0; } </syntaxhighlight> i.e. by default we set zone_local image, and then by notification calls updatezone when the attribute is set. And it should changes (image i mean), but did't not. I see that i am in the Zone_Internet (by printfs), but image not sets. Problems with 3.9 ===Removal=== <pre> void ExitClasses(void) { if (NewList) { MUI_DeleteCustomClass(NewList); NewList = NULL; } } BOOL InitClasses(void) { NewList = MUI_CreateCustomClass(NULL,MUIC_NList ,NULL,sizeof(struct NewList_Data),&NewList_Dispatcher); if (NewList) return(TRUE); else return FALSE; } </pre> Another thing, which your compiler should notice immediately, is that MyCustomClass is struct IClass * and assigning Object * to it is very, very wrong, and should effect crash at MUI_DeleteCustomClass()... <pre> #define MyCustomObject NewObject(MyCustomClass->mcc_Class,NULL, Object *mycustomobject; mycustomobject = MyCustomObject, End; if( mycustomobject != NULL ) { app = ApplicationObject, [... ] End; if( app != NULL ) { [...] MUI_DisposeObject( app ); } MUI_DisposeObject( mycustomobject ); } </pre> Or preferably you should subclass Application.mui class and do your non-visible code there... That's the best way to handle it IMHO... This way main program code will be almost untouched and going back to using standard Application.mui within seconds, just rename MyApplicationObject to ApplicationObject (always define such macros instead of writing NewObject() directly!) Objects are removed using OM_REMMEMBER method (must use parent object of course) ==References== http://alfie.altervista.org/rxmui/rxmuidoc/classes.html http://amiga.sourceforge.net/amigadevhelp/phpwebdev.php When one of the qualifier (shift, ctrl, alt) keys is clicked then the opposite key should get the same state. I tried in the callback function: <pre> BOOL shift = XGET(data->keybutton[96], MUIA_Pressed) | XGET(data->keybutton[97], MUIA_Pressed); NNSET(data->keybutton[96], MUIA_Pressed, shift); NNSET(data->keybutton[97], MUIA_Pressed, shift); </pre> Pressing the qualifier keys on the keyboard should act as if the button was clicked. I've therefore added an event handler method. It works so far as the visual state of the buttons is changed. Problem is that SET(keyobj, MUIA_Pressed, state) in that event method doesn't trigger the callback hook. Try MUIA_Selected, instead of MUIA_Pressed (which is really just a thing to be used for notification, not a real attribute). You'll also have to change code logic, because once the two SHIFT buttons are selected, it won't be possible to unselected them ("shift" var would always be TRUE). Networking with a non-blocking recv(), start with one task and make all my interfaces push-based. That is, no-one will call recv() but instead be called with the data received from a socket (when it arrives). So in your main-loop you wait for both sockets and user events and distribute these to the proper receiver (where the latter would be done by MUI). The reason for this approach is to simplify code (eliminate the need to lock resources/data with semaphores etc), and also because found out that spawning tasks had a noticeable overhead (but you could keep one network manager running all the time to get by this), not to mention that if you receive data on 8 sockets (each having its own process) then your program will be represented with 9 total tasks and thus if another program needs cpu-time it'll only get 1/10th of the time, where your program will get 9/10th, unless you fiddle with the priority of your tasks but then other problems appear. If the data you receive needs to be parsed in some way you may at first find it irritating to have to write your parser as a state-machine, but these also have advantages IMO. For example it makes it very easy to add filters to the data stream or create virtual data on the fly... Basically you need a socket operating in the non-blocking & asynchronous mode. This prevents GUI being locked while accessing network. Another step is allocate signal bit for bsdsocket and use GetSocketEvent() to find out network actions without braindead select() or WaitSelect() functions. So that whenever network signal is set you call GetSocketEvent() in loop. This GetSocketEvent() returns socket descriptor ID and possible events occurred. Avoid GetSocketEvent() and its minion like it was the bubonic plague!!!!!!!! As it turned out, it only works under Miami. Even though AmiTCP copied the API from M$, it never worked correctly. Use WaitSelect() instead of Wait() in your MUI main loop. See STRICQ 2 src. How do you receive data from sockets? Is there a way to associate a signal to a socket? You can associate a signal with a socket by using SocketBaseTags(). Use WaitSelect() in the STRICQ v2 socket code. But in v1, used a signal. You can encapsulate internet client in MUI application subclass, create some useful methods and attributes like MUIM_NetApplication_Connect/Disconnect/Send/Receive, and then when user press Connect/Disconnect button, call these methods in notification or callback function (so if NetApplication connected you will disable Connect, and enable Disconnect etc. gadgets). And so on. Never connect to the internet immediately in OM_NEW, that would be stupid as well as creating needed subprocess in there (which from other side might be not good idea). It can wait then as long as application sends the connect signal or message and then do it's network job, until it receives MUIM_NetApplication_Disconnect method.. How to... merge bsdsocket.library and muimaster.library in single, nicely OOP, application. ==Examples== <syntaxhighlight lang="c"> /* Copyright © 2002, The AROS Development Team. All rights reserved. $Id: aircos_server_gui.c 30794 2009-03-08 02:19:07Z neil $ */ //#include <exec/types.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <proto/alib.h> #include <proto/exec.h> #include <proto/dos.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <proto/utility.h> #include <dos/dos.h> #include <intuition/gadgetclass.h> #include <intuition/icclass.h> #include <clib/alib_protos.h> #include <libraries/mui.h> #include <mui/NListtree_mcc.h> #include <mui/NListview_mcc.h> #include <mui/NList_mcc.h> #include "aircos_global.h" #include "locale.h" extern struct AiRcOS_internal *AiRcOS_Base; struct List aircos_Prefs_ServerNetworks; struct List aircos_Prefs_Servers; struct aircos_servernode *aircos_Prefs_ServerActive; struct Hook aircos_serversave_hook; struct Hook aircos_networklistupdate_hook; struct Hook aircos_serverlistupdate_hook; struct Hook aircos_chooseserver_hook; BOOL aircos_Prefs_ServersLoaded = FALSE; Object *input_server_address = NULL; Object *input_server_port = NULL; Object *input_server_description = NULL; Object *input_server_network = NULL; Object *input_server_pass = NULL; Object *select_dropboxgrp_network = NULL; Object *select_dropbox_network = NULL; Object *select_dropboxgrp_server = NULL; Object *select_dropbox_server = NULL; STRPTR network_list_empty[2] = { {"<List Empty>"}, NULL }; STRPTR server_list_empty[2] = { {"<List Empty>"}, NULL }; Object *servermodWin; STRPTR *network_list; STRPTR *server_list; //network_list_empty[0] = "<List Empty>"; //MSG(MSG_LIST_EMPTY); //network_list_empty[1] = NULL; //server_list_empty[0] = "<List Empty>"; //MSG(MSG_LIST_EMPTY); //server_list_empty[1] = NULL; #define AIRCOS_DEF_SERVERSFILE "servers.dat" aircosApp_LoadServers() { aircos_Prefs_ServersLoaded = TRUE; } struct aircos_networknode *aircosApp_FindServerNetworkNode(char * findNetwork) { struct aircos_networknode *current_Node = NULL; ForeachNode(&aircos_Prefs_ServerNetworks, current_Node) { D(bug("[AiRcOS](FindServerNetworkNode) Checking against record for '%s'\n", current_Node->ann_Network)); if (strcasecmp(current_Node->ann_Network, findNetwork)==0) return current_Node; } return NULL; } struct aircos_servernode *aircosApp_FindServerNode(char * findServer) { struct aircos_servernode *current_Node = NULL; ForeachNode(&aircos_Prefs_Servers, current_Node) { D(bug("[AiRcOS](FindServerNode) Checking against record for '%s'\n", current_Node->asn_Server)); if (strcasecmp(current_Node->asn_Server, findServer)==0) return current_Node; } return NULL; } AROS_UFH3(void, chooseserver_func, AROS_UFHA(struct Hook *, unused_hook, A0), AROS_UFHA(APTR, obj, A2), AROS_UFHA(struct IRC_Channel_Priv *, hook_channel_arg, A1 )) { AROS_USERFUNC_INIT D(bug("[AiRcOS] chooseserver_func()\n")); ULONG currentPrefsServerID; get(select_dropbox_server, MUIA_Cycle_Active, &currentPrefsServerID); struct aircos_servernode *currentPrefsServer = NULL; if (!(currentPrefsServer = aircosApp_FindServerNode(server_list[currentPrefsServerID]))) { D(bug("[AiRcOS] chooseserver_func: Couldnt find Server Node!\n")); return; } aircos_Prefs_ServerActive = currentPrefsServer; AROS_USERFUNC_EXIT }; AROS_UFH3(void, updatenetworklist_func, AROS_UFHA(struct Hook *, unused_hook, A0), AROS_UFHA(APTR, obj, A2), AROS_UFHA(struct IRC_Channel_Priv *, hook_channel_arg, A1 )) { AROS_USERFUNC_INIT D(bug("[AiRcOS] updatenetworklist_func()\n")); struct aircos_networknode *currentPrefsNetwork = NULL; ULONG prefsNetworkCount = 0; ULONG setprefsNetworkActive = 0; Object *new_dropbox_network = NULL; ForeachNode(&aircos_Prefs_ServerNetworks, currentPrefsNetwork) { prefsNetworkCount++; if (aircos_Prefs_ServerActive) if (strcasecmp(currentPrefsNetwork->ann_Network, aircos_Prefs_ServerActive->asn_Network->ann_Network)==0) { setprefsNetworkActive = prefsNetworkCount -1; } } D(bug("[AiRcOS] updatenetworklist_func: %d network nodes\n", prefsNetworkCount)); if (prefsNetworkCount > 0) { if (network_list != network_list_empty) { FreeVec(network_list); } if ((network_list = AllocVec(sizeof(IPTR) * prefsNetworkCount+1, MEMF_CLEAR|MEMF_PUBLIC))) { int loop_count = 0; ForeachNode(&aircos_Prefs_ServerNetworks, currentPrefsNetwork) { network_list[loop_count] = currentPrefsNetwork->ann_Network; loop_count++; } } else { D(bug("[AiRcOS] updatenetworklist_func: ERROR - couldnt allocate memory for network name pointer table\n")); network_list = network_list_empty; } } else if (network_list != network_list_empty) { FreeVec(network_list); network_list = network_list_empty; } if (!(new_dropbox_network = MUI_MakeObject(MUIO_Cycle, NULL, network_list))) { D(bug("[AiRcOS] updatenetworklist_func: Failed to create Network dropdown\n")); return NULL; } if (DoMethod(select_dropboxgrp_network, MUIM_Group_InitChange)) { DoMethod(select_dropboxgrp_network, OM_REMMEMBER, select_dropbox_network); DoMethod(select_dropboxgrp_network, OM_ADDMEMBER, new_dropbox_network); DoMethod(select_dropboxgrp_network, MUIM_Group_ExitChange); select_dropbox_network = new_dropbox_network; } DoMethod(select_dropbox_network, MUIM_NoNotifySet, MUIA_Cycle_Active, setprefsNetworkActive); DoMethod ( select_dropbox_network, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &aircos_serverlistupdate_hook, NULL ); AROS_USERFUNC_EXIT }; AROS_UFH3(void, updateserverlist_func, AROS_UFHA(struct Hook *, unused_hook, A0), AROS_UFHA(APTR, obj, A2), AROS_UFHA(struct IRC_Channel_Priv *, hook_channel_arg, A1 )) { AROS_USERFUNC_INIT D(bug("[AiRcOS] updateserverlist_func()\n")); struct aircos_servernode *currentPrefsServer = NULL; ULONG prefsNetworkServerCount = 0; ULONG setprefsServerActive = 0; Object *new_dropbox_server = NULL; ULONG currentPrefsNetworkID; get(select_dropbox_network, MUIA_Cycle_Active, &currentPrefsNetworkID); struct aircos_networknode *currentPrefsNetwork = NULL; if (!(currentPrefsNetwork = aircosApp_FindServerNetworkNode(network_list[currentPrefsNetworkID]))) { D(bug("[AiRcOS] updateserverlist_func: Couldnt find Network Node!\n")); return; } ForeachNode(&aircos_Prefs_Servers, currentPrefsServer) { if (strcasecmp(currentPrefsServer->asn_Network->ann_Network, currentPrefsNetwork->ann_Network)==0) { prefsNetworkServerCount++; if (aircos_Prefs_ServerActive) if (strcasecmp(currentPrefsServer->asn_Server, aircos_Prefs_ServerActive->asn_Server)==0) { setprefsServerActive = prefsNetworkServerCount -1; } } } D(bug("[AiRcOS] updateserverlist_func: %d server nodes for network '%s'\n", prefsNetworkServerCount, currentPrefsNetwork->ann_Network)); if (prefsNetworkServerCount > 0) { if (server_list != server_list_empty) { FreeVec(server_list); } if ((server_list = AllocVec(sizeof(IPTR) * prefsNetworkServerCount+1, MEMF_CLEAR|MEMF_PUBLIC))) { int loop_count = 0; ForeachNode(&aircos_Prefs_Servers, currentPrefsServer) { if (strcasecmp(currentPrefsServer->asn_Network->ann_Network, currentPrefsNetwork->ann_Network)==0) { server_list[loop_count] = currentPrefsServer->asn_Server; loop_count++; } } } else { D(bug("[AiRcOS] updateserverlist_func: ERROR - couldnt allocate memory for server name pointer table\n")); server_list = server_list_empty; } } else if (server_list != server_list_empty) { FreeVec(server_list); server_list = server_list_empty; } if (!(new_dropbox_server = MUI_MakeObject(MUIO_Cycle, NULL, server_list))) { D(bug("[AiRcOS] updateserverlist_func: Failed to create Server dropdown\n")); return NULL; } if (DoMethod(select_dropboxgrp_server, MUIM_Group_InitChange)) { DoMethod(select_dropboxgrp_server, OM_REMMEMBER, select_dropbox_server); DoMethod(select_dropboxgrp_server, OM_ADDMEMBER, new_dropbox_server); DoMethod(select_dropboxgrp_server, MUIM_Group_ExitChange); select_dropbox_server = new_dropbox_server; } DoMethod(select_dropbox_server, MUIM_NoNotifySet, MUIA_Cycle_Active, setprefsServerActive); AROS_USERFUNC_EXIT }; AROS_UFH3(void, serversave_func, AROS_UFHA(struct Hook *, unused_hook, A0), AROS_UFHA(APTR, obj, A2), AROS_UFHA(struct IRC_Channel_Priv *, hook_channel_arg, A1 )) { AROS_USERFUNC_INIT D(bug("[AiRcOS] serversave_func()\n")); struct aircos_networknode *newsaveNetwork = NULL; char *newsaveNetwork_name; BOOL newsaveNetwork_update = FALSE; struct aircos_servernode *newsaveServer = NULL; char *newsaveServer_name; BOOL newsaveServer_update = FALSE; get( input_server_network, MUIA_String_Contents, &newsaveNetwork_name); get( input_server_address, MUIA_String_Contents, &newsaveServer_name); if (!(newsaveNetwork = aircosApp_FindServerNetworkNode(newsaveNetwork_name))) { D(bug("[AiRcOS](serversave_func) created new network node for '%s'\n", newsaveNetwork_name)); newsaveNetwork = AllocVec(sizeof(struct aircos_networknode), MEMF_CLEAR|MEMF_PUBLIC); newsaveNetwork->ann_Network = AllocVec(strlen(newsaveNetwork_name)+1, MEMF_CLEAR|MEMF_PUBLIC); CopyMem(newsaveNetwork_name, newsaveNetwork->ann_Network, strlen(newsaveNetwork_name)+1); AddTail((struct List *)&aircos_Prefs_ServerNetworks, (struct Node *)&newsaveNetwork->ann_Node); newsaveNetwork_update = TRUE; } newsaveNetwork->ann_ServerCount += 1; D(bug("[AiRcOS](serversave_func) %s Network node server count = %d\n", newsaveNetwork->ann_Network, newsaveNetwork->ann_ServerCount)); if (!(newsaveServer = aircosApp_FindServerNode(newsaveServer_name))) { D(bug("[AiRcOS](serversave_func) created new server node for '%s'\n", newsaveServer_name)); newsaveServer = AllocVec(sizeof(struct aircos_servernode), MEMF_CLEAR|MEMF_PUBLIC); newsaveServer->asn_Server = AllocVec(strlen(newsaveServer_name)+1, MEMF_CLEAR|MEMF_PUBLIC); CopyMem(newsaveServer_name, newsaveServer->asn_Server, strlen(newsaveServer_name)+1); newsaveServer->asn_Network = newsaveNetwork; get( input_server_port, MUIA_String_Integer, &newsaveServer->asn_Port); #warning "TODO: we need to store the password also here .." AddTail((struct List *)&aircos_Prefs_Servers, (struct Node *)&newsaveServer->asn_Node); newsaveServer_update = TRUE; } else { D(bug("[AiRcOS](serversave_func) node already exists for server '%s'\n", newsaveServer_name)); } aircos_Prefs_ServerActive = newsaveServer; set( servermodWin, MUIA_Window_Open, FALSE); if (newsaveNetwork_update) CallHookPkt(&aircos_networklistupdate_hook, obj, hook_channel_arg); if (newsaveServer_update) CallHookPkt(&aircos_serverlistupdate_hook, obj, hook_channel_arg); AROS_USERFUNC_EXIT }; Object *aircos_showServerConnect() { D(bug("[AiRcOS] showServerConnect()\n")); if (aircos_Prefs_ServersLoaded) { D(bug("[AiRcOS](showServerConnect) Server windows already configured!\n")); return NULL; } Object *tmp_connectWin = NULL; NewList((struct List *)&aircos_Prefs_ServerNetworks); NewList((struct List *)&aircos_Prefs_Servers); Object *butt_addServer = NULL; Object *butt_editServer = NULL; Object *butt_delServer = NULL; Object *butt_serverConnect = NULL; Object *butt_serverSave = NULL; network_list = network_list_empty; server_list = server_list_empty; if (!(select_dropbox_network = MUI_MakeObject(MUIO_Cycle, NULL, network_list))) { D(bug("[AiRcOS](showServerConnect) Failed to create Network dropdown\n")); return NULL; } if (!(select_dropbox_server = MUI_MakeObject(MUIO_Cycle, NULL, server_list))) { D(bug("[AiRcOS](showServerConnect) Failed to create Server dropdown\n")); return NULL; } if (!(butt_addServer = SimpleButton("Add"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'ADD' button\n")); return NULL; } if (!(butt_editServer = SimpleButton("Edit"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'EDIT' button\n")); return NULL; } if (!(butt_delServer = SimpleButton("Del"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'DEL' button\n")); return NULL; } if (!(butt_serverConnect = SimpleButton("Connect!"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'CONNECT' button\n")); return NULL; } if (!(butt_serverSave = SimpleButton("Save!"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'SAVE' button\n")); return NULL; } select_dropboxgrp_network = VGroup, Child, (IPTR) select_dropbox_network, End; select_dropboxgrp_server = VGroup, Child, (IPTR) select_dropbox_server, End; tmp_connectWin = WindowObject, MUIA_Window_Title, (IPTR) "Connect to Server..", MUIA_Window_Activate, TRUE, MUIA_Window_Width,200, MUIA_Window_Height,200, WindowContents, (IPTR) VGroup, Child, (IPTR) HGroup, GroupFrame, Child, (IPTR) VGroup, Child, (IPTR) LLabel("IRC Network"), Child, (IPTR) HGroup, Child, (IPTR) HSpace(0), Child, (IPTR) select_dropboxgrp_network, Child, (IPTR) HSpace(0), End, End, Child, (IPTR) HVSpace, End, Child, (IPTR) HGroup, GroupFrame, Child, (IPTR) VGroup, Child, (IPTR) LLabel("IRC Server"), Child, (IPTR) HGroup, Child, (IPTR) HVSpace, Child, (IPTR) select_dropboxgrp_server, Child, (IPTR) HVSpace, End, End, Child, (IPTR) HVSpace, End, Child, (IPTR) HGroup, Child, (IPTR) HVSpace, Child, (IPTR) butt_addServer, Child, (IPTR) butt_editServer, Child, (IPTR) butt_delServer, End, Child, (IPTR) butt_serverConnect, End, End; servermodWin = WindowObject, MUIA_Window_Title, (IPTR) "Edit Server..", MUIA_Window_Activate, TRUE, MUIA_Window_Width,350, MUIA_Window_Height,400, WindowContents, (IPTR) VGroup, Child, (IPTR) VGroup, GroupFrame, Child, (IPTR) HGroup, Child, (IPTR) LLabel("IRC Server Address"), Child, (IPTR) (input_server_address = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, End ), End, Child, (IPTR) HGroup, Child, (IPTR) LLabel("Port"), Child, (IPTR) (input_server_port = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, MUIA_String_Accept, "0123456789", MUIA_String_Integer, 0, End), End, Child, (IPTR) HGroup, Child, (IPTR) LLabel("Server Description"), Child, (IPTR) (input_server_description = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, End), End, Child, (IPTR) HGroup, Child, (IPTR) LLabel("IRC Network"), Child, (IPTR) (input_server_network = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, End), End, End, Child, (IPTR) VGroup, GroupFrame, Child, (IPTR) LLabel("Enter server password here if applicable."), Child, (IPTR) HGroup, Child, (IPTR) LLabel("Password"), Child, (IPTR) (input_server_pass = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, End), End, End, Child, (IPTR) butt_serverSave, End, End; if ((tmp_connectWin)&&(servermodWin)) { D(bug("[AiRcOS](showServerConnect) Created GUI objects\n")); DoMethod ( AiRcOS_Base->aircos_app, OM_ADDMEMBER, (IPTR) tmp_connectWin ); DoMethod ( AiRcOS_Base->aircos_app, OM_ADDMEMBER, (IPTR) servermodWin ); DoMethod ( tmp_connectWin, MUIM_Notify, MUIA_Window_Open, TRUE, (IPTR) AiRcOS_Base->aircos_quickconnectwin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( AiRcOS_Base->aircos_quickconnectwin, MUIM_Notify, MUIA_Window_Open, TRUE, (IPTR) tmp_connectWin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( tmp_connectWin, MUIM_Notify, MUIA_Window_Open, FALSE, (IPTR) servermodWin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( butt_addServer, MUIM_Notify, MUIA_Selected, FALSE, (IPTR) servermodWin, 3, MUIM_Set, MUIA_Window_Open, TRUE ); DoMethod ( butt_editServer, MUIM_Notify, MUIA_Selected, FALSE, (IPTR) servermodWin, 3, MUIM_Set, MUIA_Window_Open, TRUE ); // DoMethod // ( // butt_delServer, MUIM_Notify, MUIA_Selected, FALSE, // (IPTR) servermodWin, 3, MUIM_Set, MUIA_ShowMe, FALSE // ); DoMethod ( tmp_connectWin, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) tmp_connectWin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( servermodWin, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) servermodWin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( butt_serverConnect, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &AiRcOS_Base->aircos_connect_hook, NULL ); D(bug("[AiRcOS](showServerConnect) prepare list update hooks\n")); aircos_serversave_hook.h_MinNode.mln_Succ = NULL; aircos_serversave_hook.h_MinNode.mln_Pred = NULL; aircos_serversave_hook.h_Entry = HookEntry; aircos_serversave_hook.h_SubEntry = (void *)serversave_func; aircos_networklistupdate_hook.h_MinNode.mln_Succ = NULL; aircos_networklistupdate_hook.h_MinNode.mln_Pred = NULL; aircos_networklistupdate_hook.h_Entry = HookEntry; aircos_networklistupdate_hook.h_SubEntry = (void *)updatenetworklist_func; aircos_serverlistupdate_hook.h_MinNode.mln_Succ = NULL; aircos_serverlistupdate_hook.h_MinNode.mln_Pred = NULL; aircos_serverlistupdate_hook.h_Entry = HookEntry; aircos_serverlistupdate_hook.h_SubEntry = (void *)updateserverlist_func; aircos_chooseserver_hook.h_MinNode.mln_Succ = NULL; aircos_chooseserver_hook.h_MinNode.mln_Pred = NULL; aircos_chooseserver_hook.h_Entry = HookEntry; aircos_chooseserver_hook.h_SubEntry = (void *)chooseserver_func; DoMethod ( butt_serverSave, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &aircos_serversave_hook, NULL ); DoMethod ( select_dropbox_network, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &aircos_serverlistupdate_hook, NULL ); DoMethod ( select_dropbox_server, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &aircos_chooseserver_hook, NULL ); D(bug("[AiRcOS](showServerConnect) Configured NOTIFICATIONS\n")); set(tmp_connectWin, MUIA_Window_Open, TRUE); D(bug("[AiRcOS](showServerConnect) Window opened ..\n")); } else { if (!(servermodWin)) { D(bug("[AiRcOS](showServerConnect) Failed to create server edit window..\n")); } else MUI_DisposeObject(servermodWin); if (!(tmp_connectWin)) { D(bug("[AiRcOS](showServerConnect) Failed to create server selection window..\n")); } else MUI_DisposeObject(tmp_connectWin); } return tmp_connectWin; } </syntaxhighlight> <syntaxhighlight lang="c"> /* Copyright © 2002, The AROS Development Team. All rights reserved. $Id: mini2.c 30792 2009-03-07 22:40:04Z neil $ */ #include <exec/types.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <dos/dos.h> #include <intuition/gadgetclass.h> #include <intuition/icclass.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> /* the following should go in a single include file which then only ** constits of the public constants and members. Actually this is easiey */ #include <libraries/mui.h> #define DEBUG 1 #include <aros/debug.h> Object *app; int main(void) { Object *wnd; static char *radio_entries2[] = {"Paris","London",NULL}; app = ApplicationObject, SubWindow, wnd = WindowObject, WindowContents, VGroup, Child, HGroup, MUIA_InputMode, MUIV_InputMode_Immediate, /* MUIA_ShowSelState, FALSE, */ Child, ImageObject, MUIA_ShowSelState, FALSE, MUIA_Image_FontMatch, TRUE, MUIA_Image_Spec, MUII_RadioButton, MUIA_Frame, MUIV_Frame_None, End, Child, TextObject, MUIA_ShowSelState, FALSE, MUIA_Text_Contents, "London", MUIA_Frame, MUIV_Frame_None, MUIA_Text_PreParse, "\33l", End, End, End, End, End; if (app) { ULONG sigs = 0; /* #if 0 */ DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); /* #endif */ set(wnd, MUIA_Window_Open, TRUE); /* #if 0 */ while((LONG) DoMethod(app, MUIM_Application_NewInput, &sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D); if (sigs & SIGBREAKF_CTRL_C) break; if (sigs & SIGBREAKF_CTRL_D) break; } } /* #endif */ set(wnd, MUIA_Window_Open, FALSE); MUI_DisposeObject(app); } return 0; } </syntaxhighlight> <syntaxhighlight lang="c"> /* Copyright © 2002, The AROS Development Team. All rights reserved. $Id: dirlist.c 30792 2009-03-07 22:40:04Z neil $ */ #include <exec/types.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <dos/dos.h> #include <intuition/gadgetclass.h> #include <intuition/icclass.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> /* the following should go in a single include file which then only ** constits of the public constants and members. Actually this is easiey */ #include <libraries/mui.h> struct Library *MUIMasterBase; Object *app; int main(void) { Object *wnd, *str, *dirlist, *page; MUIMasterBase = (struct Library*)OpenLibrary("muimaster.library",0); app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "dirlist", MUIA_Window_Activate, TRUE, WindowContents, VGroup, MUIA_Background, MUII_GroupBack, Child, ListviewObject, MUIA_Listview_List, dirlist = DirlistObject, InputListFrame, End, End, Child, HGroup, Child, str = StringObject, StringFrame, MUIA_String_Contents, (IPTR)"SYS:", End, Child, page = PageGroup, MUIA_Weight, 0, MUIA_FixWidthTxt, (IPTR)"AA", Child, ColorfieldObject, MUIA_Colorfield_Red, 0xFFFFFFFF, MUIA_Colorfield_Green, 0, MUIA_Colorfield_Blue, 0, End, Child, ColorfieldObject, MUIA_Colorfield_Red, 0xFFFFFFFF, MUIA_Colorfield_Green, 0xFFFFFFFF, MUIA_Colorfield_Blue, 0, End, Child, ColorfieldObject, MUIA_Colorfield_Red, 0, MUIA_Colorfield_Green, 0x66666666, MUIA_Colorfield_Blue, 0, End, End, End, End, End, End; if (app) { ULONG sigs = 0; DoMethod ( wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit ); DoMethod(str, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)dirlist, 3, MUIM_Set, MUIA_Dirlist_Directory, MUIV_TriggerValue); DoMethod(dirlist, MUIM_Notify, MUIA_Dirlist_Status, MUIV_EveryTime, (IPTR)page, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue); set(dirlist, MUIA_Dirlist_Directory, "SYS:"); set(wnd,MUIA_Window_Open,TRUE); while (DoMethod(app, MUIM_Application_NewInput, (IPTR) &sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D); if (sigs & SIGBREAKF_CTRL_C) break; if (sigs & SIGBREAKF_CTRL_D) break; } } MUI_DisposeObject(app); } CloseLibrary(MUIMasterBase); return 0; } </syntaxhighlight> WaitSelect() needs a pointer to your signal mask. So you need to do something like: <pre> sigs |= SIGBREAKF_CTRL_C; ret = WaitSelect(s+1, &rdfs, NULL, NULL, &sigs); </pre> Then 'sigs' should contain the bits normally returned by Wait(). <syntaxhighlight lang="c"> /* * Amiga Generic Set - set of libraries and includes to ease sw development for all Amiga platforms * Copyright (C) 2004-2008 Tomasz Wiszkowski Tomasz.Wiszkowski at gmail.com. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "MUIPictureClass.h" #include <Generic/LibrarySpool.h> #include <libclass/intuition.h> #include <libclass/muimaster.h> #include <libraries/mui.h> #include <libclass/utility.h> using namespace GenNS; #define __NOGLOBALIFACE__ #include <proto/graphics.h> static struct Library *GfxBase = 0; #ifdef __AMIGAOS4__ static struct GraphicsIFace *IGraphics = 0; #endif MUICustomClassT<MUIPictureClass> *MUIPictureClass::muiclass = 0; static int openCount = 0; MUIPictureClass::MUIPictureClass(IClass *cls) { openCount++; parent = cls; image1 = ""; image2 = ""; width = 64; height = 48; dtimg1 = 0; dtimg2 = 0; dt = DatatypesIFace::GetInstance(44); if (dt == 0) { request("Warning", "This program requires datatypes.library v44 or later\nGraphical buttons will not be displayed.", "Continue", 0); } if (GfxBase == 0) { GfxBase = Exec->OpenLibrary("graphics.library", 39); } #ifdef __AMIGAOS4__ if ((GfxBase != 0) && (IGraphics == 0)) { IGraphics = (GraphicsIFace*)Exec->GetInterface(GfxBase, "main", 1, (TagItem*)NULL); } #endif } MUIPictureClass::~MUIPictureClass() { closeImages(); dt->FreeInstance(); openCount--; if (0 == openCount) { #ifdef __AMIGAOS4__ Exec->DropInterface((Interface*)IGraphics); IGraphics = 0; #endif Exec->CloseLibrary(GfxBase); GfxBase = 0; } } iptr MUIPictureClass::DoMtd(iptr *obj, iptr *msg) { uint16 *minmax; iptr k; switch (msg[0]) { case OM_NEW: { if (!(obj = (Object*)DoSuperMtd(parent, obj, msg))) return 0; k = (iptr)Utility->GetTagData(MUIA_Picture_NormalImage, 0, (TagItem*)msg[1]); if (k != 0) image1 = (char*)k; k = (iptr)Utility->GetTagData(MUIA_Picture_SelectedImage, 0, (TagItem*)msg[1]); if (k != 0) image2 = (char*)k; isDisabled = Utility->GetTagData(MUIA_Disabled, 0, (struct TagItem*)msg[1]) ? true : false; isSelected = Utility->GetTagData(MUIA_Selected, 0, (struct TagItem*)msg[1]) ? true : false; openImages(); return (ULONG)obj; } break; case OM_DISPOSE: case MUIM_Hide: break; case MUIM_Show: { if (dt != 0) { if (dtimg1 != 0) { dt->SetDTAttrsA(dtimg1, 0, 0, (TagItem*)ARRAY( PDTA_Screen, (iptr)_screen(obj), PDTA_DestMode, PMODE_V43, PDTA_UseFriendBitMap,true, TAG_DONE, 0)); dt->DoDTMethodA(dtimg1, 0, 0, ARRAY(DTM_PROCLAYOUT, 0, 1)); } if (dtimg2 != 0) { dt->SetDTAttrsA(dtimg2, 0, 0, (TagItem*)ARRAY( PDTA_Screen, (iptr)_screen(obj), PDTA_DestMode, PMODE_V43, PDTA_UseFriendBitMap,true, TAG_DONE, 0)); dt->DoDTMethodA(dtimg2, 0, 0, ARRAY(DTM_PROCLAYOUT, 0, 1)); } } } break; case MUIM_AskMinMax: { DoSuperMtd(parent, obj, msg); minmax = (uint16*)msg[1]; minmax[0] = width; minmax[2] = width; minmax[4] = width; minmax[1] = height; minmax[3] = height; minmax[5] = height; } return 0; case OM_SET: { bool flg; bool refresh = false; // image1 = (char*)GetTagData(MUIA_Picture_NormalImage, (int32)image1.Data(), (TagItem*)msg[1]); // image2 = (char*)GetTagData(MUIA_Picture_SelectedImage, (int32)image2.Data(), (TagItem*)msg[1]); flg = Utility->GetTagData(MUIA_Disabled, isDisabled, (struct TagItem*)msg[1]) ? true : false; if (flg != isDisabled) { isDisabled = flg; refresh = true; } flg = Utility->GetTagData(MUIA_Selected, isSelected, (struct TagItem*)msg[1]) ? true : false; if (isSelected != flg) { isSelected = flg; refresh = true; } if (refresh) MUIMaster->MUI_Redraw(obj, 0); } break; case MUIM_NoNotifySet: case MUIM_Set: { bool refresh = false; if (msg[1] == MUIA_Picture_NormalImage) image1 = (char*)msg[2]; if (msg[1] == MUIA_Picture_SelectedImage) image2 = (char*)msg[2]; if (msg[1] == MUIA_Disabled) { bool flg = msg[2] ? true : false; if (flg != isDisabled) { isDisabled = flg; refresh = true; } } if (msg[1] == MUIA_Selected) { bool flg = msg[2] ? true : false; if (flg != isSelected) { refresh = true; isSelected = flg; } } if (refresh) MUIMaster->MUI_Redraw(obj, 0); } break; case MUIM_Draw: { Object* o = 0; BitMap* bitmap = 0; void* drawinfo = 0; if (0 == _rp(obj)) break; if ((isSelected) && (dtimg2 != 0)) o = dtimg2; else if (dtimg1 != 0) o = dtimg1; else break; drawinfo = dt->ObtainDTDrawInfoA(o, (TagItem*)ARRAY( PDTA_Screen, (iptr)_screen(obj), TAG_DONE, 0)); if (drawinfo != 0) { dt->DrawDTObjectA( _rp(obj), o, _mleft(obj), _mtop(obj), width, height, 0, 0, 0); dt->ReleaseDTDrawInfo(o, drawinfo); } else { dt->GetDTAttrsA(o, (TagItem*)ARRAY( PDTA_DestBitMap, (iptr)&bitmap, TAG_DONE, 0)); if ((0 != bitmap) && (0 != GfxBase)) { #ifndef __amigaos4 BltBitMapRastPort(bitmap, 0, 0, _rp(obj), _mleft(obj), _mtop(obj), width, height, 0xc0); #else IGraphics->BltBitMapRastPort(bitmap, 0, 0, _rp(obj), _mleft(obj), _mtop(obj), width, height, 0xc0); #endif } } } return 0; } return DoSuperMtd(parent, obj, msg); } void MUIPictureClass::openImages() { if (dt == 0) return; closeImages(); dtimg1 = dt->NewDTObjectA(image1.Data(), (TagItem*)ARRAY( DTA_GroupID, (iptr)GID_PICTURE, PDTA_Remap, true, OBP_Precision, (iptr)PRECISION_EXACT, TAG_DONE, 0)); dtimg2 = dt->NewDTObjectA(image2.Data(), (TagItem*)ARRAY( DTA_GroupID, (iptr)GID_PICTURE, PDTA_Remap, true, OBP_Precision, (iptr)PRECISION_EXACT, TAG_DONE, 0)); width = 0x7fff; height = 0x7fff; if (dtimg1 != 0) { BitMapHeader *bmhd; dt->GetDTAttrsA(dtimg1, (TagItem*)ARRAY( PDTA_BitMapHeader, (iptr)&bmhd, TAG_DONE, 0)); width = width <? bmhd->bmh_Width; height = height <? bmhd->bmh_Height; } if (dtimg2 != 0) { BitMapHeader *bmhd; dt->GetDTAttrsA(dtimg1, (TagItem*)ARRAY( PDTA_BitMapHeader, (iptr)&bmhd, TAG_DONE, 0)); width = width <? bmhd->bmh_Width; height = height <? bmhd->bmh_Height; } if ((width == 0x7fff) && (height == 0x7fff)) { width = 64; height = 48; } } void MUIPictureClass::closeImages() { if (dt != 0) { if (dtimg1 != 0) { dt->DisposeDTObject(dtimg1); } if (dtimg2 != 0) { dt->DisposeDTObject(dtimg2); } } width = 64; height = 48; dtimg1 = 0; dtimg2 = 0; } iptr* MUIPictureClass::CreateClass() { if (MUIPictureClass::muiclass == 0) { MUIPictureClass::muiclass = new MUICustomClassT<MUIPictureClass>(MUIC_Area); } return (iptr*)MUIPictureClass::muiclass; } void MUIPictureClass::DestroyClass() { MUICustomClassT<MUIPictureClass> *p = MUIPictureClass::muiclass; MUIPictureClass::muiclass = 0; delete p; } </syntaxhighlight> Check out #mui on irc.freenode.net and report bugs/problems there and [http://finance.groups.yahoo.com/group/MUI/ MUI Yahoo Group] ;[https://library.morph.zone/Magic_User_Interface_Programming Magic User Interface MUI] 1sfcwbr8t5d2kk8l950mk2dxcjy2bck 4668972 4668971 2026-09-05T17:53:41Z Jeff1138 301139 4668972 wikitext text/x-wiki {{ArosNav}} ==Introduction== Mui original classes are identified by the trailing .mui like List, String, etc MUI (Zune) replacement classes MCCs came later which include Nlist, BetterString, etc which some developers frown upon. Please read autodocs/MUI_Application.doc/MUIM_Application_NewInput it has a proper example for a '''complete''' main loop. A MUI program has a main loop, but in an ideal application the loop is empty. Main loops as well as hooks are a thing of the past but backwards compatibility is still there. '''New method''' So nowadays, in order to handle notifications from buttons, sliders, etc. - you [http://guidetoamigacompatibleprogramming.googlecode.com/svn-history/r4/trunk/english/CAP_4.txt subclass Application.mui], Window.mui or <one of the groups>.mui of your choice, define your own private methods there and set up notifications on your buttons to call these methods. This lets you keep a neat internal structure rather than having everything in a one huge switch statement of return ids. Methods have no TRUE or FALSE states nor anything other defined states, they are just function calls (well, sort of). The only approach is subclassing technique and overload the method. You can then do anything you wish. The custom class is your way. To define your own private method and attribute ids you could start with TAG_USER. ;Read more [https://github.com/chfhhd/guidetoamigacompatibleprogramming here] '''Old Method''' With MUI you can also call hooks to avoid creating subclasses, but only the change of an attribute can cause an action. * First set Application and Window classes information. * Use Horizontal Groups (HGroup) or Vertical Groups (VGroup) to stuff objects (buttons, sliders, directory listers, etc) into them. Objects are not placed directly to some fixed locations but are instead grouped in special containers which are then dynamically displayed and positioned. * Use Notification to do something when object changes (pressed, slide, etc) * Release them when finished or when ending app Macros play a part in programming Zune interfaces. Get and Xget can replace GetAttrs and Set and Xset similarly with SetAttrs. When you read the mui autodocs there is a field after the function name with [ISG] and sometimes also [ISGN] And that indicates what to can do with the tag. <pre> I = Init S = SetAttr can be used G = GetAttr can be used N = Supports Notify </pre> So if you see [I.G] that means that you can use the Tag at Init and use GetAttr on it. ==MUI Zune Base Classes== {| class="wikitable" |- |+ BOOPSI rootclass connected to Zune NOTIFY.mui class ! [ Application.mui] ! [ Window.mui] ! [ Family.mui] ! [ Area.mui] |- | | Aboutmui | Menustrip | Rectangle |- | | | Menu | Balance |- | | | Menulist | Image |- | | | | Menubar |- | | | | Bitmap |- | | | | Text |- | | | | Gadget |- | | | | Gauge |- | | | | Scale |- | | | | Colorfield |- | | | | List |- | | | | Numeric |- | | | | Pendisplay |- | | | | Group |- |} encapsulation is what you have with all the MUI classes. For example to use a listview you have a well defined interface for this gadget, and all implementation details are encapsulated into the class (like private variables etc.) You would do similar with an advanced application. Locate all sub-systems and implement these as "isolated" modules with interfaces and implementation details encapsulated into the modules, not visible from the outside. inheritance via subclassing polymorphism ===Subclasses=== Good source examples [http://www.onyxsoft.se/snakee.html Snakee], [http://www.bluemind.org/amiga-lister-dopus-magellan-lister-system-amigaos/ List], ====Application==== Instead of MUI_NewObject(MUIC_Application, ,etc) is often replaced by the macro ApplicationObject, etc, etc... When subclassing window or application class there aren't MUIM_Setup/Cleanup methods at all. If you want to make a gui where everything is made of custom classes (at least the outer stuff, ie application and windows), you define all your classes as usual, and then instantiate your application with a single newobject() call. It's no problem to add elements to a group/window/application when it is being allocated (inside OM_NEW). ====Window==== Instead of MUI_NewObject(MUIC_Window, ,etc) is often shortened to the macro WindowObject,etc,etc but can be still used in Child Windows... The way to do this would be to implement a method in one of your subclasses (MUIC_Window or the window's Root MUIC_Group are always safe picks) and have a MUIA_Window_? notification call it. For the positions to be remembered, you have to close the windows (set MUIA_Window_Open to false) before disposing the Zune Application object ====Classes==== Instead of MUI_NewObject(MUIC_Group, ,etc) is often rewritten as the macro <Group>GroupObject,etc,etc... Then class creation: TheClass = MUI_CreateCustomClass (NULL, supername, NULL, sizeof (MyObjectData), dispatcher); <pre> if (!(mcc = MUI_CreateCustomClass(NULL,MUIC_Area,NULL,sizeof(struct NewClass_Data),NewClass_Dispatcher))) { printf("Cannot create custom class.\n"); return(0); } </pre> Is it ok to inherit from other types of object? Yes, to subclass slider class to overload MUIM_Numeric_Stringify method. How to check for a minimum version of a MUI MCC when building a GUI? [...] Your best chance is that the custom class writer has overloaded MUIA_Version/Revision. ===Doing Stuff=== And here is a way to access this inside a method: <pre> LONG AnyMethod (Class *cl, Object *obj, Msg msg) { struct MyObjectData *data = INST_DATA(cl,obj); /*...*/ if (!strcmp ("Amiga", data->Pointer)) DoSomething(); /*...*/ } </pre> Memory allocated for object data structure is freed automatically by MUI in object destructor, you have to do nothing. struct MyObjectData *data = (MyObjectData *)INST_DATA(cl, obj); ====Dispatcher==== Then, in your dispatcher subprogram, you write something like case MUIM_NList_ContextMenuBuild then MyOwnContextMenuBuild(cl,obj,msg); then you write a subprogram MyOwnContextMenuBuild that does what you want your class to do when this method is called. Every object in your subclass gets its own data area added to the object "structure". Also known as a data instantation. It is your own var area privately for the object with the given size in the MUI_CreateCustomClass() call but do not use the obsolete MUI_GetClass() and MakeClass() pairing. See the [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=2765 Class2.c] example in the MUI:Developer/C/Examples dir. ====Overloading==== '''Overloading''' class methods is the main and best design to use when you need to add some class features or use some specials behaviours. In MUI C version this is done by creating a new MCC (MUI Custom Class) and a dispatcher routine catching incoming BOOPSI messages when DoMethod() is called on instance of this MCC. To find out when a superclass's attribute changes without using a Notify? Yes, just overload OM_SET. Most (if not all) calls to OM_SET are done with a temporary tag list allocated on the stack, so it'll be lost anyway... If you need this pointer separate for every object, you should place it in object data structure. <pre> struct MyObjectData { char *Pointer; }; </pre> Tag list or method structures should be untouched in any way if it's not documented. If MUI or 3rd party mcc's do this they're broken... Example of documented method structures touched by MUI are MUIM_Draw and MUIM_AskMinMax... MUI will call MUIM_Hide, MUIM_Show on your object if the dimension change. So no need to check this in MUIM_Draw. MUIM_Draw is btw always called for a reason, so see no reason for you to omit a redraw here. <pre> ULONG NewList_New(struct IClass *cl , Object *obj, Msg msg) { return 0; } ULONG NewList_Set(struct IClass *cl , Object *obj, Msg msg) { return(DoSuperMethodA(cl, obj, msg)); } ULONG NewList_Get(struct IClass *cl, Object *obj, Msg msg) { return(DoSuperMethodA(cl, obj, msg)); } </pre> ===Application and Window=== How can you get a pointer to an active window object at any time? Normally you should search for MUIA_Window_Active in Application window list. Can create MUIC_Window subclass and intercept MUIA_Window_Active, and create your API for this. On the other hand, you can set up notification on this tag and if window receives it you will know about it and set some field in memory to window pointer or so. MUIA_Window_Screen for your own screen and trying to have window size completely under control. Setting MUIA_Window_Width and MUIA_Window_Height always works when you don't specify window ID (MUIA_Window_ID) for WindowObject. In case you specify this ID, height and width are set automatically by system and are remembered for next time you run application. <pre> app = ApplicationObject, MUIA_Application_Title, (IPTR)"KeyShow", MUIA_Application_Version, (IPTR)"$VER: KeyShow 1.0 (24.02.2012)", MUIA_Application_Copyright, (IPTR)_(MSG_AppCopyright), MUIA_Application_Author, (IPTR)"The AROS Development Team", MUIA_Application_Description, (IPTR)_(MSG_AppDescription), MUIA_Application_Base, (IPTR)"KEYSHOW", SubWindow, (IPTR)(win = WindowObject, MUIA_Window_Title, (IPTR)_(MSG_WI_TITLE), MUIA_Window_ID, MAKE_ID('K','S','W','N'), WindowContents, (IPTR)KeyboardGroupObject, End, End), End; if (app == NULL) </pre> <syntaxhighlight lang="c"> /* Copyright © 2002, The AROS Development Team. All rights reserved. $Id: dtpic.c 30792 2009-03-07 22:40:04Z neil $ */ #include <dos/dos.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <libraries/mui.h> struct Library *MUIMasterBase; Object *app; int main(void) { Object *wnd; MUIMasterBase = (struct Library*)OpenLibrary("muimaster.library",0); app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "dtpic test", MUIA_Window_Activate, TRUE, WindowContents, VGroup, Child, MUI_NewObject("Dtpic.mui",MUIA_Dtpic_Name,"SYS:System/Images/AROS.png",TAG_DONE), End, End, End; if (app) { ULONG sigs = 0; DoMethod ( wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit ); set(wnd,MUIA_Window_Open,TRUE); while (DoMethod(app, MUIM_Application_NewInput, (IPTR) &sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D); if (sigs & SIGBREAKF_CTRL_C) break; if (sigs & SIGBREAKF_CTRL_D) break; } } MUI_Object(app); } CloseLibrary(MUIMasterBase); return 0; } </syntaxhighlight> You must OM_ADDMEMBER a window to an application before opening it and you must OM_ADDMEMBER an area object to a group object (in a MUIM_Group_InitChange/ExitCHange pair) if you want to show it in a window (be part of your GUI). Mui Dev docs have a section on Dynamic Windows (Dynamic Object Linking/Windows) which are detailed documentation for dynamic window creation. But you can create a custom class and get notified just by looking for incoming methods. Overloading MUIM_Setup is probably the best idea. You can subclass your window and put screen change detection in MUIM_Setup. E.g. in every MUIM_Setup you can remember screen pointer somewhere in object data, compare it with the previous value and do some things if screen has changed. use _app(obj) after MUIM_Setup. You could have subclass of MUIC_Group where the all objects are placed... When you detect in MUIM_Setup that _screen() changed, you set MUIA_Window_CloseRequest to TRUE... If you app runs on WB screen user can change WB screen resolution/depth at any time. User can change your screen from the custom screen database at any time. Other thing to consider is iconify from the Exchange or ARexx. You _must_ react for screen changes. Then you should place MUIM_Application_Save after your main loop. Overloading MUIM_Window_Snapshot with some code which saves the prefs would do a save whenever the user selects the Snapshot icon on the window border, it would not do that only at program end. If you really want to save on Snapshot, you have to create a new class with CreateCustomClass() which must be a subclass of MUIC_Window. In the dispatcher of this sub class you have to call your own code whenever the dispatcher receives the MUIM_Window_Snapshot method. Then you have to change the application creation code: You have to replace every window creation with creation of an object of your window sub class (Intuition.NewObject()). There seems to be a general problem when disposing windows: You must *not* reference the application object in a windows dispose method! Why? Because before disposing a window, you unlink it from the application (OM_REMMEMBER). After that, the window does no longer belong to an application and using _app(obj) is illegal. You don't have _app(obj) available during OM_NEW, the same is true for OM_DISPOSE. Using _app(obj) anywhere in setup/cleanup methods (either before or after the DoSuperMethod) is fine. In fact, there is another layer between new/dispose and setup/cleanup where an object learns about its application context. However, this layer has not been made publically available through methods yet. MUIA_Window_IsSubWindow does exactly this (skipping OM_REMMEMBER and OM_DISPOSE). However, this is not the solution to all problems which arise from the "global" window list in the application object. Window class should probably be able to have more window children itself. How do we get the actual Window from my MUI-object ??? <pre> struct Window *win; DoMethod(obj,MUIA_Window,&win); </pre> MUIA_Window is an attribute. You can read attributes by calling GetAttr() from Intuition: GetAttr(MUIA_Window, obj, &x); And few warnings: * MUIA_Window is only valid when the window is opened * MUIA_Window is an area class tag. Use MUIA_Window_Window for window objects. To call ChangeWindowBox on MUI windows. Just take care that the window is currently open (MUIA_Window_Window!=NULL) need the screen, you can always get MUIA_Window_Window and use window->WScreen etc. like with other intuition windows. '''MUIM_Application_PushMethod''' So you want to get out of the object context first, and this is easily done with MUIM_Application_PushMethod. <pre> /* From your mail window */ DoMethod(_app(obj), MUIM_Application_PushMethod, _app(obj), 2, MUIM_MyApplication_RemoveObject, obj); /* From your application subclass */ case MUIM_MyApplication_RemoveObject: { DoMethod(obj, OM_REMMEMBER, msg->Obj); MUI_DisposeObject(msg->Obj); } break; </pre> Basically have a rendering task that does a heap of computation and renders into an offscreen rastport. When it's finished a frame, it sets a flag (Drawn) to FALSE, releases a semaphore, and does a PushMethod. The main program, waiting patiently in its event loop, at some point will be awakened by the PushMethod, which triggers the custom class to do a MUI_Redraw() internally, which in turn obtains the semaphore, copies the offscreen bitmap to the window, sets Drawn to TRUE, and releases the semaphore. Then it goes back to sleep. The rendering subtask, in the meantime, has done an ObtainSemaphore. When it gets it, it checks to see if Drawn is TRUE. If so, it can continue because it means the main task successfully copied the bitmap. Otherwise it releases it, does a little Delay, and tries again, to try and give the main task time to snatch the semaphore and do its work. So, the semaphore is, in effect, protecting the offscreen rastport (and the Drawn flag) - neither task can access or change it without obtaining the semaphore first, and the flag is used to tell the draw task whether the main task has had a chance to do its job or not. Most of the time (i.e. almost always) the main task does, in fact, manage to grab the semaphore immediately so the draw task doesn't manage to steal it back again too quickly. If the main task finishes quickly, then when the draw task tries to obtain the semaphore it succeeds immediately, so there's no penalty. PushMethod should not be too heavily overloaded, however, for inter-process communication recommends using private messageports for more intensive stuff. Use it as a signalling mechanism to wake up the main task and get it to send a MUI_Redraw to the custom class, and only ever send one at once (although there are 30-60 of them per second). Never had any problems with it in those circumstances. <pre> struct SignalSemaphore lock_AddEntry_Sem; ... InitSemaphore(&lock_AddEntry_Sem); ... while(something){ ... ObtainSemaphore(lock_AddEntry_Sem); // Grab the semaphore while (lock_AddEntry){ // Main task completed its job? ReleaseSemaphore(lock_AddEntry_Sem); // No, release semaphore Delay(1); // Wait a bit ObtainSemaphore(lock_AddEntry_Sem); // Try again } ... lock_AddEntry = TRUE; // Set flag ReleaseSemaphore(lock_AddEntry_Sem); // Give CPU back to main task ... } </pre> MsgPorts are slower. Semaphores are better to use under any AmigaOS like. MUIM_HandleEvent is called for each event handler node unless MUI_EventHandlerRC_Eat is returned. MUIM_HandleInput is called for an active object if it was not eaten by MUIM_HandleEvent. Should use EventHandler and not request? To avoid getting events even if my object is not the active one ? Yes - eventhandlers respect properties such as the active and default object, priorites etc. HotkeyString is a subclass of BetterString. It adds a new eventhandler with a higher priority, thus get the events before its superclass, which wouldn't be the case for the other approach (one could override MUIM_HandleInput, but this was just *one* example...) Eventhandlers also allow you to swallow input, another thing which isn't possible with IDCMP-requesting. This means many objects (which use the old way) will only interpret input when they are the active or default object, which is bad e.g. in IProbe where I want HTMLview to react on arrow up/down, even when the URL-string is active - and this is AFAIK only possible with eventhandlers. the proper way to know the current active window (IDCMP_ACTIVEWINDOW/IDCMP_INACTIVEWINDOW was what I tracked before). What is the proper MUI way to know a window has become active? You can attempt a setup dispatcher that add the required actions to the event handler. <pre> struct your_data { struct MUI_EventHandlerNode ehnode; }; ULONG yoursetup(struct IClass *cl, Object *obj, Msg msg) { struct your_data *data = (struct your_data *)INST_DATA(cl, obj); if (!DoSuperMethodA(cl, obj, msg)) return(FALSE); data->ehnode.ehn_Object = obj; data->ehnode.ehn_Class = cl; data->ehnode.ehn_Events = IDCMP_ACTIVEWINDOW | IDCMP_INACTIVEWINDOW; DoMethod(_win(obj), MUIM_Window_AddEventHandler, &data->ehnode); return(TRUE); } </pre> add a cleanup dispatcher that looks like : <pre> ULONG yourcleanup(struct IClass *cl, Object *obj, struct MUIP_HandleInput *msg) { struct your_data *data = (struct your_data *)INST_DATA(cl, obj); DoMethod(_win(obj), MUIM_Window_RemEventHandler, &data->ehnode); return(DoSuperMethodA(cl,obj,msg)); } </pre> Add a dispatcher for MUIM_HandleEvent and take care of your wanted event like : <pre> ULONG yourhandler(struct IClass *cl, Object *obj, struct MUIP_HandleInput *msg) { struct your_data *data = (struct your_data *)INST_DATA(cl, obj); if (msg->imsg) { case IDCMP_ACTIVEWINDOW: // Do what you want here break; case IDCMP_INACTIVEWINDOW: // Do what you want... break; } return(DoSuperMethodA(cl, obj, (Msg)msg)); } </pre> or You could try to install an event listener that triggers every time MUIA_Window_Activate gets changed. Be able to receive mouse co-ordinates and keypresses into my application, even when the window is not active. You can poll intuition base and read mouse coords at any time. An interrupt routine would be the best solution if your app wants keep an eye on it all the time... (might be possible with other libraries) Everything is single threaded unless you specifically use MUIM_Application_InputBuffered. No functions are interrupted in order to handle a signal. Would a better method be to offload the MUI interface handling onto a separate task, and communicate with the network task through signals? This would at least solve the problem mentioned above. STRICQ uses MUI and is setup to handle any number of simultaneous sockets, both TCP and UDP. First create another window, then call MUIM_Application_InputBuffered (even though you should really try to avoid this) and then do the PushMethod. What should I do if the InputBuffered had to be used to handle other actions? Come up with a design pattern that avoids this nasty input probing in the middle of your program Creating a subclass of application class for this purpose where you could call one method with the object to be deleted as an argument and the application sub-class then stored a pointer to this object and deleted it after MUIM_Application_Input returned (and a nested counter tells me that there is no other recursive call to MUIM_Application_Method). Remember that the MUIM_PushMethod is not safe in the sense that it can fail (e.g. out of memory) and then your object doesn't get deleted (i.e. memory leak). The solution using a sub class of application class is safe as there is no need to allocate memory for the pointer to the object by adding it to an 'internal' Group class. ====Iconify==== <pre> #ifdef __amigaos4__ MUIA_Application_DiskObject , diskobject = GetDiskObject(_ProgramName), #endif </pre> MUIA_Application_DiskObject,GetDiskObject("PROGDIR:mp3player"), where PROGDIR:mp3player is the name of your app. Be aware, that you are leaking the disk object this way. Be sure to assign it to pointer and FreeDiskObject after your application has ended.. <pre> struct DiskObject *my_app_icon; MUIA_Application_DiskObject,my_app_icon=GetDiskObject("PROGDIR:zamp"), ULONG iconified=0; get(application, MUIA_Application_Iconified, &iconified); if( !iconified) </pre> How to execute an arexx script from your own program as though it was run from your program's arexx port. An application subclass that adds one method called MUIM_Application_RunScript, just call this method with the scriptname and its arguments then it will be launched with your (MUI) port as host and it will make sure your program doesn't quit before the script has completed. <pre> ULONG ListWindows( Object *application ) { ULONG windows = 0; struct MinList *windowlist; windowlist = (struct MinList *) xget( application, MUIA_Application_WindowList ); if( windowlist && !IsListEmpty( (struct List *) windowlist ) ) { Object *object, *objectstate = (Object *) windowlist->mlh_Head; while( object = NextObject( &objectstate ) ) { Printf( "Object 0x%08lx is %swindow.\n", object, IsWindow( object ) ? "" : "not " ); windows++; } } return( windows ); } </pre> You can check whether object class is class or subclass of MUIC_Window, using similar code to below: <pre> BOOL IsWindow( Object *object ) { struct IClass *windowclass = MUI_GetClass( MUIC_Window ); struct IClass *class; for( class = OCLASS( object ); class; class = class->cl_Super ) if( class == windowclass ) return( TRUE ); return( FALSE ); } </pre> ====External input====  MUIM_Application_AddInputHandler(struct( MUI_InputHandlerNode ) in the MUIM_Setup and MUIM_Cleanup methods of your class (not subclass?). Remove with MUIM_Application_RemInputHandler '''Obsolete Hooks''' Is it safe to call the MUI_DisposeObject() inside a hook which is called by a notification if it frees the object the notification is attached to? This is not safe. The hook contents are not freed because after returning from the hook, there is still some return code from the calling class which has to be executed. <pre> MUIM_Application_AboutMUI MUIM_Application_AddInputHandler MUIM_Application_CheckRefresh MUIM_Application_InputBuffered MUIM_Application_Load MUIM_Application_NewInput (replaces old Input) MUIM_Application_OpenConfigWindow MUIM_Application_PushMethod MUIM_Application_RemInputHandler MUIM_Application_ReturnID MUIM_Application_Save MUIM_Application_SetConfigItem MUIM_Application_ShowHelp </pre> <pre> MUIA_Application_Active MUIA_Application_Author MUIA_Application_Base MUIA_Application_Broker MUIA_Application_BrokerHook MUIA_Application_BrokerPort MUIA_Application_BrokerPri MUIA_Application_Commands MUIA_Application_Copyright MUIA_Application_Description MUIA_Application_DiskObject MUIA_Application_DoubleStart MUIA_Application_DropObject MUIA_Application_ForceQuit MUIA_Application_HelpFile MUIA_Application_Iconified MUIA_Application_MenuAction MUIA_Application_MenuHelp MUIA_Application_Menustrip MUIA_Application_RexxHook MUIA_Application_RexxMsg MUIA_Application_RexxString MUIA_Application_SingleTask MUIA_Application_Sleep MUIA_Application_Title MUIA_Application_UseCommodities MUIA_Application_UsedClasses MUIA_Application_UseRexx MUIA_Application_Version MUIA_Application_Window MUIA_Application_WindowList </pre> <pre> MUIM_Window_AddEventHandler MUIM_Window_Cleanup MUIM_Window_RemEventHandler MUIM_Window_ScreenToBack MUIM_Window_ScreenToFront MUIM_Window_Setup MUIM_Window_Snapshot MUIM_Window_ToBack MUIM_Window_ToFront </pre> <pre> MUIA_Window_Activate MUIA_Window_ActiveObject MUIA_Window_AltHeight MUIA_Window_AltLeftEdge MUIA_Window_AltTopEdge MUIA_Window_AltWidth MUIA_Window_AppWindow MUIA_Window_Backdrop MUIA_Window_Borderless MUIA_Window_CloseGadget MUIA_Window_CloseRequest MUIA_Window_DefaultObject MUIA_Window_DepthGadget MUIA_Window_DisableKeys MUIA_Window_DragBar MUIA_Window_FancyDrawing MUIA_Window_Height MUIA_Window_ID MUIA_Window_InputEvent MUIA_Window_IsSubWindow MUIA_Window_LeftEdge MUIA_Window_MenuAction MUIA_Window_Menustrip MUIA_Window_MouseObject MUIA_Window_NeedsMouseObject MUIA_Window_NoMenus MUIA_Window_Open MUIA_Window_PublicScreen MUIA_Window_RefWindow MUIA_Window_RootObject MUIA_Window_Screen MUIA_Window_ScreenTitle MUIA_Window_SizeGadget MUIA_Window_SizeRight MUIA_Window_Sleep MUIA_Window_Title MUIA_Window_TopEdge MUIA_Window_UseBottomBorderScroller MUIA_Window_UseLeftBorderScroller MUIA_Window_UseRightBorderScroller MUIA_Window_Width MUIA_Window_Window </pre> ===Objects=== DoMethod( object1, method, attribute, value, object2, parameter_number, method2, attribute2, value2 [,...]) * MUIM_Application_NewInput * MUIM_Window_ * MUIM_CallHook MUIM_FindUData MUIM_GetUData MUIM_SetUData * MUIM_KillNotify MUIM_NoNotifySet MUIM_Notify * MUIM_Set MUIM_MultiSet MUIM_SetAsString * MUIM_List_InsertSingle When a Zune object is created and destroyed several methods are called: <pre> OM_NEW MUIM_Setup MUIM_AskMinMax [ window is opened here ] MUIM_Show MUIM_Draw MUIM_Hide [ window is closed here ] MUIM_Cleanup OM_DISPOSE </pre> If something is only valid between setup and cleanup it means that the first place where you can use it is the setup method and you aren't allowed to use it after cleanup. If you want to manage a set of invisible objects the class MUIC_Family may be of help. Need to know size of object while program is between MUIM_GroupInitChange and MUIM_GroupExitChange. Simple asking about MUIA_Width a MUIA_Height returns 0. Anyone have any idea? Width/height is not valid until you call ExitChange again. But if you need to know object dimensions subclassing is probably the best way to do so. You can get object dimensions by using _width()/_height() macros. The object can't tell the difference of whether OM_SET was invoked through SetAttr() or through MUIM_MultiSet. Some standard MUI classes do indeed modify the taglist passed to them. A good example is Group class; it sets certain tags to TAG_IGNORE, because they either cannot be forwarded to the children, or shouldn't be handled by its superclass (Area). How do you add a selected image to an app to use a different image for normal and selected states ? Most people are using a Group with PageMode set, so that the group simply toggle the displayed page, when pressed, and each page has the desired image shown on it. ====Notifications==== Basically, MUI doesn't use BOOPSI's notification system. Notification happens transparently; the only thing you need to do is pass the method up to your superclass, and you should be doing that anyway—you don't need to use the approach that non-MUI BOOPSI classes use. You can put notification on every attribute of your custom class. That's assuming your class is derived from MUIC_Notify. Then MUI will automagically execute the notification whenever you set an attribute. You can place a notification on any (public) attribute of any class (or its ancestors) using the MUIM_Notify method. These notifications can be placed at any time from anywhere. All you have to do is only change attributes of your object using set(), and in your set method handler add return (DoSuperMethodA(cl, obj, msg)); at the end. This will pass on the OM_SET up the class hierarchy to Notify.mui, which will then perform the notifications. The other thing, of course, is to always use set() whenever you want to change a value, rather than just assigning it directly. Only within the OM_SET method should you assign it directly. When some other class puts a notification on one of your attributes, and your attribute gets changed using set() (or OM_SET), then when it does the DoSuperMethod() call the OM_SET will eventually reach the root class of all MUI classes—Notify.mui. This keeps a list of notifications to be performed. <pre> /* This is setting up a notification on the MUIA_Robot_FrameRate * attribute */ DoMethod(MyObj, MUIM_Notify, MUIA_Robot_FrameRate, MUIV_EveryTime, FrameCntObj, 4, MUIM_SetAsString, MUIA_Text_Contents, MUIX_R"%ld", MUIV_TriggerValue ); ... /* This is setting the frame rate (actually done within the class * itself -- ie. I use set() rather than just changing the value * directly in case there are notifications on it. */ set(obj, MUIA_Robot_FrameRate, data->framecnt - data->lastframecnt); ... /* This is the relevant part of my custom class's OM_SET method * handler. */ static ULONG mSet(struct IClass * cl, Object * obj, Msg msg) { struct MyData *data = INST_DATA(cl, obj); struct TagItem *tags, *tag; for (tags = ((struct opSet *) msg)->ops_AttrList; tag = NextTagItem(&tags);) { switch (tag->ti_Tag) { ... case MUIA_Robot_FrameRate: data->framerate = (ULONG) tag->ti_Data; break; ... } } return(DoSuperMethodA(cl, obj, msg)); } </pre> If you have an attribute MUIA_Xxx_Yyy that is readable and notifiable, and recognized by mGet() (your OM_GET method). Internally it reads from data->Yyy. Further, let's say you have a private attribute MUIA_Xxx_YyyP (probably best to give it a numeric value quite different to the rest in your class) that is recognized by mSet() and writes to data->Yyy. mSet(), however, does *not* recognize MUIA_Xxx_Yyy. The code in the mSet() switch statement that recognizes MUIA_Xxx_YyyP, in addition to writing to data->Yyy, changes tag->ti_Tag to MUIA_Xxx_Yyy. Then, when the DoSuperMethodA() call is made, Notify class recognizes the attribute that was changed as MUIA_Xxx_Yyy and correctly performs the notification. Suppose your class use the custom attribute MUIA_HHH_MyAttr. Other objects can ask MUI to be notified whenever this attribute is set()ted to a given value,for example you can have something like this: DoMethod(obj1,MUIM_Notify,MUIA_HHH_MyAttr,32,obj2,1,MUIM_MyObj_Changed); Here object obj2 asks to be notified with method MUIM_MyObj_Changed whenever the attribute MUIA_HHH_MyAttr of obj1 is set()ted to 32. Child, Label2("Allow duplicates:"), Child, ck6 = CheckMark(TRUE), DoMethod(ck6, MUIM_Notify, MUIA_Selected, MUIV_EveryTime, app, 2, MUIM_Application_ReturnID, ACT_CK6); The confusing thing about this bug is that it only affects CheckMark(TRUE) objects (or if you use MUIM_Application_Load to restore the state of checkmarks then those that become set to TRUE will exhibit the same problem). The autodocs state you 'simply' add your checkmarks and strings (paired together) even in 'invisible' space. You need the string because the autostring for a checkmark is only place-able at the left side (which would be unintuitive). <pre> Object *MakeCheck(BYTE state, char *label) { return ImageObject, ImageButtonFrame, MUIA_Text_Contents, label, MUIA_InputMode , MUIV_InputMode_Toggle, MUIA_Image_Spec , MUII_CheckMark, MUIA_Background , MUII_ButtonBack, MUIA_ShowSelState, state, MUIA_CycleChain , TRUE, End; } </pre> DoMethod(timerobj,MUIM_Notify,MA_Timer_Seconds,MUIV_EveryTime,obj,2,MM_Clock_Seconds,MUIV_TriggerValue); This should call MM_Clock_Seconds everytime MA_Timer_Seconds changes. <pre> WaitIO(data->req); CurrentTime(&raw,&micros); today = raw%86400; SetAttrs(obj,MA_Timer_Seconds,today%60,TAG_DONE); </pre> Notify does not happen <pre> data->seconds = today%60+30; data->minutes = (today%3600)/60; data->hours = today/3600; data->req->tr_node.io_Command = TR_ADDREQUEST; data->req->tr_time.tv_secs = 1; data->req->tr_time.tv_micro = 0; SendIO((struct IORequest *)data->req); </pre> timerobj's OM_GET: <pre> case MA_Timer_Seconds: *msg->opg_Storage = data->seconds; return TRUE; </pre> Class has no OM_SET but you '''must implement OM_SET''' to notify. I would not use MUI notifications for this kind of events because due to BOOPSI latency. The timer does work (tested by getting MA_Timer_Seconds in every MUIM_Draw for the clock class, but MM_Clock_Seconds never gets called. SetAttrs(NULL, ... In theory you do not have to because SetAttrsA() is only a wrapper call to DoMethodA() which accepts NULL object pointer but this is not documented behaviour either in SetAttrsA() nor DoMethodA(). So do not rely on it but use macro instead to save you from typing if statements. Restore a button frame - D&D lately but it seems it clashes with MUI's own D&D drawing. You could look into Ambient D&D for ideas. It uses its own dropmarks. <pre> MUI_DISPATCH(NewList_Dispatcher) { switch (msg->MethodID) { case OM_NEW : return(NewList_New (cl,obj,(APTR)msg)); case OM_SET : return(NewList_Set (cl,obj,(APTR)msg)); case OM_GET : return(NewList_Get (cl,obj,(APTR)msg)); case MUIM_DragQuery : return(NewList_DragQuery(cl,obj,(APTR)msg)); case MUIM_DragDrop : return(MyList_DragDrop (cl,obj,(APTR)msg)); case MUIM_ExternDrop :return(MyList_ExternDrop(obj,(APTR)msg)); } return(DoSuperMethodA(cl,obj,msg)); } </pre> added an internal notification method to each checkmark (checkbox) and added the method to the dispatcher, <pre> DISPATCHERPROTO(MCC_BIA_dispatcher) { struct mydata *mydata = INST_DATA(cl,obj); switch (msg->MethodID) { case OM_NEW: return( MCC_BIA_New (cl, obj, (APTR) msg)); case OM_SET: return( MCC_BIA_Set (cl, obj, (APTR) msg)); case OM_GET: return( MCC_BIA_Get (cl, obj, (APTR) msg)); case OM_DISPOSE: return( MCC_BIA_Dispose (cl, obj, (APTR) msg)); case MUIM_AskMinMax: return( MCC_BIA_AskMinMax (cl, obj, (APTR) msg)); case MUIM_BIA_Changed: return( MCC_BIA_Changed (cl, obj, (APTR) msg)); default: return( DoSuperMethodA (cl, obj, msg)); } } </pre> Each time click on one of the checkboxes you get an MUIM_BIA_changed and the function get's called. Within the function readout the checkboxes and rebuild the bit array which can be read and set by using the MUIA_BIA_Array tag. Now a notification for MUIA_BIA_Array is required. Do I need to call the class itself by using set(MUIA_BIA_Array) to cause a notification to take place, or is there a more simple way. Calling the class from inside would cause the checkboxes to change and this would result in another MUIM_BIA_changed and we have an endless loop. The problem is that setting would cause an update of the class internal gadgets. These would cause a notify and the notify would cause another set(). <pre> //The best way to handle it is to filter out tag list.. struct TagItem *tagitem; tagitem = FindTagItem( MUIA_xxx_name, taglist ); if( tagitem != NULL ) { tagitem->ti_Tag = TAG_IGNORE; } </pre> do-notify set might still causing infinite loop in some circumstances that vary on super class attributes implementation, and therefore in one class version working fine, in second crashing system... <pre> MUIA_ApplicationObject MUIA_AppMessage MUIA_HelpLine MUIA_HelpNode MUIA_NoNotify MUIA_ObjectID MUIA_Parent MUIA_Revision MUIA_UserData MUIA_Version MUIM_CallHook MUIM_Export MUIM_FindUData MUIM_GetConfigItem MUIM_GetUData MUIM_Import MUIM_KillNotify MUIM_KillNotifyObj MUIM_MultiSet MUIM_NoNotifySet MUIM_Notify MUIM_Set MUIM_SetAsString MUIM_SetUData MUIM_SetUDataOnce MUIM_WriteLong MUIM_WriteString </pre> ====Layouts==== <pre> // Create your GUI app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, (IPTR) "Title", MUIA_Window_CloseGadget, FALSE, WindowContents, (IPTR) VGroup, MUIA_Group_SameWidth, TRUE, Child, (IPTR) HGroup, Child, (IPTR) VGroup, Child, TextObject, MUIA_Text_Contents, "33cText1", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText2", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText3", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText4", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText5", End, [...] End, Child, VGroup, Child, TextObject, MUIA_Text_Contents, "33cText6", End, [...] End, End, Child, HGroup, Child, Scan_button = SimpleButton("Button"), Child, Quit_button = SimpleButton("Quit"), End, End, End, End; </pre> <pre> Object *exampleWinObj, *exampleVirtGObj, *exampleContainerObj; Object *exampleChildObj; exampleWinObj = (Object *)WindowObject, MUIA_Window_CloseGadget, FALSE, MUIA_Window_Title, (IPTR)"Example Window", WindowContents, (IPTR) (exampleVirtGObj= (Object *)GroupObject, MUIA_Group_Virtual, TRUE, Child, (exampleContainerObj = (Object *)VGroup, End), End), End; if (exampleWinObj) { int i; for (i = 0; i < 10; i++) { exampleChildObj = HVSpace; if (DoMethod(exampleContainerObj, MUIM_Group_InitChange)) { DoMethod(exampleContainerObj, OM_ADDMEMBER, exampleChildObj); DoMethod(exampleContainerObj, MUIM_Group_ExitChange); } } } </pre> Change the HVSpace for whatever object (group, etc) you want to add.. '''Obsolete Hooks.''' MUI does not allow own position of Components, only automatic positions available (group concept) but by setting and Layout Hook and add and Left, Top, Width and Height to every Object, you can disable this behaviour Your notify should preferably invoke a method on the class responsible for the action you want to have executed. Tend to gather more general stuff in window or application subclasses. If there's really no place it belongs then you can have it call a hook instead. You must add your own layout hook which reports the size. Then simply invoke MUIM_Group_Init/ExitChange on your virtgroup object, as that will cause a re-layout == invocation of your layout hook, which can report new sizes for the contents. If your family tree needs any layout (before rendering) then the layout hook is also the ideal place for this. Take a look at 2b_VRastPort sources on Aminet. <pre> /* gcc syntax */ ULONG __attribute__((regparm(3))) Genealo_Layout(struct Hook *hook, struct MUI_LayoutMsg *lmsg, Object *obj ) { ULONG result = 0; int longueur=500, haut=500; switch(lmsg->lm_Type) { case MUILM_MINMAX: { printf("MinMax\n"); lmsg->lm_MinMax.MinWidth = 500; lmsg->lm_MinMax.MinHeight = 500; lmsg->lm_MinMax.MaxWidth = 500; lmsg->lm_MinMax.MaxHeight = 500; lmsg->lm_MinMax.DefWidth = 500; lmsg->lm_MinMax.DefHeight = 500; } break; case MUILM_LAYOUT: { printf("Layout...\n"); lmsg->lm_Layout.Width = longueur; lmsg->lm_Layout.Height = haut; result = TRUE; } break; } return result; } </pre> <pre> ULONG __attribute__((regparm(3))) Genealo_Dispatcher(struct IClass *cl , void *msg,Object *obj ) { Msg msg2 = ( Msg ) msg; struct Genealo_Data *data; ULONG result; switch (msg2->MethodID) { case OM_NEW: { result = DoSuperMethodA(cl,obj,msg); if(obj = (Object *)(result)) { data = (struct Genealo_Data *)INST_DATA(cl,obj); data->LayoutHook.h_Entry = (ULONG(*) ())Genealo_Layout; data->LayoutHook.h_Data = data; SetAttrs(obj,MUIA_Group_LayoutHook, &data->LayoutHook,TAG_DONE); } printf("%p\n",result); return( result ); } break; /* ..... */ </pre> How to do multithreading in MUI, where the same thread to be running several times simultaneously? Your application tree may only be accessed by one task, as no MUI object is re-entrant nor thread-safe (the classes are, not the objects). Using DoMethod(app,MUIM_CallHook,&hook) works fine for running different threads at the same time but when calling the same hook a second time, the first one pauses. It is because both threads are running on the same OS task. If you want to have them running simultaneously, you have to create a separate task for each thread, e.g. by CreateProc() from dos.library. That method is the same as CallHookA(&hook, app, NULL) which again is the same as just calling the hook-function directly, with 'app' and '&hook' as parameters. Not sure why you think this equals 'multi-threading'. If the second event then terminates, the first one continues, but it seems all the local variables have been altered by the second event. Because your code is not reentrant. ====Finding==== there is also a user field in IClass and you can access to this through MUI_CreateCustomClass() as in the Dispatcher. <pre> mcc = MUI_CreateCust..() mcc->mcc_Class->cl_UserData = data; </pre> in the Dispatcher: <pre> data = cl->cl_UserData; </pre> use MUIA_UserData, to store a pointer to a private struct where IT store information that object/related code might need ... e.g pointers to paths/filenames, whatever you like really. the MUIA_UserData of the object contains the given udata\ and returns the object pointer in this case. ====Area (dragging, RMB etc)==== Let the program know if the user clicks anywhere on the map, the answer is yes: Group class is a child of area class, thus you can use any attribute of area class, for example MUIA_Pressed. Let the program know, if and where the user clicked on the map, the answer is no. That's exactly what custom classes are for. If any drawing will be manipulated by the user (e.g. an area for painting with the mouse), you write a subclass of Area class. Bitmap is just for displaying rastered images. If you want to have a (resizeable) area for application specific drawings, sub-classing Area is still the right thing to do. If you want to create a bitmap of them tiled, which would then be displayed inside the application. For this application it is certainly simpler to use a Column group with Bitmap objects as children, or even a group with a custom LayoutHook that adapts the number of columns to the size of the area. <pre> // want the image to be the same size as the picture or if the object has to be bigger then the picture, // it should be centered (horiz and vertically). TextAttr ta = { "topaz", 8, 0, 0 }; TextFont *Topaz8Font = OpenFont(&ta); Object *guiobject = ImageObject, MUIA_Image_Spec, "5:<path>", MUIA_Image_FreeHoriz, FALSE, MUIA_Image_FreeVert, FALSE, MUIA_Image_FontMatch, TRUE, MUIA_Font, Topaz8Font, End; </pre> the Image class is a subclass of Area class, and the Area class can handle input, thus it should be possible to create an Image object that behaves like an ordinary button. Simply try to create an Image object, init the attribute MUIA_Image_Spec as "5:picture_filename" (to load the image via datatypes) and try to init the Area class attribute MUIA_InputMode as MUIV_InputMode_RelVerify. Then set up a notification for that object, so you will hear from it, open the window... It might help to have a look at the "default macros" for images and buttons in mui.h to initialize the other attributes (frame type etc.) properly. # Call MUIM_Group_InitChange on a parent group of your object. # OM_REMMEMBER it from the group. # Change the size ie you should modify the data used in MUIM_AskMinMax to fill the structure. # OM_ADDMEMBER it back. # Call MUIM_Group_ExitChange on the group. =====MUIM_DRAW===== If you want to code yourself what your class will display (eg the wireframe drawing with the mui class1 demoprogram), you implement this overriding the MUIM_Draw method. (have a look at the three examples of custom classes class1 (ok), class2 (ok), class3 (obsolete). Is it possible to draw on objects outside of MUIM_Draw? MUIM_Draw adds some overhead compared to direct draw (like in gadtools) but overhead is very minimal and you can't notice any slow down either... Is there a safe way to do draw into a window/MUI-object outside a Draw-event? You can draw only inside MUIM_Draw because: * your object may belong to virtual group and needs clipping (MUI installs this automatically for MUIM_Draw) * your application can be hidden (in the iconified state) at anytime and thus _rp(obj) is not always valid. * your object could be hidden for some reason (page and register groups) If you just want draw new parts of your objects without full redraw? Then you could do something like this: <pre> data->DrawCommand = MY_OWN_DRAW_COMMAND; MUI_Redraw(obj, MADF_DRAWUPDATE); </pre> And then in your MUIM_Draw method: <pre> MyDraw() { DoSuperMethod(); if (msg->flags & MADF_DRAWUPDATE) { switch (data->DrawCommand) { /* UPDATE PARTS YOU WANT TO */ } } else { /* FULL REDRAW */ } } </pre> In MUIM_Draw simply call BltBitMapRastPort() to display stuff in screen: BltBitMapRastPort(data->RastPort.BitMap, 0, 0, rp, mleft, mtop , mwidth, mheight, 0xc0); create a bitmap, embed it in a rastport and set this rastport in your MUI renderinfo - then simply call MUIM_DrawBackground, and the background is drawn into your off-screen bitmap. Remember to set back the rastport within your objects area you ae absolutely free to render whatever you want. And about the rastport: You *should* attach an own rastport to the object, if you use any graphics.library functions: Mui expects to find the objects own rastport in the same state after MUIM_Draw is executed. If MUIM_Draw not being called (blank area with a frame) then check that you are not calling DoSuperMethodA() first in your MUIM_Draw method and that the MUIM_Draw Method only checks for msg->flags == MADF_DRAWOBJECT. <pre> switch( msg->MethodID ) { [...] case MUIM_Draw: return( draw( class, object, msg ) ); [...] } </pre> solved the problem, replaced them in the draw method <pre> if(!DoSuperMethodA(cl,obj,(APTR)msg)) DoSuperMethodA(cl,obj,(APTR)msg); </pre> Typically your object should have an internal buffer where you store the objects state after the last MUIM_Draw. This allows you to draw only those parts of your map, that need to be updated. Stuff the parameters into you instance data and call MUI_Redraw() with MADF_DRAWUPDATE. That's what it is for. Basically, all rendering is done inside MUIM_Draw. If another method wants to render, it sets up parameters and calls MUI_Redraw(). MUI_Redraw() will then call MUIM_Draw for you. However, you must be aware that MUIM_Draw might _not_ be called, e.g. when your object is currently hidden. So, MUIM_Draw should only draw; your other methods should do all the other stuff (if you draw an ellipse, you have to store that information somewhere in case a refresh comes in, the application is iconified etc. So, you MUIM_xxx_DrawEllipse will store all that information somewhere (adding the ellipse to a list or drawing it into an offscreen bitmap), then it will call MUI_Redraw(TheObject,MADF_DRAWUPDATE) to update the display). What about a 3ds viewer with mui buttons ? Titler display opengl and mui on the same window, so what class/methods can use to display/redirect opengl output onto mui win? You need an area subclass to display your GL stuff in MUI window. You only need an offscreen bitmap which is blitted to the window in your MUIM_Draw method. InitRastPort(&data->RastPort) is done in other part of code! Once opengl context is initialized you can render to your offscreen bitmap using GL calls. Have a look to aminet/wazp3d in soft3d_opengl.c. Inside there is code to start mesa for aros (seek ifdef aros...) But aros mesa cant render in a bitmap: You will need to use your mui window + glscissor [http://aminet.net/package/dev/mui/GLArea_src AreaGL] may be helpful. <pre> MUIA_Image_FontMatch MUIA_Image_FontMatchHeight MUIA_Image_FontMatchWidth MUIA_Image_FreeHoriz MUIA_Image_FreeVert MUIA_Image_OldImage MUIA_Image_Spec MUIA_Image_State </pre> =====MUI_Redraw===== With MUI_Redraw(), an object tells itself to refresh, e.g. when some internal attributes were changed. Calling MUI_Redraw() is only legal within a custom class dispatcher, "using this function within an applications main part is invalid!". To solve the same problem with my GUI for the UAE port of AROS, and simply wrapped the MUI_Redraw inside a custom method. <pre> MUIM_UAEDisplay_Update, struct MUIP_UAEDisplay_Update *, ({ if (message->top >= data->height || message->bottom <= 0) return TRUE; if (message->top <= 0) message->top = 0; data->update_top = message->top; data->update_bottom = message->bottom; MUI_Redraw(self, MADF_DRAWUPDATE); return TRUE; }) case OM_SET: { struct TagItem *tagitem, *tagstate = msg->ops_AttrList; while( tagitem = NextTagItem( &tagstate ) ) { case MUIA_[classname]_Update: { MUI_Redraw( obj, MADF_DRAWUPDATE); break; } } return( DoSuperMethodA( cl, obj, msg ) ); } </pre> But better might be making just attribute to passing array of vectors.. When it's passed redraw is called.. or custom method: <pre> case MUIM_[classname]_Update: { MUI_Redraw( obj, MADF_DRAWUPDATE); return( 0 ); } </pre> You must not completely intercept OM_SET. Program sub-class some MUI class like Area.mui or Group.mui and they have their own attributes that might be set during program running.. Intercepting them or redrawing window might cause illegal actions.. =====Groups===== The group class was designed to contain other groups and gadgets not to be a gadget by self. It's a side effect because it's a subclass of area class (making it a subclass of notify class and copying part of methods would be senseless). Well... if you want create an image button (button with text and gfx), apart from the group class it could be done by creating subclass of MUIC_Area which in MUIM_Setup load necessary picture(s) using datatypes.library, draw it in MUIM_Draw and dispose in MUIM_Cleanup. Btw. the group class isn't a subclass of area class by mistake. Only group objects can have children. To get children there's MUIA_Group_ChildList. Walking through list is done with NextObject(). Example: <syntaxhighlight lang="c"> Object *obj1; struct List *children = (struct List *)XGET(_maingrp, MUIA_Group_ChildList); APTR pObj = GetHead(children); // Parse the children while(NULL != (obj1 = NextObject((Object **)&pObj))) { printf("ID is: %ld\n", XGET(obj1,MUIA_ObjectID)); } </syntaxhighlight> To get parent there's MUIA_Parent. If you don't know number of children or it's variable you would have to alloc some memory for the method struct ( sizeof(struct MUIP_Group_Sort) + sizeof(Object *) * num_children) and then call it with DoMethodA(obj, alloc'd_method). Then free the method struct again. num_children = number of successful NextObject() calls on child list. There's MUIM_Group_Sort method allowing you to tell the group object the exact order of the childs. NListview.mcc uses this and the group_initchange/group_exitchange stuff to dynamically show/hide scrollbars. Almost all attributes you set on a group will be forwarded to its children. You can set MUIA_Group_Forward to FALSE to prevent this (while setting the tag in question). a MUIM_Group_Insert method for inserting a child into a group in specified place, just like MUIM_Family_Insert. Currently move the child list from the group to my private family, insert the new child into my family with MUIM_Family_Insert and move all children from the family to the group again. on groups just like MUIM_Family_Sort on families. <pre> #define MUIM_Group_Sort 0x80427417 /* V4 */ DoMethod(parent, MUIM_Group_InitChange); DoMethod(parent, REMMEMBER, obj); set(obj, MUIA_FixWidth, 100); // just some changing beyond the object borders DoMethod(parent, ADDMEMBER, obj); DoMethod(parent, MUIM_Group_ExitChange); </pre> InitChange/ExitChange during setup/cleanup is not a good idea. You should add your childs in MUIM_Setup *before* the DoSuperMethod() and remove your childs in MUIM_Cleanup *after* the DoSuperMethod(). should not disable groups anyway just to disable its children. Better disable each child for itself, since this will indeed look nicer. You can do this with one DoMethod, e.g. MUIM_MultiSet or MUIM_SetUData Group is intended for objects having visual representation. For a text editor, if you group Buffer and Display objects it will be a bit tricky since Buffer isn't really a gadget. Editor should be a subclass of Display, and Buffer should be attached via pointer in object data structure. It better shows relations between Buffer and Display, they are not just a gadgets in a group. Basically you have to call MUIM_InitChange before removing or adding objects and then call MUIM_ExitChange: <pre> DoMethod(yourgroup,MUIM_InitChange) DoMethod(OM_ADDMEMBER,newobject) DoMethod(yourgroup,MUIM_ExitChange) </pre> to trigger a relayout by doing a MUIM_Group̠InitChange and MUIM_Group_Exitchange on the _parent(obj) Every object should be responsible for passing the new settings on to its children. Like when you have a subclass of group that contains a numeric and a string gadget, it will have some attribute that holds a structure of the gadgets' respective values, and the group object has to know which value goes to which of its children and set them accordingly when itself it receives an OM_SET. Then you'd ideally do a set(mywindow,PREFS_ATTRIBUTE,&some_structure) and the object tree would handle the rest by itself. Then there's no other way than to remember each object that needs to be updated in some structure and set() it "by hand". virtgroup.mui are internal part of MUI (they're "inside" muimaster.library). The virtual group it's like a container that can scroll if the content exceeds its boundaries. A Virtual group makes sense inside a ScrollGroup. you should not use MUIA_Pressed for notifying toggle gadgets (only for RelVerify ones like buttons). Use MUIA_Selected. <pre> window ---> group (<--- set MaxWidth/MaxHeight here, works) ------> scrollgroup ---------> virtgroup ------------> text ------> rectangle (<--- or here, works, too) </pre> How to get a virtgroup which is only in the horiz direction virtual w/o using scrollgroup (use MUIA_Scrollgroup_FreeVert, FALSE) or is there a way to have the scrollbar hidden all the time? You need a [http://morphosambient.cvs.sourceforge.net/morphosambient/ambient/virtgroupclass.c?revision=1.5&view=markup custom class] which uses fixed height or width thus locking virtgroup vertically or horizontally. Adding objects to a group on the fly. First you have to '''init''' the changes you want to do, then '''perform''' them and then declare you have '''finished'''. Example of code to add or remove a group from another group: <syntaxhighlight lang="c"> Object *_maingrp = .... // the container Object *_subgrp = .... // the content // add the subgroup if(DoMethod(_maingrp, MUIM_Group_InitChange)) { DoMethod(_maingrp, OM_ADDMEMBER, _subgrp); DoMethod(_maingrp, MUIM_Group_ExitChange); } // remove the subgroup if(DoMethod(_maingrp, MUIM_Group_InitChange)) { DoMethod(_maingrp, OM_REMMEMBER, _subgrp); DoMethod(_maingrp, MUIM_Group_ExitChange); } </syntaxhighlight> <pre> LONG sigs; DoMethod(app,MUIM_Application_NewInput,&sigs); </pre> This seems to be a general pitfall for MUI programmers, but 'sigs' really has to be initialized to zero! It's worse: sigs is the result of Wait(), i.e. the signals received by the process. So if you give a random value, MUI will think random signals were received, and act on these. Normally the effect of this is not noticeable, as a message-port signal will just cause a "while(GetMsg(port))", which will immediately terminate, but in theory serious problems could arise Want to reproduce the Workbench way of dealing with icons. Want to be able to move images from a point to another. Derive a Group (virtual or otherwise) with its own custom layout hook and make the objects of that group Draggable; when you get a drop event, re-layout the group (force this using MUIM_Group_InitChange = followed by ExitChange) [http://www.henning-thielemann.de/ProgramsE.html TableGroup] <pre> MUIM_Group_ExitChange MUIM_Group_InitChange MUIM_Group_Sort MUIA_Group_ActivePage MUIA_Group_Child MUIA_Group_ChildList MUIA_Group_Columns MUIA_Group_Horiz MUIA_Group_HorizSpacing MUIA_Group_LayoutHook MUIA_Group_PageMode MUIA_Group_Rows MUIA_Group_SameHeight MUIA_Group_SameSize MUIA_Group_SameWidth MUIA_Group_Spacing MUIA_Group_VertSpacing </pre> =====RMB and LMB===== RMB menus to gadgets. Context menus are a feature of the Area class, and can be set with MUIA_ContextMenu, or dynamically created by overloading MUIM_ContextMenuBuild. Is it possible to use rmb as lmb in MUI? Yes, you should override MUIM_ContextMenuBuild for your object. Create fake Menu object (just with one menu and no items), give it to MUIA_ContextMenu attribute and do your job in MUIM_ContextMenuBuild, returning NULL from there (it means no context menu will be drawn). Well, its not easy, because there is no simple method to get informed about RMB _release_. You have to sub-class Text class and write own MUIM_HandleInput, which is mentioned in docs as obsolete. But unfortunately MUI event handlers don't react to RMB (bug in MUI?). can look at the MUIMine source (on Aminet). It does something like that and mentions problems with the RMB. It's also using MUIM_HandleInput. =====Dragging===== <pre> ULONG MyList_DragQuery(struct IClass *cl,Object *obj,struct MUIP_DragDrop *msg) { if (msg->obj==obj) { //return(MUIV_DragQuery_Accept); return(DoSuperMethodA(cl,obj,(Msg)msg)); } else { if (msg->obj==(Object *)muiUserData(obj)) return(MUIV_DragQuery_Accept); else return(MUIV_DragQuery_Refuse); } } </pre> Whenever there are no conflicting inputs, MUI starts the drag operation immediately. If the LMB is needed for anything else (ie on a button), MUI starts dragging like specified in the prefs. set MUI_Draggable, TRUE to an object of a MUI_Area subclass <pre> get(obj,MUIA_List_DropMark,&dropmark); DoMethod(obj,MUIM_List_InsertSingle,entry,dropmark); </pre> Note that you must get the dropmark from the destination object, *not* from the source. One mode allows you to enter the data in the string gadget. The other allows dragging. In the dragging mode you make the StringObject a TextObject. That way you have no problems dragging the objects around. You could also try making a Custom string class. How to get MUI to report the dropped position relative to the object that is accepting the drop? Also is there some way to get mui to report based on the top, left of the object that was grabbed and not report from where you grabbed the object at? If the position is screen based, just substract from it _mleft(obj) and _window(obj)->LeftEdge, _mtop(obj and _window(obj)->TopEdge. Is there a way to react to a dragging of a workbench icon into an appwindow created with MUI. The desktop manager sends message to an application only when user stopped dragging so it is not possible. MUI has its way to handle d&d with MUIM_DragBegin/DragFinish for its MUI object.... MUIM_DragBegin/Finish are for internal MUI D&D. AppWindow messages are externally generated and MUI can not control it. This is typically a method that you usually won't call yourself (like the drag'n'drop methods of area.mui) <pre> MUIM_AskMinMax MUIM_Cleanup MUIM_ContextMenuBuild MUIM_ContextMenuChoice MUIM_CreateBubble MUIM_CreateShortHelp MUIM_DeleteBubble MUIM_DeleteShortHelp MUIM_DragBegin MUIM_DragDrop MUIM_DragFinish MUIM_DragQuery MUIM_DragReport MUIM_Draw MUIM_DrawBackground MUIM_HandleEvent MUIM_HandleInput MUIM_Hide MUIM_Setup MUIM_Show MUIA_Background MUIA_BottomEdge MUIA_ContextMenu MUIA_ContextMenuTrigger MUIA_ControlChar MUIA_CycleChain MUIA_Disabled MUIA_Draggable MUIA_Dropable MUIA_ExportID MUIA_FillArea MUIA_FixHeight MUIA_FixHeightTxt MUIA_FixWidth MUIA_FixWidthTxt MUIA_Font MUIA_Frame MUIA_FramePhantomHoriz MUIA_FrameTitle MUIA_Height MUIA_HorizDisappear MUIA_HorizWeight MUIA_InnerBottom MUIA_InnerLeft MUIA_InnerRight MUIA_InnerTop MUIA_InputMode MUIA_LeftEdge MUIA_MaxHeight MUIA_MaxWidth MUIA_Pressed MUIA_RightEdge MUIA_Selected MUIA_ShortHelp MUIA_ShowMe MUIA_ShowSelState MUIA_Timer MUIA_TopEdge MUIA_VertDisappear MUIA_VertWeight MUIA_Weight MUIA_Width MUIA_Window MUIA_WindowObject </pre> ====register (TABS)==== how can a child (a tab) of a register (Tab) know that he is currently visible w/o knowing in which tab it is? Have a .mcc which is a subclass of group and creates a row of cycletitle-objects (like cycle gadget, but with a fixed title string within the cyclegadget) where each button represents a window. The group gets notified (by notifyintuition.library) when a new window is opened or one win gets closed. or create a subclass of group which has a new attribute of something like MUIA_XGroup_PageIndex. You could then compare this to the "main groups" objects active page. You should know the "main group" object as it gets this from reading MUIA_Parent of the "tab page". if tabpage.pageindex = tabpage.parent.activepage then (simple pseudo code) Or create a subclass of register which as well as MUIA_Group_ActivePage has say MUIA_Group_ActivePageObj which is set on a change of MUA_Group_ActivePage. You could then compare this to the "tab page". if tabpage = tabpage.parent.activepageobj then (simple pseudo code) Or create a new method of register that returns the current obj (similar to your above idea) but as a method it will be usable for all your register groups. <pre> MUIA_Register_Frame MUIA_Register_Titles </pre> ====Lists==== * The list class is a class which can hold and manipulate (to some extent) a linked list of data. * The listview class is a group subclass which handles the layout and interconnection of a list and the required sliders. Listtree which uses images for the branches, but afaik doesn't allow you to change the image. At startup the list is empty and add entries with MUIM_List_InsertSingle. MUIA_List_SourceArray to assign an strarray then use the MUIA_List_Active result as the index for that array. MUIM_List_Remove listview to have the width of the text inside and no more and no less. MUIA_List_Format - MAXWIDTH/MINWIDTH MUIA_List_AdjustWidth, TRUE to insert strings in a ListView: DoMethod(projectfiles,MUIM_List_InsertSingle,(long unsigned int)TXT.sfilename.c_str(),(IPTR)MUIV_List_Insert_Bottom); COPYING you will need to define Construct & Destruct hooks as List object does NOT copy your string (just takes a pointer) until you order otherwise. If you got simple one column list and you will be satisfied storing just strings in it, MUI offers builtin construct hooks for this. Refer autodocs for construct & destructs (must set both!). MUIA_List_ConstructHook, MUIV_List_ConstructHook_String MUIA_List_DestructHook, MUIV_List_DestructHook_String MUIV_List_Remove_Selected You can call MUIM_List_CreateImage as soon as the list class completed its setup method. You must call MUIM_List_DeleteImage before the list completes its cleanup method. MUIM_Insert_xyz inserts an Object to a List, this meant that the List class can handle any Object and so you can not add only Strings to it. only a Pointer is stored and not the content of it. Note the List is not responsible for Displaying its' content, this was done by the Listview and by default it´s Displayhook expects pointers to a Text in the list. how to add a small image next to a string in the list? game/think/MUIMastermind.lha might have a simple approach without CreateImage() and so on. Reading MUIA_List_Active gives me the entry number, but if the order's changed, it doesn't mean anything? GetEntry returns pointer to your entry and you can access any column you wish. It's your private pointer anyway. If you want a page background for an app, simply use MUIA_Background, MUII_PageBack for your group object. '''Obsolete Hooks.''' If hooks are being used, multicolumn List object to display the result but want to add title to columns <pre> HOOKPROTO(ResultList_Display, ULONG, char **array, struct ReqData *reqdata) { if (reqdata) { int n; for (n=0; n<reqdata->nb ; n++) { *array++ = reqdata->columns[n]; } } else { reqdata = (struct ReqData *)hook->h_Data; // list titles int n; for (n=0; n<reqdata->nb ; n++) { *array++ = reqdata->columns[n]; } } return 0; } MakeStaticHook(hook_ResultList_Display, ResultList_Display); Somewhere in your code you set h_Data: hook_ResultList_Display.h_Data = (APTR)reqdata_titles; </pre> You can either build a hook object that h_entry part is your function and use MUIM_CallHook or subclass the object id_main_add so that it handles a particular method, and in the case of your method is received call your add some function (it's the recommended way).. the callhook stuff would be something like struct Hook h = { addsome, NULL, NULL }; DoMethod(id_main_add, MUIM_Notify, MUIA_Pressed, FALSE, id_main_add,2, MUIM_CallHook, &h ); for AROS you have to change <pre> #define MUI_LIST_DISP(x,y) ULONG SAVEDS ASM x (REG(a2,char **array), REG(a1, y )) to #define MUI_LIST_DISP(x,y) ULONG SAVEDS ASM x (REG(a0,struct Hook *h), REG(a2,char **array), REG(a1, y )) </pre> so that a pointer to the Hook is the 1st argument. Same for other [hook macros http://aros.sourceforge.net/documentation/developers/headerfiles/aros/asmcall.h]. We have some hints about hooks in our [documentation http://aros.sourceforge.net/documentation/developers/app-dev/portable.php#hooks] <pre> MUIM_List_Clear MUIM_List_CreateImage MUIM_List_DeleteImage MUIM_List_Exchange MUIM_List_GetEntry MUIM_List_Insert MUIM_List_InsertSingle MUIM_List_Jump MUIM_List_Move MUIM_List_NextSelected MUIM_List_Redraw MUIM_List_Remove MUIM_List_Select MUIM_List_Sort MUIM_List_TestPos MUIA_List_Active MUIA_List_AdjustHeight MUIA_List_AdjustWidth MUIA_List_AutoVisible MUIA_List_CompareHook MUIA_List_ConstructHook MUIA_List_DestructHook MUIA_List_DisplayHook MUIA_List_DragSortable MUIA_List_DropMark MUIA_List_Entries MUIA_List_First MUIA_List_Format MUIA_List_InsertPosition MUIA_List_MinLineHeight MUIA_List_MultiTestHook MUIA_List_Pool MUIA_List_PoolPuddleSize MUIA_List_PoolThreshSize MUIA_List_Quiet MUIA_List_ShowDropMarks MUIA_List_SourceArray MUIA_List_Title MUIA_List_Visible </pre> ====Strings==== How to get notification of when an MUI string gadget is made active? So I know when the user has clicked on the gadget and activated the cursor, but before they start typing anything? I've tried setting MUIA_InputMode to MUIV_InputMode_RelVerify and MUIV_InputMode_Immediate, but neither work with either the MUIA_Pressed or MUIA_Selected notifications. Build a subclass of String.mui and do what ever you need to do in the MUIM_GoActive and MUIM_GoInactive methods. Converts input from a 'text box' (using Zune/MUI) to a floating point number. <pre> get(my-string-object, MUIA_String_Contents, &str); stcd_l(str, &num); </pre> Subclass the gadget and overload MUIM_GoInactive. Just be sure you've considered every situation the user may be in, e.g. leaving the gadget temporarily to copy the rest of the value from some other place or similar. Needed to subclass string gadget and add own event handler. As a workaround (imho), return DoSuperMethodA(cl,obj,(Msg)msg); when you return 0. You can notify MUIA_String_Contents, which will be triggered each time the content change. You can probably also use MUIA_Window_ActiveObject, which should be set to everything but the string gadget when it goes inactive. And if you use one of the string gadget replacements then there's also the possibility of overloading MUIM_GoInactive for the string class (Textinput, Newstring or Betterstring). But keep in mind that inactivating the gadget (using tab, the mouse, opening a new window or similar) should never have a confirming effect! <pre> MUIA_String_Accept MUIA_String_Acknowledge MUIA_String_AdvanceOnCR MUIA_String_AttachedList MUIA_String_BufferPos MUIA_String_Contents MUIA_String_DisplayPos MUIA_String_EditHook MUIA_String_Format MUIA_String_Integer MUIA_String_LonelyEditHook MUIA_String_MaxLen MUIA_String_Reject MUIA_String_Secret </pre> ====Numeric (slider, knobs, levelmeters etc)==== Releasing the button when NOT over the gadget is well regarded to be a "cancel" action. Like "whoops! I accidentally pressed the button, but now I don't want to exit, so I'll move my mouse away" Sliders also keep the value you dragged them to if you release the mouse outside the gadget. How about getting a notification on a slider when the slider is released only? I tried MUIA_Pressed but that didn't work. If you also use Area.mui/MUIA_InputMode. Also, I noted that MUIA_Slider_Level says (OBSOLETE). Use MUIA_Numeric_Value instead. If pressing TAB key cycles options. How can I implement that ? You just set MUIA_CycleChain (area class) as TRUE in all the objects you want to be part of the cycle-chain. Cycle object <pre> STRPTR colors[] = { "Red", "Green", "Blue", NULL }; ULONG colorsV; STRPTR ch; // then in the program... get(cy1, MUIA_Cycle_Active, &colorsV); ch = (char *)colorsV; </pre> Cycle_active contains the NUMBER of the selected item. To get the string you need to do something like this: ch = colors[ colorsv ]; Since MUIA_Cycle_Entries is [I..] the only way is to create a new cycle every time you want to change the entries. To do this you do MUIM_Group_InitChange on the group containing the cycle, then OM_REMMEMBER the old one, OM_ADDMEMBER the new one and do MUIM_Group_ExitChange. You may have to use MUIM_Group_Sort to get the cycle to the right place or put it into a separate group. Can anyone tell me if it is possible to create a dynamic cycle gadger You can "emulate" it by removing the gadget and creating a new one with MUIA_Cycle_Entries changed. Use MUIM_Group_InitChange/ExitChange for this. <pre> MUIA_Cycle_Active MUIA_Cycle_Entries </pre> a slider with gradient background. You can set gradient by MUIA_Background (but attribute string is undocumented) or maybe overloading MUIM_DrawBackground... Sliders that look like a regular button when not pressed, but when pressed, they pop up and become a slider. They save a lot of space. It's a NumericbuttonObject - it's used in the demo program Slidorama. <pre> MUIM_Numeric_Decrease MUIM_Numeric_Increase MUIM_Numeric_ScaleToValue MUIM_Numeric_SetDefault MUIM_Numeric_Stringify MUIM_Numeric_ValueToScale MUIA_Numeric_CheckAllSizes MUIA_Numeric_Default MUIA_Numeric_Format MUIA_Numeric_Max MUIA_Numeric_Min MUIA_Numeric_Reverse MUIA_Numeric_RevLeftRight MUIA_Numeric_RevUpDown MUIA_Numeric_Value </pre> ====Menus==== Mui has its own methods for menus but the old NewMenu calls can still be used. The best way is maybe to create&dispose the context menus you need in a subclass of window class. Menu items are set for currently active window? In the case you can set up different menu for each of window, preferably inside window subclass, and with notification which will call method or attribute or your's window class and it'll be able to react. <syntaxhighlight lang="c"> </syntaxhighlight> How to notify on pressing shortcut combination with shift, control and alt keys? I tried such code: DoMethod(win, MUIM_Notify,MUIA_Window_InputEvent, "-control x",app, 2,MUIM_Application_ReturnID,MEN_RUN); but I get notification each time X button is pressed (no matter whether control is pressed). You need a normal eventhandler in your class for that. Please do not use returned stuff? So I see the only way is to use rawkey hook. Want such shortcuts for menu items, there are too many of them so I can't use combinations with Amiga for each one. menu item "MUI Settings...". To set a notify to the menu item that calls MUIM_Application_OpenConfigWindow The way to do this would be to implement a MenuTrigger method in one of your subclasses (MUIC_Window or the window's Root MUIC_Group are always safe picks) and have a MUIA_Window_MenuAction notification call it. There you could either have a switch with all the IDs, or simply use methodIDs instead of menu IDs and just do it like: <pre> ULONG mMenuTrigger(struct IClass *cl, Object *obj, struct mpMenuTrigger *msg) { DoMethod(obj, msg->menutriggercommand); } </pre> Once all menu triggers are nicely done as methods (say MUIM_MyClass_Open, MUIM_MyClass_DoSomething) and you've built a menu using those IDs, you could also implement an eventhandler in the Group subclass I mentioned and simply map raw keys into methods again. This could be done nicely using something like: <pre> struct MenuKey { ULONG methodForQualifierShift; ULONG methodForQualifierControl; ULONG methodForQualifierAlt; ULONG methodForQualifierAltShift; }; </pre> and then have these mapped like <pre> struct MenuKey hotkeys[256] = { {0, MUIM_MyClass_Jump}, // RAWKEY_TILDE {MUIM_MyClass_First}, // RAWKEY_1 .... }; </pre> so you can easily map every key combo into a method. Well... just one of the many possible approaches to this problem, but one that will leave you with a nice OO structure in the source. Added a check for msg->imsg->Code==MENUDOWN which reatcs the RMB being pressed and stops the timer. I also did the reverse msg->imsg->Code==MENUUP which would start the timer again. BUT - once the Menu is open the mouse button presses are attached to the menu and not my window/object so the MENUUP button event is never seen so my timer remains stopped and does not start again after using a menu. You could use MUIA_Window_MenuAction to be notified when a menuitem was chosen, DoMethod (win, MUIM_Notify, MUIA_Window_MenuAction, MUIV_EveryTime, obj, 2, MM_Main_MenuAction, MUIV_TriggerValue); Not sure if the attribute gets triggered when no item was selected... Checking window activation does not help either as the window remains active when a menu is opened so nothing changes. You could add a global input handler for checking of RMB pressing and releasing and then also check if the mouse pointer is over your window... '''Redundant''' MUIA_Application_Menu and MUIA_Window_Menu (old New Menus system) '''Redundant''' MUIM_Application_GetMenuCheck, MUIM_Application_GetMenuState, MUIM_Application_SetMenuCheck, MUIM_Application_SetMenuState '''Redundant''' MUIM_Window_SetMenuCheck, MUIM_Window_SetMenuState, MUIM_Window_GetMenuCheck, MUIM_Window_GetMenuState <pre> MUIA_Menu_Enabled MUIA_Menu_Title </pre> =====MenuStrip===== Menustrip class is the base class for MUI's object oriented menus. Its children are objects of Menu class, each of them describes exactly one menu. A Menustrip object doesn't feature many options itself, but as a subclass of Family class, it simply acts as father for multiple Menu objects. The Menustrip object is usually specified as a child of either Application class or window class with the attributes MUIA_Application_Menustrip or MUIA_Window_Menustrip. Have you tried using MenustripObject and MenuObject instead of MenuitemObject, and MUIA_Menu_Title instead of MUIA_Menitem_Title? Though to be honest, I'm not sure if all of those macros exist in AROS. the hierarchy is: MenustripObject -> MenuObject -> MenuitemObject Using Menuitems everywhere worked before, but it was not compatible with MUI and was changed. With family objects (from Wanderer/Info): DoMethod(_win(obj), MUIM_Notify, MUIA_Window_MenuAction, MUIV_EveryTime, obj, 2, MUIM_MySubClass_MenuThingy, MUIV_TriggerValue); Read more about Menus in MUIA_Window_MenuAction section of muidevs. See also DiskSpeed.c in DiskSpeed drawer of the contrib-source of AROS. In one MenuItem tag there wasn`t a "MUIA_UserData" tag identifier in front of the ID of that menuitem and so on a dispose gcc somehow freed an area in memory that caused the crash where sas/c didn`t somehow. <pre> entry = MUI_MakeObject(MUIO_Menuitem,advance_name_translation(i),NULL,0,0); set(entry,MUIA_UserData,i); DoMethod(entry,MUIM_Notify,MUIA_Menuitem_Trigger, MUIV_EveryTime, entry,6, MUIM_CallHook, &civstandard_hook, diplomacy_tech, pdialog, plr0->player_no,entry); DoMethod(menu_title,MUIM_Family_AddTail, entry); </pre> <pre> MUIA_Menustrip_Enabled </pre> ====Requesters==== MUI_Request(app, mainwnd, 0L, "Sorry...", "Close", "...but this feature is not yet implemented", NULL); Either create your new objects outside this huge MUI constructions, and in there use just a pointer, or get rid of the "End" macro and exchange it with "TAG_DONE)". On MOS and AmigaOS, the NewObject variadic function is kept in the static library. It takes most of the parameters on the stack - thanks to that the implementation of NewObject calls the NewObjectA function. Everything works perfect, and the typical MUI macros may be easily used. This, however, is not the case when you compile for AROS. Here, NewObject is a variadic macro, not a function. Thanks such approach we do not need any custom compiler in case of systems, where the arguments of variadic functions are passed partially through registers and partially through the stack (This is the case of PPC and x86_64, this is also the reason why both OS4 and MOS require specially patched compilers). Since NewObject is a macro, the gcc's preprocessor expects the list of macros arguments enclosed within parentheses. In MUI macros it is not the case. =====ASL requester===== this should [http://aros-exec.org/modules/newbb/viewtopic.php?topic_id=1430&forum=2&post_id=11642#forumpost11642 help]: <syntaxhighlight lang="c"> struct FileRequester *req; if ((req=MUI_AllocAslRequestTags(ASL_FileRequest, ASLFR_Window,win , ASLFR_TitleText, "A requester for AmiDevCpp", ASLFR_InitialDrawer , "T:", ASLFR_InitialFile, "foo.txt", ASLFR_InitialPattern , "#?.txt", ASLFR_DoPatterns , TRUE, ASLFR_RejectIcons , TRUE, TAG_DONE))) { if (MUI_AslRequestTags(req,TAG_DONE)) { /* you can find the drawer in req->fr_Drawer and the file in req->fr_File */ } } </syntaxhighlight> MUI_AslRequest() functions and MUI takes care of window refresh for you. <pre> MUIA_Popasl_Active MUIA_Popasl_StartHook MUIA_Popasl_StopHook MUIA_Popasl_Type </pre> ====Pop Up Pen etc==== MUIA_Window or MUIA_WindowObject? MUIA_Window should refer to struct Window * but MUIA_WindowObject to Object * Both are always NULL for a popup list, whether open or not. An interesting point is that the window object pointer supplied to the MUIA_Popobject_WindowHook is non-NULL. checking for whether popup is open such work around anyway? Popup object is open only a while, when user clicked popup button and popup object appeared on screen- any clicking causes popup object to disappear. So, I can't even imagine where and why are you checking this.. From 2nd parallel running task? If popup object is made by you, you always can subclass any MUI class. And this way you will get all methods and attributes like f.e. OM_SET/OM_GET and MUIM_Setup/MUIM_Cleanup/MUIM_Show/MUIM_Hide. Probably listening on show/hide might help checking whether popup is currently open. This method probably should work also for other MUI applications, if you're not owner of app, but making monitor software- but instead subclassing get and store dispatcher address, then put your own, and listen methods/attrs like above, then call original dispatcher to return control to original application. It looks like [http://www.sasg.com/mui/autodocs/MUI_Popstring.html Popstring] has special hooks for this task * MUIA_Popstring_OpenHook * MUIA_Popstring_CloseHook Shift up/down is (normally) bound to page up/down, and if the listview hasn't been drawn once, then there are no page dimensions. DoMethod(PP_String, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, App_p, 2, MUIM_Application_ReturnID, RID_EXECUTE); A notify watch if a tag changes (for the given object) - MUIA_String_Acknowledge is a tag of the string class (not the Popph-string) and is set (and therefor changed) for the string object. So the notify must be on this object, rather than the container (which is Popph) Either get the pointer to the internal string-object, and setup a notify on this (and do try to avoid ReturnID's ;-) ) Should just be to forward MUIM_Notify to the child objects, preferably only if OM_GET returns TRUE for the tag in question. I.e. if OM_GET returns TRUE for the Popph object itself (an Area class tag probably) then keep the notify, otherwise try to see which of the children supports it. Or maybe it'd be better if Popph introduced two new methods a la MUIM_Popph_NotifyString & List. Then one could use either of these to setup a notify on an internal object. nothing wrong with ObtainBestPenA() if you don't want the user to configure the pen values (which you often do want) - though avoid placing the pen-stuff in MUIM_Show/Hide, it should be MUIM_Setup/Cleanup, otherwise it'll re-allocate pens each time you resize the window If you want the user to be able to configure the pens then you do so by using the Poppen-object together with MUI_ObtainPen() - here's a snip from MUI_PopPen.Doc: Anyway, you do not have to care about the internals of this class. Just create it like obj = MUI_NewObject(MUIC_Poppen, MUIA_CycleChain , 1, MUIA_Window_Title, "Followed Links Color", TAG_DONE); somewhere in your prefs window and everything will be fine. You can get/set the current color from a Poppen object by using the MUIA_Pendisplay_Spec attribute. The resulting struct MUI_SpenSpec may then be saved somewhere in your preferences and used as parameter for MUI_ObtainPen() and MUI_ReleasePen(). comes back in the format of: "rxxxxxxgxxxxxxbxxxxxx". There are 3 parameters in MUI_ObtainPen() *mri , *spec & flags.l look in libraries/mui.h and you will fin a macro like this muiRenderInfo() just do this mymri = muiRenderInfo(myobj); and should have a valid MUI_RenderInfo but this macro should only be used between MUIM_Setup/MUIM_Cleanup A popobject which is connected to a string gadget. The popobject is a listview. So that pressing up/down in the string gadget will scroll the listview updown (even when the listview is hidden) ? MUIA_String_AttachedList -- (V4 ) [ISG], Object * <pre> MUIA_Popobject_Follow MUIA_Popobject_Light MUIA_Popobject_Object MUIA_Popobject_ObjStrHook MUIA_Popobject_StrObjHook MUIA_Popobject_Volatile MUIA_Popobject_WindowHook </pre> <pre> MUIA_Poplist_Array </pre> <pre> MUIM_Popstring_Close MUIM_Popstring_Open MUIA_Popstring_Button MUIA_Popstring_CloseHook MUIA_Popstring_OpenHook MUIA_Popstring_String MUIA_Popstring_Toggle </pre> ====Text==== * (N)Floattext already does exactly the same as you did using the list. It splits a long text into separate lines, inserts some spaces to produce an aligned text and displays them. * The TextEditor class in read-only does more or less the same like Floattext, but with the ability to apply different styles and coloring apart from the standard MUI text engine. Furthermore it allows to let the user edit the text in read-write mode. YAM makes heavy use of it in both modes to show and edit the mails. Where ony Text() is done. So the size of the area depends on the size of the actual default font. Using rp(obj)->Font, but in AskMinMax it seems that when it is first called, the Font is not yet initialized. You can use _font(obj) to obtain the font. If you also need a rastport then you can setup one temporarily to do your calculations. <pre> struct RastPort rp; InitRastPort(&rp); SetFont(&rp, _font(obj)); WORD size = TextLength(&rp, "The Text", 8); </pre> The problem is that text will not stay the right size. They are either spread all over the window, or cramped into one edge, when all I want them to do is to stay on the right and just as big to display 6 chars (as long as possible). MUIA_String_Maxlen seems to have no effect, and just forcing one width doesn't seem right as you never know wether the user may prefer to use a font 50 pixels wide. Use tag MUIA_FixWidthTxt. For example str = StringObject, MUIA_FixWidthTxt, "0000000", End; Note 7 characters there: one is for cursor. And use characters which are wide by nature (read MUI_Area.doc and you understand why). It could also be solved by using MUIA_Weight, weight. Try a combination of "MUIA_Weight, weight" for the string(s) and Put RectangleObjects before/and/or/after the stringobject. For example, to align a gadget to the right <pre> HGroup, Child, RectangleObject, MUIA_Weight, 75, End, Child, StringObject,...,MUIA_Weight, 25, End, End, </pre> Which means that if you want to change the label and the key shortcut using one attr, you should subclass text, and handle a specific tag for changing the label and the shortcut, parsing yourself the string. Examples of subclassing a mui class can be found in mui dev kit (especially psi contains many subclasses...) and some tools can help you to have a skeleton class using a meta definition of the class you want (mui2c or bcc do such things). If you create a subgroup something like: <pre> mygroup=Group ( MUIA_Group_PageMode,True Child,SimpleButton("_Download"), Child,SimpleButton("_Resume"), TAG_DONE) </pre> you get much better result. The "Download" button is now visible, but if you set (mygroup, MUIA_Group_ActivePage, 1) "Download" disappears and "Resume" becomes visible. This is very common trick in MUI applications. Buttons are simply text objects, which have the following tag: MUIA_Text_SetVMax, TRUE Setting this to FALSE makes a TextObjects y-size unlimited. Defaults to TRUE which means the objects height is fixed. A plain text object cannot be higher than its text, unless you set MUIA_Text_SetVMax to FALSE (default is TRUE). This will give your object unrestricted height, but the text will be displayed vertically centered, unless you set MUIA_Text_VCenter to FALSE. MUIA_Text_Contents is ISG so: SetAttrs(text, MUIA_Text_Contents, "NewContent", TAG_DONE); set (object->STR_text, MUIA_Text_Contents, myText); object->STR_Text ? Looks like MUIBuilder generated code :) If your 'text-edit-box' is a String object, you'd rather use set( object->STR_text, MUIA_String_Contents, myText ); How to calculate the x/y coords to use with the Move() function so that when using Text() to draw the label it appears centred. There is bunch of macros in mui.h: <pre> _mleft() = starting x coordinate of your drawing area _mtop() = starting y coord etc. _mwidth() = width of your drawing area _mheight() = obvious =) </pre> <pre> text_height=GetItSomeHow(); text_len=TextLength("heipparallaa"); Move(rp, _mleft(obj) + ((_mwidth(obj) - text_len) / 2), _mtop(obj) + ((_mheight(obj) - text_height) / 2) ); </pre> (TextObject) If you really need to change the text, then you must set() it again after the modification. If using a TextObject, then it has the FULL initial size... but if appending extra lines then these are not visible (although a bug causes it to write outside of itself!). The only way to get it to enlarge for the new text is to iconise & then uniconise the MUI window. Also, the text is not word-wrapped. You must not modify the text as long as it is "in use" by the object. MUI will calculate the required dimensions on basis of the given text and expects it to be constant. If you really need to change the text, then you must set() it again after the modification. This will let MUI do a relayout to display all of the new text. But this will work to a certain extend only, namely when the complete text's height becomes larger than the window's maximum height. If you need to display larger texts, then the object should be placed into a Scrollgroup object (some of which is MUI4 compatible) like this: <pre> ScrollgroupObject, MUIA_Scrollgroup_AutoBars, TRUE, MUIA_Scrollgroup_Contents, VGroupV, Child, TextObject, MUIA_Text_Contents, "insert your text here", MUIA_Text_Copy, TRUE, End, End, End, </pre> The attribute MUIA_Scrollgroup_AutoBars will let the scrollgroup show the scrollbars only if they are really needed, i.e. the contents' dimensions are larger than the scrollgroup's dimensions. This attribute is available in MUI4 only like MUIA_Text_Copy, MUI3 will silently ignore it and always show the scrollbars. Second, the attribute MUIA_Text_Copy instructs Text.mui to keep a copy of your text. This makes it possible to free() the text given to MUIA_Text_Contents after object creation of after set() and it also allows you to modify the text without risking any graphical glitches due to redraw operations while the text is still modified. However, your text will always be displayed exactly as you specify it. This means that you need to insert line breaks yourself. If using FloattextObject or TextEditorObject, then no matter the initial contents, the initial size is always three lines of text (which is the minimum space needed by the scrollbar + arrows), but it is at least vertically scrollable. Also, the text is word-wrapped. Since Floattext.mui inserts line breaks itself you cannot expect a variable height, because the text's height depends on the object's width. You can enforce a certain object height by using something like MUIA_FixHeightTxt, "\n\n\n\n". This will give you a fixed height of four lines while respecting the object's font. Floattext.mui is a subclass of List.mui and as such has no restrictions on its dimensions, except you enforce them, i.e. by using MUIA_FixHeightTxt or by subclassing Floattext.mui yourself with a restricting implementation of MUIM_AskMinMax. MUI cannot just resize an object to display the entire initial content, because the content is arbitrary. It may be zero lines, but it may be a million lines. What should the initial size be in this case? Of course you can override MUIM_AskMinMax and return the dimensions which fit you best, but you must be prepared and accept that MUI will adapt the actual dimensions of the object within the limits that your (or the default) MUIM_AskMinMax method returns. If want to the Floattext object to be resizeable then you must make the label resizeable as well by adding at least one space object above or below the label object like this: Child, VGroup, Child, Label2("FloattextObject"), Child, VSpace(0), End, This will give you a top aligned label. Placing the label after the VSpace(0) object will make it bottom aligned. Using VCenter() will give you a vertically centered label. Choose the solution which fits your needs best. Have a look at MUI's demo application MUI-Demo. It uses Floattext objects in every single window. <pre> MUIA_Text_Contents MUIA_Text_PreParse MUIA_Text_SetMax MUIA_Text_SetMin MUIA_Text_SetVMax </pre> ====Fonts==== try putting SetFont(_font(obj)); in your MUIM_Draw. In OM_NEW you should set MUIA_Font to one of the predefined values (the MUIV_Font_XXXXXX values) and mui will open the font for you and make it accessible using _font(obj) In MUIM_Draw, SetFont() to my fonts opened in MUIM_Setup. If SetFont(_font(obj)) otally lose user-settable-fonts. You are not allowed to change settings of _rp( obj ) directly! So make sure you are working on a copy of original rastport and then set fonts, colours or whatever. <pre> struct RastPort rp1 = *_rp( obj ); struct RastPort *rp = &rp1; SetAPen( rp, 0 ); </pre> The same applies to normal gadgetclass BOOPSI objects, where before drawing anything you have to ObtainGIRPort(), draw and then ReleaseGIRPort()... MUICFG_Font_Fixed ====Gadgets==== MUIM_Import/Export and handle the loading and saving yourself. The advantages are that you don't need to create, and call MUIM_Export for the pages that the user doesn't visit, as you'll export the settings (from the created/visited pages) into an already filled dataspace object (loaded during program startup) - which should save both time, memory and complexity. Another advantage is that it makes it very easy to add options such as "Reset to defaults", "Restore" etc. Two functions which should make it easier to save/read IFF files into dataspace objects. <syntaxhighlight lang="c"> VOID LoadDataspace (STRPTR file, Object *dataspace) { BPTR fh; if(fh = Open(file, MODE_OLDFILE)) { struct IFFHandle *iff; if(iff = AllocIFF()) { InitIFFasDOS(iff); iff->iff_Stream = (ULONG)fh; if(!OpenIFF(iff, IFFF_READ)) { if(!StopChunk(iff, 'PREF', 'IPRB')) { if(!ParseIFF(iff, IFFPARSE_SCAN)) DoMethod(dataspace, MUIM_Dataspace_ReadIFF, iff); } CloseIFF(iff); } FreeIFF(iff); } Close(fh); } } </syntaxhighlight> <syntaxhighlight lang="c"> VOID SaveDataspace (STRPTR file, Object *dataspace, Object *app) { BOOL retry; do { retry = FALSE; BPTR fh; if(fh = Open(file, MODE_NEWFILE)) { struct IFFHandle *iff; if(iff = AllocIFF()) { InitIFFasDOS(iff); iff->iff_Stream = (ULONG)fh; if(!OpenIFF(iff, IFFF_WRITE)) { if(!PushChunk(iff, 'PREF', 'FORM', IFFSIZE_UNKNOWN)) DoMethod(dataspace, MUIM_Dataspace_WriteIFF, iff, 0, 'IPRB'); CloseIFF(iff); } FreeIFF(iff); } Close(fh); } else { UBYTE buf[84]; Fault(IoErr(), "DOS", buf, 84); retry = MUI_Request(app, NULL, 0L, "Error", "_Retry|_Cancel", "\33cError saving:\n%s\n\n%s", file, buf); } } while(retry); } </syntaxhighlight> One object can't belong to two parents. How does one insure free pens being allocated? I am running most applications on 16 bit screens. Not sure what is required but I would think there should be some way to have some free. What/how does on "free" pens? On True/Hi color screens You may expect to have unlimited number of free pens (or at least 65536/16777216 pens), because you can change the color of every single pixel without affecting the rest. But unfortunately all RastPort rendering functions rely on pen scheme and pen fields in RastPort are only 8-bit wide. It gives you only 256 pens. Tried to use the MUIA_Bitmap_SourceColors and the MUIA_Bitmap_Precision but all I get is a big black rectangle in place of the discoloured image. Did you set MUIA_Bodychunk_Depth to 5 and MUIA_Bodychunk_Masking to 0 (but check if you save the brush *without* mask plane)? And remember that you should repeat R, G, B values in every byte of a longword, so for example some colour like R=$A5, G=$32, B=$0A, in palette data it looks like $A5A5A5A5,$32323232,$0A0A0A0A. So every palette entry takes 12 bytes. You need to set the MUIA_Window_UseBottomBorderScroller (or whatever side you want) on the window. Then create a Prop Object and set the MUIA_Prop_UseWinBorder to the corresponding side(s) that you did in the window. Then just set up a notification on the prop object to listen for changes in MUIA_Prop_First. When you place the one on the right and open the window, MUI opens the window the smallest possible and doesn't draw any of the other objects that should be in the window. ====dtpic Datatypes==== If you would like to get a pointer to the bitmap that holds the data of the picture or a way to copy it to your own bitmap but all Zune attributes did not work. In that case you will want to use datatypes.library directly. Dtpic AFAIK is just for easily including datatype images into MUI/Zune GUIs (as button imagery, in listviews and so on...). If AROS supports the superbitmap window refresh method then you can. For a non-borderless window you will probably want to make it gimmezerozero (gzz) as well so that the borders and window contents have separate layers (uses slightly more memory). That being said just blitting the bitmap into the window is probably a simpler and more portable solution. How to "convert" e.g. a png image to a bitmap structure (datatypes?). DTpic.mui is your friend. Using picture.datatype and then blitting bitmap to object rastport in MUIM_Draw. <syntaxhighlight lang="c"> Child, image_button = MakeButton("PROGDIR:Imagesg/test_but.png", 't',"\33uT\33nest Button"), static APTR MakeButton(UBYTE *Image, UBYTE Key, UBYTE *Help) { return(MUI_NewObject("Dtpic.mui", MUIA_Dtpic_Name,Image, MUIA_InputMode, MUIV_InputMode_RelVerify, MUIA_ControlChar, Key, MUIA_Background, MUII_ButtonBack, MUIA_ShortHelp, Help, PropFrame,TRUE, ImageButtonFrame, TAG_DONE)); } </syntaxhighlight> <syntaxhighlight lang="c"> if(app) { struct BitMapHeader *bmhd; struct BitMap *bitmap; Object *datatype_obj; /* pointer to the Datatype Object */ Object *bitmap_obj; /* a mui BitmapObject */ Object *list_obj; /* the one that should be used in the list */ if(datatype_obj = NewDTObject("Images/www.iff", DTA_SourceType , DTST_FILE, DTA_GroupID , GID_PICTURE, TAG_DONE)) { if(DoMethod(datatype_obj, DTM_PROCLAYOUT, NULL, 1)) { get(datatype_obj, PDTA_BitMapHeader, &bmhd); GetDTAttrs(datatype_obj, PDTA_DestBitMap, &bitmap, TAG_DONE); if(!bitmap) GetDTAttrs(datatype_obj, PDTA_BitMap, &bitmap, TAG_DONE); if(bitmap_obj = BitmapObject, MUIA_Bitmap_SourceColors , xget(datatype_obj, PDTA_CRegs), MUIA_Bitmap_Width , bmhd->bmh_Width, MUIA_Bitmap_Height , bmhd->bmh_Height, MUIA_FixWidth , bmhd->bmh_Width, MUIA_FixHeight , bmhd->bmh_Height, MUIA_Bitmap_Transparent , 0, MUIA_Bitmap_Bitmap , bitmap, End) { list_obj = (Object *)DoMethod(LV_ButtonBank, MUIM_List_CreateImage, bitmap_obj, NULL); } } } } </syntaxhighlight> in MUI4.0 <syntaxhighlight lang="c"> Child, zoneimage = (Object *) MUI_NewObject(MUIC_Dtpic, MUIA_Dtpic_Name, "PROGDIR:resource/zone_local.png", TAG_DONE), DEFSMETHOD(OWBWindow_UpdateZone) { GETDATA; char *image; switch(msg->zone) { default: case MV_OWBBrowser_Zone_Local: image = "PROGDIR:resource/zone_local.png"; break; case MV_OWBBrowser_Zone_Internet: image = "PROGDIR:resource/zone_internet.png"; break; } set(data->zoneimage, MUIA_Dtpic_Name, image); return 0; } </syntaxhighlight> i.e. by default we set zone_local image, and then by notification calls updatezone when the attribute is set. And it should changes (image i mean), but did't not. I see that i am in the Zone_Internet (by printfs), but image not sets. Problems with 3.9 ===Removal=== <pre> void ExitClasses(void) { if (NewList) { MUI_DeleteCustomClass(NewList); NewList = NULL; } } BOOL InitClasses(void) { NewList = MUI_CreateCustomClass(NULL,MUIC_NList ,NULL,sizeof(struct NewList_Data),&NewList_Dispatcher); if (NewList) return(TRUE); else return FALSE; } </pre> Another thing, which your compiler should notice immediately, is that MyCustomClass is struct IClass * and assigning Object * to it is very, very wrong, and should effect crash at MUI_DeleteCustomClass()... <pre> #define MyCustomObject NewObject(MyCustomClass->mcc_Class,NULL, Object *mycustomobject; mycustomobject = MyCustomObject, End; if( mycustomobject != NULL ) { app = ApplicationObject, [... ] End; if( app != NULL ) { [...] MUI_DisposeObject( app ); } MUI_DisposeObject( mycustomobject ); } </pre> Or preferably you should subclass Application.mui class and do your non-visible code there... That's the best way to handle it IMHO... This way main program code will be almost untouched and going back to using standard Application.mui within seconds, just rename MyApplicationObject to ApplicationObject (always define such macros instead of writing NewObject() directly!) Objects are removed using OM_REMMEMBER method (must use parent object of course) ==References== http://alfie.altervista.org/rxmui/rxmuidoc/classes.html http://amiga.sourceforge.net/amigadevhelp/phpwebdev.php When one of the qualifier (shift, ctrl, alt) keys is clicked then the opposite key should get the same state. I tried in the callback function: <pre> BOOL shift = XGET(data->keybutton[96], MUIA_Pressed) | XGET(data->keybutton[97], MUIA_Pressed); NNSET(data->keybutton[96], MUIA_Pressed, shift); NNSET(data->keybutton[97], MUIA_Pressed, shift); </pre> Pressing the qualifier keys on the keyboard should act as if the button was clicked. I've therefore added an event handler method. It works so far as the visual state of the buttons is changed. Problem is that SET(keyobj, MUIA_Pressed, state) in that event method doesn't trigger the callback hook. Try MUIA_Selected, instead of MUIA_Pressed (which is really just a thing to be used for notification, not a real attribute). You'll also have to change code logic, because once the two SHIFT buttons are selected, it won't be possible to unselected them ("shift" var would always be TRUE). Networking with a non-blocking recv(), start with one task and make all my interfaces push-based. That is, no-one will call recv() but instead be called with the data received from a socket (when it arrives). So in your main-loop you wait for both sockets and user events and distribute these to the proper receiver (where the latter would be done by MUI). The reason for this approach is to simplify code (eliminate the need to lock resources/data with semaphores etc), and also because found out that spawning tasks had a noticeable overhead (but you could keep one network manager running all the time to get by this), not to mention that if you receive data on 8 sockets (each having its own process) then your program will be represented with 9 total tasks and thus if another program needs cpu-time it'll only get 1/10th of the time, where your program will get 9/10th, unless you fiddle with the priority of your tasks but then other problems appear. If the data you receive needs to be parsed in some way you may at first find it irritating to have to write your parser as a state-machine, but these also have advantages IMO. For example it makes it very easy to add filters to the data stream or create virtual data on the fly... Basically you need a socket operating in the non-blocking & asynchronous mode. This prevents GUI being locked while accessing network. Another step is allocate signal bit for bsdsocket and use GetSocketEvent() to find out network actions without braindead select() or WaitSelect() functions. So that whenever network signal is set you call GetSocketEvent() in loop. This GetSocketEvent() returns socket descriptor ID and possible events occurred. Avoid GetSocketEvent() and its minion like it was the bubonic plague!!!!!!!! As it turned out, it only works under Miami. Even though AmiTCP copied the API from M$, it never worked correctly. Use WaitSelect() instead of Wait() in your MUI main loop. See STRICQ 2 src. How do you receive data from sockets? Is there a way to associate a signal to a socket? You can associate a signal with a socket by using SocketBaseTags(). Use WaitSelect() in the STRICQ v2 socket code. But in v1, used a signal. You can encapsulate internet client in MUI application subclass, create some useful methods and attributes like MUIM_NetApplication_Connect/Disconnect/Send/Receive, and then when user press Connect/Disconnect button, call these methods in notification or callback function (so if NetApplication connected you will disable Connect, and enable Disconnect etc. gadgets). And so on. Never connect to the internet immediately in OM_NEW, that would be stupid as well as creating needed subprocess in there (which from other side might be not good idea). It can wait then as long as application sends the connect signal or message and then do it's network job, until it receives MUIM_NetApplication_Disconnect method.. How to... merge bsdsocket.library and muimaster.library in single, nicely OOP, application. ==Examples== <syntaxhighlight lang="c"> /* Copyright © 2002, The AROS Development Team. All rights reserved. $Id: aircos_server_gui.c 30794 2009-03-08 02:19:07Z neil $ */ //#include <exec/types.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <proto/alib.h> #include <proto/exec.h> #include <proto/dos.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <proto/utility.h> #include <dos/dos.h> #include <intuition/gadgetclass.h> #include <intuition/icclass.h> #include <clib/alib_protos.h> #include <libraries/mui.h> #include <mui/NListtree_mcc.h> #include <mui/NListview_mcc.h> #include <mui/NList_mcc.h> #include "aircos_global.h" #include "locale.h" extern struct AiRcOS_internal *AiRcOS_Base; struct List aircos_Prefs_ServerNetworks; struct List aircos_Prefs_Servers; struct aircos_servernode *aircos_Prefs_ServerActive; struct Hook aircos_serversave_hook; struct Hook aircos_networklistupdate_hook; struct Hook aircos_serverlistupdate_hook; struct Hook aircos_chooseserver_hook; BOOL aircos_Prefs_ServersLoaded = FALSE; Object *input_server_address = NULL; Object *input_server_port = NULL; Object *input_server_description = NULL; Object *input_server_network = NULL; Object *input_server_pass = NULL; Object *select_dropboxgrp_network = NULL; Object *select_dropbox_network = NULL; Object *select_dropboxgrp_server = NULL; Object *select_dropbox_server = NULL; STRPTR network_list_empty[2] = { {"<List Empty>"}, NULL }; STRPTR server_list_empty[2] = { {"<List Empty>"}, NULL }; Object *servermodWin; STRPTR *network_list; STRPTR *server_list; //network_list_empty[0] = "<List Empty>"; //MSG(MSG_LIST_EMPTY); //network_list_empty[1] = NULL; //server_list_empty[0] = "<List Empty>"; //MSG(MSG_LIST_EMPTY); //server_list_empty[1] = NULL; #define AIRCOS_DEF_SERVERSFILE "servers.dat" aircosApp_LoadServers() { aircos_Prefs_ServersLoaded = TRUE; } struct aircos_networknode *aircosApp_FindServerNetworkNode(char * findNetwork) { struct aircos_networknode *current_Node = NULL; ForeachNode(&aircos_Prefs_ServerNetworks, current_Node) { D(bug("[AiRcOS](FindServerNetworkNode) Checking against record for '%s'\n", current_Node->ann_Network)); if (strcasecmp(current_Node->ann_Network, findNetwork)==0) return current_Node; } return NULL; } struct aircos_servernode *aircosApp_FindServerNode(char * findServer) { struct aircos_servernode *current_Node = NULL; ForeachNode(&aircos_Prefs_Servers, current_Node) { D(bug("[AiRcOS](FindServerNode) Checking against record for '%s'\n", current_Node->asn_Server)); if (strcasecmp(current_Node->asn_Server, findServer)==0) return current_Node; } return NULL; } AROS_UFH3(void, chooseserver_func, AROS_UFHA(struct Hook *, unused_hook, A0), AROS_UFHA(APTR, obj, A2), AROS_UFHA(struct IRC_Channel_Priv *, hook_channel_arg, A1 )) { AROS_USERFUNC_INIT D(bug("[AiRcOS] chooseserver_func()\n")); ULONG currentPrefsServerID; get(select_dropbox_server, MUIA_Cycle_Active, &currentPrefsServerID); struct aircos_servernode *currentPrefsServer = NULL; if (!(currentPrefsServer = aircosApp_FindServerNode(server_list[currentPrefsServerID]))) { D(bug("[AiRcOS] chooseserver_func: Couldnt find Server Node!\n")); return; } aircos_Prefs_ServerActive = currentPrefsServer; AROS_USERFUNC_EXIT }; AROS_UFH3(void, updatenetworklist_func, AROS_UFHA(struct Hook *, unused_hook, A0), AROS_UFHA(APTR, obj, A2), AROS_UFHA(struct IRC_Channel_Priv *, hook_channel_arg, A1 )) { AROS_USERFUNC_INIT D(bug("[AiRcOS] updatenetworklist_func()\n")); struct aircos_networknode *currentPrefsNetwork = NULL; ULONG prefsNetworkCount = 0; ULONG setprefsNetworkActive = 0; Object *new_dropbox_network = NULL; ForeachNode(&aircos_Prefs_ServerNetworks, currentPrefsNetwork) { prefsNetworkCount++; if (aircos_Prefs_ServerActive) if (strcasecmp(currentPrefsNetwork->ann_Network, aircos_Prefs_ServerActive->asn_Network->ann_Network)==0) { setprefsNetworkActive = prefsNetworkCount -1; } } D(bug("[AiRcOS] updatenetworklist_func: %d network nodes\n", prefsNetworkCount)); if (prefsNetworkCount > 0) { if (network_list != network_list_empty) { FreeVec(network_list); } if ((network_list = AllocVec(sizeof(IPTR) * prefsNetworkCount+1, MEMF_CLEAR|MEMF_PUBLIC))) { int loop_count = 0; ForeachNode(&aircos_Prefs_ServerNetworks, currentPrefsNetwork) { network_list[loop_count] = currentPrefsNetwork->ann_Network; loop_count++; } } else { D(bug("[AiRcOS] updatenetworklist_func: ERROR - couldnt allocate memory for network name pointer table\n")); network_list = network_list_empty; } } else if (network_list != network_list_empty) { FreeVec(network_list); network_list = network_list_empty; } if (!(new_dropbox_network = MUI_MakeObject(MUIO_Cycle, NULL, network_list))) { D(bug("[AiRcOS] updatenetworklist_func: Failed to create Network dropdown\n")); return NULL; } if (DoMethod(select_dropboxgrp_network, MUIM_Group_InitChange)) { DoMethod(select_dropboxgrp_network, OM_REMMEMBER, select_dropbox_network); DoMethod(select_dropboxgrp_network, OM_ADDMEMBER, new_dropbox_network); DoMethod(select_dropboxgrp_network, MUIM_Group_ExitChange); select_dropbox_network = new_dropbox_network; } DoMethod(select_dropbox_network, MUIM_NoNotifySet, MUIA_Cycle_Active, setprefsNetworkActive); DoMethod ( select_dropbox_network, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &aircos_serverlistupdate_hook, NULL ); AROS_USERFUNC_EXIT }; AROS_UFH3(void, updateserverlist_func, AROS_UFHA(struct Hook *, unused_hook, A0), AROS_UFHA(APTR, obj, A2), AROS_UFHA(struct IRC_Channel_Priv *, hook_channel_arg, A1 )) { AROS_USERFUNC_INIT D(bug("[AiRcOS] updateserverlist_func()\n")); struct aircos_servernode *currentPrefsServer = NULL; ULONG prefsNetworkServerCount = 0; ULONG setprefsServerActive = 0; Object *new_dropbox_server = NULL; ULONG currentPrefsNetworkID; get(select_dropbox_network, MUIA_Cycle_Active, &currentPrefsNetworkID); struct aircos_networknode *currentPrefsNetwork = NULL; if (!(currentPrefsNetwork = aircosApp_FindServerNetworkNode(network_list[currentPrefsNetworkID]))) { D(bug("[AiRcOS] updateserverlist_func: Couldnt find Network Node!\n")); return; } ForeachNode(&aircos_Prefs_Servers, currentPrefsServer) { if (strcasecmp(currentPrefsServer->asn_Network->ann_Network, currentPrefsNetwork->ann_Network)==0) { prefsNetworkServerCount++; if (aircos_Prefs_ServerActive) if (strcasecmp(currentPrefsServer->asn_Server, aircos_Prefs_ServerActive->asn_Server)==0) { setprefsServerActive = prefsNetworkServerCount -1; } } } D(bug("[AiRcOS] updateserverlist_func: %d server nodes for network '%s'\n", prefsNetworkServerCount, currentPrefsNetwork->ann_Network)); if (prefsNetworkServerCount > 0) { if (server_list != server_list_empty) { FreeVec(server_list); } if ((server_list = AllocVec(sizeof(IPTR) * prefsNetworkServerCount+1, MEMF_CLEAR|MEMF_PUBLIC))) { int loop_count = 0; ForeachNode(&aircos_Prefs_Servers, currentPrefsServer) { if (strcasecmp(currentPrefsServer->asn_Network->ann_Network, currentPrefsNetwork->ann_Network)==0) { server_list[loop_count] = currentPrefsServer->asn_Server; loop_count++; } } } else { D(bug("[AiRcOS] updateserverlist_func: ERROR - couldnt allocate memory for server name pointer table\n")); server_list = server_list_empty; } } else if (server_list != server_list_empty) { FreeVec(server_list); server_list = server_list_empty; } if (!(new_dropbox_server = MUI_MakeObject(MUIO_Cycle, NULL, server_list))) { D(bug("[AiRcOS] updateserverlist_func: Failed to create Server dropdown\n")); return NULL; } if (DoMethod(select_dropboxgrp_server, MUIM_Group_InitChange)) { DoMethod(select_dropboxgrp_server, OM_REMMEMBER, select_dropbox_server); DoMethod(select_dropboxgrp_server, OM_ADDMEMBER, new_dropbox_server); DoMethod(select_dropboxgrp_server, MUIM_Group_ExitChange); select_dropbox_server = new_dropbox_server; } DoMethod(select_dropbox_server, MUIM_NoNotifySet, MUIA_Cycle_Active, setprefsServerActive); AROS_USERFUNC_EXIT }; AROS_UFH3(void, serversave_func, AROS_UFHA(struct Hook *, unused_hook, A0), AROS_UFHA(APTR, obj, A2), AROS_UFHA(struct IRC_Channel_Priv *, hook_channel_arg, A1 )) { AROS_USERFUNC_INIT D(bug("[AiRcOS] serversave_func()\n")); struct aircos_networknode *newsaveNetwork = NULL; char *newsaveNetwork_name; BOOL newsaveNetwork_update = FALSE; struct aircos_servernode *newsaveServer = NULL; char *newsaveServer_name; BOOL newsaveServer_update = FALSE; get( input_server_network, MUIA_String_Contents, &newsaveNetwork_name); get( input_server_address, MUIA_String_Contents, &newsaveServer_name); if (!(newsaveNetwork = aircosApp_FindServerNetworkNode(newsaveNetwork_name))) { D(bug("[AiRcOS](serversave_func) created new network node for '%s'\n", newsaveNetwork_name)); newsaveNetwork = AllocVec(sizeof(struct aircos_networknode), MEMF_CLEAR|MEMF_PUBLIC); newsaveNetwork->ann_Network = AllocVec(strlen(newsaveNetwork_name)+1, MEMF_CLEAR|MEMF_PUBLIC); CopyMem(newsaveNetwork_name, newsaveNetwork->ann_Network, strlen(newsaveNetwork_name)+1); AddTail((struct List *)&aircos_Prefs_ServerNetworks, (struct Node *)&newsaveNetwork->ann_Node); newsaveNetwork_update = TRUE; } newsaveNetwork->ann_ServerCount += 1; D(bug("[AiRcOS](serversave_func) %s Network node server count = %d\n", newsaveNetwork->ann_Network, newsaveNetwork->ann_ServerCount)); if (!(newsaveServer = aircosApp_FindServerNode(newsaveServer_name))) { D(bug("[AiRcOS](serversave_func) created new server node for '%s'\n", newsaveServer_name)); newsaveServer = AllocVec(sizeof(struct aircos_servernode), MEMF_CLEAR|MEMF_PUBLIC); newsaveServer->asn_Server = AllocVec(strlen(newsaveServer_name)+1, MEMF_CLEAR|MEMF_PUBLIC); CopyMem(newsaveServer_name, newsaveServer->asn_Server, strlen(newsaveServer_name)+1); newsaveServer->asn_Network = newsaveNetwork; get( input_server_port, MUIA_String_Integer, &newsaveServer->asn_Port); #warning "TODO: we need to store the password also here .." AddTail((struct List *)&aircos_Prefs_Servers, (struct Node *)&newsaveServer->asn_Node); newsaveServer_update = TRUE; } else { D(bug("[AiRcOS](serversave_func) node already exists for server '%s'\n", newsaveServer_name)); } aircos_Prefs_ServerActive = newsaveServer; set( servermodWin, MUIA_Window_Open, FALSE); if (newsaveNetwork_update) CallHookPkt(&aircos_networklistupdate_hook, obj, hook_channel_arg); if (newsaveServer_update) CallHookPkt(&aircos_serverlistupdate_hook, obj, hook_channel_arg); AROS_USERFUNC_EXIT }; Object *aircos_showServerConnect() { D(bug("[AiRcOS] showServerConnect()\n")); if (aircos_Prefs_ServersLoaded) { D(bug("[AiRcOS](showServerConnect) Server windows already configured!\n")); return NULL; } Object *tmp_connectWin = NULL; NewList((struct List *)&aircos_Prefs_ServerNetworks); NewList((struct List *)&aircos_Prefs_Servers); Object *butt_addServer = NULL; Object *butt_editServer = NULL; Object *butt_delServer = NULL; Object *butt_serverConnect = NULL; Object *butt_serverSave = NULL; network_list = network_list_empty; server_list = server_list_empty; if (!(select_dropbox_network = MUI_MakeObject(MUIO_Cycle, NULL, network_list))) { D(bug("[AiRcOS](showServerConnect) Failed to create Network dropdown\n")); return NULL; } if (!(select_dropbox_server = MUI_MakeObject(MUIO_Cycle, NULL, server_list))) { D(bug("[AiRcOS](showServerConnect) Failed to create Server dropdown\n")); return NULL; } if (!(butt_addServer = SimpleButton("Add"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'ADD' button\n")); return NULL; } if (!(butt_editServer = SimpleButton("Edit"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'EDIT' button\n")); return NULL; } if (!(butt_delServer = SimpleButton("Del"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'DEL' button\n")); return NULL; } if (!(butt_serverConnect = SimpleButton("Connect!"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'CONNECT' button\n")); return NULL; } if (!(butt_serverSave = SimpleButton("Save!"))) { D(bug("[AiRcOS](showServerConnect) Failed to create 'SAVE' button\n")); return NULL; } select_dropboxgrp_network = VGroup, Child, (IPTR) select_dropbox_network, End; select_dropboxgrp_server = VGroup, Child, (IPTR) select_dropbox_server, End; tmp_connectWin = WindowObject, MUIA_Window_Title, (IPTR) "Connect to Server..", MUIA_Window_Activate, TRUE, MUIA_Window_Width,200, MUIA_Window_Height,200, WindowContents, (IPTR) VGroup, Child, (IPTR) HGroup, GroupFrame, Child, (IPTR) VGroup, Child, (IPTR) LLabel("IRC Network"), Child, (IPTR) HGroup, Child, (IPTR) HSpace(0), Child, (IPTR) select_dropboxgrp_network, Child, (IPTR) HSpace(0), End, End, Child, (IPTR) HVSpace, End, Child, (IPTR) HGroup, GroupFrame, Child, (IPTR) VGroup, Child, (IPTR) LLabel("IRC Server"), Child, (IPTR) HGroup, Child, (IPTR) HVSpace, Child, (IPTR) select_dropboxgrp_server, Child, (IPTR) HVSpace, End, End, Child, (IPTR) HVSpace, End, Child, (IPTR) HGroup, Child, (IPTR) HVSpace, Child, (IPTR) butt_addServer, Child, (IPTR) butt_editServer, Child, (IPTR) butt_delServer, End, Child, (IPTR) butt_serverConnect, End, End; servermodWin = WindowObject, MUIA_Window_Title, (IPTR) "Edit Server..", MUIA_Window_Activate, TRUE, MUIA_Window_Width,350, MUIA_Window_Height,400, WindowContents, (IPTR) VGroup, Child, (IPTR) VGroup, GroupFrame, Child, (IPTR) HGroup, Child, (IPTR) LLabel("IRC Server Address"), Child, (IPTR) (input_server_address = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, End ), End, Child, (IPTR) HGroup, Child, (IPTR) LLabel("Port"), Child, (IPTR) (input_server_port = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, MUIA_String_Accept, "0123456789", MUIA_String_Integer, 0, End), End, Child, (IPTR) HGroup, Child, (IPTR) LLabel("Server Description"), Child, (IPTR) (input_server_description = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, End), End, Child, (IPTR) HGroup, Child, (IPTR) LLabel("IRC Network"), Child, (IPTR) (input_server_network = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, End), End, End, Child, (IPTR) VGroup, GroupFrame, Child, (IPTR) LLabel("Enter server password here if applicable."), Child, (IPTR) HGroup, Child, (IPTR) LLabel("Password"), Child, (IPTR) (input_server_pass = StringObject, StringFrame, MUIA_CycleChain, TRUE, MUIA_String_Format, MUIV_String_Format_Right, End), End, End, Child, (IPTR) butt_serverSave, End, End; if ((tmp_connectWin)&&(servermodWin)) { D(bug("[AiRcOS](showServerConnect) Created GUI objects\n")); DoMethod ( AiRcOS_Base->aircos_app, OM_ADDMEMBER, (IPTR) tmp_connectWin ); DoMethod ( AiRcOS_Base->aircos_app, OM_ADDMEMBER, (IPTR) servermodWin ); DoMethod ( tmp_connectWin, MUIM_Notify, MUIA_Window_Open, TRUE, (IPTR) AiRcOS_Base->aircos_quickconnectwin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( AiRcOS_Base->aircos_quickconnectwin, MUIM_Notify, MUIA_Window_Open, TRUE, (IPTR) tmp_connectWin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( tmp_connectWin, MUIM_Notify, MUIA_Window_Open, FALSE, (IPTR) servermodWin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( butt_addServer, MUIM_Notify, MUIA_Selected, FALSE, (IPTR) servermodWin, 3, MUIM_Set, MUIA_Window_Open, TRUE ); DoMethod ( butt_editServer, MUIM_Notify, MUIA_Selected, FALSE, (IPTR) servermodWin, 3, MUIM_Set, MUIA_Window_Open, TRUE ); // DoMethod // ( // butt_delServer, MUIM_Notify, MUIA_Selected, FALSE, // (IPTR) servermodWin, 3, MUIM_Set, MUIA_ShowMe, FALSE // ); DoMethod ( tmp_connectWin, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) tmp_connectWin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( servermodWin, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) servermodWin, 3, MUIM_Set, MUIA_Window_Open, FALSE ); DoMethod ( butt_serverConnect, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &AiRcOS_Base->aircos_connect_hook, NULL ); D(bug("[AiRcOS](showServerConnect) prepare list update hooks\n")); aircos_serversave_hook.h_MinNode.mln_Succ = NULL; aircos_serversave_hook.h_MinNode.mln_Pred = NULL; aircos_serversave_hook.h_Entry = HookEntry; aircos_serversave_hook.h_SubEntry = (void *)serversave_func; aircos_networklistupdate_hook.h_MinNode.mln_Succ = NULL; aircos_networklistupdate_hook.h_MinNode.mln_Pred = NULL; aircos_networklistupdate_hook.h_Entry = HookEntry; aircos_networklistupdate_hook.h_SubEntry = (void *)updatenetworklist_func; aircos_serverlistupdate_hook.h_MinNode.mln_Succ = NULL; aircos_serverlistupdate_hook.h_MinNode.mln_Pred = NULL; aircos_serverlistupdate_hook.h_Entry = HookEntry; aircos_serverlistupdate_hook.h_SubEntry = (void *)updateserverlist_func; aircos_chooseserver_hook.h_MinNode.mln_Succ = NULL; aircos_chooseserver_hook.h_MinNode.mln_Pred = NULL; aircos_chooseserver_hook.h_Entry = HookEntry; aircos_chooseserver_hook.h_SubEntry = (void *)chooseserver_func; DoMethod ( butt_serverSave, MUIM_Notify, MUIA_Pressed, FALSE, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &aircos_serversave_hook, NULL ); DoMethod ( select_dropbox_network, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &aircos_serverlistupdate_hook, NULL ); DoMethod ( select_dropbox_server, MUIM_Notify, MUIA_Cycle_Active, MUIV_EveryTime, (IPTR) AiRcOS_Base->aircos_app, 3, MUIM_CallHook, &aircos_chooseserver_hook, NULL ); D(bug("[AiRcOS](showServerConnect) Configured NOTIFICATIONS\n")); set(tmp_connectWin, MUIA_Window_Open, TRUE); D(bug("[AiRcOS](showServerConnect) Window opened ..\n")); } else { if (!(servermodWin)) { D(bug("[AiRcOS](showServerConnect) Failed to create server edit window..\n")); } else MUI_DisposeObject(servermodWin); if (!(tmp_connectWin)) { D(bug("[AiRcOS](showServerConnect) Failed to create server selection window..\n")); } else MUI_DisposeObject(tmp_connectWin); } return tmp_connectWin; } </syntaxhighlight> <syntaxhighlight lang="c"> /* Copyright © 2002, The AROS Development Team. All rights reserved. $Id: mini2.c 30792 2009-03-07 22:40:04Z neil $ */ #include <exec/types.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <dos/dos.h> #include <intuition/gadgetclass.h> #include <intuition/icclass.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> /* the following should go in a single include file which then only ** constits of the public constants and members. Actually this is easiey */ #include <libraries/mui.h> #define DEBUG 1 #include <aros/debug.h> Object *app; int main(void) { Object *wnd; static char *radio_entries2[] = {"Paris","London",NULL}; app = ApplicationObject, SubWindow, wnd = WindowObject, WindowContents, VGroup, Child, HGroup, MUIA_InputMode, MUIV_InputMode_Immediate, /* MUIA_ShowSelState, FALSE, */ Child, ImageObject, MUIA_ShowSelState, FALSE, MUIA_Image_FontMatch, TRUE, MUIA_Image_Spec, MUII_RadioButton, MUIA_Frame, MUIV_Frame_None, End, Child, TextObject, MUIA_ShowSelState, FALSE, MUIA_Text_Contents, "London", MUIA_Frame, MUIV_Frame_None, MUIA_Text_PreParse, "\33l", End, End, End, End, End; if (app) { ULONG sigs = 0; /* #if 0 */ DoMethod(wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit); /* #endif */ set(wnd, MUIA_Window_Open, TRUE); /* #if 0 */ while((LONG) DoMethod(app, MUIM_Application_NewInput, &sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D); if (sigs & SIGBREAKF_CTRL_C) break; if (sigs & SIGBREAKF_CTRL_D) break; } } /* #endif */ set(wnd, MUIA_Window_Open, FALSE); MUI_DisposeObject(app); } return 0; } </syntaxhighlight> <syntaxhighlight lang="c"> /* Copyright © 2002, The AROS Development Team. All rights reserved. $Id: dirlist.c 30792 2009-03-07 22:40:04Z neil $ */ #include <exec/types.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <dos/dos.h> #include <intuition/gadgetclass.h> #include <intuition/icclass.h> #include <proto/exec.h> #include <proto/intuition.h> #include <proto/muimaster.h> #include <clib/alib_protos.h> /* the following should go in a single include file which then only ** constits of the public constants and members. Actually this is easiey */ #include <libraries/mui.h> struct Library *MUIMasterBase; Object *app; int main(void) { Object *wnd, *str, *dirlist, *page; MUIMasterBase = (struct Library*)OpenLibrary("muimaster.library",0); app = ApplicationObject, SubWindow, wnd = WindowObject, MUIA_Window_Title, "dirlist", MUIA_Window_Activate, TRUE, WindowContents, VGroup, MUIA_Background, MUII_GroupBack, Child, ListviewObject, MUIA_Listview_List, dirlist = DirlistObject, InputListFrame, End, End, Child, HGroup, Child, str = StringObject, StringFrame, MUIA_String_Contents, (IPTR)"SYS:", End, Child, page = PageGroup, MUIA_Weight, 0, MUIA_FixWidthTxt, (IPTR)"AA", Child, ColorfieldObject, MUIA_Colorfield_Red, 0xFFFFFFFF, MUIA_Colorfield_Green, 0, MUIA_Colorfield_Blue, 0, End, Child, ColorfieldObject, MUIA_Colorfield_Red, 0xFFFFFFFF, MUIA_Colorfield_Green, 0xFFFFFFFF, MUIA_Colorfield_Blue, 0, End, Child, ColorfieldObject, MUIA_Colorfield_Red, 0, MUIA_Colorfield_Green, 0x66666666, MUIA_Colorfield_Blue, 0, End, End, End, End, End, End; if (app) { ULONG sigs = 0; DoMethod ( wnd, MUIM_Notify, MUIA_Window_CloseRequest, TRUE, (IPTR) app, 2, MUIM_Application_ReturnID, MUIV_Application_ReturnID_Quit ); DoMethod(str, MUIM_Notify, MUIA_String_Acknowledge, MUIV_EveryTime, (IPTR)dirlist, 3, MUIM_Set, MUIA_Dirlist_Directory, MUIV_TriggerValue); DoMethod(dirlist, MUIM_Notify, MUIA_Dirlist_Status, MUIV_EveryTime, (IPTR)page, 3, MUIM_Set, MUIA_Group_ActivePage, MUIV_TriggerValue); set(dirlist, MUIA_Dirlist_Directory, "SYS:"); set(wnd,MUIA_Window_Open,TRUE); while (DoMethod(app, MUIM_Application_NewInput, (IPTR) &sigs) != MUIV_Application_ReturnID_Quit) { if (sigs) { sigs = Wait(sigs | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_D); if (sigs & SIGBREAKF_CTRL_C) break; if (sigs & SIGBREAKF_CTRL_D) break; } } MUI_DisposeObject(app); } CloseLibrary(MUIMasterBase); return 0; } </syntaxhighlight> WaitSelect() needs a pointer to your signal mask. So you need to do something like: <pre> sigs |= SIGBREAKF_CTRL_C; ret = WaitSelect(s+1, &rdfs, NULL, NULL, &sigs); </pre> Then 'sigs' should contain the bits normally returned by Wait(). <syntaxhighlight lang="c"> /* * Amiga Generic Set - set of libraries and includes to ease sw development for all Amiga platforms * Copyright (C) 2004-2008 Tomasz Wiszkowski Tomasz.Wiszkowski at gmail.com. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "MUIPictureClass.h" #include <Generic/LibrarySpool.h> #include <libclass/intuition.h> #include <libclass/muimaster.h> #include <libraries/mui.h> #include <libclass/utility.h> using namespace GenNS; #define __NOGLOBALIFACE__ #include <proto/graphics.h> static struct Library *GfxBase = 0; #ifdef __AMIGAOS4__ static struct GraphicsIFace *IGraphics = 0; #endif MUICustomClassT<MUIPictureClass> *MUIPictureClass::muiclass = 0; static int openCount = 0; MUIPictureClass::MUIPictureClass(IClass *cls) { openCount++; parent = cls; image1 = ""; image2 = ""; width = 64; height = 48; dtimg1 = 0; dtimg2 = 0; dt = DatatypesIFace::GetInstance(44); if (dt == 0) { request("Warning", "This program requires datatypes.library v44 or later\nGraphical buttons will not be displayed.", "Continue", 0); } if (GfxBase == 0) { GfxBase = Exec->OpenLibrary("graphics.library", 39); } #ifdef __AMIGAOS4__ if ((GfxBase != 0) && (IGraphics == 0)) { IGraphics = (GraphicsIFace*)Exec->GetInterface(GfxBase, "main", 1, (TagItem*)NULL); } #endif } MUIPictureClass::~MUIPictureClass() { closeImages(); dt->FreeInstance(); openCount--; if (0 == openCount) { #ifdef __AMIGAOS4__ Exec->DropInterface((Interface*)IGraphics); IGraphics = 0; #endif Exec->CloseLibrary(GfxBase); GfxBase = 0; } } iptr MUIPictureClass::DoMtd(iptr *obj, iptr *msg) { uint16 *minmax; iptr k; switch (msg[0]) { case OM_NEW: { if (!(obj = (Object*)DoSuperMtd(parent, obj, msg))) return 0; k = (iptr)Utility->GetTagData(MUIA_Picture_NormalImage, 0, (TagItem*)msg[1]); if (k != 0) image1 = (char*)k; k = (iptr)Utility->GetTagData(MUIA_Picture_SelectedImage, 0, (TagItem*)msg[1]); if (k != 0) image2 = (char*)k; isDisabled = Utility->GetTagData(MUIA_Disabled, 0, (struct TagItem*)msg[1]) ? true : false; isSelected = Utility->GetTagData(MUIA_Selected, 0, (struct TagItem*)msg[1]) ? true : false; openImages(); return (ULONG)obj; } break; case OM_DISPOSE: case MUIM_Hide: break; case MUIM_Show: { if (dt != 0) { if (dtimg1 != 0) { dt->SetDTAttrsA(dtimg1, 0, 0, (TagItem*)ARRAY( PDTA_Screen, (iptr)_screen(obj), PDTA_DestMode, PMODE_V43, PDTA_UseFriendBitMap,true, TAG_DONE, 0)); dt->DoDTMethodA(dtimg1, 0, 0, ARRAY(DTM_PROCLAYOUT, 0, 1)); } if (dtimg2 != 0) { dt->SetDTAttrsA(dtimg2, 0, 0, (TagItem*)ARRAY( PDTA_Screen, (iptr)_screen(obj), PDTA_DestMode, PMODE_V43, PDTA_UseFriendBitMap,true, TAG_DONE, 0)); dt->DoDTMethodA(dtimg2, 0, 0, ARRAY(DTM_PROCLAYOUT, 0, 1)); } } } break; case MUIM_AskMinMax: { DoSuperMtd(parent, obj, msg); minmax = (uint16*)msg[1]; minmax[0] = width; minmax[2] = width; minmax[4] = width; minmax[1] = height; minmax[3] = height; minmax[5] = height; } return 0; case OM_SET: { bool flg; bool refresh = false; // image1 = (char*)GetTagData(MUIA_Picture_NormalImage, (int32)image1.Data(), (TagItem*)msg[1]); // image2 = (char*)GetTagData(MUIA_Picture_SelectedImage, (int32)image2.Data(), (TagItem*)msg[1]); flg = Utility->GetTagData(MUIA_Disabled, isDisabled, (struct TagItem*)msg[1]) ? true : false; if (flg != isDisabled) { isDisabled = flg; refresh = true; } flg = Utility->GetTagData(MUIA_Selected, isSelected, (struct TagItem*)msg[1]) ? true : false; if (isSelected != flg) { isSelected = flg; refresh = true; } if (refresh) MUIMaster->MUI_Redraw(obj, 0); } break; case MUIM_NoNotifySet: case MUIM_Set: { bool refresh = false; if (msg[1] == MUIA_Picture_NormalImage) image1 = (char*)msg[2]; if (msg[1] == MUIA_Picture_SelectedImage) image2 = (char*)msg[2]; if (msg[1] == MUIA_Disabled) { bool flg = msg[2] ? true : false; if (flg != isDisabled) { isDisabled = flg; refresh = true; } } if (msg[1] == MUIA_Selected) { bool flg = msg[2] ? true : false; if (flg != isSelected) { refresh = true; isSelected = flg; } } if (refresh) MUIMaster->MUI_Redraw(obj, 0); } break; case MUIM_Draw: { Object* o = 0; BitMap* bitmap = 0; void* drawinfo = 0; if (0 == _rp(obj)) break; if ((isSelected) && (dtimg2 != 0)) o = dtimg2; else if (dtimg1 != 0) o = dtimg1; else break; drawinfo = dt->ObtainDTDrawInfoA(o, (TagItem*)ARRAY( PDTA_Screen, (iptr)_screen(obj), TAG_DONE, 0)); if (drawinfo != 0) { dt->DrawDTObjectA( _rp(obj), o, _mleft(obj), _mtop(obj), width, height, 0, 0, 0); dt->ReleaseDTDrawInfo(o, drawinfo); } else { dt->GetDTAttrsA(o, (TagItem*)ARRAY( PDTA_DestBitMap, (iptr)&bitmap, TAG_DONE, 0)); if ((0 != bitmap) && (0 != GfxBase)) { #ifndef __amigaos4 BltBitMapRastPort(bitmap, 0, 0, _rp(obj), _mleft(obj), _mtop(obj), width, height, 0xc0); #else IGraphics->BltBitMapRastPort(bitmap, 0, 0, _rp(obj), _mleft(obj), _mtop(obj), width, height, 0xc0); #endif } } } return 0; } return DoSuperMtd(parent, obj, msg); } void MUIPictureClass::openImages() { if (dt == 0) return; closeImages(); dtimg1 = dt->NewDTObjectA(image1.Data(), (TagItem*)ARRAY( DTA_GroupID, (iptr)GID_PICTURE, PDTA_Remap, true, OBP_Precision, (iptr)PRECISION_EXACT, TAG_DONE, 0)); dtimg2 = dt->NewDTObjectA(image2.Data(), (TagItem*)ARRAY( DTA_GroupID, (iptr)GID_PICTURE, PDTA_Remap, true, OBP_Precision, (iptr)PRECISION_EXACT, TAG_DONE, 0)); width = 0x7fff; height = 0x7fff; if (dtimg1 != 0) { BitMapHeader *bmhd; dt->GetDTAttrsA(dtimg1, (TagItem*)ARRAY( PDTA_BitMapHeader, (iptr)&bmhd, TAG_DONE, 0)); width = width <? bmhd->bmh_Width; height = height <? bmhd->bmh_Height; } if (dtimg2 != 0) { BitMapHeader *bmhd; dt->GetDTAttrsA(dtimg1, (TagItem*)ARRAY( PDTA_BitMapHeader, (iptr)&bmhd, TAG_DONE, 0)); width = width <? bmhd->bmh_Width; height = height <? bmhd->bmh_Height; } if ((width == 0x7fff) && (height == 0x7fff)) { width = 64; height = 48; } } void MUIPictureClass::closeImages() { if (dt != 0) { if (dtimg1 != 0) { dt->DisposeDTObject(dtimg1); } if (dtimg2 != 0) { dt->DisposeDTObject(dtimg2); } } width = 64; height = 48; dtimg1 = 0; dtimg2 = 0; } iptr* MUIPictureClass::CreateClass() { if (MUIPictureClass::muiclass == 0) { MUIPictureClass::muiclass = new MUICustomClassT<MUIPictureClass>(MUIC_Area); } return (iptr*)MUIPictureClass::muiclass; } void MUIPictureClass::DestroyClass() { MUICustomClassT<MUIPictureClass> *p = MUIPictureClass::muiclass; MUIPictureClass::muiclass = 0; delete p; } </syntaxhighlight> Check out #mui on irc.freenode.net and report bugs/problems there and [http://finance.groups.yahoo.com/group/MUI/ MUI Yahoo Group] ;[https://library.morph.zone/Magic_User_Interface_Programming Magic User Interface MUI] 6iunzm4qg6p1qkkgouuo4eqo5px49io History of Western Theatre: 17th Century to Now/Russian Realist 0 242439 4669089 4528515 2026-09-06T09:09:54Z WereSpielChequers 248949 typo 4669089 wikitext text/x-wiki =Anton Chekhov= [[File:Anton Chekov 1901.jpg|thumb|Anton Chekhov was the dominant playwright of late 19th century Russian theatre, 1901]] The dominant playwright of the Russian realist school is Anton Chekhov (1860-1904), whose main play of the 19th century is "Дядя Ваня" (Uncle Vanya, 1899), characterized like the rest of his mature plays by tragicomic characters ridden with anguish and purposelessness, some of whom with great hopes that their life, contrary to what seems, has not spent in vain, but serves as a harbinger of humankind's future happiness. In the view of Bakshy (1916), "the Russian intelligentsia of the time of Chekhov presented, in its greatest part at least, a class of weak-willed individuals, handicapped in applying their gifts to the solution of practical problems by the peculiar social and political conditions prevalent at the time, and for this reason mostly given to introspection and dreaming, that helped to relieve the soul. Despair and pessimism born of aimless life, and the pursuit of dreamy idealism in the hope of finding refuge from a depressing environment, concealed innumerable elements of personal tragedy which, in the irresistible and unalterable flow of events, approached even the ancient tragedy of fate" (p 41). On Chekhov's plays in general, Williams (1965) commented that "there is no modern dramatist whose characters are more consistently concerned with explicit self-revelation. All his plays might be described as plays of confession" (p 132). Thompson (1942) further related that "nobody in a Chekhov play seems to forward the action, such as it is. On the contrary, each character spends his time in egotistical self-absorption or hopeless yearning. Characteristically the dialogue is not about something to be done or faced, but is rather a series of self-revelatory monologues cut up in alternate speeches. One's interlocutor interrupts momentarily but scarcely disturbs one's train of introspection or reminiscence. These people do not listen; they merely think aloud. As their thoughts flitter from one thing to another, they change the subject without warning. At times they fall silent (a most revolutionary thing for the stage of Chekhov's time). Just as their minds wander on and off the subject, so their bodies wander on and off the stage without apparent dramatic occasion. They seem to be living their inconsequent and will-less lives before us" (p 337). Gruber (1977) took issue with the notion that Chekhov's plays are plotless. "Chekhov structures the action of his plays to create an illusion of inaction. In the plays of Chekhov, as in real life, the future is only vaguely felt. Chekhovian drama...presents the fate that we expect to issue from dramatic action is repeatedly denied, even as each separate act is 'undramatic' not because he portrays his characters' inner lives, nor because his plays are unified by emotion and not plot...Chekhov is undramatic because he does not cultivate in his plays the sense of impending destiny we normally expect of the dramatic illusion" (p 512). In Chekhov’s dramaturgy, there is no big scene “no obligatory or great denouements...used to reveal through action the truth about the play’s central characters...We see...the drama and the complexity of the seemingly trivial...Almost all his dramatic devices were ironical...best seen in the disparity between what the characters say and what they do...Chekhov characters are addicted at making speeches...[by which we see how the character views himself rather than how others view him]...Chekhov’s symbol are...always concrete...effective because they grow out of the action...e.g. Moscow [as] the symbol of the three sisters’ dream of happiness...[There is also] the tendency on the part of his characters to aestheticize life...the most obvious is the tendency...to identify with great artists of the past” (Corrigan, 1965 pp 86-93). Agate (1944) was overly negative about the dramatic characters in "Uncle Vanya". “Chekhov’s Uncle Vanya is an embroidery upon the theme of apprenticeship to sorrow...Vanya, the sentimentalist, unpacks his heart with words, nags at the fate he will not unbend his idealistic soul to conquer. Astrov, the man of action, gives his life to drunkenness and the cultivation of trees. Serebryakov, the invalid, is pure humbug. His wife, Elena, loving Astrov, lacks the courage of adultery; she is in no sense moral. Sonia, his daughter, loving Astrov, is a sick lily” (pp 99-100). Other critics have been more generous-minded: life in Uncle Vanya "simply rusts away. And, what is truly important, these lives did not deserve to rust away, because they are rich with sensitivity and with the capacity for service. Vanya, who might have gone out into the world and advanced himself, fixed his life to the false star of a pedantic brother-in-law from whom he expected great things. Unhappily, he is too gentle and too isolated in the provinces to start a new life once he realizes that he was not serving humanity by relieving the professor of economic burdens. He is left with nothing except his fierce longing: 'If only one could live the remnant of one's life in some new way'. He knows only that 'we must make haste and work, make haste and do something' if life is not to become unbearable...And Vanya’s dream is expressed even more strongly by the district doctor, Astrov, who is in despair because in the whole district there are only two decent, well-educated people, himself and Uncle Vanya, both of whom have been swamped by 'the common round of trivial life...with its putrid vapors'. Astrov cannot even do justice to his profession, fighting as he does alone and without adequate means and preparation against a typhus epidemic. 'Those who will live a hundred or two hundred years after us, for whom we are struggling now to beat out a road,' he wonders, 'will they remember and say a good word for us?' The play is thus both a personal tragedy (or tragi-comedy perhaps) and the drama of a shipwrecked generation" (Gassner, 1954a pp 516-517). Astrov “is a man of ideals, respected by all in the play except the self-centered Serebryakov. Yelena sees his excellence clearly...The symbol of tree planting is particularly apt in communicating Chekov’s vision, for it is an act which yields no instant gratification. Astrov sees that the casual destruction of forests will create a dismal future, but deliberate efforts to restore them will bring hope for a better life” (Short, 1986 p 378). “It seems to me especially meaningful that the most energetic, the most vital, the most balanced, the most intelligent, and all in all, the most attractive person in the play carries the point that work as it has meaning after death is the only good and meaningful work that we can ultimately do” (Freedman, 1967 p 39). Astrov is “the very image of what the good country doctor should be: dedicated, self-denying, sensitive to the needs of those around him. But that he is in fact over-sensitive leads to his one crippling quality: he cannot deal with the guilt he associates with his real or imagined deficiencies as a doctor, and so has turned to excessive drink” (Manheim, 2002 pp 126-127). Vanya must be seen as gifted and his resentment towards the professor justified; otherwise he is “merely a shallow kvetch occupying the stage for long periods with nothing more than cryptic and surly behavior. The play becomes little more than a sterile exercise devoid of compassion” (Krasner, 2012 p 125). “Only in flashes do we glimpse the man within, an adolescent who can neither be his age nor live up tom his looks. It is a lightweight who peers out through the pale eyes of the heavyweight face. He knows that he squandered his life on an old humbug, he knows that he has lost the power to live for himself, yet always he keeps up appearances. Dignity never deserts him. He clings to it even in the shooting spree, which becomes in its mad way a matter of honour, an assertion of principle rather than a display of temperament, and in tenacity like this there is a kind of heroism” (Tynan, 1961 p 437). “When Chekhov found it justifiable to expose the professor-egotist who had been subsisting ungratefully on the devotion and labor of Vanya, he produced a vivid and scathing portrait of a pedant who expects everyone to cater to him...[the] hard glitter of an educated parasite” (Gassner, 1960 p 190). “One point of the play may well be that the world exists to serve people like the professor and Elena. He is a pompous ass and she is beautiful but bored, idle, and utterly useless. The soft characters lack the will, the potency, the energy to change things” (Abbott, 1989 p 36). Vanya, Sonya, and Astrov discover that “our ordinary existence has a genuine horror in it...Sebryakov has all the...obtuseness, vainglory, and ignorance that are the curse of the academic profession” (Bloom, 2005 pp 181-182). In Uncle Vanya, "Chekhov follows in the steps of Turgenev. His favourite theme is disillusionment, and as for the kind of beauty he creates, beneath it also might be written ‘desolation is a delicate thing’. He is fond of the same kind of setting for his stories as Turgenev: summer woods, an old country-house full of cultivated people, who talk and talk. There you will find the idealist who melts over the futility of his own idealism, the girl who keeps a faster clutch upon daily duties in order to forget that youth is sliding away under her feet, the slightly stronger, clever man turned maudlin-cynical after his failure to find a purpose which can hold him- to think, so he feels, he, too, should be wasted- the old woman who only wants things to go on peaceably on old humdrum lines. The current of days is slow here; the air they breathe is sultry with undischarged energy, and broken only by unrefreshing nerve-storms; it is an atmosphere of sighs and yawns and self-reproaches, vodka, endless tea, and endless discussion. These people are like those loosely agglutinated sticks and straws which revolve together slowly in some sluggish eddy. They long to be detached and ride down the rushing stream, which they imagine somewhere near sparkles for ever past them. Where it is rushing they do not know. Some day- two hundred, five hundred years hence- perhaps life will be life...Elena...has already played her stake. In the professor she thought- heaven help her!- she had found a great mind, one it would be good and thrilling always to be near. Now, she has found her mistake. She is like a ship aground on a mudbank, and the only breezes which come to shake her sails are the passions she rouses in men, but she does not believe that they will blow her to any port where she would be. Like the others she has no sense of direction, no destination. Vanya’s helpless passion merely pesters her, and what between that and the exactions and pomposities of her eminent husband, who, now he has retired, only wants to watch his diseases and jaw to admirers, she is almost beside herself. The doctor, Astrov, through knowing better than the others what he wants and despising them, does move her a little. She nearly [succumbs to him]. . .but she is afraid. This man throws a fascination over poor, plain, dutiful Sonya,too. He has that attraction for women which the idealist a little damaged often exercises. Astrov, to Sonya, is so fine in himself; his slackness and coarseness are to her but wounds he got beneath the devil-defended walls of his peculiar virtues. He is a person to be saved (there is joy, too, in that) and comforted as well as loved; then he is handsome, and his voice is beautiful, and she is most affectionate. Lastly, the old professor, he is an industrious and magniloquent fraud. We know his prototypes and regret that so large a public should read again with so much admiration what has often been written before. For years Uncle Vanya and Sonya have slaved on the estate to provide tribute for the loquacious monster, the former at first with the conviction he was watering the roots of genius. On retirement the professor came to live there, bringing his beautiful, unhappy, baleful wife. That was event number one in the play; event number two, they departed. In between arrival and departure: nerve-storms (one of them homicidal), exasperations, and draggle-tailed disorder. Astrov seeking to renew his capacity to feel by keeping near Elena’s charms, forgets his work, Sonya is tortured by his continual presence, the long-retarded tide of youth is loosed together with a flood of bitterness in Uncle Vanya, and upstairs the tyrannic old invalid gasses and scribbles and groans among his medicine bottles" (MacCarthy, 1940 pp 124-128). "The attitude of the various characters in the play towards work provides the underlying unity of theme in Uncle Vanya. Elena alone has no theories about it, but her devotion to her husband is itself a kind of work. Her husband, the professor, is extremely rigid in his demands on the people who surround him. He has lectured on art for twenty-five years; theoretically he believes in the importance of work, although his own work has always been of an impractical and selfish sort. Vanya, who has worked hard all his hfe, has become completely demoralized by the appearance of Yelena. At the end of the play, when he realizes that his love for her is doomed to disappointment, he takes up his work again as a help to him in enduring his mental anguish. Sonya is a thorough idealist. She keeps on doggedly at her work, sustained by her hope of a reward after death. She realizes that there is very little happiness in store for her in this world. She is not beautiful or attractive, and there is no hope that her love for Astrov will ever be returned. The views of Astrov, the doctor loved by Sonya and drawn to Elena, give 'Uncle Vanya' much of its distinctive tonal coloring. He is a curious combination of idealism and disillusionment. He is the antithesis of Uncle Vanya in that Vanya takes to drink during his temporary loss of ideals; Astrov drinks vodka regularly, and only under its influence can he recapture the dreams of his youth" (Perry, 1939 p 347). "Chekhov’s dualistic vision of reality is reflected in Astrov’s alternation between moods of hope and despair. Just as the terminally sick Dr Chekhov knew that, from his individual short-term view, there was little he could do to improve humanity’s lot during his brief lifetime, so Dr Astrov, in his darker moods, is depressed by the fact that his own puny efforts seem pointless and will even fail to be noticed. At the beginning of the play the overworked doctor is in just such a depressed mood. He has just lost a patient and this reminds him of the limitations of his profession and his own inability to significantly improve the lot of the peasants. Astrov, in this mood, loses the scientific objectivity that is vital for survival in the profession of medicine where the inevitability of death is a given. He recounts how his personal emotions became involved when his patient died. This leads him to voice his current feeling that perhaps his work, and life in general, are futile...Despite Astrov’s awareness that from his personal individual viewpoint there is no hope, he nevertheless continues to behave in a manner that takes into account future generations...Nothing could be more ludicrous than Vanya’s perfect comic entrance bearing autumn roses for Helen and finding her in the arms of Astrov. It is Vanya who, having wasted his own life, blames the professor for his own lack of vision and then makes the comically ludicrous claim, which even he realises is silly, that, but for the professor, he would have been a man of genius...Sonya’s long speech of faith at the end of the play is undercut by the fact that she is preaching to the unconverted" (Borny, 2006a pp 178-181). =="Uncle Vanya"== [[File:Uncle Vanya MAT.jpg|thumb|From left to right: Artem as Telegin, Lilina as Sonya, Raevskaya as Maria Voynitsky, Constantin Stanislavsky (1863-1938) as Dr Astrov, Olga Knipper (1868-1959) as Elena, Vishnevsky as Voynitsky, Moscow Art Theater, 1899]] Time: 1890s. Place: Russia. Text at http://en.wikisource.org/wiki/Uncle_Vanya http://www.gutenberg.org/ebooks/1756 http://www.readbookonline.net/plays/ https://archive.org/details/dli.ernet.241587 https://archive.org/details/dli.ernet.2826 https://archive.org/details/dli.ernet.234940 Astrov, a country doctor, attends to a retired professor, Alexander Serebryakov, master of an estate, mainly under the management of Vanya, the brother of his deceased wife, and Sonya, his daughter by this previous marriage. Vanya complains that the order of the household is disrupted by the arrival of the professor. He virulently criticizes himself for misjudging the intellectual quality of his former brother-in-law in front of Astrov, having wasted twenty-five years at the service of a charlatan, to which Vanya’s mother mildly objects. In contrast, Vanya only has praises for the professor's present wife, Elena. After noting that Alexander has no physical ailment as such, Astrov criticizes the idleness and indifference of country life, particularly the mismanagement of the environment. Vanya declares his love for Elena, but she rejects him. Late that night, Alexander complains to his wife of breathing problems and old age. Because of her father's complaints, Sonya sends for Astrov again, but the professor, suddenly feeling better, nonchalantly leaves without seeing him. Elena is distraught by discords in the house, Vanya by lost hopes. In his view, he met Elena too late, and the professor is not the genius he first thought he was in his youth, having accomplished nothing of worth. Concerned with their own woes, Astrov and Vanya drink heavily. Sonya scolds Vanya for it, convinced that the only way out of their doldrums is by working. Sonya also laments Astrov's heavy drinking in a tone suggesting love and concern of him, to which he appears unaware. Sonya meets Elena to resolve their past differences, but both are fixated on their own problems. Elena is unhappy about her marriage, Sonya hoping to marry Astrov. The following day, Alexander calls for a family meeting. Aside with Elena, Vanya urges her to break free from her husband, but once again she rejects him. Noticing Sonya's love for Astrov, Elena proposes to sound him on his feelings towards her. When she does so, Astrov reveals he has no amorous passion for Sonya whatsoever, laughingly concluding that this question is meant to sound his eligibility for her own passion towards him. Astrov kisses Elena as Vanya pathetically enters with a bunch of roses. More distraught than ever, Elena begs Vanya to use his influence on her husband so that the married couple may leave the house immediately. As the retired professor enters, Elena briefly signals to Sonya Astrov's negative response. Alexander proposes to sell the estate, at which, Vanya, crushed, asks him where does he propose he and Sonya should live. Vanya casts in his former mentor's teeth his ingratitude, for it is he and Sonya who have managed his estate. Angry words are exchanged and Vanya quickly leaves the room. Alexander follows to placate him, but a pistol shot is heard whereby Alexander returns, chased by Vanya, who fires again, misses, laughs at himself, and sinks into a chair. Later, Astrov demands that Vanya give him back a vial of morphine, enough to kill a man, which he relunctantly does after Sonya's intervention. Agreed to leave the estate, Alexander and Elena bid everyone farewell. As so many times in the past, Sonya and Vanya are left to take care of house accounts. "We shall live a long line of days, endless evenings; we’ll bear patiently the trials fate sends us; we’ll work for others now and in our old age without ever knowing any rest, and when our hour comes, we’ll die humbly and there beside the coffin we’ll say that we suffered, that we cried, that we felt bitter, and God will take pity on us, and you and I, uncle, darling uncle, shall see life bright, beautiful, fine, we shall be happy and will look back tenderly with a smile on these misfortunes we have now and we shall rest. I have faith, I believe warmly, passionately, we shall rest," Sonya asserts. =Ivan Turgenev= [[File:Félix Nadar 1820-1910 portraits Yvan Tourgueniev.jpg|thumb|Ivan Turgenev described the pains of unrequited love in country life. Photo of the author by Félix Nadar (1820-1910)]] An important precursor of Chekhov's plays is "Месяц в деревне" (A month in the country, 1855) by Ivan Turgenev (1818-1883). In particular, "A Month in the Country anticipates Chekhov in its attention to psychological detail and also in the way the story returns full circle to its starting-point” (Lamm, 1952 p 181). "A month in the country" "is as well made as though it concerned nothing in particular. The subtlety throughout is extraordinary, and Turgenev pays our minds a compliment by leaving the most important things unsaid. Natalia’s anguish in declining self-respect, Viera’s transition from the child to the woman who knows that her life will never be lived- these things have no words, yet they move us deeply. Ultimately both the languid lover and the tutor go away, leaving Viera to a loveless marriage and Natalia to the house which the presence of her well-meaning husband makes all the emptier. There is no climax, but then why should there be? A gentle melancholy suffuses this piece, and like Shelley’s wave, gives an ‘intenser day’ to all that it envelops” (Agate, 1944 p 94). "The substance of A Month in the Country is the manner in which the restless Natalia tries to keep the devotion of each of several men but succeeds only in losing all of them except her docile and patient husband. She is one of those types never quite ready to relinquish her hold upon anyone, no matter what the cost in misery to the captive. As the play ends, the house will soon be quite empty. Natalia has reaped the harvest of her egotism" (Skinner, 1931 p 257). A Month in the Country “is really a bitter satire on sentimental, conventional love, with a dénouement featuring two very unromantic betrothals. Vera’s engagement with Bolshintsov and Lizaveta Bogdanova’s to Dr Shpigelsky are arrangements of convenience; the parties enter into their relationships only because they have admitted defeat in their quest for live. Vera’s disillusionment with her guardian is heightened by her tragically delayed realization that she loves Belyayev...Natasha’s jealous machinations thwarted any chance Vera might have of finding a young, romantic mate. In bitterness and defeat, she scorns Natasha and rejects the social and financial dependence she has grown to hate. Elizaveta, already 37 years old, knows that she is doomed to be the companion of an aging woman who will always treat her as a servant. Her union with Shpigelsky, though loveless, will free her from genteel servitude...Vera will be merely a pretty object; Bolshintsov will be unable to communicate with her at any level. Curiously, the wordly and sophisticated Shpigelsky is in a similar position. Weary of his own duplicity, he confesses his strengths and weaknesses to Lizaveta, offering her a loveless union that may give both of them the security they need to continue their twisted and stupid existences” (Grace, 1973 pp 96-97). “Vera’s plight moves us all the more because she is such an ordinary girl, and even Natalya, who deliberately consigns her to unhappiness, seems in some respects almost as pitiable as her victim. She is, after all, brought down by two uncontrollable forces: the ageing process, which is just beginning to tell on her, although she is not yet quite thirty, and the power of erotic passion, which we know to have ruined stronger persons than her. She is also trapped in an unrewarding marriage. Her unforgivable behaviour can at least be understood. The pull towards sympathy which Turgenev exerts upon us in relation to this ostensibly shameful character demonstrates his deep knowledge of human personality and his interest in the complexities of motivation and behaviour” (Briggs, 1999 p 102). "A month in the country" "ends without having reached a very decisive conclusion. Natalya, her husband, her husband’s mother, her son, and her son’s German tutor will continue living on the estate. Life will go on in much the same way as it has done heretofore, and Natalya will no doubt continue to be restless and dissatisfied. She and Belyayev seem to be badly coordinated people by comparison with Rakitin and Vera, both of whom have secured emotional tranquillity at the cost of immediate happiness. None of the four principal characters in this play has an agreeable prospect for the future. Only Natalya’s stupid husband thinks that everything has come out in the best possible way for himself and all the others...All of the people in A Month in the Country have more or less violent passions, but no one of them is able to satisfy his impulses. There is some inhibiting force within them, all which makes it impossible for them to express themselves as they would like to do. The practical circumstances of their lives have too much influence over them. They lack the strength of character that they should have if they are to be the masters of their own fates" (Perry, 1939 p 331). In the final scene, "as he bids them all farewell, Belyaev suddenly understands that he himself has been the cause of all this tangled web of misdirected affections, and in a rush of remorse such as only a Russian can comprehend, he, too, departs, and life on the estate resumes its monotonous course above the wreckage of unfulfilled passions" (Sayler, 1921 p 396). =="A month in the country"== [[File:Stanislavski&Knipper1909.jpg|thumb|Mihail loves Natalia but is not loved in return, played respectively by Constantin Stanislavski (1863-1938) and Olga Knipper (1868-1959) at the Moscow Art Theatre in 1909]] Time: 1850s. Place: Russia. Text at http://gutenberg.net.au/ebooks03/0300831h.html https://archive.org/details/in.ernet.dli.2015.105455 https://archive.org/details/in.gov.ignca.29218 A wealthy landowner and bachelor friend of the family, Mihail Rakitin, spends much time in the company of Arkady Islayev's wife, Natalia. When Mihail questions Alexey Belyaev, the recently hired tutor to their son, about his past life, the latter mentions once translating a French novel without even knowing any French at all. A neighbor of theirs, Afanasy Bolshintsov, owner of over three hundred serfs, requests the advice of their family doctor, Ignaty Shpigelsky, concerning a possible marriage between himself and Vera, orphaned ward of the Islayevs. Should this be accomplished, Afanasy will give him three horses. Ignaty introduces the subject to Mihail, who, in turn, does so to Natalia, who dislikes the idea, considering the man a "stupid creature". Of greater importance to himself, in view of his love of her, Mihail notices Natalia's infatuation for Alexey. When Natalia questions Vera about her feelings for Afanasy, she miserably answers: "I'm in your power, Natalia Petrovna." Natalia assures her that she will be free to choose her choice of a husband. Then she learns that Vera loves the man she herself loves, Alexey, her son's tutor. Suspecting he may lose Natalia, a worried Mihail selfishly advises her to dismiss Alexey. Instead, Natalia seeks to find out whether Alexey loves Vera. He does not seem to. Meanwhile, Ignaty courts Lizaveta, another family friend, and seems to make some headway there. Vera discovers that Alexey does not love her and also that Natalia loves him and perhaps plans to marry her off to Afanasy after all. To Alexey's astonishment, Natalia declares her love to him, but she hesitates on whether he should leave the house, finally deciding she cannot have him go. Meanwhile, Arkady notices Mihail's attachment towards his wife. A sad witness to Natalia's love of another, Mihail decides to leave the house. Also unable to live any longer with Natalia, Vera questions the doctor about Afanasy, who assures her he is most kind-hearted and "like dough". To Natalia's grief, Alexey, uncomfortable with his position as the recipient of his mistress' love, decides to leave the house as well. Mihail grits his teeth while Arkady expresses his gratitude for this sacrifice to their friendship. Lizaveta is also free to go, having agreed to marry Ignaty, most glad at obtaining the horses. =Leo Tolstoy= [[File:Ilya Efimovich Repin (1844-1930) - Portrait of Leo Tolstoy (1887).jpg|thumb|Leo Tolstoy wrote about greed and murder in the peasant class. Portrait of the author by Ilya Repin (1844–1930), 1887]] Of further interest in Russian realistic drama is a gritty peasant play: "Власть тьмы" (The power of darkness, 1886) by Leo Tolstoy (1828-1910). "I am much disposed...to recognise in The Power of Darkness one of the most perfect masterpieces which ever graced any literature, and to perceive that Tolstoi seems to have imported in it a new form of popular drama, and one capable of universal application. The idea that a fault may be atoned for by voluntary confession and expiation is certainly not a new one. But none of Tolstoi's predecessors has succeeded, so far as my knowledge goes, in expressing it in so dramatic a fashion, nor with so much true and simple grandeur. He gives us Nature herself, as she lives and moves, taken from the rustic life, without the smallest affectation, or the slightest touch of rhetoric. Figures and surroundings, methods of speech and ways of feeling, have all been observed, noted even to their most delicate shades, and rendered in a fashion that is miraculous. Though Nikita, the guilty peasant, speaks the ordinary language of the populace, he uses some phrases and expressions which reveal his knowledge of circles other than those of his own village. You realise that a railway must have been made through the place, and that the foam of city civilisation has thus been cast, by way of the tavern, on to the threshold of the peasant's hut" (Waliszewski, 1900 pp 391-392). "Act 1 introduces a problem in terms long familiar to the comic theatre. Peter...is the typical cuckold. He has taken as his second wife some ten years junior in years...Anisya is correct in her complaint to her husband that his plans are based on desires for his own comfort and a disinterest in hers...It is typical of the comedy of cuckolding, too, that the wife should take a younger man as her lover...The other characters, too, are presented in this first act in comic terms. Matrena, Nikita's mother, is the old bawd- crafty, vulgar, hypocritical...In Act 2 greed becomes 
the controlling motive...[it] opens with the problem of the lovers' ridding themselves of Peter, finding his money, and concealing the crime, and almost every speech in this act is concerned with this problem...There is [in act 3] not merely the 
grimness that we expect from the naturalistic view, but there is also the hopelessness...Nikita offers his father money, his father refuses. He orders Anisya from the house, but she does not leave, Akim speaks of the 'ruin' that is coming, but, in truth, the ruin is already there. Only the half-witted Akulina finds any pleasure at all...Act 4 [is] a scene of horror, a drama of the grotesque...more closely akin to Webster's 'The duchess of Malfi'...than to anything in modern drama...[This play] is the only modern drama that systematically uses dramatic points of view, not for the purpose of arriving at a relativist conclusion about the impossibility of truth, but to demonstate the supremacy of the moral-religious view" (Nolan, 1965, pp 3-9). "Of the three chief characters involved, all the blackest of criminals, only two suffer from the pangs of a guilty conscience. Matryona, the mother of Nikita, is at the bottom of aU the crimes. Her husband is a devout and god-fearing man, who pleads with his son to forsake his evil ways. Yet she encourages her son in his downward career and finally helps in forcing him to murder his own child. Yet she does not seem to have the slightest feeling of guilt. She is even pious about her crimes, insists on baptizing the infant before it is murdered by its father, and constantly has the name of God on her lips: 'Well, but with the Lord's help, when we've covered this business, there'll be an end of it'...Aniaya, who with the help of Matryona murdered her husband to get his wealth and to be able to marry Nikita, gradually becomes more hardened in her career of crime. Yet her guilt weighs heavily upon her conscience...She feels remorse, but with her it does not change to repentance as in the case of Nikita. To revenge herself on him for having betrayed her, she, fiend-like, drives him on to the same condition. He, on the other hand, after he has once been brought to his senses, assumes not only his own guilt but also that of his wife and of his mother. He makes his confession not because his crime has been found out, but at the very point when it is least likely to be discovered. The pangs of remorse, a deep conviction of guilt, force him to make his confession" (Cast, 1917 pp 523-524). “Matriona...is a bustling old woman, quite unscrupulous in her desire to make her son’s fortune, and perfectly ready to serve as procuress or a blender of poisons...Her husband Akim...seems half crazy; he is a shy stammering man...and every good action is the result of some impulse of his...Akulina, an ugly over-grown child, is at first completely under her mother’s thumb, but later on, with the help of Nikita and after her father's death, she learns to browbeat her in her turn...Everything, even scenes of horror, seems to happen and be discussed as if it were quite natural, with the result that the audience is doubly moved...Nikita...is always musing about his crimes, partly because his conscience is uneasy but partly also because they have served no purpose” (Lamm, 1952 pp 183-185). Nikita "drifts through life along the line of least resistance. He is not deliberately vicious; yet he is impelled from crime to crime by influences that are stronger than himself. The germs of sin are fructified within his soul by the power of darkness" (Hamilton, 1920 p 152). Matryona is "a memorable character, repulsive, hypocritical and callous, yet in a queer, perverted fashion devoted to her son" (Wilson, 1927 p 191). “The women in this play are enslaved by superstition and convention. The men weigh morality, the women consider expediency only. After he has murdered his infant, Nikita constantly emphasizes his terrible fall and the destructiveness of the women...But Matrena and Anisya, oblivious to moral as opposed to social consequences, devote their energies to the continuation of a corrupt society that is based upon money, security, and respectability” (Grace, 1973 p 106). Gassner (1954a) concluded that "if the play derives its strength from the marvelous naturalistic portrayal of the culprits, it is the totality of effect that is important. The play is a tragedy of sin and expiation, and it takes the Russian drama beyond Ostrovsky in one important respect: it adds the dimension of humanitarianism to the stark photography of life" (p 506). Goldman (1914) described the social impact of the play as "a terrible picture of poverty, ignorance and superstition. To write such a work it is not sufficient to be a creative artist: it requires a deeply sympathetic human soul. Tolstoy possessed both. He understood that the tragedy of the peasants' life is due not to any inherent viciousness but to the power of darkness which permeates their existence from the cradle to the grave. Something heavy is oppressing them- in the words of Anisya- weighing them down, something that saps all humanity out of them and drives them into the depths. 'The power of darkness' is a social picture at once appalling and gripping" (p 282). =="The power of darkness"== [[File:Scene from The Power of Darkness.jpg|thumb|Illustration of "The power of darkness" from Russian Theatre, Brentano's, New York, 1922]] Time: 1880s. Place: Rural Russia. Text at http://en.wikisource.org/wiki/The_Power_of_Darkness https://archive.org/details/in.ernet.dli.2015.531140 https://archive.org/details/in.gov.ignca.29219 Nikita, a laborer on Peter Ignatitch's estate, is forced by his father to marry Marina. Anisya, Peter's wife but Nikita's lover, weeps at these news and feels betrayed. "My old man will die one of these fine days, I'm thinking; then we could cover our sin, make it all right and lawful, and then you'll be master here," she says, consoling herself. Matryona, Nikita's mother, observing their embraces, is content merely to say: "What I saw I didn't perceive, what I heard, I didn't hearken to. Playing with the lass, eh? Well,- even a calf will play. Why shouldn't one have some fun when one's young?" She is against the marriage, preferring Nikita to keep his well-paid position, and so she buys poison so that Anisya may use it on her husband, at which the latter pays her back. Matryona's husband, Akim, finds a job in town cleaning cesspools and prefers to have his son stay at home, all the more so because otherwise he will wrong Marina if he does not marry her, but Matryona calls her a common slut and her son suggests in a roundabout way the same. Marina accuses Nikita of deceit, knows he does not love her any more, and knows whom he loves at the moment, at which he brutally sends her on her way. As Peter is being slowly poisoned over the course of several months, Anisya's anxieties grow because she does not yet know where her husband hides his money. He may give it to his sister, Martha. While tea is prepared, Matryona assures the suffering Peter he will obtain a fine burial service. As Matryona helps him into the house, she feels the money on his person, so that Anisya succeeds in retrieving it and gives it to Nikita to bury. She then re-enters the house and comes out screaming. Matryona rolls up her sleeves to lay out the body. As Anisya wished, Nikita becomes the new master, but he quickly becomes enamored of Anisya's step-daughter, Akoulina, and squanders on her the money his wife killed for. He puts on airs with Akoulina and throws money at Akim, who finds such doings filthy, but nevertheless keeps the money. Akoulina quarrels with Anisya and accuses her of murdering Peter. To settle the quarrel, Nikita pushes Anisya out of the house, but after a while calls her back and gives her a present. Even more disgusted at such doings and considering he is heading for ruin, Akim gives back the money to his son. Several months later, Akolina is about to give birth as Matryona tries to arrange a marriage for her. Since she is unmarried, Anisya and Matryona plot to get rid of the baby, asking Nikita to dig a hole in the cellar, which he reluctantly does. Anisya retrieves the newborn wrapped in rags and throws it for Nikita to take care of, who is surprised to see it still alive. "Be quick and smother it, and then it won't be alive." she says. "It's your doing and you must finish it." Nikita comes out of the cellar trembling and upset: "How the little bones crunched under me!" he exclaims. He imagines he hears it whimpering still. In mortal conflict, he chases Anisya about with the spade. "How can it whimper?" asks his mother. "Why, you've flattened it into a pancake. The whole head is smashed to bits." During Akolina's wedding ceremony with another man, Nikita feels unable to give the blessing. Instead, he ties a rope around his neck. Matryona removes it. Anisya invites him back to the party. As they go, he picks up the rope again, but one of his laborers hangs on to it laughingly and drunkenly till he gives up. On entering the room with the guests, he falls drunkenly and declares: "Christian Commune, I have sinned and I wish to confess." Very much alarmed at the beginning of this speech, Matryona says her son must be taken away. Despite her intervention, he confesses to Akim's joy to the murder of Peter and the baby, which Akoulina confirms to have borne. He says he did everything alone. =Alexander Ostrovsky= [[File:Aleksandr Nikolayevich Ostrovsky 2.jpg|thumb|Alexander Ostrovsky described the vehement conflicts between a mother, her son, and his wife, 1870s]] Another dramatist of interest is Alexander Ostrovsky (1823–1886), who wrote 48 plays from 1847 to 1884, including three major ones: "Гроза" (The thunderstorm, 1859), "Лес" (The forest, 1871), and “На всякого мудреца довольно простоты” (No fool like a wise one, 1868, also known as Enough stupidity in every wise man). The Thunderstorm "is the atmosphere of the little Russian town, with its primitive inhabitants, merchants, and workpeople, an atmosphere untouched, unadulterated by the ideas of any exterior European influence. It is the Russia of Peter the Great and Catherine's time, the Russian patriarchal family life that has existed for hundreds of years through all the towns and villages of Great Russia, that lingers indeed today in out-of-the-way corners of the Empire, though now invaded and much broken up by modern influences. It is, in fact, the very Muscovite life that so puzzled our forefathers, and that no doubt will seem strange to many English readers. But the special triumph of The Thunderstorm is that although it is a realistic picture of old-fashioned Russian patriarchal life, it is one of the deepest and simplest psychological analyses of the Russian soul ever made. It is a very deep though a very narrow analysis. Katerina, the heroine, to the English will seem weak, and crushed through her weakness; but to a Russian she typifies revolt, freedom, a refusal to be bound by the cruelty of life" (Garnett, 1922 pp 136-137). The play "is one of the best dramas in the modern repertoire of the Russian stage. From the stage point of view it is simply admirable. Every scene Is impressive, the drama develops rapidly, and everyone of the twelve characters introduced in it is a joy to the dramatic artist" (Kropotkin, 1905 p 270). “Boris and Katerina have only two stones alone together during the play: one at the end of the 3rd act and their scene of parting in the 5th act. Boris appears momentarily in the 4th act; but while his presence is dramatic, no words are spoken between them. This situation involving unlawful love and marital infidelity would have given rise to a very different series of scenes in the hands of a contemporary French, German or English dramatist. Either a problem play or a semi-romantic tragedy would have evolved. Ostrovski does not emphasize either plot or the discussion of the problem of marriage. Therefore, he has plenty of time to analyze his characters and to present his theme through their actions, personalities and conversations, especially as the actual story of the play does not begin to unfold until towards the dose of the third act…Katerina does not exist primarily as a study of a dramatic character. She is entirely subservient to the theme; but diminution of the element of plot made such analysis of character possible in drama as well as in the novel in which the element of time is not a vital question” (Stuart, 1960 pp 601-603). Ostrovsky “knew his types and presented them with faithful realism...But his realism was more than photography. For her refused to give his plays an ending, just as plots of real life always carry on into new ones. The endings of his last acts always show a vista of the story that continues beyond. The peasant heroine of The Thunderstorm, after her faithlessness has been discovered and her lover drowned, sees the long, bitter life ahead of her: slavery and social disgrace” (Moderwell, 1972 p 181). "The conflict is very strongly marked between the mysticism and hunger for beauty, which are the dominant characteristics of Katerina, and the narrow ignorance and tyranny, which are exemplified in the household of Kabanova...The next act stresses still further the cramped environment of Katerina, in showing the jealous tyranny of her mother-in-law and the weakness and selfishness of her husband, who, anxious to escape from Kabanova's domineering for a few weeks of dissipation, turns a deaf ear to his wife's premonitions of evil and refuses to spoil his holiday by taking her with him...Katerina's longing for some colour and beauty in life is too great for her to make any long resistance...The superstitions and rough despotism of the older generation are contrasted with the sentimentality of Varvara and her friend and the passionate tenderness of the newly-met lovers...The crisis comes with the fourth act, where the storm of the elements is re-echoed by the tempest in Katerina's heart and mind. After her husband's unexpected return, she realises her guilt and, in her suffering, feels that the storm, according to the beliefs of the townspeople, had come as punishment for her sin. Everything conspires to play on her overstrained nerves,- the storm, a sudden meeting with Boris, the denunciations of a religious maniac, who appears at intervals throughout the play, and an inscription about Gehenna and the Day of Judgment on the walls of the ruins, where they have taken shelter. These last two details, together with Katerina's fear of storms, have been suggested much earlier in the play and therefore fit in quite easily in obtaining the cumulative effect of strain, which breaks down her silence and makes her cry aloud her shame...She...eludes the careful watch, which is kept over her, and coming down to the river, half-dazed from the emotional struggle she has undergone, she meets Boris. This rather inadequate lover is completely dependent on his uncle and therefore, when sent to an appointment in Siberia, can think of no other course than to obey instructions. Family discipline was very strong among the merchants. He can only return tender words to Katerina's request for freedom and show her that it is impossible to take her with him. Life then holds no possibilities for her. Feeling herself completely accursed, she does not hesitate long. What does another sin matter? Better suicide than this half-death" (Beasley, 1928 pp 606-608). "Kabanova...declares that Katerina cannot love her husband, because otherwise, when he went away, she would have howled for an hour and a half and fallen down on the porch. That was the accepted method as Kabanova understands it, and she abuses Katerina for not doing it. She treats her son as badly as she does his wife. Her daughter has learned the method of acting under this regime. She obeys meekly and slips out the back door to her lover. Katerina is induced to try it but she takes that also too seriously and finally she drowns herself. Her husband who loves her dearly threatens to rebel against the harsh rule of his mother, but she merely sneers...We agree to the moral callousness of the old woman but she is the dominating character. Katerina with her charm is really weak. So is the son, and there will be a long way yet to go before they seriously threaten the rule of the old shrew...Thus, as we run through the plays of Ostrovsky, we find that they picture the newer life which was replacing that of the stern old patriarchs of the thirties and the forties" (Manning, 1930 pp 37-40). "Catherine is a romantic, with leanings towards mysticism. She sins and curses her love and her lover even as she yields to them. Her husband is a brute, with coarse instincts and some good feeling. His mother is a domestic tyrant, brought up in the school of Pope Sylvester. When, at the moment of her indifferent husband's departure, Catherine, with a presentiment of her impending fate, casts herself on his breast, beseeching him to stay, or to take her with him, the old woman interferes...and so Catherine seeks in another man's arms the caress, the loving words, the tender clasp for which her soul- the soul of a modern woman- hungers" (Waliszewski, 1900 p 274). “Dikoy represents the greedy miser, whose every walking movement is planned to exhort money dishonestly. When confronted by logic, he uses brute force and outmoded irrational arguments to maintain his position. The equally vile matriarch, Kabanikha, defends medieval practices, among them absolute submission by her family...Tikhon passively assents to [Katerina’s] mistreatment, too fearful of his mother to defend his wife. Katerina’s lover, Boris, is similarly weak-willed and sacrifices her to Dikoy’s cruel dictates...Katerina...is torn between rejecting the strictures of the old and remaining loyal to religious tradition” (Frank, 1986 p 1450). The Forest "shares with The Thunderstorm the honor of being regarded as his masterpiece. Less exclusively original, the comedy is extraordinarily rich in its character drawing. Of all Ostrovsky’s plays, it is the one in which the essential nobility of man is most triumphantly asserted. But it also contains the most unsweetened types of cynical and compla- cent meanness and selfishness in the whole of Russian literature" (Mirsky, 1949 p 239). The play "is a concentration of all the previous history of both west European and Russian theater. This effect is provided first of all (though not entirely) by the characters of two actors, the tragedian Gennady Neschastlivtsev (Unlucky) and the comedian Arkashka (Arkady) Schastlivtsev (Lucky). They both behave theatrically in real life, and their theatricality is the sum of all the roles they have ever played. For Neschastlivtsev, these include, first of all, Shakespeare (Hamlet), Schiller (Karl Moor), and Cervantes (the non-dramatic role of Don Quixote). Meanwhile, Schastlivtsev, who acts as Sganarelle, the role once played by Molière himself, with its roots in French théâtre de la foire (‘fair theater’) and Italian commedia dell’arte, impersonates the tradition of all the ‘comic unfortunates'" (Kuptsova, 2019a p 114). “Ostrovsky presents two provincial actors, Grigory Neschastlivtsev and Arkashka Schastlivtsev, whose dramatic talents are doubtful and whose everyday behaviors are flawed, as far superior to and more noble than the residents of the Penki Estate (the shabby-genteel nobility and the emerging ravenous entrepreneurs). It is interesting (from a historical perspective, too) in this regard to observe the successive set of the actors’ self-characterizations in the play, their gradual evolution from skomorokh (the nomadic type, ‘unmounted travelers’), court jester, actor, to noble artist...The roles they play in life correspond to the characters they play on stage, Neschastlivtsev being a tragic, Schastlivtsev a comedic actor...All of the quotes from Shakespeare’s tragedy pronounced by Neschastlivtsev (whether appropriately or not, whether they be small or very important fragments of the role) in The Forest rhyme the story of Penki residents with that of the Prince of Denmark. In both cases, deception, hypocrisy, and crime are discovered with the help of comedians...In the final part, one of the two dramas in the prompter Arkashka Schastlivtsev’s parcel turns out to be the five-act The Robbers by Friedrich Schiller, whose influence on Russian Romantic theater was at least as significant as that of Shakespeare. The robbers theme is represented in The Forest in two parallel dimensions. On the one hand, the social perception of skomorokhs/actors and robbers is very much identical. On the other hand, the theme of noble robbers is of central importance in the Romantic repertoire. Therefore, the forest fellowship of noble robbers and the guild fellowship of “noble artists” act as contextual synonyms, forming a unique theatrical metaphor” (Kuptsova, 2019b pp 209-211). "No fool like a wise one" "emphasizes the fact that simple human beings like to be flattered, even when they know the painful truth about themselves, and also points out that some flaw is to be found in the armor of the most hardened hypocrite" (Perry, 1939 p 333). "While Gogol, Griboyedov, and their contemporaries had confined themselves to a bitter exposure of the nobles and the bureaucrats, Ostrovsky went further, and showed up this unproductive section of society in direct contrast to the bourgeoisie, whose character and conduct he paints sympathetically, though not without some shrewd criticism. His comedies were the first to deal, on a large with the mentality of a class which no Russian dramatist as yet had thought it worthwhile to describe with such particularity. His method was to exclude any touch of romance or pathos, his sole concern being to represent men and matters as they actually are; his plays mark the beginning of realism on the Russian stage- that realism to which it was to owe its most important successes in the future" (Fülöp-Miller and Gregor, 1930 p 40). Ostrovsky's "plays, as a rule, are neither comedies nor dramas. Dobrolioubov called them 'representations of life'. The audience is not given anything to laugh at, nor yet anything to cry over. The general setting of the piece is some social sphere which has little or no connection with the characters we see in it. These characters moving themselves are neutral in tint neither heroes nor malefactors. Not one of them rouses direct sympathy. They are all overwhelmed by a condition of things the weight of which they might shake off, the danger of which would vanish, if they showed some little energy. But of this they have not a spark. And the struggle is not between them, but between the facts, the fatal influence of which they undergo, for the most part, unconsciously. A sort of gloomy fatalism presides over this conception of mundane matters, an idea that anyman belonging to a particular moral type must act in a particular manner. The natural deduction from this theory is that actions are not good or bad in themselves. They are merely life. And so life itself is neither good nor evil. It is as it is, and has no account to give to anybody. Ostrovski's pieces have generally no denouement, or, if they have one, it is always of an uncertain nature. The dramatic action never really closes, it is broken off; the author cutting it short, not by an effective scene or phrase, but frequently, and deliberately, at the most commonplace point, or in the middle of a rejoinder. He seems to avoid effect just where it naturally would occur in the situation. Ostrovski's admirers hold this to be his manner of typifying real life, which, in nature, has neither beginning nor end. I have already made my reservations on this head; and I am glad indeed to affirm that no other Russian writer, save Tolstoi, has painted so great a number of types and circles corresponding with almost every group in Russian society. His language, full of power and fancy, constitutes, with that of Krylov, the richest treasure-house of picturesque and original expressions to be found in Russia. Pushkin had already declared that the way to learn Russian was by talking to the Moscow Prosvirnie (the women who make the sacred bread, prosford). They taught Ostrovski precious lessons" (Waliszewski, 1900 pp 276-277). "Ostrovsky’s pictures of the sordid and disagreeable world into which he introduces us do not provide the relief of either noble suffering or hearty laughter. The flat realism which he presents is more inclusive than that of Gogol or Turgenev and therefore less selectively refined than that of the earlier writers. It is, however, a powerful description of the externals of a mediocre social group. It is, in addition, thoroughly representative of the aesthetic tendencies of the nineteenth century in Russia and elsewhere throughout Europe. The continuous rise of the middle class tended to stimulate a kind of art which does not make excessive demands upon the imagination. Ostrovsky offered his audiences plenty of variety in scenes drawn from observation and experience. In some of his plays the merchants are good; in others they are bad. In some, children get their way; in others, parents or guardians get theirs. Conditions are never the same in any two cases, and therefore, in his view, no general principles can be extracted from the welter of human society. The aim of a realistic artist like Ostrovsky is to present life as he sees it, vividly and accurately, with the utmost photographic exactness" (Perry, 1939 pp 334-335). "The virtues and defects of Ostrovsky’s plays are, on the whole, the same which we find in Russian prose writers. He is, above all, simple and natural- so natural that he gives the impression of following the depicted events rather than organizing them. He neglects the plot and concentrates upon the characters and their dramatic conflicts. These arc taken straight from life with great tolerance and objectivity. This is why his plays have the logic of life itself and not that of literary inventions. His sober eye, as well as his strong sense of measure, avoids all tricks or effects for their own sake. His very irony seems to be the irony of life caught by the author quite by chance, as it were. Yet there is perhaps just one flaw in his figures they are those of a great observer rather than a great creator" (Lavrin, 1928 p 54). “It is diversity of his characterisation which provides one of the most striking features of Ostrovsky’s work. His plays explore a whole spectrum of humanity from peasants to the nobility. A brief examination of the principal characters in his early works alone reveals civil servants, noblemen, landowners, peasants, teachers and servants, depicted alongside the merchants. His later works would go on to portray members of ‘high society’, provincial actors and representatives of the emerging capitalist class” (Rahman, 1999 pp 169-170). =="The thunderstorm"== [[File:Merchant Dikoy from Storm (Ostrovskiy) by Kustodiev (1920, priv.coll).jpg|thumb|Dukoy deviously robs Boris of his inheritance. 1920 picture of the merchant by Boris Kustodiev (1878-1927]] Time: 1850s. Place: Kalinov, Russia. Text at http://www.gutenberg.org/ebooks/7991 https://archive.org/details/storm01ostrgoog https://archive.org/details/cu31924026730311 https://archive.org/details/cu31924026730329 https://archive.org/details/storm00ostr Being an orphan, Boris is the recipient of his grandmother's will whereby his uncle, Dukoy, a merchant, is to pay him and his sister a fair share of her fortune provided he shows proper respect for his authority. But Dukoy takes advantage of the situation by pretending never to be satisfied and thereby keeps the money for himself. In the Kabanov household, Marfa is unhappy about the way her son, Tihon, handles his wife, Katerina, too softly in her view. Tihon does not understand why he should foster fear in his wife. "Why should she fear you!" she exclaims. "What do you mean? Why, you must be crazy. If she doesn't fear you, she's not likely to fear me." Katerina confesses to Varvara, Tihon' sister, that she is in love with another man. Varvara promises to help her. "No, no, that must not be," she says. "What are you saying! God forbid!" She fears a storm is brewing. "Don't talk of not being afraid," she says. "Everyone must be afraid. What is dreadful is not it's killing you, but that death may overtake you all of a sudden, just as you are, with all your sins, with all your erring thoughts. I have no fear of death, but when I think that I shall be brought all at once before the face of God just as I am here, with you, after this talk,- that's what is awful! What I had in my heart! What wickedness! Fearful to think of!" Varvara guesses correctly that Katerina loves Boris. As Tihon prepares to leave on a two-week journey, his mother mentions some specific recommendations. "Lay your commands on your wife, exhort her how she is to live in your absence," his mother insists, "and then when you come back, you can ask if she has performed everything exactly." Varvara steals the garden-key from her mother, so that Katerina can meet her lover in the summerhouse and delivers at the same time a message to Boris that he must be near. While waiting for her, he confides to a friend, Kudriash, that he loves a married woman. Kudriash guesses who it is. Katerina meets Boris, veiled. "Do you know that never by any prayer can I be free of this sin, never again?" she asks. "Like a stone it will lie on my soul, like a stone." But yet she is determined to go on. "If they lock me up, that will be my death. And if they don't lock me up, I will find some way to see you again," she adds. As they retire together, Kudriash meets Varvara. They kiss and yawn. When Tihon eventually returns from his journey, Marfa notes how unhappy Katerina appears. A storm is on its way and Katerina is afraid. Tihon says that being afraid of storms is a question of temperament, to which Marfa comments: "The heart of another is darkness." When Boris suddenly appears for a visit, Katerina shrieks. After he leaves, she reveals to her husband and his mother in the thunderstorm that from the first night and every night of his voyage, she went out with Boris. "Well, son! You see what freedom leads to," says Marfa triumphantly. "I told you so, but you wouldn't heed me. See what you've brought on yourself!" Tihon tells a friend it is not his fault, but his mother's. He still loves her, cannot hurt her, only giving her a few blows now and then at his mother's bidding. Meanwhile, Dukoy orders Boris away to Siberia. Varvara flees the house with Kudriash. Tihon then learns that Katerina has disappeared. By chance, Katerina finds Boris and asks to go with him, but he, being dependent on his uncle's will, says he cannot. Her condition is miserable, her husband's kindness being worse than his blows. They go their separate ways. A bystander notices a woman in the river. As a fearful Tihon heads in that direction, his mother holds him. When Katerina's corpse is carried in, Tihon blames his mother for her death, crying out to her ghost: "It is well with you, Katia, but why am I left to live and suffer!" =="The forest"== [[File:Larix_gmelinii_Kochechum.jpg|thumb|Trouble starts when Raissa Gourmyskaia wants to sell her forest. Larix gmelinii forest, Kochechum River, Evenkiyskiy Avtonomnyy Okrug, Russia]] Time: 1870s. Place: Russia. Text at ? To reduce her expenses, a rich widow, Raissa Gourmyskaia, plans to marry off two of her dependants, Alexis and Axinia, to each other, although neither love the other. To augment her revenues, she intends to sell part of the forest surrounding her estate. A prospective buyer is found: Ivan Vosmibratof, who arrives to negotiate with her along with his son, Piotr, who secretly loves Axinia as much as she loves him. Raissa has already sold one part of the woods to Ivan for 1,500 roubles but cannot find the receipt. Before her properties are discussed, Ivan asks whether she agrees to a marriage between his son and Axinia. She immediately refuses, but agrees to let go another part of the woods for 1,500 roubles. Ivan's assent to this proposition is rather vague. After sounding out Axinia about the proposed marriage with Alexis, Raissa finds her unwilling and defiant. Unexpectedly, Raissa's long-lost nephew, Guennari, arrives, in dire straits as a failing actor, along with a fellow-actor, Arkadi, also fallen on hard times. She finds their visit to be a wearisome load on her finances and hopes to be rid of both. When Ivan returns, Raissa discovers she has lost her receipt again. Nevertheless, she gives him a certificate stating she has received the entire sum of 3,000 roubles. Ivan takes the certificate and to her dismay hands over only 1,800 roubles, the sum he pretends to have agreed to until Guennari arrives and intimidates him into yielding the correct sum. Piotr needs his father's consent to marry Axinia. Ivan agrees provided that they obtain 2,000 roubles as a dowry. Thinking he is rich, Axinia begs Guennari to give her the money. Instead, the actor proposes to turn her into an actress. One day, the housekeeper announces to Raissa that Axinia has left the house. "Perfect!" she exclaims. With her gone, Raissa all the more boldly flirts with Alexis. But when he kisses her and takes her familiarly by the waist, she cries out: "Are you crazy?" Nevertheless, she makes him her steward. No longer wanted, Guennari prepares to leave the house. Raissa gives him 1,000 roubles, only part of the sum she owes him from long ago. As Axinia prepares to follow the actors, Piotr succeeds in reducing his father's demands down to 1,000 roubles, which Guennari yields to so, that he and Axinia can marry. ==“No fool like a wise one”== [[File:Stanislavski_and_Kachalov_in_Ostrovsky%27s_Enough_Stupidity_in_Every_Wise_Man_1910.jpg|thumb|Vasili Kachalov pretends subservience to General Krutitski, played respectively by Vasili Kachalov (1875-1948) and Konstantin Stanislavski (1863-1938), at the Moscow Art Theatre, 1910]] Time: 1860s. Place: Moscow, Russia. Glafira Glumova points out to her son, Yegor, that Masha Turusina with her 200 hundred thousand rouble dowry, will be difficult to obtain in view of their poverty relative to the prospects of Vasilich Kurchayev, a hussar and nephew of a rich man, Nil Mamayev, also Yegor’s more distant uncle. Yegor sees his chance when Vasilich scribbles a drawing of Nil supplemented by a legend of the liberal satirist, Golutvin, which Yegor pockets up for future use. Another possible stroke of luck arises when Vasilich informs Yegor that Mamayev’s wife, Cleopatra Mamayeva, has taken a fancy to him with a mere glance at a theater. To his mother’s surprise, Yegor already has a trap set for Nil after having falsely advertised apartments to a man who likes to visit them. When Nil arrives as expected, Yegor shows him Vasilich’s satirical drawing, at which he is affronted. More plotting is in store when Yegor offers to pay Manefa, a fortune-teller, in his interest. Vasilich returns, suspecting Yegor as the cause of why his rich uncle now appears angry with him, at which Yegor pretends innocence. Nil’s friend, Krutitsky, is looking for a writer who will support conservative causes. Nil believes he knows the man for him: Yegor Glumov. Meanwhile, Glafira complains to Cleopatra Mamayeva that her son is liable to languish in obscurity, to which the latter says that women should enlist their husbands to help him out. When Glafira mentions how much he admires his uncle and aunt, Cleopatra is enthused. “Let us love him together,” she says. After his mother leaves, Yegor himself shows up, pretending to be shy as her aunt appears so young. She is intrigued and stipulates that a word from her should procure him a situation. To follow up his advantage, Yegor insinuates that he loves someone but is unable to declare who she is, at which his aunt is led to think it might be herself. She first asks an enterprising man, Gorodulin, whether a position may be obtained for this handsome young man. He answers positively and immediately requests him to write a speech for him. Equally impressed, Nil advises the apparently timid Yegor to flatter his wife more often, to which Yegor pretends to hesitate. Gorodulin returns to Cleopatra to say that in two weeks Yegor will have an appointment. Yegor is elated, Cleopatra anxious to know who his loved one is. “You,” he says falling on his knee. “I forgive you,” she responds while kissing his forehead. Masha Turusina is bored with her present life, requesting more freedom from her superstitious aunt, Sofia, inclined to be choosy as to her choice of husband. They receive the visit of Krutitsky, who speaks favorably of a man he has heard good things about: Yegor Glumov, followed by Gorodulin, also impressed by Yegor, and then Manefa, who, in the pay of Yegor, as if in an inspired trance, pronounces that a good choice of a husband might be ‘Yegor of a foreign shore’. To crown the piece, Nil introduces his nephew, Yegor himself, solemnly kissing Sofia’s hand. Still in pursuit of a conservative treatise, Krutitsky eagerly subscribes to Yegor’s ideas. After learning of Gorodulin’s promise of a post, Krutitsky promises him a better one. After Yegor leaves, Krutitsky informs Cleopatra of Yegor’s intention to marry Masha, which she finds impossible to believe, feeling ill at the thought. She rushes to Yegor’s house and, though he denies loving the heiress, she suspects the worst. She hides in the adjoining room as Golutvin shows up with evidence of some of Yegor’s tricks, requesting 25 roubles to keep quiet. But Yegor refuses. While ushering the tell-tale out, she discovers Yegor’s diary, containing a daily summary of his activities, and takes off with it. When Gorodulin learns of Yegor’s treatise on behalf of Krutitsky, he proposes to sign his name to Yegor’s attack against his own treatise. Meanwhile, Cleopatra encourages Vasilich to keep hoping in regard to Masha, with all the more reason when Sofia receives an envelope containing a satiric article against Yegor accompanied by his hand-written diary. She apologizes to her niece for trying to control her choice of a husband. “My choice has already been made, aunt,” Masha declares as Sofia turns to Vasilich. =Mikhail Saltykov-Shchedrin= [[File:Kramskoj - saltykov-schedrin.jpg|thumb|Saltykov-Shchedrin exposed the schemes of legacy hunters. Portrait of the author by Ivan Kramskoi (1837-1887), 1879]] Mikhail Saltykov-Shchedrin (1826-1889) continued the realist tradition with “Смерть Пазухина” (Pazukhin’s death, 1857). “Saltykov’s play returns to the ancient Roman theme of legacy-hunting, which has already proven to be fruitful for Ben Jonson. Indeed, in its indignant savagery, Shchedrin’s play has more than a little in common with ‘Volpone’: there is the same division of mankind into knaves and gulls, the same exuberant wielding of odd idioms and dialects, the same sarcastic belief that money makes the world go round and, if it doesn’t, ego does. But where Jonson feels the moral need to submit his villains to poetic justice, Saltykov, more jaundiced, lets the big fish eat the little fish and swim victoriously away…The town’s panorama of vice can range from the Pecksniffian hypocrisy of State Councilor Furnachyov, who finds legal camouflage for his thefts, to Prokofy Pazukhin, whose conversion to a fundamentalist creed cannot withstand the temptations of a rich inheritance, to a variegated assortment of hangers-on and dependents whose only social adhesive is greed” (Senelick, 1997 pp 16-17). ==“Pazukhin’s death”== [[File:Luzhsky Lobastov.jpg|thumb|Played by Vasily Luzhsky (1869-1931) in the 1916 Moscow Art Theatre production, General Andrei Lobastov intends to take away the Pazukhin family fortune from the son and heir]] Time: 1857. Place: Fictional city of Krutogorsk, Russia. Text at ? Prokofy Pazukhin is frustrated because his rich father, Ivan, has disowned him because he grew a beard and married against his wishes, a second marriage to Vasiliva’s daughter, Mavra. Prokofy requests his father’s friend, General Andrei Lobastov, to help him in his need. General Lobastov informs Prokofy that his father is near death and that he was sent for because of his intention to make up his will. When Andrei arrived, Semyon Furnachyov, a state councilor, and Gavrilo, Prokofy’s son, were already there. But Ivan threw the unsigned will on Semyon’s face, claiming to be able to outlive them all. Andrei promises to help Prokofy provided he agrees to a marriage between Gavrilo and his 31-year old crippled daughter, Lenochka, and that she obtain one third of the Pazukhin fortune. Prokofy agrees but haggles till he gets it down to one fourth. Prokofy’s musings are interrupted by retired second lieutenant Fyodor Zhivnovsky, who contradicts Andrei’s version of his visit to Ivan’s bedside by stating that he himself witnessed the signing of the will. “Part of the estate, says he, goes to my grandson, Gavrilo,” Fyodor announces, “part to my beloved daughter, Nastasya Ivanovna, part to be used to erect cathedrals to God, and to my beloved son, Prokofy Ivanych, l leave my paternal blessing.” Along with her husband, Semyon, Nastasya sympathizes with the troubles of Anna Petrovna, Ivan’s housekeeper and mistress since the age of 15, who, like Prokofy, might receive nothing after her master’s death. With his wife out of hearing, Semyon proposes that Anna obtain a waxen impression of the lock on Ivan’s strongbox. Despite her fears, Semyon takes her agreement for granted and receives the visit of Prokovy, still convinced that the will is unsigned, who proposes that in exchange for 150,000 roubles, Semyon prevent his father from signing it. Semyon refuses and, in front of his own father, reveals Prokovy’s attempt at bribery. “Begone, my good sir,” Semyon sententiously orders, “and remember that virtue is as honorable and praiseworthy as vice is ignoble and indecent.” Andrei succeeds in finding out from the still fearful Anna about the plan to pick Ivan’s strongbox, proposing to divide the spoils between the three of them. Meanwhile, before an infirm Ivan ensconced in his chair, Lenochka announces that Gavrilo appears uninterested in her. Despite Anna’s pleas to shut him out, a beardless Prokofy appears contrite before his father, who accepts the suggestion that his son visit him more often, alongside his wife, provided that she comes at night when no one is around. These pleasant feelings between father and son are disrupted by the arrival of Semyon, who reminds Ivan of Prokofy’s attempt at bribery, so that the irate father flings his cane at his son and orders him out. Late at night, Anna sends word to Semyon and Andrei that her master is dying, but Ivan’s mentor, Finagei Gayev, learns of the message and ushers in Prokovy, who hides in a store-room and overhears her tell Andrei that her master is dead and of their plan to steal the strongbox. Prokovy appears alongside Fyodor and Trofim and watches Andrei enter the dead man’s room. By peeking through the key-hole, he observes Andrei stuff his pockets with the strongbox’ contents. When Andrei comes back out, Prokovy orders Fyodor and Trofim to frisk the thief’s bulging pockets and then calls for Mavra and Nastasya as witnesses to his shame. He then requests the thief to sign a paper admitting his deed. =Aleksey Pisemski= [[File:Перов Писемский.jpg|thumb|Alexsey Pisemski exposed troubles that arise when a woman commits adultery with her master. Portrait of the author by Vasily Perov (1833-1882), 1862]] In addition to Tolstoy’s peasant drama laden with crime, Alexsey Pisemski (1821-1881) contributed an earlier one fraught with similar intensity: "Горькая судьбина" (A bitter fate, 1859). "A bitter fate" "is a genuine tragedy at supreme logical unity which is the great characteristic of the plays of Racine. The subject, like those of Racine, is simple, almost geometrical. A squire, a weakling of the Hamlet, idealist type, has seduced, in the absence of her husband, the wife of one of his serfs. The husband is a strong character of the type that occurs in Pisemsky’s and Leskov’s popular stories. Though a serf, he is a prosperous tradesman and has made money in Petersburg. He returns home (this is the initial situation) and by degrees discovers the guilt of his wife and reacts accordingly. The squire is the master of the husband, while the husband is the master of his wife- so it is a conflict between, on the one hand, the squire’s rights as a serf owner and the dignity of his serf; on the other, between the rights of free love (an essential point is that the squire and the serf’s wife do love each other) and the rights of the master of the house over his wife. The double conflict is unfolded with supreme mastery, and the spectator’s sympathy is held in balance between the rights of human dignity and the rights of free love. The tragedy ends in the husband’s killing the lovers’ child and then (a trait particularly praised by Russian critics but suggested to Pisemsky by the actor Martynov) delivering himself into the hand of the law" (Mirsky, 1949 pp 240-241). “Of the three protagonists of the play, Anany, Lizaveta, and Cheglov, it is Anany who occupies the central place. He is a truly tragic figure and, like so many of Shakespeare's characters, he carries the seeds of his tragedy within himself. If Othello's tragedy springs from his jealousy and that of Richard III or Macbeth from unbridled ambition, Anany's tragedy is the result of excessive pride. It is not by chance that a critic compared him precisely with a memorable character from Shakespeare and called him ‘King Lear of the peasant kingdom’...Anany is observed through the eyes of other characters placed against different backgrounds. Thus, he is discussed by his mother-in-law and her friend who sympathize with him, by his wife who bitterly resents him, by the bailiff who holds a grudge against him, and finally by police officials to whom he is just another criminal...The scene where the husband and lover, serf and master, face other is one of the most striking in the play. The result of this encounter is a complete misunderstanding, which eventually leads to the tragic climax. Cheglov unwittingly does and say wrong things, for Anany, by virtue of his very character, cannot appreciate Cheglov's good intentions. Cheglov’s assurances that Lizaveta never loved Anany, which he makes in the presence of the bailiff, only aggravate Anany's annoyance with his wife, for it is loyalty and obedience and not love which in Anany’s moral code is the primary factors of marriage...As in classical tragedy, in this play there is a presentiment of doom from the very early scenes, which is intensified by the absence of sub-plots or comic interludes. Nothing is irrelevant to the main course of the story, every remark is linked with a further remark or resolved finally in some action. It is significant that throughout the drama, its central figure, Anany, is either on the stage himself, or the subject of conversation, and always present in the mind of the reader or spectator” (Jenkins, 1958 pp 82-85). ==“A bitter fate”== [[File:Strepetova_as_Elizabeth_by_Repin.jpg|thumb|As played by Pelageya Antipevna Strepetova (1850-1903) depicted in a 1881 painting by Ilya Repin (1844–1930), Lizaveta is overwhelmed with troubles]]‎ Time: 1850s. Place: Sokovina, Russia. Text at ? While Anany Yakovlich has been away as a merchant for business purposes to St Petersburg, his wife, Lizaveta, entered into an adulterous relation with their master, Squire Cheglov, and has borne him a baby. As Anany returns to his home along with an old laborer, Uncle Nikon, the two argue over technological discoveries and who is the most valuable, a merchant or a laborer, until the latter, angry at being contradicted, insinuates that his companion is a cuckold. When Anany confronts his wife with this rumor, she bends her head. “There is no reply I can make,” she says. ‘”You can do to me whatever you please.” But then she proffers some excuses. “I didn’t want to do it, but then they gave me all sorts of orders and commands and I couldn’t disobey,” she says. But Anany dismisses these. To avoid disgrace, he opts to pretend that nothing has happened and that the baby is his. On leaning of the cuckold’s return, Cheglov is tormented about what will happen to Lizaveta and his baby, leading him to drink excessive amounts of vodka. In contrast, his friend, Sergey Zolotilov, considers that there is little cause to worry, suggesting that he raise the baby in his house. “I am also convinced,” Sergey adds, “that this woman encourages you in this unfortunate weakness, because it is easier to fish in troubled waters.” The bailiff, Kalistrat, brings her over with the news that Anany behaves awfully. Indeed, she enters tentatively to announce that Anany stares at her like a wild beast, “as if he were trying to kill me with his look,” she adds. As she scampers off, the bailiff leads her husband in. Cheglov offers Anany money, but he refuses. He wants to bring his wife and baby to St Petersburg, but Cheglov refuses. Cheglov next proposes a duel, but Anany declines that solution as well. “Our blood is worthless next to a gentleman’s,” he declares. The squire can only command Kalistrat to watch over Lizaveta day and night. At Anany’s house, Kalistrat leads a group of peasants and a deputy to protect Lizaveta and to judge the husband, because is unable to control him. The peasants are bewildered, want to be left alone, and wish her to the devil. “My axe is very sharp,” Anany warns. “Bind him with ropes for me,” Kalistrat commands, “and set the wife free.” Anany further warns them that he will punish his wife before their very faces. “You’ve ruled over me long enough,” Lizaveta declares. “I was carried off in the bridal sledge almost bound. I’d rather have thrown away my innocence to a bandit in the forest than to him.” Admitting she is the squire’s mistress, she collects her clothes, aiming to be taken to him. “I won’t give you the baby,” Anany states. When she advances to take the baby away, Anany splits his skull and escapes as the peasants run after him. As a result, Kalistrat is interrogated by the district police chief and a lawyer. In an attempt to prevent the squire knowing about the escape, the bailiff bribes the two men with 150 roubles. They try to interrogate Lizaveta’s mother, Matrena, but soon let her go as she babbles in fright. The two men are joined by Shpringel, the government official, and interrogate Uncle Nikon, but he is drunkenly incoherent. They receive news that Anany has been captured. Sergey tries to prevent the legal procedures, but they urge Anany forward. However, he gives little information, keeping silent as to who cuckolded him as a throng of peasants enter, including the sobbing Lizaveta. Nikon avers that she committed adultery with the squire, but Anany keep silent despite Shpringel’s protest that he may receive a lighter sentence in that case. Shpringel rises to see the governor, convinced of the existence of collusion among both officials and peasants. Still seeking to protect Cheglov, Sergey intends to counteract this move. “You can’t give over a noblemen, bound hand and foot, to any young puppy,” he decrees. {{BookCat}} 7e8u708m7xywf35txvztopqodjlpm00 User:Jimmy Pitt 2 245219 4668993 1996443 2026-09-05T19:05:20Z ShakespeareFan00 46022 4668993 wikitext text/x-wiki <div style="font-size:85%; vertical-align:top; background:#E0E8EF;{{Text default color}}; border:1px solid #E0E8EF; {{{style|margin-bottom:4pt; padding:2pt; margin-top:4pt; padding-top:2pt}}}; text-align:center;"> <div style="padding:0 .3em 0;">Unified login: '''Jimmy Pitt''' is the [[m:Help:Unified login|unique login]] of this user for all public [[wmf:Our projects|Wikimedia projects]]. </div> </div> {{userpage}} {{Babel|en|es-1|fr-1}} qb79wdonay0efa7wk78amjz3472rlzu User:Wd930/EnergyHampsterLaboratory/Periodic table 2 246039 4669018 2007605 2026-09-05T19:33:24Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669018 wikitext text/x-wiki <onlyinclude>{| border="0" cellpadding="0" cellspacing="1" style="width:80%; background:#f7f7e9;{{Text default color}}; {{{1|}}} border:1px solid #a9a9a9; margin-left: auto; margin-right: auto;" |- style="background-color:#e9e955;{{Text default color}};" ! scope="col" style="width: 1.0%;" | [[Periodic table group|Group]]&nbsp;# ! scope="col" style="width: 5.5%;" | [[Alkali metal|1]] ! scope="col" style="width: 5.5%;" | [[Alkaline earth metal|2]] ! scope="col" style="width: 5.5%;" | [[Group 3 element|3]] ! scope="col" style="width: 5.5%;" | [[Group 4 element|4]] ! scope="col" style="width: 5.5%;" | [[Group 5 element|5]] ! scope="col" style="width: 5.5%;" | [[Group 6 element|6]] ! scope="col" style="width: 5.5%;" | [[Group 7 element|7]] ! scope="col" style="width: 5.5%;" | [[Group 8 element|8]] ! scope="col" style="width: 5.5%;" | [[Group 9 element|9]] ! scope="col" style="width: 5.5%;" | [[Group 10 element|10]] ! scope="col" style="width: 5.5%;" | [[Group 11 element|11]] ! scope="col" style="width: 5.5%;" | [[Group 12 element|12]] ! scope="col" style="width: 5.5%;" | [[Boron group|13]] ! scope="col" style="width: 5.5%;" | [[Carbon group|14]] ! scope="col" style="width: 5.5%;" | [[Nitrogen group|15]] ! scope="col" style="width: 5.5%;" | [[Chalcogen|16]] ! scope="col" style="width: 5.5%;" | [[Halogen|17]] ! scope="col" style="width: 5.5%;" | [[Noble gas|18]] |- ! scope="col" | [[Periodic table period|Period]] | colspan="18" | <br /> |- ! scope="row" | [[Period 1 element|1]] | {{element cell| 1|hydrogen |H |1.00794(7) |Gas |Nonmetals|Primordial}} | colspan="16" | <br /> | {{element cell| 2|helium |He|4.002602(2) |Gas |Noble gases|Primordial}} |- ! scope="row" | [[Period 2 element|2]] | {{element cell| 3|lithium |Li|6.941(2) |Solid|Alkali metals|Primordial}} | {{element cell| 4|beryllium |Be|9.012182(3) |Solid|Alkaline earth metals|Primordial}} | colspan="10" | <br /> | {{element cell| 5|boron |B |10.811(7) |Solid|Metalloids|Primordial}} | {{element cell| 6|carbon |C |12.0107(8) |Solid|Nonmetals|Primordial}} | {{element cell| 7|nitrogen |N |14.00674(7) |Gas |Nonmetals|Primordial}} | {{element cell| 8|oxygen |O |15.9994(3) |Gas |Nonmetals|Primordial}} | {{element cell| 9|fluorine |F |18.9984032(5) |Gas |Halogens|Primordial}} | {{element cell|10|neon |Ne|20.1797(6) |Gas |Noble gases|Primordial}} |- ! scope="row" | [[Period 3 element|3]] | {{element cell|11|sodium |Na|22.98976928(2)|Solid|Alkali metals|Primordial}} | {{element cell|12|magnesium |Mg|24.3050(6) |Solid|Alkaline earth metals|Primordial}} | colspan="10" | <br /> | {{element cell|13|aluminium |Al|26.9815386(8) |Solid|Poor metals|Primordial}} | {{element cell|14|silicon |Si|28.0855(3) |Solid|Metalloids|Primordial}} | {{element cell|15|phosphorus|P |30.973762(2) |Solid|Nonmetals|Primordial}} | {{element cell|16|sulfur |S |32.066(6) |Solid|Nonmetals|Primordial}} | {{element cell|17|chlorine |Cl|35.4527(9) |Gas |Halogens|Primordial}} | {{element cell|18|argon |Ar|39.948(1) |Gas |Noble gases|Primordial}} |- ! scope="row" | [[Period 4 element|4]] | {{element cell|19|potassium |K |39.0983(1) |Solid|Alkali metals|Primordial}} | {{element cell|20|calcium |Ca|40.078(4) |Solid|Alkaline earth metals|Primordial}} | {{element cell|21|scandium |Sc|44.955912(6) |Solid|Transition metals|Primordial}} | {{element cell|22|titanium |Ti|47.867(1) |Solid|Transition metals|Primordial}} | {{element cell|23|vanadium |V |50.9415(1) |Solid|Transition metals|Primordial}} | {{element cell|24|chromium |Cr|51.9961(6) |Solid|Transition metals|Primordial}} | {{element cell|25|manganese |Mn|54.938045(5) |Solid|Transition metals|Primordial}} | {{element cell|26|iron |Fe|55.845(2) |Solid|Transition metals|Primordial}} | {{element cell|27|cobalt |Co|58.933195(5) |Solid|Transition metals|Primordial}} | {{element cell|28|nickel |Ni|58.6934(2) |Solid|Transition metals|Primordial}} | {{element cell|29|copper |Cu|63.546(3) |Solid|Transition metals|Primordial}} | {{element cell|30|zinc |Zn|65.39(2) |Solid|Transition metals|Primordial}} | {{element cell|31|gallium |Ga|69.723(1) |Solid|Poor metals|Primordial}} | {{element cell|32|germanium |Ge|72.61(2) |Solid|Metalloids|Primordial}} | {{element cell|33|arsenic |As|74.92160(2) |Solid|Metalloids|Primordial}} | {{element cell|34|selenium |Se|78.96(3) |Solid|Nonmetals|Primordial}} | {{element cell|35|bromine |Br|79.904(1) |Liquid|Halogens|Primordial}} | {{element cell|36|krypton |Kr|83.80(1) |Gas |Noble gases|Primordial}} |- ! scope="row" | [[Period 5 element|5]] | {{element cell|37|rubidium |Rb|85.4678(3) |Solid|Alkali metals|Primordial}} | {{element cell|38|strontium |Sr|87.62(1) |Solid|Alkaline earth metals|Primordial}} | {{element cell|39|yttrium |Y |88.90585(2) |Solid|Transition metals|Primordial}} | {{element cell|40|zirconium |Zr|91.224(2) |Solid|Transition metals|Primordial}} | {{element cell|41|niobium |Nb|92.90638(2) |Solid|Transition metals|Primordial}} | {{element cell|42|molybdenum|Mo|95.94(1) |Solid|Transition metals|Primordial}} | {{element cell|43|technetium|Tc|[97.9072] |Solid|Transition metals|Natural radio}} | {{element cell|44|ruthenium |Ru|101.07(2) |Solid|Transition metals|Primordial}} | {{element cell|45|rhodium |Rh|102.90550(2) |Solid|Transition metals|Primordial}} | {{element cell|46|palladium |Pd|106.42(1) |Solid|Transition metals|Primordial}} | {{element cell|47|silver |Ag|107.8682(2) |Solid|Transition metals|Primordial}} | {{element cell|48|cadmium |Cd|112.411(8) |Solid|Transition metals|Primordial}} | {{element cell|49|indium |In|114.818(3) |Solid|Poor metals|Primordial}} | {{element cell|50|tin |Sn|118.710(7) |Solid|Poor metals|Primordial}} | {{element cell|51|antimony |Sb|121.760(1) |Solid|Metalloids|Primordial}} | {{element cell|52|tellurium |Te|127.60(3) |Solid|Metalloids|Primordial}} | {{element cell|53|iodine |I |126.90447(3) |Solid|Halogens|Primordial}} | {{element cell|54|xenon |Xe|131.29(2) |Gas |Noble gases|Primordial}} |- ! scope="row" | [[Period 6 element|6]] | {{element cell|55|caesium |Cs|132.9054519(2)|Solid|Alkali metals|Primordial}} | {{element cell|56|barium |Ba|137.327(7) |Solid|Alkaline earth metals|Primordial}} | {{element cell|*|lanthanides| | |Solid|Lanthanoids|Undiscovered}} | {{element cell|72|hafnium |Hf|178.49(2) |Solid|Transition metals|Primordial}} | {{element cell|73|tantalum |Ta|180.94788(2) |Solid|Transition metals|Primordial}} | {{element cell|74|tungsten |W |183.84(1) |Solid|Transition metals|Primordial}} | {{element cell|75|rhenium |Re|186.207(1) |Solid|Transition metals|Primordial}} | {{element cell|76|osmium |Os|190.23(3) |Solid|Transition metals|Primordial}} | {{element cell|77|iridium |Ir|192.217(3) |Solid|Transition metals|Primordial}} | {{element cell|78|platinum |Pt|195.084(9) |Solid|Transition metals|Primordial}} | {{element cell|79|gold |Au|196.966569(4) |Solid|Transition metals|Primordial}} | {{element cell|80|mercury |Hg|200.59(2) |Liquid|Transition metals|Primordial|mercury (element)}} | {{element cell|81|thallium |Tl|204.3833(2) |Solid|Poor metals|Primordial}} | {{element cell|82|lead |Pb|207.2(1) |Solid|Poor metals|Primordial}} | {{element cell|83|bismuth |Bi|208.98040(1) |Solid|Poor metals|Primordial}} | {{element cell|84|polonium |Po|[208.9824] |Solid|Metalloids|Natural radio}} | {{element cell|85|astatine |At|[209.9871] |Solid|Halogens|Natural radio}} | {{element cell|86|radon |Rn|[222.0176] |Gas |Noble gases|Natural radio}} |- ! scope="row" | [[Period 7 element|7]] | {{element cell|87|francium |Fr|[223.0197] |Solid|Alkali metals|Natural radio}} | {{element cell|88|radium |Ra|[226.0254] |Solid|Alkaline earth metals|Natural radio}} | {{element cell|**|actinides | | |Solid|Actinoids|Undiscovered}} | {{element cell|104|rutherfordium|Rf|[264] |UnknownPhase|Transition metals|Synthetic}} | {{element cell|105|dubnium |Db|[265] |UnknownPhase|Transition metals|Synthetic}} | {{element cell|106|seaborgium |Sg|[266] |UnknownPhase|Transition metals|Synthetic}} |- | colspan="19" | <br /> |- ! scope="row" colspan="3" style="text-align: right; padding-right: 1em;" | * [[Lanthanoid]]s | {{element cell|57|lanthanum |La|138.90547(7)|Solid|Lanthanoids|Primordial}} | {{element cell|58|cerium |Ce|140.116(1) |Solid|Lanthanoids|Primordial}} | {{element cell|59|praseodymium|Pr|140.90765(2)|Solid|Lanthanoids|Primordial}} | {{element cell|60|neodymium |Nd|144.242(3) |Solid|Lanthanoids|Primordial}} | {{element cell|61|promethium |Pm|[144.9127] |Solid|Lanthanoids|Natural radio}} | {{element cell|62|samarium |Sm|150.36(2) |Solid|Lanthanoids|Primordial}} | {{element cell|63|europium |Eu|151.964(1) |Solid|Lanthanoids|Primordial}} | {{element cell|64|gadolinium |Gd|157.25(3) |Solid|Lanthanoids|Primordial}} | {{element cell|65|terbium |Tb|158.92535(2)|Solid|Lanthanoids|Primordial}} | {{element cell|66|dysprosium |Dy|162.500(1) |Solid|Lanthanoids|Primordial}} | {{element cell|67|holmium |Ho|164.93032(2)|Solid|Lanthanoids|Primordial}} | {{element cell|68|erbium |Er|167.259(3) |Solid|Lanthanoids|Primordial}} | {{element cell|69|thulium |Tm|168.93421(2)|Solid|Lanthanoids|Primordial}} | {{element cell|70|ytterbium |Yb|173.04(3) |Solid|Lanthanoids|Primordial}} | {{element cell|71|lutetium |Lu|174.967(1) |Solid|Lanthanoids|Primordial}} | <br /> |- ! scope="row" colspan="3" style="text-align: right; padding-right: 1em;" | ** [[Actinoid]]s | {{element cell|89|actinium |Ac|227.02700 |Solid|Actinoids|Natural radio}} | {{element cell|90|thorium |Th|232.03806(2)|Solid|Actinoids|Primordial}} | {{element cell|91|protactinium|Pa|231.03588(2)|Solid|Actinoids|Natural radio}} | {{element cell|92|uranium |U |238.02891(3)|Solid|Actinoids|Primordial}} | {{element cell|93|neptunium |Np|[237.0482] |Solid|Actinoids|Natural radio}} | {{element cell|94|plutonium |Pu|[244.0642] |Solid|Actinoids|Primordial}} | {{element cell|95|americium |Am|[243.0614] |Solid|Actinoids|Synthetic}} | {{element cell|96|curium |Cm|[242.1562] |Solid|Actinoids|Synthetic}} | {{element cell|97|berkelium |Bk|[248.4595] |Solid|Actinoids|Synthetic}} | {{element cell|98|californium |Cf|[248.8953] |Solid|Actinoids|Synthetic}} | {{element cell|99|einsteinium |Es|[252.9999] |Solid|Actinoids|Synthetic}} | {{element cell|100|fermium |Fm|[253.7698] |Solid|Actinoids|Synthetic}} | {{element cell|101|mendelevium|Md|[258.0984] |Solid|Actinoids|Synthetic}} | {{element cell|102|nobelium |No|[259.1011] |Solid|Actinoids|Synthetic}} | {{element cell|103|lawrencium |Lr|[263.0353] |Solid|Actinoids|Synthetic}} | <br /> |} 9k1waborglqlrq06u5eze25dhflyxhw User:German Lessons/Level I/Essen 2 247930 4668995 4644003 2026-09-05T19:08:38Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668995 wikitext text/x-wiki <br clear="all"> {|style="magin:0 auto;" | __TOC__ |} <big><big><big>Lesson I.6: Essen</big></big></big> ---- ==Dialogue== {| {{German table|Dialogue|I'm hungry!|Ich habe Hunger!|0|2}} !Franz |Hallo, Greta! Wie geht's? |- !Greta |Sehr gut. Ich bin hungrig. |- !Franz |Ich auch. Möchtest du etwas essen? |- !Greta |Ja! |- !||''In der Gaststätte'' |- !Greta |Ich möchte Salat, Brot und Wasser. |- !Franz |Hast du jetzt keinen Hunger? |- !Greta |Doch, ich habe großen Hunger. Was bekommst du? |- !Franz |Ich bekomme ein Stück Apfelstrudel und einen Eisbecher. |- !Greta |Warum das? Du sollst eine Bratwurst nehmen. |- !Franz |Nein, ich bin zufrieden. Ich habe keinen großen Hunger. |- !Greta |Ach so, dann ist das genug. |- !||''Nach zwanzig Minuten'' |- !Greta |Diese Gaststätte ist schrecklich! Ich möchte etwas zu essen! |- !Franz |Wir gehen! |} ==Food!== {| {{German table|Vocabulary|Food|die Nahrungsmittel (pl.)|0|4}} ! colspan=2 | die Früchte (das Obst) - fruits ! colspan=2 | das Gemüse - vegetables |- |die Banane||banana||die Möhre, die Karotte||carrot |- |die Kirsche||cherry||der Spinat||spinach |- |die Zitrone||lemon||die Zwiebel||onion |- |die Erdbeere||strawberry||die Erbsen||peas |- |die Orange||orange||die Kartoffel||potato |- |der Apfel||apple||die Tomate||tomato |- |die Traube||grape||der Spargel||asparagus |- |die Grapefruit||grapefruit||die Bohnen|| beans |- !colspan=2 | das Fleisch - meat !colspan=2 | die Meeresfrüchte - shellfish, seafood |- |das Lammfleisch||lamb||die Kammmuschel||scallop |- |der Truthahn||turkey||die Krabbe||crab |- |der Schinken||ham||die Garnele||shrimp |- |das Schweinefleisch||pork !colspan=2 | der Fisch - fish |- |das Hähnchen||chicken||die Sardellen||anchovies |- |das Rindfleisch||beef||der Lachs||salmon |- |die Wurst||sausage||der Aal||eel |- ! colspan=2 | die Milchprodukte - dairy products ! colspan=2 | Other Foods |- |die Butter||butter||die Suppe||soup |- |der Käse||cheese||die Fritten||French fries |- |die Milch||milk||die Pizza||pizza |- |der Joghurt||yogurt||der Hamburger||hamburger |- ! colspan=2 | die Nachspeise - dessert |der Senf||mustard |- |das Bonbon||candy||das Brot||bread |- |die Schokolade||chocolate||die Butter||butter |- |die Torte||tart||der Salat||salad |- |der Kuchen||cake||der Pfeffer||pepper |- |der Apfelstrudel||apple strudel||der Reis||rice |- |der (Apfel)Kuchen||(apple) pie||das Salz||salt |- |das Eis||ice cream||der Zucker||sugar |- |der Eisbecher||bowl of ice cream||die Konfitüre||jam |} <big>[[/Problems#Food!|Section Problems]] >></big> ==<span style="color: green;">Accusative Case</span>== As you know from the [[../Introduction|introduction]], in German, there are four cases. Three are used often. The first, <span style="color: blue;">'''Nominative Case'''</span>, you learned in [[../Wie heißt du?#Nominative Case|Lesson 1]]. It covers the [[w:Subject (grammar)|subject]], and the predicate noun (in "He is (noun).", (noun) is the predicate noun). The second, the <span style="color: green;">'''Accusative Case'''</span>, you will learn now. It covers the [[w:Direct object|direct object]] and the [[w:Preposition|object of several prepositions]]. The third, the <span style="color: red">'''Dative Case'''</span> will be taught later on. It covers the [[w:Indirect object|indirect object]] and the object of many other prepositions. The object of a sentence will be in accusative case. In, "You hurt me.", 'me' would be accusative. Note: The <span style="color: green;">'''Accusative Case'''</span> and <span style="color: red">'''Dative Case'''</span> are identical in English; that's why German has one case extra. ===Articles=== {| border="1" style="background-color: #99FF99;{{Text default color}}; width:50%" |- style="text-align:center;" | || <u>Masculine</u> || <u>Feminine</u> | <u>Neuter</u> || <u>Plural</u> |- style="text-align:center;" | Definite Article || '''den''' || die | das || die |- style="text-align:center;" | Indefinite Article || '''einen''' || eine | ein || -eine* |} <small>'''* The indefinite article for plurals is non-existent. However related words, such as possessives and the kein- words that you will learn later this lesson, will end in ''eine'' for plurals.'''</small> In the articles, the memory hook for accusative case is "Der goes to den (pronounced "dane" {{audio|De-den.ogg|audio}}) and the rest stays the same." The masculine indefinite article goes to ''einen'', and everything else stays the same there. Therefore above, ''der'' Hamburger goes to ''den'' Hamburger and ''ein'' Hamburger goes to ''einen'' Hamburger when the hamburger is the direct object, such as in "Er hat einen Hamburger." ("He has a hamburger.") If you are getting confused, it's fine. This topic is one of the hardest for English speakers to grasp. Here are some solutions: To find out the case of something, first find the verb. The verb rules the sentence. Everything revolves around it. Next you find the subject of the sentence. The subject is the thing/person that is ''doing'' the verb. '''The subject is always in the <span style="color: blue;">Nominative Case</span>, so it takes on the der, die, das, die, or ein, eine, ein.''' Now you look back at the verb. If it is a being verb (am, are, is, etc.), the next noun after the verb is the '''predicate noun'''. An easy way to figure this out is to write an equation. If the verb can be replaced with an equals sign (=), then the following noun is a predicate noun. If it can't be replaced by an equals sign, refer to the next paragraph. '''The predicate noun is also always in the <span style="color: blue;">Nominative Case</span>, so the same rules apply to it.''' <span style="color: blue;">Ich</span> bin <span style="color: blue;">'''ein''' Junge</span>. <span style="color: blue;">Sie</span> ist <span style="color: blue;">'''eine''' Frau</span>. If the verb of the sentence is an action verb (playing, throwing, making, eating), find what the subject is doing the verb to. For example, if the verb is "makes" (macht), you look for what is being made. That is the direct object. '''The direct object is always in the <span style="color: green;">Accusative Case</span>, so it takes on the den, die, das, die, or einen, eine, ein.''' <span style="color: blue;">Sie</span> haben <span style="color: green;">'''den''' Cheeseburger</span>. Habt <span style="color: blue;">ihr</span> <span style="color: green;">'''einen''' Salat</span>? The indefinite articles, when you just look at their endings, select e, -, e for nominative case, and en, e, -, e for accusative. Remember, between nominative and accusative, the only third-person change is in the masculine form. <big>[[/Problems#Articles|Section Problems]] >></big> ===Pronouns=== The pronouns experience a much bigger change than the articles. This is also true in English, as the articles (a, an, the) do not change ever, but ''I'' goes to ''me'', ''we'' goes to ''us'', etc. Not everything is the same, though. While ''me'' is ''mich'' and ''us'' is ''uns'', the second and third persons undergo different changes. In third person, as in the articles, the only change is in masculine singular. Following the "der goes to den" rule, ''er'' goes to ''ihn'' when in the accusative case. The second person in English never changes. In German, ''du'' goes to ''dich'' and ''ihr'' goes to ''euch''. ''Sie'', the formal version of either, stays the same. Remember, ''Sie'' (2nd person formal) and ''sie'' (3rd person plural) only differ in their meanings and the fact that the former is capitalized and the latter is not. This stays true throughout German grammar. Here is a tabular representation of the above. {| border="1" style="background-color: #99FF99;{{Text default color}}; width:50%;" |- style="text-align:center;" | Person || colspan="2" | '''Singular''' | | colspan="2" | '''Plural''' |- style="text-align:center;" | || <u>English</u> || <u>German</u> || || <u>English</u> | <u>German</u> |- style="text-align:center;" | 1st || me || ''mich'' || || us | ''uns'' |- style="text-align:center;" | 2nd || you || ''dich'' || || you (all) | ''euch'' |- style="text-align:center;" | 3rd || him, her, it || ''ihn, sie, es'' | || them || ''sie'' |} <big>[[/Problems#Pronouns|Section Problems]] >></big> ===Antecedents=== Note: ''This is just a quick lesson in English grammar applied into German. If you already know all about antecedents in English, skip the first paragraph.'' When using a pronoun, you have to know what it is for it to work. There are some rare exceptions, such as in mysteries or drama, but otherwise this is always true. Sometimes in dialogue this is taken care of by pointing or making some other gesture, but most of the time, the pronoun modifies something already mentioned. '''The object/person mentioned earlier that turns into a pronoun later is called the antecedent.''' In German this is very useful. You can't simply say 'it' anymore. Many food words are masculine and feminine, and when you turn them into pronouns, they turn into 'he', 'she', 'him', and 'her', not always 'it'. For example, the sentence "The cheeseburger tastes good. It's very crunchy." turns into "The cheeseburger tastes good. ''He's'' very crunchy." Note: You will learn how to say this in German later in this lesson. Why is it "he"? This is where the antecedent comes in. Because there are foods that are masculine and feminine in German, you can't assume the 'es'. You have to look back at the previous sentence, at the antecedent, ''der Cheeseburger''. "Der Cheeseburger" is replaced by ''er'' (since it is the subject, and therefore in Nominative Case). Therefore, all you need to know are these connections: der/den-er/ihn, die-sie, das-es, die-sie. <big>[[/Problems#Antecedents|Section Problems]] >></big> ==Food-Related Verbs== * ''essen (I)'' - to eat, to be eating, to do eat * ''trinken'' - to drink, to be drinking, to do drink * ''bekommen'' - to get/receive, to be getting/receiving, to do get/receive * ''möchten (M)'' - would like * ''wollen (M)'' - to want, to be wanting, to do want Of these five verbs, only trinken and bekommen are regular. Essen is ''irregular'' (that's what the "I" means). Do you remember from the last lesson 'lesen' and 'sehen'? In both of them, the first 'e' changed to 'ie' in the du- and er/sie/es-forms. Well ''essen'' experiences the same change, except that it changes to 'i', not 'ie'. Also, it acts the same as 'lesen' in the du-form: You don't have three s's in a row. {| border="1" style="background-color: #FFFF66;{{Text default color}}; width:50%" |- style="text-align:center;" | <u>Person</u> || colspan="2" | <u>Singular</u> | | colspan="2" | <u>Plural</u> |- style="text-align:center;" | '''1st''' || ich || ''esse'' || || wir | ''essen'' |- style="text-align:center;" | '''2nd''' || du || ''isst'' || || ihr | ''esst'' |- style="text-align:center;" | '''3rd''' || er/sie/es || ''isst'' | || sie || ''essen'' |} ''Isst'' sounds and looks a lot like ''ist''. The minute difference happens to be in the way you pronounce the ''s''. When you mean ''eats'' it is sometimes an overstressed hissing (i.e. extremely sharp) sound. In normal life Germans, too, can only tell which verb is meant from knowing the context. Just like in last lesson, where you could say, ''"Ich spiele gerne Fußball."'', you can also extend it to food. "I like to eat cheeseburgers." is translated as ''"Ich esse gerne Cheeseburger."'' Before [[w:German spelling reform of 1996|1996]], the usage of ''ißt'' and ''eßt'' were common, but the new reform rules specify that these spellings are now the only correct spellings. The last two verbs (marked ''(M)'') are ''modals''. They will be discussed in the next section. <big>[[/Problems#Food-Related Verbs|Section Problems]] >></big> ==Modals== In [[../Introduction|the introduction]], you learned that German has no helping verbs. Instead, they have '''modals''', words that basically do the same thing. Modals are conjugated very differently from normal verbs. The ich- and er/sie/es-forms are always the same, while the du-form adds an 'st'. Most modals experience a vowel change from singular to plural, and the rest is the same. ===Möchten=== 'Möchten' isn't technically a modal, but it acts exactly the same. There is no vowel change, and the ich- and er/sie/es forms are "möchte". Here is the complete conjugation: {| border="1" style="background-color: #FFFF66;{{Text default color}};; width:50%" |- style="text-align:center;" | <u>Person</u> || colspan="2" | <u>Singular</u> | | colspan="2" | <u>Plural</u> |- style="text-align:center;" | '''1st''' || ich || ''möchte'' || || wir | ''möchten'' |- style="text-align:center;" | '''2nd''' || du || ''möchtest'' || || ihr | ''möchtet'' |- style="text-align:center;" | '''3rd''' || er/sie/es || ''möchte'' | || sie || ''möchten'' |} 'Möchten' means "would like" and can be applied to food (i.e. Ich möchte einen Cheeseburger.). Möchten can be translated even more literally as "would like to", and is traditionally used with an infinitive verb at the end of the sentence (i.e. "Ich möchte jetzt gehen"/"I would like to go now"). However, this infinitive is not neccesary if it's completely obvious what you're talking about (If you say "Ich möchte einen Cheeseburger", everyone will assume that you would like a cheeseburger to eat.) (Note: ''Technically, "möchten" is not a word. The above cited conjugation is actually the "Konjunktiv" of "mögen", which has become so popular as a phrase, that even many Germans today aren't aware of it anymore, so you don't need to worry about it. "Etwas mögen" means "to like to", and "I would like" is the closest translation of "ich möchte."'') ===Wollen=== 'Wollen' is a true modal; it even changes vowels. Ich/er/sie/es ''will'' and du ''willst''. Here is the complete conjugation: {| border="1" style="background-color: #FFFF66;{{Text default color}}; width:50%" |- style="text-align:center;" | <u>Person</u> || colspan="2" | <u>Singular</u> | | colspan="2" | <u>Plural</u> |- style="text-align:center;" | '''1st''' || ich || ''will'' || || wir | ''wollen'' |- style="text-align:center;" | '''2nd''' || du || ''willst'' || || ihr | ''wollt'' |- style="text-align:center;" | '''3rd''' || er/sie/es || ''will'' || || sie | ''wollen'' |} 'Wollen' can also be applied to food, but may be considered impolite and demanding ("Ich will einen Cheeseburger!" roughly means "I demand a cheeseburger!" ''Möchten'' should be used instead: "Ich möchte einen Cheeseburger!" = "I want a cheeseburger!"). 'Wollen' should not be confused with the future tense, despite the presence of the English word 'will' in the conjugations. However, [[Wiktionary:will|will]] can also mean an intent or a document showing what one ''wants'' to happen. So it is not so different from 'to want' as possibly originally presumed. ===Modals with other verbs=== '''This is very important.''' When you need to use another verb with a modal (such as expressing you would like or want to perform an action), the sentence's word order is somewhat different than it would be in English. In English, you would state the subject pronoun (such as "I"), an English equivalent to the modal verb (such as "want"), the action you want to perform (such as "to eat") and then what the action will be performed on (such as "hamburger"), making the sentence "I want to eat a hamburger." In German you must put the action at the end of the sentence, making the sentence "I want a hamburger to eat." (''"Ich will einen Hamburger essen."'') <big>[[/Problems#Modals|Section Problems]] >></big> ==Hunger and Thirst== In German, instead of saying, "I'm hungry.", you say "I have hunger." The same applies to thirst. Here are the German translations of the corresponding nouns: Hunger - der Hunger Thirst - der Durst Like in English, these two words do not have a plural form. When using them, you don't need to worry about the 'der'; you can just say, "Ich habe Hunger." to say "I am hungry." <big>[[/Problems#Hunger and Thirst|Section Problems]] >></big> ==Formal Conversations== In [[../Wie heißt du?|Lesson 1]], you learned how to talk formally, using phrases like "Guten Morgen!" and "Wie heißen Sie?". There are, however, a few words that are 'survival words' in Germany, specifically: '''Danke''' - Thank you, Thanks '''Bitte''' - Please ''and'' You're welcome. To make this even more formal, you can tack on the word 'schön' to the end of "Thank you" and "You're welcome" to make 'dankeschön' and 'bitteschön' (both one word) in response. 'Schön' literally means 'pretty' (you'll relearn this next lesson). '''Some other ways to say "thank you":''' * Dankeschön - Thank you very much * Danke sehr - Thanks a lot * Herzlichen Dank ("herzlichen" means sincere or from the heart; you may remember it from "<u>Herzlichen</u> Glückwunsch zum Geburtstag!" last lesson) * Vielen Dank - Thanks a lot * Tausend Dank* - Thanks a million (literally meaning a thousand, but English is more generous) * Aufrichtigen Dank* - would be "thank you sincerely" (''very'' formal) <small>* - You will not be tested on these phrases.</small> '''Some other ways to say "You are welcome":''' * Bitteschön! * Bitte sehr! * Gern geschehen! - Don't mention it * Gerne! - also meaning "gladly" * Kein Problem! - No problem * Dafür nicht!* - (Do) not (thank me) for this (only used in Northern Germany) <small>* - You will not be tested on this phrase.</small> These might also be useful: '''Entschuldigung''' - Excuse me, Pardon '''Es tut mir leid''' - Sorry, I'm sorry <big>[[/Problems#Formal Conversations|Section Problems]] >></big> ==Kein-words== Twice you have been taught that the ending of the indefinite article for plurals ''would be'' eine (for Nominative and Accusative cases), if there was an indefinite article for plurals. Now that lesson applies. The '''k'''ein-words have the same endings as the ein-words, and they mean the opposite: no, not any, none. For example, "kein Cheeseburger" means "no cheeseburger". "Keine Cheeseburger" (in this case Cheeseburger is plural) means "No cheeseburger'''s'''". Notice the 'e' at the end of 'keine'. That's the ending for plurals and feminine nouns and can be likened to the "der, die, das -> die" relationship, where the feminine article serves for the plural as well. <big>[[/Problems#Kein-words|Section Problems]] >></big> ==Ordering at a Restaurant in Germany== das Restaur'ant' (French pronunciation)<!--Gaststätte is older German and somewhat "deprecated"--> - Restaurant {{Audio|Fr-Restaurant.ogg}} There are many restaurants you might find in Germany. Much like in English-speaking countries, you would more likely use the name of the restaurant than name what kind of restaurant. If you want to address the wish to eat a certain food, there are two ways: example: "wanting to eat chinese food" 1. "Ich möchte gerne zum Chinesen." - literally: "I want to go to the Chinese (restaurant)." 2. "Ich möchte gerne chinesisch essen (gehen)." - literally: "I want to (go) eat Chinese (style food)." Here are some more restaurants you can find in Germany: * American food: "zum Amerikaner" / "amerikanisch essen"* * Arabic food: "zum Araber" / "arabisch essen" * Chinese food: "zum Chinesen" / "chinesisch essen" * French food: "zum Franzosen" / "französisch essen" * Greek food: "zum Griechen" / "griechisch essen" * Italian food: "zum Italiener" / "italienisch essen" * Indian food: "zum Inder" / "indisch essen" * Japanese food: "zum Japaner" / "japanisch essen" * Mexican food: "zum Mexikaner" / "mexikanisch essen" * Spanish food: "zum Spanier" / "spanisch essen" * Turkish food: "zum Türken" / "türkisch essen" <small>* "zum Amerikaner" is often used in a jokey way, to express that one is going to either McDonald's or Burger King. There are few American restaurants, in Germany and they are mostly referred to as "(American) Diner", so it is not used like "zum Italiener".</small> ==Accusative case prepositions== You read at the beginning of this lesson that the <span style="color: green;">'''Accusative Case'''</span> covers the direct object and the objects of some prepositions. Here are those prepositions that always fall under Accusative Case ''bis'' - until ''durch'' - through ''entlang'' - along ''für'' - for ''gegen'' - against ''ohne'' - without ''um'' - at, around You learned ''um'' last lesson, and ''ohne'' earlier this lesson. ''Bis'', ''durch'', ''entlang'' and ''gegen'' will be taught in depth later, and ''für'' will be taught now. Up until this point, you have only worried about the Accusative Case in third person. ''Für'', meaning 'for', can and should be used in the first and second persons, too. Here's an example: "The cheeseburger is for me." - "Der Cheeseburger ist ''für mich''." As you can see, 'me' is put into accusative case because the preposition is ''für''. <big>[[/Problems#Accusative case preparations|Section Problems]] >></big> ==Saying How Food Tastes== In German (as in English) there are several ways of telling how food tastes. You can do this with 'gut' and 'schlecht' from [[../Wie heißt du?|Lesson 1]] to say: '''Der Cheeseburger schmeckt gut - The cheeseburger tastes good''' '''Der Cheeseburger schmeckt schlecht - The cheeseburger tastes bad''' But this is bland. Hopefully the food has more flavor than the description of it. You can use the following words to more colorfully describe how the cheeseburger tastes: * delicious - ''lecker'' * delicious - ''delikat''* (a lot more formal than lecker) * tasty - ''schmackhaft'' * juicy - ''saftig''* * crunchy - ''knackig'' (can also mean ''crispy'') * crispy - ''knusprig''* * spicy - ''würzig'', ''pikant'' * stale, tasteless - ''fade''* (Austria: fad) * salty - ''salzig'' * oversalted - ''versalzen''* * sweet - ''süß'' * bitter - ''bitter'' * sour - ''sauer'' * creamy - ''cremig''* * hot (in the sense of "very spicy") - ''scharf'' - literally meaning "sharp" * hot (in the sense of "very warm") - ''heiß'' * burnt - ''angebrannt''* * cold - ''kalt'' * disgusting, terrible - ''schrecklich'' <small>* - You will not be tested on these descriptors.</small> '''Schmecken''' is a regular verb. Here is it's conjugation: {| border="1" style="background-color: #FFFF66;{{Text default color}}; width:50%" |- style="text-align:center;" | <u>Person</u> || colspan="2" | <u>Singular</u> || || colspan="2" | <u>Plural</u> |- style="text-align:center;" | '''1st''' || ich || ''schmecke'' || || wir | ''schmecken'' |- style="text-align:center;" | '''2nd''' || du || ''schmeckst'' || || ihr | ''schmeckt'' |- style="text-align:center;" | '''3rd''' || er/sie/es || ''schmeckt'' | || sie || ''schmecken'' |} The first and second persons really shouldn't be used. No one is going to say, "You guys taste salty" or "I taste creamy." So the only forms you ''really'' need to know are er/sie/es ''schmeckt'' and sie (plural) ''schmecken''. You can use 'schmeckt' and 'schmecken' or 'ist' and 'sind' to state how the food tastes. Just use whichever one you would use in English and it'll usually be correct. Although the English meaning of ''schmecken'' is simply ''to taste'', ''"Schmeckt der Cheeseburger?"'' can be taken in a positive way to mean "Do you like the cheeseburger?". In other words, ''schmecken'' alone can mean ''to taste good''. <big>[[/Problems#Saying How Food Tastes|Section Problems]] >></big> ==Dieser-forms== "''The'' cheeseburger tastes good." does not sound that specific as to which cheeseburger you are talking about. You could be talking about a cheeseburger that is not directly in front of you. It just isn't clear. Now, if you said, "''This'' cheeseburger tastes good.", it would be obvious that you're talking about the cheeseburger you're eating. 'Dieser' is the German translation for 'this': "Dieser Cheeseburger schmeckt gut." ===Dieser=== 'Dieser' is a special adjective. It changes forms in different situations: different genders and different cases. It can also mean 'these' when modifying a plural. Here are its forms: {| border="1" style="background-color: #99FF99;{{Text default color}}; width:50%" |- style="text-align:center;" | || <u>Masculine</u> || <u>Feminine</u> | <u>Neuter</u> || <u>Plural</u> |- style="text-align:center;" | Nominative Case || dies'''er''' || dies'''e''' | dies'''es''' || dies'''e''' |- style="text-align:center;" | Accusative Case || dies'''en''' || dies'''e''' | dies'''es''' || dies'''e''' |} As you can see, ''dieser'' is only appropriate for modifying masculine nouns in nominative case. But 'Cheeseburger', which is masculine, is the subject of the sentence, "Dieser Cheeseburger schmeckt gut." So it is correct in that circumstance. ===Jeder=== ''Jeder'' means 'every'. It acts exactly like 'dieser' in its endings, so it should be easy to remember. Here are the different forms: {| border="1" style="background-color: #99FF99;{{Text default color}}; width:50%" |- style="text-align:center;" | || <u>Masculine</u> || <u>Feminine</u> | <u>Neuter</u> |- style="text-align:center;" | Nominative Case || jed'''er''' || jed'''e''' | jed'''es''' |- style="text-align:center;" | Accusative Case || jed'''en''' || jed'''e''' | jed'''es''' |} Notice the absence of the plural form. When you think about this, it's the same in English: no one says 'every books'. ===Welcher=== 'Welcher' is the third of this threesome of adjectives. 'Welcher' means 'which' and is used like the other [w:Interrogative word|interrogatives] (wer, was, wann, wo, warum, wie, and welcher). However, because the general subject has to be specified, ''welcher'' must be inflected before use: "Welcher Hamburger ist seine?" Its forms have the same endings as 'dieser'. {| border="1" style="background-color: #99FF99;{{Text default color}}; width:50%" |- style="text-align:center;" | || <u>Masculine</u> || <u>Feminine</u> | <u>Neuter</u> || <u>Plural</u> |- style="text-align:center;" | Nominative Case || welch'''er''' || welch'''e''' | welch'''es''' || welch'''e''' |- style="text-align:center;" | Accusative Case || welch'''en''' || welch'''e''' | welch'''es''' || welch'''e''' |} ===Connection with Time=== You might want to say 'every day', 'this week', 'every morning', or 'which Tuesday night?'. But to do this, not only do you need to know the jeder-forms, but also the genders of the times and the cases. The second one is easy: '''Whenever you do something at a certain time, that time is put into <span style="color: green;">Accusative Case</span>.''' Last lesson, you learned the gender of one time: ''der'' Tag. So now you know everything to say 'diesen Tag', 'jeden Tag', and 'welchen Tag?' (this day, every day, and which day?). Here are the cases of all the times in [[../Freizeit|Lesson 2]]: {| border="1" style="width:50%" |- style="text-align:center;" | <u>Masculine</u> || <u>Feminine</u> || <u>Neuter</u> |- style="vertical-align:top;" | * Tag * Monat * Morgen * Abend * Nachmittag | * Woche * Nacht | * Jahr * Wochenende |} When extending to 'which Tuesday night?', remember that the night stays feminine on Tuesday, so it stays "Welche Dienstagnacht?". Likewise, you can say 'every June' the same as 'every month': 'jeden Juni'. ===This and That=== ''Ich möchte einen Cheeseburger. Der schmeckt sehr gut.'' ''Ich esse jeden Tag Cheeseburger. Die habe ich gern.'' Look at the second sentence of each of these German dialogues. What's missing? That's right, instead of "Der Cheeseburger schmeckt sehr gut." and "Die Cheeseburger habe ich gern.", both of the 'Cheeseburger's, so to speak, are dropped. We're left with just the articles, only in this case, they aren't articles. They're '''demonstrative pronouns'''. Demonstrative pronouns aren't scary. They're just the same as the normal pronouns, only they give more ''oomph'' to the sentence. They can be translated as either 'this' or 'that' ("I'd like a cheeseburger. That tastes very good."), or 'these' or 'those' for plurals ("I eat cheeseburgers every day. These I like."). Demonstrative pronouns are exactly the same as the definite articles (well, there is one change in dative, but that will be covered in [[../Das Fest|Lesson 7]]). If you are not sure of the gender (meaning in context, the speaker doesn't know, not that you've forgotten that it's 'der Cheeseburger'), use 'das', like in "Was ist das?" (What is that?). ==Money and Paying== Germany, Austria, Luxemburg, Belgium and Südtirol – in other words: all German speaking regions except Switzerland and Liechtenstein– have given up their former currencies and adopted the Euro as of 1999. One ''Euro'' is worth 100 ''Cents''. Because they are not members of the European Union, Switzerland and Liechtenstein have kept the Swiss Francs (''Franken'' = 100 ''Rappen''). 'Euro' normally does not change in the plural in German, so you would still say "Ich habe 500 Euro." Nevertheless, there is an exception: Euro ''coins''. If you say "Ich habe vier Euros.", you actually are saying that you have four 1-Euro coins. Because the backsides of euro coins look different in each country, many people in Europe have started collecting foreign euro coins. In this case you can say "Ich habe irische Euros." (I have Irish euro coins.) for example. There is not yet a rule whether or not the word ''"Cent"'' has a different plural form. The majority of Germans are using the word ''"Cent"'' as a plural form, but when they don't it is simply ''"Cents"''. In German "euro" is pronounced [‘oi-ro], not [you-ro]. For "Cent" there are two pronunciations: you can either pronounce it as in English or you say "tzent". The latter version seems to be preferred by older people. When at a restaurant, you will want to pay at the end. You can use this vocabulary to help you. * to pay - ''zahlen'' * the bill - ''die Rechnung''* * the waiter - ''der Kellner'', ''die Bedienung'' (also ''der Ober'')** * the waitress - ''die Kellnerin'' (but '''not''' ''die Oberin'' because this means ''Reverend Mother'') * "How much is that?" - ''"Was macht das?"'' ("What does that make?") or the "umgangssprachliche" ''"Wie viel kostet das?"'' <small> * To ask for the bill you can say, "Bitte zahlen!", or make it a complete sentence: "Ich würde gern zahlen!", or "Wir möchten/wollen zahlen!". You can also say, "(Herr Ober), die Rechnung bitte!". The term "der Ober" is the waiter, but this sounds very old fashioned and is hardly ever used today. To address the waiter you would probably say "Entschuldigen Sie, ..." ("Pardon, ...") like in "Entschuldigen Sie, wir würden gern zahlen" (Pardon me, we would like to pay").</small> <small> ** Although it is perfectly OK to say “Bedienung” or “Kellner” when talking about a waiter or a waitress, you should not address the waiter by saying "Bedienung!" or even “Fräulein!” which is regarded very impolite since the 1980s. </small> <big>[[/Problems#Dieser-forms|Section Problems]] >></big> ==Test== The test will be located [[/Test|here]], but the test for this lesson is not yet completed. <noinclude>{{German/Level I/Footer|100%}}{{BookCat}}</noinclude> reiu9v7trv5jsofxbyt1ihrs1b5fril OpenSSH/Server 0 248406 4668914 4629160 2026-09-05T12:00:24Z WereSpielChequers 248949 typo 4668914 wikitext text/x-wiki The OpenSSH Server, [http://man.openbsd.org/sshd.8 sshd(8)], listens for connections from clients and starts a new process or two for each new incoming connection to handle key exchange, encryption, authentication, program execution, and data exchange. In the case of multiplexing, some processes are reused. It can run standalone and wait in the background, be run in the foreground, or it can be loaded on demand by any Internet services daemon. Since version 8.2, the listening process title shown in [http://man.openbsd.org/ps.1 ps(1)] also shows the number of connections pending authentication. <syntaxhighlight lang="shell-session"> $ ps -p $(pgrep -u root sshd) -o pid,user,args PID USER COMMAND 44476 root sshd: /usr/sbin/sshd [listener] 0 of 10-100 startups (sshd) </syntaxhighlight> Note that this is the number pending authentication, not the number which of those which have already been authenticated. Those each have their own separate handler process owned by the account which has authenticated. <noinclude>__TOC__</noinclude> ==sshd(8)== [http://man.openbsd.org/sshd.8 sshd(8)] is the secure shell daemon and it listens for incoming connections. The standard port for [http://man.openbsd.org/ssh.1 ssh(1)] as specified by IANA is 22 <ref name="IANA_ports">{{cite web |url=http://www.ietf.org/assignments/service-names-port-numbers/service-names-port-numbers.txt |title=Service Name and Transport Protocol Port Number Registry |publisher=IETF |year=2012}}</ref>. If [http://man.openbsd.org/sshd.8 sshd(8)] does not listen to a privileged port, it does not have to be launched by root, as long as the host keys are readable. However there are few, if any occasions where a non-standard port should be considered. A single instance of [http://man.openbsd.org/sshd.8 sshd(8)] can be bound to specific addresses, or even multiple addresses. Multiple instances of [http://man.openbsd.org/sshd.8 sshd(8)], each with a different configuration, can be run on the same machine, something which may be useful on multi-homed machines or in testing new a configuration. An absolute path must be given to launch [http://man.openbsd.org/sshd.8 sshd(8)], i.e. <code>/usr/sbin/sshd</code> :[http://man.openbsd.org/sshd.8 sshd(8)] - The SSH daemon that permits you to log in. :[http://man.openbsd.org/sshd_config.5 sshd_config(5)] - The server configuration file. :[http://man.openbsd.org/sftp-server.8 sftp-server(8)] - SFTP server subsystem, started automatically by [http://man.openbsd.org/sshd.8 sshd(8)] when needed. :[http://man.openbsd.org/ssh-keysign.8 ssh-keysign(8)] - Helper program for hostbased authentication, also started automatically by [http://man.openbsd.org/sshd.8 sshd(8)] when needed. The first time a server configuration directive is matched it is set and subsequent values will be ignored. Configuration data is parsed first from the run time arguments and options passed by the shell. After that the system-wide configuration file is read. For testing, the [http://man.openbsd.org/sshd.8 sshd(8)] daemon can be made to parse its configuration file, while testing it for validity, and then report on the effective configuration settings. This is done by running the extended test mode ('''-T''') which will print out the actual default server settings. Or, apply various inputs by adding the '''-C''' option as well. In either case, output from the '''-T''' option is long so it might be sensible to organize it by piping it through [http://man.openbsd.org/sort.1 sort(1)] and then view it through a pager like [http://man.openbsd.org/less.1 less(1)]. See the section on [[OpenSSH/Logging_and_Troubleshooting#Debugging_a_server_configuration| Debugging a Server Configuration]] for more options. Again, the directives are taken by the daemon in the following order at start or upon receiving SIGHUP: # run time options for [http://man.openbsd.org/sshd.8 sshd(8)] # directives from the system configuration file [http://man.openbsd.org/sshd_config.5 sshd_config(5)] By default, login is allowed for all groups. However, if either '''AllowGroups''' or '''AllowUsers''' is specified, then all users or groups not listed are prohibited from logging in. The allow/deny directives are processed in the following order: # '''DenyUsers''', # '''AllowUsers''', # '''DenyGroups''', and finally, # '''AllowGroups'''. For the most flexibility, it is recommended to use '''AllowGroups'''. But, if '''AllowUsers''' exists it will completely override '''AllowGroups''' regardless of the order in which they appear in the configuration file. Note that '''DenyUsers''' and '''DenyGroups''' take precedence over both but, in contrast, '''DenyUsers''' and '''DenyGroups''' do not interfere with each other and may be used together. Groups can be identified by their names directly or included through patterns matching group names, all separated by spaces. If a group is specified directly or via a pattern, login is allowed or denied only for users who are members of a group that matches a group or pattern on the list. Only the names of group or user accounts are valid here; numerical group or user IDs are not recognized. ===The Sequence In Which Files Are Read From /etc/ssh/sshd_config.d/ Matters=== If additional configuration files are read from the '''/etc/ssh/sshd_config.d/''' directory as a result of an '''Include''' directive, then the order in which these files are read really matters<ref name="order of files in sshd_config.d">{{cite web |url=https://utcc.utoronto.ca/~cks/space/blog/sysadmin/OpenSSHConfigOrderMatters |title=The order of files in /etc/ssh/sshd_config.d/ matters (and may surprise you) |publisher=The University of Toronto | date=2025-04-02 | accessdate=2025-05-23 | author=Chris Siebenmann}}</ref> a lot. As mentioned above, configuration values are set on a first-match basis. So if files contain contradictory settings, the first file read takes precedence and any conflicting configuration directives from subsequent files will be ignored. It is easy to check and verify the final server settings using the '''-T''' option, with or without the '''-C''' option. <syntaxhighlight lang="shell"> $ /usr/sbin/sshd -T | sort | less -X </syntaxhighlight> Since [http://man.openbsd.org/sshd_config sshd_config(5)] affects the behavior of outward facing services, it is most important to ensure that the end results are correct. So the '''-C''' option might be included when using '''-T''' to check the what happens when the '''Match''' directive is applied in regards to relevant combinations of source addresses, incoming account names, resolved source host names, local server addresses, local server port numbers, and routing tables respectively. The following will print out the specific configurations which will be applied if the user 'fred' tries to log in to the host ''server.example.org'' from the address ''192.168.100.5''. <syntaxhighlight lang="shell-session"> $ /usr/sbin/sshd -TC user=fred,host=server.example.org,addr=192.168.100.5 </syntaxhighlight> The options for '''-C''' are discussed more in the [[OpenSSH/Logging_and_Troubleshooting#Debugging_a_server_configuration| Debugging a Server Configuration]] section. ==sshd under inetd / xinetd== An Internet services daemon is a server to launch other servers on demand. [http://linux.die.net/man/8/xinetd xinetd(8)] and [http://man.openbsd.org/inetd.8 inetd(8)] are two variants, either of which can be used to specify additional parameters and constraints, including running the launched service as a particular user and group. By having a single daemon active, which invokes others as needed, demands on the system can be reduced. Launching [http://man.openbsd.org/sshd.8 sshd(8)] this way means [http://man.openbsd.org/inetd.8 inetd(8)] waits for an incoming request, launches [http://man.openbsd.org/sshd.8 sshd(8)] and then when the SSH session is over, closes [http://man.openbsd.org/sshd.8 sshd(8)]. <pre> Packet Internet --> Filter --> tcpwrappers --> (x)inetd --> sshd (firewall) (aka tcpd) </pre> Either can be used for additional logging such as successful or unsuccessful login, access restriction even including time of day, cpu priority, and number of connections. There are many more possibilities. See the manual pages for [http://linux.die.net/man/5/xinetd.conf xinetd.conf(5)] or [http://man.openbsd.org/inetd.conf.5 inetd.conf(5)] for a full overview of configuration options. [http://man.openbsd.org/inetd.8 inetd(8)] was '''tcpd'''-aware and could make use of '''tcpd''''s tcpwrappers to further control access or logging. So was [http://man.openbsd.org/sshd.8 sshd(8)] by itself, up through 6.6. See the manual pages for [ht ormation about how to use the configuration files '''hosts.allow''' and '''hosts.deny'''. Since 6.7, OpenSSH itself no longer supports tcpwrappers because current packet filters filters made it mostly redundant. The two main disadvantages of using [http://man.openbsd.org/inetd.8 inetd(8)] or xinetd(8) are that there can be a slight increase in the delay during the start of the connection and that [http://man.openbsd.org/sshd.8 sshd(8)] must be configured to allow launching from the services daemon. The delay only affects the initial connection and thus does not get in the way of actual operation. An Internet services daemon should not be used for stateless services like HTTP and HTTPS, where every action is essentially a new connection. Again, see the manual page for [http://linux.die.net/man/5/xinetd.conf xinetd.conf(5)] or [http://man.openbsd.org/inetd.conf.5 inetd.conf(5)] for more details. Example from [http://linux.die.net/man/5/xinetd.conf xinetd.conf(5)] <pre> service ssh { socket_type = stream protocol = tcp wait = no user = root server = /usr/sbin/sshd server_args = -i per_source = UNLIMITED log_on_failure = USERID HOST # log_on_success = PID HOST DURATION TRAFFIC EXIT # instances = 10 # nice = 10 # bind = 192.168.0.100 # only_from = 192.168.0.0 # access_times = 08:00-15:25 # no_access = 192.168.54.0 # no_access += 192.168.33.0 # banner = /etc/banner.inetd.connection.txt # banner_success = /etc/banner.inetd.welcome.txt # banner_fail = /etc/banner.inetd.takeahike.txt } </pre> Example from [http://man.openbsd.org/inetd.conf.5 inetd.conf(5)] <pre> ssh stream tcp nowait root /usr/sbin/sshd -i ssh stream tcp6 nowait root /usr/sbin/sshd -i </pre> There are several advantages with [http://linux.die.net/man/8/xinetd xinetd(8)] over [http://man.openbsd.org/inetd.8 inetd(8)] in capabilities but use-cases where either would be useful are rare. ==The SFTP Server Subsystem== The SFTP subsystem first appeared in OpenBSD 2.8 / OpenSSH 2.3<ref name="OpenSSH_2.3.0p1_Release_Notes">{{cite web |url=http://www.openssh.org/txt/release-2.3.0p1 |title=OpenSSH 2.3.0p1 release notes |publisher=OpenSSH.org |orig-date=2000}}</ref>. It is called by [http://man.openbsd.org/sshd.8 sshd(8)] as needed using the '''Subsystem''' configuration directive and not intended to operate standalone. There are two forms of the subsystem. One is the regular [http://man.openbsd.org/sftp-server.8 sftp-server(8)]. The other is an in-process SFTP server, which requires no support files when used with the '''ChrootDirectory''' directive. The '''Subsystem''' configuration directive can be used to pass options: '''-d''' specifies an alternate starting directory for users, the default is the user's home directory. (First in 6.2) <syntaxhighlight lang="text"> Subsystem sftp internal-sftp -d /var/www </syntaxhighlight> '''-e''' causes logging information to be sent to '''stderr''' instead of [http://man.openbsd.org/syslog.3 syslog(3)]. <syntaxhighlight lang="text"> Subsystem sftp internal-sftp -e </syntaxhighlight> '''-f''' specifies the [http://man.openbsd.org/syslog.3 syslog(3)] facility code that is used when logging messages from [http://man.openbsd.org/sftp-server.8 sftp-server(8)]. The possible values are: DAEMON, USER, AUTH, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7. <syntaxhighlight lang="text"> Subsystem sftp /usr/libexec/sftp-server -f LOCAL0 </syntaxhighlight> '''-l''' Specifies which messages will be logged by [http://man.openbsd.org/sftp-server.8 sftp-server(8)]. The default is AUTH. The other possible values are: QUIET, FATAL, ERROR, INFO, VERBOSE, DEBUG, DEBUG1, DEBUG2, and DEBUG3. INFO and VERBOSE log transactions that sftp-server performs on behalf of the client. DEBUG and DEBUG1 are equivalent while DEBUG2 and DEBUG3 each specify higher levels of debugging output. Log levels DEBUG through DEBUG3 will violate user privacy and should not be used for regular operation. The default log level is ERROR. The actual path will vary depending on distro or operating system. <syntaxhighlight lang="text"> Subsystem sftp /usr/libexec/sftp-server -l VERBOSE </syntaxhighlight> '''-p''' and '''-P''' specify whitelisted and blacklisted protocol requests, respectively. The comma separated lists are permitted or prohibited accordingly, the blacklist is applied first if both are used. '''-Q''' provides a list of protocol features supported by the server. All three are available as of version 6.5. The actual path will vary depending on distro or operating system. In version 6.5 ''requests'' are the only protocol features queriable. <syntaxhighlight lang="shell-session"> $ /usr/libexec/sftp-server -Q requests </syntaxhighlight> '''-R''' places the SFTP subsystem in read-only mode. Attempts to change the filesystem, including opening files for writing, will fail. '''-u''' overrides the user's default umask and explicitly sets the [http://man.openbsd.org/umask.2 umask(2)] to be used for creating files and directories. See the manual page for [http://man.openbsd.org/syslog.conf.5 syslog.conf(5)] for more information about log level or log facility. [http://man.openbsd.org/sshd.8 sshd(8)] must be able to access '''/dev/log''' for logging to work. Using the [http://man.openbsd.org/sftp-server.8 sftp-server(8)] subsystem in conjunction with the main SSH server's '''ChrootDirectory''' option therefore requires that [http://man.openbsd.org/syslogd.8 syslogd(8)] establish a logging node inside the chrooted directory. <syntaxhighlight lang="text"> Subsystem sftp internal-sftp -u 0002 </syntaxhighlight> That sets the umask for the SFTP subsystem in OpenSSH 5.4 and later. ==Environment Variables== [http://man.openbsd.org/ssh.1 ssh(1)] and [http://man.openbsd.org/sshd.8 sshd(8)] set some environment variables automatically when logging in. Other variables can be explicitly defined by users in the '''~/.ssh/environment''' file if the file exists and if the user is allowed to change the environment. Variables can also be set on a key by key basis in the '''authorized_keys''' file, again only if the user is allowed to change the environment. In '''~/.ssh/environment''', the format '''NAME=value''' is used to set the variable. In '''~/.ssh/authorized_keys''' and '''/etc/ssh/authorized_keys''' the format is '''environment="NAME=value"''' For more information, see the '''PermitUserEnvironment''' and '''AcceptEnv''' configuration directives in [http://man.openbsd.org/sshd_config.5 sshd_config(5)] and the '''SendEnv''' directive in [http://man.openbsd.org/sshd_config.5 ssh_config(5)]. The following variables can be set by [http://man.openbsd.org/ssh.1 ssh(1)], depending on the situation. '''DISPLAY''' If X11 is tunneled, this is set so that the '''DISPLAY''' variable indicates the location of the X11 server. When it is automatically set by [http://man.openbsd.org/ssh.1 ssh(1)] it points to a value in the form ''hostname'':''n'', where ''hostname'' indicates the host where the shell runs, and ''n'' is an integer greater than or equal to one. [http://man.openbsd.org/ssh.1 ssh(1)] uses this special value to forward X11 connections over the secure channel. The user should normally not set '''DISPLAY''' explicitly, as that will render the X11 connection insecure and will require the user to manually copy any required authorization cookies. '''HOME''' The path of the user's home directory. '''LOGNAME''' Synonym for USER. This is set for compatibility with systems that use this variable. '''MAIL''' The path of the user's mailbox. '''PATH''' The default PATH, as specified when compiling [http://man.openbsd.org/ssh.1 ssh(1)]. '''SSH_ASKPASS''' If '''DISPLAY''' and '''SSH_ASKPASS''' are both set, and the SSH session does not have an associated terminal or pseudo-terminal, the program specified by '''SSH_ASKPASS''' will execute and open an X11 window to read the passphrase when one is needed. This is particularly useful when calling [http://man.openbsd.org/ssh.1 ssh(1)] from an xsession or related script. On some machines it may be necessary to redirect the input from '''/dev/null''' to make this work. '''SSH_AUTH_SOCK''' The path on the client machine to tell [http://man.openbsd.org/ssh.1 ssh(1)] the UNIX-domain socket used to communicate with an SSH key agent. '''SSH_CLIENT''' Identifies the client end of the connection. It contains three space-separated values: the client IP address, client port number and the server port number. '''SSH_CONNECTION''' Identifies the client and server ends of the connection. The variable contains four space-separated values: client IP address, client port number, server IP address, and server port number. '''SSH_ORIGINAL_COMMAND''' If the '''ForceCommand''' directive was used, or '''Command="..."''' in a key, then this variable contains the original command including the original options. It can be used to extract the original arguments. '''SSH_TTY''' This is set to the name of the TTY (path to the device) associated with the current shell or command. If the current session has no TTY, this variable is not set. '''SSH_USER_AUTH''' This will contain the name of a temporary file containing the authentication methods used for this particular session if '''ExposeAuthInfo''' is set in [http://man.openbsd.org/sshd_config.5 sshd_config(5)]. '''TZ''' This variable is set to indicate the present time zone if it was set when the daemon was started. The SSH daemon passes this value on to new connections. '''USER''' Set to the name of the user logging in. <noinclude> == References == {{reflist}} {{OpenSSH/TOC|mini}} </noinclude> {{BookCat}} {{status|100%}} ml12elkukxhlfhi2xp5weq8k5j6wbac User talk:Garygaryj 3 255252 4669053 2231040 2026-09-06T06:37:08Z ShakespeareFan00 46022 4669053 wikitext text/x-wiki <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Garygaryj!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> <div style="text-align:right; padding:0.2em 0.5em 0.2em 0.5em;">Thanks. [[User:Recent Runes|Recent Runes]] ([[User talk:Recent Runes|discuss]] • [[Special:Contributions/Recent Runes|contribs]]) 23:35, 9 August 2011 (UTC)</div> </div> <div style="clear:both;"> </div> 60x6tacs8xghpu78ah6hjhwsyvxm7f7 User talk:AshishDandekar7 3 258533 4669048 2193633 2026-09-06T06:34:09Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669048 wikitext text/x-wiki <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, AshishDandekar7!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}};; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> <div style="text-align:right; padding:0.2em 0.5em 0.2em 0.5em;">Thanks. [[User:Recent Runes|Recent Runes]] ([[User talk:Recent Runes|discuss]] • [[Special:Contributions/Recent Runes|contribs]]) 18:50, 18 October 2011 (UTC)</div> </div> <div style="clear:both;"> </div> 5qt3xikmlztc7qwapuxmd6ulxwz1s1a User:U118656/Wikibooks projects/Reversing the Effects of Insulin Resistance with Aerobic Exercise Fact Sheet 2 258901 4668918 2199473 2026-09-05T12:07:52Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668918 wikitext text/x-wiki ==What is Insulin Resistance? <ref name="Appel">Appel, SJ. Sizing up patients for metabolic syndrome. Nursing 35: 20-21, 2005.</ref> <ref name="Diabetes">Diabetes Australia. National Diabetes Services Scheme. 2011, 2011.</ref> <ref name="Gallagher">Gallagher, EJ, LeRoith, D, and Karnieli, E. Insulin Resistance in Obesity as the Underlying Cause for the Metabolic Syndrome. Mount Sinai Journal of Medicine 77: 511-523, 2010.</ref> <ref name="Valensi">Valensi, P, Chanu, B, and Cosson, E. Obesity, Metabolic Syndrome, Diabetes and Arterial Hypertension. Immunology, Endocrine & Metabolic Agents - Medicinal Chemistry 6: 407-423, 2006.</ref>== Insulin Resistance (IR) is a condition in which the cells of the body become resistant to the effects of insulin. Thus, a person is said to have impaired glucose tolerance / pre-diabetes. IR results in higher levels of insulin being required to maintain normal blood glucose levels. Eventually, the pancreas may be unable to keep up with insulin demand leading to long term health issues. *''1 in 4 adults in Australia may at some time in their life have impaired glucose tolerance'' *''Being diagnosed with impaired glucose tolerance does not necessarily mean you will develop diabetes, but it makes you 10-20 times more likely than a normal person'' *''It is estimated that up to 1.8 million Australians are living with diabetes / impaired glucose tolerance'' ==Who is at Risk of Developing Insulin Resistance? Patients who - <ref name="Appel"/> <ref name="Diabetes"/> <ref>Akram, T, Hasan, S, Imran, M, Karim, A, and Arslan, M. Association of polycystic ovary syndrome with cardiovascular risk factors. Gynecological Endocrinology 26: 47-53, 2010.</ref> <ref>Viljoen, A, and Wierzbicki, AS. Potential Options to Treat Hypertriglyceridaemia. Curr. Drug Targets 10: 356-362, 2009.</ref>== {| | *Are overweight / obese *Are Aboriginal or Torres Strait Islanders *Are pregnant | *Have a high fat diet *Have a family history of type 2 diabetes, hypertension or heart disease *Have a sedentary lifestyle |} ==Classic Side Effects <ref name="Diabetes"/> <ref name="Gallagher"/> <ref name="Valensi"/> <ref>Reinehr, T. Clinical presentation of type 2 diabetes mellitus in children and adolescents. Int. J. Obes. 29: S105-S110, 2005.</ref>== A patient with IR may remain asymptomatic (no signs of symptoms) for an extended period of time, classic symptoms are often linked to: {| class="wikitable" style="margin: 1em auto 1em auto;" |+ '''Acute Side Effects''' ! scope="col" style="width:230px;" | Hyperglycaemia Symptoms ! scope="col" style="width:230px;" | Hyperinsulinemia Symptoms |- | Slow Healing || Brain Fogginess (inability to concentrate) |- | Frequent Thirst || Blurred Vision |- | Frequent Urination || Fatigue |} {| class="wikitable" style="margin: 1em auto 1em auto;" |+ '''Chronic Side Effects''' ! scope="col" style="width:225px;" | Macro Vascular Issues ! scope="col" style="width:225px;" | Micro Vascular Issues ! scope="col" style="width:225px;" | Hyperinsulinemia Issues |- | Stroke || Retinopathy (Blindness) || Type 2 Diabetes |- | Heart Disease || Nephropathy (Kidney Disease) || Hypertension |- | || Neuropathy (Nervous Tissue Damage) || Bad Cholesterol |- | || || Weight Gain / Central Obesity |- | || || Polycystic Ovary Disease |} ==Recommendations for Insulin Resistance Management <ref>Department of Health and Ageing. Physical Activity Guidelines. 2011, 2011.</ref> <ref>Exercise & Sports Science Australia. Adult Pre-Exercise Screening System. 2011, 2011.</ref> <ref>Nocon, M, Hiemann, T, Müller-Riemenschneider, F, Thalau, F, Roll, S, and Willich, SN. Association of physical activity with all-cause and cardiovascular mortality: a systematic review and meta-analysis. Eur J Cardiovasc Prev Rehabil 15: 239-246, 2008.</ref> <ref>Sassen, B, Cornelissen, V, Kiers, H, Wittink, H, Kok, G, and Vanhees, L. Physical fitness matters more than physical activity in controlling cardiovascular disease risk factors. Eur J Cardiovasc Prev Rehabil 16: 677-683, 2009.</ref>== ''Always seek professional health guidance before commencing a training regime'' ''Remember adherance to any form of physical activity is the most crucial step in reversing Insulin Resistance'' {| class="wikitable" style="margin: 1em auto 1em auto;" |+ '''Aerobic Exercise Recommendations''' ! scope="col" style="width:500px;" | Guidelines ! scope="col" style="width:10px; background: black; color:white;" | ! scope="col" style="width:500px;" | Benefits |- | At least 30 minutes / moderate intensity on most days of the week || style="background: black;color:white;" | || Improves insulin sensitivity (Reverses IR) |- | Or at least 20 minutes / vigorous intensity three times per week || style="background: black;color:white;" | || Improves quality of life |- | Influencing lifestyle choices can also contribute to daily aerobic activity || style="background: black;color:white;" | || Controls blood glucose, insulin and blood pressure levels |- | • Transport - substitute driving with walking or cycling to work || style="background: black;color:white;" | || Reduces the risk of obesity, death and illness |- | • Recreation - substitute indoor activities for outdoor activities || style="background: black;color:white;" | || Reduces the risk of chronic IR issues |- | • Occupation - substitute the elevator for the stairs to the office || style="background: black;color:white;" | || • Macro Vascular issues |- | • Home - subtitute take away for a home cooked meal || style="background: black;color:white;" | || • Micro Vascular issues |- | || style="background: black;color:white;" | || • Hyperinsulinemia issues |} {| class="wikitable" style="margin: 1em auto 1em auto;" |+ '''Examples of Aerobic Activity that Meets the Guidelines''' ! scope="col" style="width:300px;" | Low Intensity ! scope="col" style="width:300px;" | Moderate Intensity ! scope="col" style="width:300px;" | High / Vigorous Intensity |- | Does not cause a noticeable change in breathing rate || Able to maintain a conversation uninterrupted || Unable to maintain a conversation uniterrupted |- | • Washing || • Walking || • Jogging |- | • Cooking || • Swimming || • Aerobics |- | • Cleaning in the Home || • Social Sports || • Competitive Sports |} ==Further Reading / Informational Sources== *Diabetes Australia - National Diabetes Services Scheme - http://www.diabetesaustralia.com.au/ndss/ *Department of Health and Ageing – http://www.health.gov.au/ *Exercise & Sports Science Australia - http://www.essa.org.au/ <references/> {{BookCat}} 2zpzs1zgu04kbbbfhdy12wy2s6b98rp User talk:Collinheretick 3 262378 4669054 2229121 2026-09-06T06:37:51Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669054 wikitext text/x-wiki <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Collinheretick!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> <div style="text-align:right; padding:0.2em 0.5em 0.2em 0.5em;">Thanks. [[User:Recent Runes|Recent Runes]] ([[User talk:Recent Runes|discuss]] • [[Special:Contributions/Recent Runes|contribs]]) 21:21, 5 December 2011 (UTC)</div> </div> <div style="clear:both;"> </div> atmf9pkq996harjh7bfauknthej665h User:Abdars 2 264926 4668989 2259228 2026-09-05T19:01:56Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668989 wikitext text/x-wiki {{Userpage}} ---- == Dear visitors == Hi! My name is Abdullah Danish Shervani... Thanks for paying a visit to my page. Please visit my talk page to leave a message. Appreciated! -- <span style="position:relative;overflow:hidden;"> <span style="position:absolute;bottom:1px;width:100%;height:5px;background:#eee;{{Text default color}};">&nbsp;</span>[[User:abdars| <span style="position:relative;border:1px solid #bbb">&nbsp;abdars&nbsp;</span> ]]</span> aazto4f6pp23t2rqpyh3akjagrecc3a User talk:AstroAlgebra 3 274461 4669052 2365561 2026-09-06T06:36:23Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669052 wikitext text/x-wiki <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, AstroAlgebra!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> </div> <div style="clear:both;"> </div> 0qd0n6x0e8lxcn5d0k7odcmmagf76ki User talk:Dokidokis 3 276639 4669046 3417540 2026-09-06T06:32:34Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669046 wikitext text/x-wiki <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Scchriz!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> </div> <div style="clear:both;"> </div> --[[User:Pi zero|Pi zero]] ([[User talk:Pi zero|discuss]] • [[Special:Contributions/Pi zero|contribs]]) 12:09, 14 August 2012 (UTC) q16z3c8eal9rfhardgkgn7bzyry6xiv User talk:Lisa Svenska 3 276944 4669045 4594987 2026-09-06T06:31:50Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669045 wikitext text/x-wiki {| style="margin: 1em auto 1em auto" |+ |- | {| style="text-align:center; border: 1px solid #000000; background-color:#F8EFFF;{{text default color}};" |- style="padding:1em;padding-top:0.5em;" |style="font-size: 85%"|'''This is a &#x0057;&#x0069;<!-- Wikipedia -->&#x006B;&#x0069;&#x0070;&#x0065;&#x0064;&#x0069;&#x0061; user talk page.''' If you find this page on any site other than &#x0057;&#x0069;<!-- Wikipedia -->&#x006B;&#x0069;&#x0070;&#x0065;&#x0064;&#x0069;&#x0061;, you are viewing a mirror site. Be aware that the page may be outdated, and that the user this page belongs to may have no personal affiliation with any site other than &#x0057;&#x0069;<!-- Wikipedia -->&#x006B;&#x0069;&#x0070;&#x0065;&#x0064;&#x0069;&#x0061; itself. The original page is located at http://en.wiki<!---->pedia.org/wiki/{{FULLPAGENAMEE}}. |} {| width="100%" align="center" cellspacing="3" style="border: 1px solid #000000; background-color: #F8EFFF;{{text default color}}; margin-bottom: 0px;" |align=center|'''This is the [[Wikipedia:Talk_page#User_talk_pages|User talk page]] for [[User:{{PAGENAME}}|{{PAGENAME}}]] ''' |} {| width="100%" align="center" cellspacing="3" style="border: 1px solid #000000; background-color: #F8FCFF;{{text default color}}; margin-bottom: 3px;" |align=left| {| width="100%" align="left" cellspacing="10" style="border: 0px solid #000000; background-color: #F8FCFF;{{text default color}}; margin-bottom: 0px;" |align=left valign=middle|Please sign your comments using four tildes (&#126;&#126;&#126;&#126;). Place comments that start a new topic at the bottom of the page by [{{fullurl:{{ns:3}}:{{PAGENAMEE}}|action=edit&section=new}} starting a new thread]<!--and give them a <nowiki>==A Descriptive Header==</nowiki>-->. If you're new to Wikipedia, please see [[Wikipedia:Introduction|Welcome to Wikipedia]] and [[Wikipedia:FAQ|frequently asked questions]]. |} |align=right valign=middle| {| width="90%" align="center" cellspacing="3" style="border: 1px solid #000000; background-color: #F8EFFF;{{text default color}}; margin-left: 20px; margin-bottom: 0px; margin-right: 3px;" |align=center|'''[[Wikipedia:Talk page guidelines|Talk page guidelines]]''' |- |align=center|Please respect [[Wikipedia:Wikiquette|Wikiquette]], [[Wikipedia:Assume good faith|assume good faith]] and [[Wikipedia:no personal attacks|be nice]], and bear in mind [[Wikipedia:What Wikipedia is not|what Wikipedia is not]]. |} |} |+ |- | |+ |- | |} l19uy2hovlsiy14jldyf8gvonapneyx User talk:Areil314 3 277010 4669047 2398999 2026-09-06T06:33:21Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669047 wikitext text/x-wiki <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Areil314!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> </div> <div style="clear:both;"> </div> d6wuk3li6tv65u76yqcvnvae921zlcs User talk:Avocato 3 277237 4669044 2402036 2026-09-06T06:30:57Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669044 wikitext text/x-wiki <div dir=ltr><div style="background: #FFFFFF;{{text default color}}; text-align: center; font-family: Calibri; font-size: 1.6em; font-weight: bold;"><div style="padding: 5px; border: 3px solid #003882; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px;">Please, Do not leave your message here. You can contact me using any of the following: <div style="margin-top: 10px; padding: 2px; background: #f4f3f0;{{text default color}}; border: 2px solid #fb139e; -moz-border-radius: 10px; -webkit-border-radius: 10px; border-radius: 10px;">[[w:ar:User talk:Avocato|w:ar:user talk:Avocato]] &#124; [[w:en:User talk:Avocato|w:en:user talk:Avocato]] &#124; [[m:User talk:Avocato|meta:user talk:Avocato]]</div></div></div></div> 2exlkgy7yimeangumn0rfqeh69zz80b User:Writ3562 2 278077 4669012 2412275 2026-09-05T19:28:15Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669012 wikitext text/x-wiki ==About writ3562== {| align="right" border="1" cellspacing="0" cellpadding="2" width="350px" ! style="background:#efefef;{{Text default color}}; text-align:right; vertical-align:top"| Name: | writ3562 |- ! style="background:#efefef;{{Text default color}}; text-align:right; vertical-align:top"| Hometown: | Midwest, USA |- ! style="background:#efefef;{{Text default color}}; text-align:right; vertical-align:top"| Current Home: | Midwest, USA |- ! style="background:#efefef;{{Text default color}}; text-align:right; vertical-align:top"| Education: | College of Education and Human Development<br>Big Ten University<br> |- ! style="background:#efefef;{{Text default color}}; text-align:right; vertical-align:top"| Websites: | [http://www.pinterest.com My favorite website] [http://www.tumblr.com Another fun website]<br> |} =About Me= I am a college student at Big Ten University in the United States. I grew up in a small town, but love big cities. =Academics= I am halfway through my college degree, but plan on attending Graduate school after obtaining my undergraduate degree. My focus is on languages and healthcare. My main goal is to find a career I am passionate about and help the people around me. =Interests= I love to travel the world and the United States. Two of my favorite things to do are read and run. I am an aspiring cook; I loved to try new, healthy recipes. I am an animal lover and cannot wait to be able to have time for my own pet. =Family= My family is extremely important to me. My immediate family is small, but I grew up surrounded by my extended family whom I am very close to. I also have a dog who I consider to be my baby. She is definitely the princess of our family. 6w4p5ypjho855kjpwt8chj8u2ybfeqo Structural Biochemistry/Vyvanse 0 281983 4669094 3117667 2026-09-06T10:31:05Z WereSpielChequers 248949 typo 4669094 wikitext text/x-wiki ==Introduction== [[Image:Lisdexamfetamine.svg|250px|thumb|Lisdexamfetamine]] ''Vyvanse'' is a nervous controlled medication used to treat people with attention deficit hyperactivity disorder (ADHD) who show symptoms of loss of memory or having difficulty focusing. Its structure consists of dextroamphetamine with an amino acid L-lysine. ADHD is caused by some of the natural substances in the brain, and Vyvanse can help to manipulate the amount of these substances to work properly. Vyvanse also helps patients dealing with particular symptoms of ADHD; it can increasing their attention and decrease the impulsiveness. ==History and Usage== Vyvanse was developed by New River Pharmaceuticals and has been on the market since 2008. Vyvanse can be taken directly by mouth and usually in the morning because it can cause difficulty in sleeping if you take it in late afternoon or at night. It is suggested that Vyvanse should not be taken more than what it is prescribed because it can cause some severe side effects. A doctor will probably prescribe a patient with a low dose to see how their body can adapt to the medication. Oftentimes, the physician will adjust the dosage during a patient's treament. Besides taking Vyvanse as a part of a complete treatment, patients with ADHD should follow up with other therapies. ==Side Effects== Because Vyvanse can lead to dependence or addiction, it should be used properly. Just as other drugs, Vyvanse does have some common side effects: *Difficulty falling asleep *Stomach pain *Flu, fever, sweating *Headache, dizziness, diarrhoea. But for some people, this drug can have some serious side effects: *Seizures *Vision problems *Slowing of growth in children *Worsening of sudden A doctor should be contacted if these side effects occur. ==References== http://www.drugs.com/pro/vyvanse.html http://www.vyvanse.com/ {{BookCat}} cpeaif44ua529l016mp23j6wwenql7l Aros/Platforms/Arm Raspberry Pi support 0 286123 4668931 4668855 2026-09-05T12:41:43Z Jeff1138 301139 4668931 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsinks on 3b to prevent cpu 80C+ overheating * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=60&pid=13363#post_13363 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works if a little slower than SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon Prefs needed? Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs *2026 RPI AI HAT+ 2 - Hailo 40TOPs [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box with pi4 *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} 788x7cxdpgtal4i28fcmtk17j5er7z4 4668936 4668931 2026-09-05T13:18:54Z Jeff1138 301139 4668936 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsinks on 3b to prevent cpu 80C+ overheating * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=60&pid=13363#post_13363 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works, double time of SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon Prefs needed? Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs *2026 RPI AI HAT+ 2 - Hailo 40TOPs [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box with pi4 *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} jwdttynx1ttuo17ld89xzaibbkws27f 4668937 4668936 2026-09-05T13:30:50Z Jeff1138 301139 4668937 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsinks on 3b to prevent cpu 80C+ overheating * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=60&pid=13363#post_13363 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works but slower than SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon Prefs needed? Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs *2026 RPI AI HAT+ 2 - Hailo 40TOPs [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box with pi4 *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} s9skvae7riexe51pe1x46xw6j2lag7x 4668940 4668937 2026-09-05T13:39:57Z Jeff1138 301139 4668940 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsinks on 3b to prevent cpu 80C+ overheating * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=60&pid=13363#post_13363 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works but slower than SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon exchange in works Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs *2026 RPI AI HAT+ 2 - Hailo 40TOPs [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box with pi4 *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} av3gem5g0d7mrfduu0ttpdkr6zayvwp 4668941 4668940 2026-09-05T14:40:50Z Jeff1138 301139 4668941 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsink/fan on 3b to prevent cpu 82C+ throttling * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=60&pid=13363#post_13363 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works but slower than SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon exchange in works Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs *2026 RPI AI HAT+ 2 - Hailo 40TOPs [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box with pi4 *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} tlrughq2epuzgpjg6p5q3lw8bx2x986 4668942 4668941 2026-09-05T14:44:10Z Jeff1138 301139 4668942 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsink/fan on 3b to prevent cpu 82C+ throttling * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works but slower than SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon exchange in works Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs *2026 RPI AI HAT+ 2 - Hailo 40TOPs [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box with pi4 *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} 6qqyi29ke9gpwv9jjlxbb0lslz5gi53 4668949 4668942 2026-09-05T16:14:55Z Jeff1138 301139 4668949 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsink/fan on 3b to prevent cpu 82C+ throttling * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works but slower than SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon exchange in works Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs no LLMs *2026 RPI AI HAT+ 2 - Hailo 40TOPs slightly better? [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box with pi4 *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} bd7pmzn1k2ck9ozfrdig8v9aq5xjkbt 4669087 4668949 2026-09-06T07:53:12Z Jeff1138 301139 4669087 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsink/fan on 3b to prevent cpu 82C+ throttling * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works but slower than SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon exchange in works Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs no LLMs *2026 RPI AI HAT+ 2 - Hailo 40TOPs slightly better? [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box has 128x64 oled display, micro hdmi, 19Whr battery with pi4 and 15V PD 36W min needed *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} msxa4p9de17gcuzokkx64mezeliplp5 4669088 4669087 2026-09-06T08:03:47Z Jeff1138 301139 4669088 wikitext text/x-wiki {{ArosNav}} [[#Native]] [[#Hosted]] [[#Build]] [[#Hardware]] [[#References]] ==Introduction== [[File:Scalos00.png|thumb|Scalos on Aros Pi3b]] Aros aims to cover Pi 3 to 5 1Gb+ RAM ideally as you may have to switch to 256Mb gfx mode depending on the application running - it is still a work in progress Options to boot from using a good power source to prevent the yellow lightning symbol. Testing procedure is put sd card in, connect board to board if necessary, plug in hdmi and then power nothing else is done especially CSI DSI etc *Up to Pi3b+ the max you can get is 5.1V 2.5A with micro usb. *With Pi4 5.1V 3A with usb-c *With Pi5 5.1V 5A, the amps went ever upwards, even to 5.1V 9A with usb-c Pi500+ keyboard wedge - Pi400 RPI-400 keyboard wedge - resolution changing and audio from micro hdmi0 (near 40pin) and micro hdmi1 (near usb-c psu) - Fn F10 0x5e power on and off works or held down for over 7 seconds auto shutdown - keyboard ok but not great - wifi and lan ethernet partial working but no web browser to fully test - * Pi 5 - Quad A76 64bit ARMv8 and RP1 "southbridge" with VideoCore 7 Pre-D0 (Rev1.0) or D0 (rev1.1) * Pi 4 - Quad A72 64bit ARMv8 with VideoCore 6 * Pi 3 - Quad A53 [https://www.raspberrypi.com/documentation/computers/processors.html 64 bit] ARMv8 with VideoCore 4 with heatsink/fan on 3b to prevent cpu 82C+ throttling * Pi 2 - Quad 32bit ARMv6 with VideoCore 4 - mostly not 64bit compatible * Pi Model B+ 32bit ARMv6 with VideoCore 4 - not 64bit compatible * Pi Model A and B 32bit ARMv6 with VideoCore 4 - not 64bit compatible ===Native=== * 2013-03 Kalamatee starts work * 2015-04 Work continues with mschulz on the kernel and Kalamatee (NicJA) on gpio and usb * 2018 [https://www.patreon.com/posts/i-owe-you-some-20956961 mschulz resume adding BE big endian support], [https://www.patreon.com/michal_schulz/posts Big endian on Pi] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bsek latest commits for pi 3b, 4 and 5 64bit] * 2026 [https://github.com/aros-development-team/AROS/commits?author=metaneutrons latest commits for Pi5] * 2026 [https://github.com/aros-development-team/AROS/commits?author=bitplane latest commits for ARM] '''Download''' [https://aros.sourceforge.io/nightly1.html RaspberryPi 3, 3+, 4 and 5 64bit ArmV8 builds] [https://sourceforge.net/projects/aros/files/ Alternative site and nightly2] both raspi-aarch64-system and raspi-aarch64-contrib can be unbz2'd and copied to fat32 8GB+ microSD card (there will be folders - boot c Classes Demos Developer Devs Extras etc only showing). The SD can be plugged in to the Pi 64bit build works well on a single core LE little endian. Multicore [https://github.com/aros-development-team/AROS/commit/1df0747c2bda3523a43029725a709b1f377d84ec may follow]. Any issues booting could be down to the SD card so please use another SD to see if it is resolved. Please report your experiences in the [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80 Aros Raspberry pi 3 64bit thread] Boots with '''USB3''' port based sata3 ssd on Pi400 but untested on Pi4 (may need eeprom update from PiOS or Pi SD Imager) and Pi5 Pi 3 B+ is pre-configured for USB sata3 boot - untested Pi 3 B may need [https://www.youtube.com/watch?v=ubnwvxF3Klc PiOS to set OTP to boot from usb - do so at your own risk] - if OTP set to usb boot it works but slower than SD card Like most amiga like OSs the audio and networking need to be setup manually Audio AHI prefs - Mode settings tab - needs both Music unit and Unit 0 set to RPiHDMI:16 bit stereo++ or RPiPWM:16 bit stereo++ at 44100Hz. Press '''Save or Use''' button after each choice Double left mouse click on most picture (Developer/Debug/Tests/Datatypes), audio and video files are supported, via datatypes, by the multiview application. Esc escape key usually closes open windows even the desktop Windows can be manipulated by the top (moving) and the bottom right corner (resizing) only. In Prefs/Appearance some decorative theming elements need work. There is a few Mason icons in /Prefs/Presets/Icons/Mason/ and the ever present default Gorilla - Icon exchange in works Printing only with Postscript but [https://github.com/bohunamiga/MintPRINT one] of [https://github.com/boingball/MintPRINT two] [https://github.com/Andiweli/AmiAirPrint/tree/main AirPrint] IPP has been attempted with [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2061&pid=13954#post_13954 discussion] For more intensive graphics applications, you may need to edit config.txt in the root folder and change 128M to 256M to adjust more memory to graphics usage [[File:Wifi00.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi01.png|thumb|Setup wifi on Aros Pi3b]] [[File:Wifi02.png|thumb|Setup wifi on Aros Pi3b]] Wifi setup needs the network prefs with the TCP/IP tab click add interface -> change Device to bwfm.device as net0:, IP Mode as DHCP and IPv4 Once you’ve configured the device, simply save the Wireless Networks tab Wi-Fi configuration even if it’s empty. This will create the Wireless.prefs file in the Env-Archive/SYS directory, and you’ll automatically see the Wireless Manager icon in Wanderer. Although a reboot maybe necessary. Wireless tab gets your router settings. If it does not set to start at boot, settings are preserved. Instead, add this to the user-startup: <pre> execute sys:system/network/arostcp/s/startnet run wirelessmanager device=bwfm.device >nil: </pre> Network will start automatically on boot. If you don't want the wirelessmanager icon on Wanderer desktop, just add 'nogui' to the wirelessmanager line Lan ethernet port on *lan9514 Pi3b Pi2 no support at the moment *lan7515 Pi3b+ type into Device usblan78xx.device as net0: remove other device(s) *bcmgenet Pi4 Pi400 choose for Device bcmgenet.device There is normally no Bluetooth support for most amiga like OSs but Aros has one [https://github.com/aros-development-team/AROS/commit/6942cbfbf66426d21963a7fcd8aba6aff611a9e0 work in progress] [https://forums.raspberrypi.com/viewtopic.php?t=338466 firmware] *Bluetooth 4.1 BCM43430A1.hcd Pi3B, Pi3A, Zero W *Bluetooth 4.2 BCM4345C0.hcd Pi3B+, Pi4 *Bluetooth 5.0 BCM4345C5.hcd Pi4B rev, CM4 and maybe Pi5 and CM5 *bthid keyboard mouse support *btserial serial *btpan short range wireless connecting devices Only the Pi5 has a RTC real time clock, the other Pis will need to use [https://aminet.net/package/util/time/NTPSync ntpsync] or similar to get the date and time from the internet USB classes support from Prefs/Trident is still work in process *usbaudio not working as no rt isochronous on usb2otg (white or black) for pi3b and zero 2w but '''working''' on usb3 port (blue) on pi4, 400 *camdusbmidi no class compiled but eventually 64bit ports of [https://aminet.net/package/mus/midi/camdtools camdtools], [https://github.com/timoinutilis/midi-sequencer-amigaos horny src], [https://aminet.net/package/mus/midi/horny-base horny-base], [http://bnp.hansfaust.de/index.html BnP], Regarding 680x0 emulation, there are several options that could be considered *[https://github.com/aros-development-team/AROS/blob/6722a0ae9e03fe5d26e32703360bd2059e0864cc/rom/m68kemu/README.md?plain=1#L424 m68kemu.library] for some Amiga productivity where the cpu is emulated and the system calls are redirected to Aros ones *[https://github.com/BlitterStudio/amiberry amiberry] (winuae) for everything else like games *[https://github.com/jonx/AROS/tree/aarch64-darwin-graft/arch/all-darwin/libs/emu68k emu68k] Youtube [], [], [https://www.youtube.com/watch?v=X4fmWAIv7FE Aros native on Pi3b], [], [], [https://www.youtube.com/watch?v=TSxlYb1eQWU Installed on Pi3b+], [], [], [https://www.youtube.com/watch?v=NFF1H3jCoz8 testing Aros native on Pi400], [], [], [https://www.youtube.com/watch?v=nIVx7mh1E1Q&pp=ygUHYXJvcyBwadIHCQkTDAGHKiGM7w%3D%3D Aros on Thumb 2 based 32bit-ish ARM STM32H743 board], [https://gpiozero.readthedocs.io/en/stable/installing.html Current] [https://gpiozero.readthedocs.io/en/v1.2.0/api_boards.html old support for gpiozero is unknown at present] [https://energenie4u.co.uk/res/pdfs/ENER314%20UM.pdf and associated 433MHz equipment] [ USA X10 security and lights via USB] [ OpenHab with Shelly Smart Plug connected over Wi-Fi, controlled by MQTT or HTTP] The status of AROS native ARMv6 for 32bit RasPi was OK. System booting, USB working (although with some issues but plans to fix them). 32bit native [http://www.aros.org/nightly1.html ARMv6 32bit nightlys] raspi-armhf-system raspi-armhf-contrib unbz2'd to fat32 microSD ===Hosted=== AArch64 CPU backend for AROS, a Cocoa/Metal display, clipboard / host-volume / CoreAudio / BSD-sockets bridges, GPU 2D via gpufx.library, a 68k→AArch64 JIT (run68k), and a full Rust std port. On [https://www.jkn.me/blog/macaros-aros-on-apple-silicon/ latest Apple Silicon] [https://github.com/jonx/Macaros early buggy alpha version of hosted Aros .dmg on MacOS12+]. Please use MACAros github for discussion, features etc and possibly [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2030&pid=13910#post_13910 here] [http://www.aros.org/snapshots1.html old linux and android hosted 32bit] ===Good sites to visit=== *[https://github.com/raspberrypi/firmware/tree/master/ Raspberry Pi Firmware build] *[https://www.raspberrypi.com/documentation/computers/software-sources.html Documentation] *[https://rpilocator.com/ RPiLocator] Linux only *[https://github.com/raspberrypi/linux Raspberry Pi Linux Build] *[https://www.raspberrypi.com/software/operating-systems/ PiOS Lite] and then [https://hstwb.firstrealize.com/ HST] *[https://dietpi.com/ DietPi] *[http://www.tinycorelinux.net/ports.html piCore] *[https://wiki.alpinelinux.org/wiki/Raspberry_Pi Alpine Linux] *[https://github.com/armbian/build Armbian] *[ PiMiga] *[ FydeOS] *[ TwisterOS based on ChromiumOS] *[https://note.com/jamesmondo/n/nc76e31402be8?hl=en BSD] Other alternative lighter smaller than Pi OS *[https://aros.sourceforge.io/nightly1.html Aros 64bit ARMV8 single core] *[https://www.riscosopen.org/wiki/documentation/show/Welcome%20to%20RISC%20OS%20Pi RiscOS on Pi3 and Pi4] *[https://github.com/michalsc/Emu68 ARM based realtime JIT 68k for amiga computers] *[https://github.com/JJDSNT/bellatrix/releases/ Alternative use of Emu68 on Pi3b] *[https://github.com/stevereaver/uaos uaOS with Emu68k] *[https://github.com/aros-development-team/AROS/commit/f80a268607dfae81b2db94755ab4e4d31ccb72d6 m68kemu library reference] *[ HaikuOS] *[https://github.com/raspberrypi/noobs NOOBS] os loader with successor [https://github.com/procount/pinn PINN] *[https://github.com/maxnet/berryboot berryboot] *[https://github.com/brianwiddas/pi-baremetal Bare Metal Access on Pi 32bit] [https://pinout.xyz/ GPIO 40 pins] [https://learn.sparkfun.com/tutorials/raspberry-gpio/gpio-pinout pinout] Some exceptions: *Physical pins 27, 28 (GPIO0, 1) are an internal I2C bus and should not be used *The other I2C on pins 3, 5 (GPIO 2, 3) can be used generally, but be aware they have permanent pull-up resistors to 3.3V *For MIDI use USB but there are dedicated UART pins 8, 10 (GPIO 14, 15). With a HAT it's more awkward -- you need to know which pins are used by the HAT and avoid them. Hopefully this will be documented. Remember all GPIOs are 3.3V (not 5V tolerant), floating/noisy inputs can cause odd behaviour, and that shorting the power supplies can cause instant death of the Pi. In the shell GPIO PIN/A/N,SET/N,GET/S,MODE/K,PULL/K Controls and queries hardware GPIO pins via gpio.resource which is stored in the rom or Devs/ - work in process *PIN -- (Required) Target GPIO pin number (e.g. 12). *SET -- Set pin output value to 0 (LOW) or 1 (HIGH). *GET -- Read and print current digital input level (0 or 1). *MODE -- Configure pin mode: IN (Input), OUT (Output), ALT (Alternate). *PULL -- Configure pull resistor: NONE, UP, DOWN. EXAMPLES <pre> GPIO 12 MODE OUT GPIO 12 SET 1 GPIO 12 GET GPIO 13 PULL UP </pre> ==== Hosted ==== =====64bit===== [https://www.arosworld.org/infusions/forum/viewthread.php?thread_id=2019&rowstart=80&pid=13667#post_13667 Linux hosted Pi build] [https://github.com/BlitterStudio/aros-compiler-docker Aros Docker for various systems], [https://github.com/aros-development-team/AROS/commit/d84b9a337f9aa059154d9af69275935125166bdd Apple Silicon support] =====32bit===== Ubuntu VM approach to compiling [http://lallafa.de/blog/2013/06/building-aros-hosted-for-raspbian/ Linux hosted AROS June 04, 2013] ../AROS/configure --target=linux-armhf --enable-includes=/usr/arm-linux-gnueabihf/include --x-includes=/usr/arm-linux-gnueabihf/include --x-libraries=/usr/arm-linux-gnueabihf/lib arm-elf- is symbol-linked to arm-linux-gnueabi- (arm-linux-gnueabi- is more correct in this case, because it's going to be compiling the ARM AROSBootstrap for ARM Linux) *armel - many of the "android" machines require since the entire OS is made for soft float VFP. *armfp - Efika MX target, Raspberry PI, EfikaMX, Pandora and virtually everything (VFP) Keep in mind it's possible to start hardfp AROS hosted on softfp system, though, as long as no calls between AROS and host require floating point parameters. NOTE: hardfloat objects *cannot* be linked with softfloat objects - they have a different ABI. Just keep in mind the arm nightly build machine is quite complex beast. It needs the x86_64 host compiler to compile AROS tools. The arm version is built every night using gcc-4.6.2 crosscompiler (built together with AROS) and successfully builds armel and armhf linux hosted targets. *needs an AROS code compiler for ARM target *as well as unix compiler for ARM linux host (would be best to have both softfp and armhf, we have softfp only now) with full set of libraries and includes. with—disable-crosstools $AROS_CC is always a wrapper around $KERNEL_CC ? If so, this is wrong for some ports. This can break Darwin, Windows and Android port. Yes, Android port will build. And even work. But it's not good because the port will not be ABI-compatible with other ARM ports. Android's ABI is different from GNUEABI. For example: <pre> enum test {foo, bar}; enum test testvar; </pre> sizeof(testvar) will be equal to sizeof(int) in GNUEABI (Linux and AROS) and sizeof(short) on Android. This affects linking objects from static linklibs, for example. Previously everything worked because $AROS_CC was a wrapper on top of $HOST_CC. And a real crosscompiler was used on non-ELF hosts. Android is the same. $KERNEL_CC is incompatible with AROS. compiler=kernel is appropriate _ONLY FOR CODE WHICH RUNS ON HOST OS_ (or barebone hardware, if we talk about native). This includes bootstraps, their linklibs, and host-side dynamic libraries (Windows makes extensive use of them because of architectural considerations. No single AROS object should be compiled with this setting. $KERNEL_CC is really compatible with AROS *ONLY IN LINUX-HOSTED* and no more. On other systems (Darwin, Windows, Android) this is not true any more, and compiler=kernel is never going to work. If you want to compile your AROS module against host OS includes, append the following to USER_INCLUDES (or USER_CFLAGS, this is effectively the same): -isystem $(GENINCDIR) $(KERNEL_INCLUDES) $(KERNEL_INCLUDES) expands to: -isystem <your_os_includes> -isystem <host_OS_gcc_private_includes> -nostdinc This makes AROS compiler adhering to host OS APIs. If you want some preprocessor symbols based on what your host OS actually is, add something like -DHOST_OS_$(AROS_HOST_ARCH). Why is there $(GENINCDIR) at all? Because host OS has its own libc includes, which would conflict with AROS ones. And the host OS libc is not binary-compatible with AROS one. Why doesn't Windows-hosted port use $(KERNEL_INCLUDES) ? Because WinAPI includes conflict with AROS ones in fundamental typedefs, like WORD, BYTE and BOOL. It's almost impossible to deal with this in any other way than rewriting WinAPI definitions using AROS types. Building under centos 6.3 (i386) currently, and AROS creates the toolchain itself. haven't yet committed the necessary changes but "./configure --target=raspi-armhf" is enough to start, then "make arosboot-raspi" will generate arosraspi.img (containing the bootstrap, kernel.resource, and exec.library) as well as arosraspi.rom (containing all the other essentials components such as dos, graphics etc). It will also copy over a config.txt file to make the raspi bootstrap code load the correct kernel, and a cmdline.txt that enables exec debug output. *armel = typically Debian 6, Ubuntu Maverick, Android, *armhf = typically Debian 7, Debian 8, Ubuntu Precise, Cross-compiling Ubuntu ARM softfp <pre> sudo sh echo 'foreign-architecture armel' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armel] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armel.list apt-get update apt-get install gcc-arm-linux-gnueabi libx11-dev:armel libsdl-dev:armel </pre> <pre> ./configure --target=linux-arm --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabi/include </pre> Cross-compiling Ubuntu ARM hard-float <pre> sudo sh echo 'foreign-architecture armhf' >>/etc/dpkg/dpkg.cfg.d/multiarch echo 'deb [arch=armhf] http://ports.ubuntu.com/ precise main universe' >/etc/apt/sources.list.d/armhf.list apt-get update apt-get install gcc-arm-linux-gnueabihf libx11-dev:armhf libsdl-dev:armhf </pre> <pre> ./configure --target=linux-armhf --x-includes=/usr/include \ --enable-includes=/usr/arm-linux-gnueabihf/include </pre> Now, the AROS build is configured properly and all you need to do is: make ==Build== ===64bit=== ===32bit=== # download/checkout the source someplace, e.g. /build/AROS-Src/ # make a directory to store external sources AROS downloads, e.g. /build/Ports # make a build directory, e.g. /build/aros-raspi-armhf # cd into the build dir, configure, and then run make -: <pre> >cd /build/aros-raspi-armhf >/build/AROS-Src/configure --target=raspberrypi-armhf --with-serial-debug --enable-ccache --with-portssources=/build/Ports >make >make arosboot-raspi </pre> then copy the files from /build/aros-raspi-armhf/bin/raspi-armhf/AROS/ onto an sdcard, and download/copy the Raspi firmware files onto it. You should then be able to boot the sdcard on your RasPi. The current W.I.P tree to svn. it can be built as follows .. <pre> ./configure --target=raspi-armhf make arosboot-raspi </pre> That will generate arosraspi.img, arosraspi.rom and config.txt in bin/raspi-arm/AROS - so either copy just those files to a fat formatted SD card (with the firmware files on), or copy the whole contents of the AROS folder. NB - if you have a Linux/other install, backup the existing config.txt first arosraspi.img contains the bootstrap (which has very basic mailbox code, framebuffer/gpio init, and console "emulation" via code pinched from our libbootconsole), kernel.resource, and exec.library arosraspi.rom contains all the other components needed to boot AROS. The config.txt file will tell the RasPI bootstrap to load the arosraspi kernel and ramdisk (rom). the bootstrap has minimal mailbox code, planning on adding either a resource or library that driver/app code will use to access it (likewise for GPIO) Help building AROS hosted on Linux ARM Was looking a way to use more my Handheld ARM based called Pyra (Dragonbox Pyra) an ARM (Omap5 cpu with 4GB ram) linux based machine (Debian Buster v10 with kernel 5.6.19 adapted) and have a try to compile the latest Aros sources by Deadwood directly on this device. Compilation stops after build libpopupmenu.a and trying to build libatomic have this error: <pre> Configuring build in bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic configure: WARNING: unrecognized options: --disable-nls, --without-x checking for --enable-version-specific-runtime-libs... no checking for --enable-generated-files-in-srcdir... no checking build system type... arm-unknown-linux-gnu checking host system type... arm-unknown-aros checking target system type... arm-unknown-aros checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for arm-aros-strip... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-strip checking for a thread-safe mkdir -p... /usr/bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking whether make supports nested variables... yes checking for arm-aros-gcc... /media/farox/pyra2/arosbuilds/toolchain-core-armhf/arm-aros-gcc checking whether the C compiler works... no configure: error: in /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic': configure: error: C compiler cannot create executables See config.log' for more details make[2]: *** [mmakefile:4489: /media/farox/pyra2/arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic/.configured] Error 77 [MMAKE] make --no-print-directory TOP=/media/farox/pyra2/arosbuilds/toolchain-core-armhf-build SRCDIR=/media/farox/pyra2/arosbuilds/AROS CURDIR=tools/crosstools/gnu TARGET=tools-crosstools-gcc-libatomic-configure -s --file=mmakefile tools-crosstools-gcc-libatomic-configure failed: 512 [MMAKE] Error: Error while running make in tools/crosstools/gnu: No such file or directory make[1]: *** [Makefile:361: linklibs-libatomic] Error 10 make: *** [Makefile:183: crosstools] Error 2 </pre> looking at config.log on arosbuilds/toolchain-core-armhf-build/bin/linux-arm/gen/host/tools/crosstools/gnu/gcc/arm-aros/libatomic found that arosbuilds/toolchain-core-armhf/arm-aros-ld: cannot find -laeabi so do make linklibs-aeabi-arm-quick and the missing lib was built. now the next stop is at fatal error: bits/libc-header-start.h: No such file or directory and fatal error: sys/cdefs.h: No such file or directory in many places so after checking that have this missing include files i have noted that my include path is a bit different, standard searching path is /usr/arm-linux-gnueabihf but in my system is /usr/include/arm-linux-gnueabihf so if i add my path to some mmakefiles compilation goes on....but is a better way to add this path to avoid every mmakefiles to be changed? fixed with adding -I/usr/include/arm-linux-gnueabihf to where is missing on mmakefiles like USER_INCLUDES := -isystem $(GENINCDIR) -I/usr/include/arm-linux-gnueabihf $(KERNEL_INCLUDES) P.s. I have changed many mmakefiles and have at least compiled (after many hours) the toolchain doing make every time in arosbuilds/toolchain-core-armhf-build (also have to disable making tests under cplusplus but don't remember the directory ...) but ask an help to have an automated way to correctly build without modify mmakefiles. Last time built armhf target was around 2 years ago. At that point built is via cross-compilation from linux (ubuntu 22.04) using linux armhf crosscompiler (this can explain the path differences you are experiencing) as well as using AROS gcc cross-compiler in version 6.5.0 (build with option 21) in rebuild.sh). Since then AROS GCC has been updated to 10.5.0 and don't believe anyone tried to build the armhf target again. My suggestion would be to downgrade GCC to 6.5.0 (via editing AROS/config/gcc_def file) and try to first build using cross-compilation from x86_64 linux. Once that works, you will have a "template" to compare to native compilation under arm linux. Thanks for your suggestion...but think the toolchain with GCC 10.5.0 is compilable if i found a way to pass the path of my system to the script that build (option 21 on rebuild). The other only changes are (but don't know where to modify...) is to add the build of libaeabi and disable the building of some tests under cplusplus that use exceptions and is not supported under ARM. try to crosscompile with my Linux amd64 PC. For paths look into core-linux-armhf/bin/linux-armhf/gen/config/target.cfg. A number of build-wide variable is set there containing paths to local build system. These variables and the target.cfg file are generated by AROS ./configure script. Thanks compilation now go forward...changed target.cfg under "toolchain-core-armhf-build/bin/linux-arm/gen/config" and do make on "toolchain-core-armhf-build" dir. Need to find where to enable build libaeabi.a so can build the entire toolchain with option 21 of rebuild.sh Found something that looks like libeabi in AROS/arm-all/arm-aeabi/mmakefile.src. Try adding a third line there: #MM- linklibs-armhd : libklibs-aeabi-arm Don't remember needing this library. Possibly the 6.5.0 GCC somehow does this while 10.5.0 is missing this. Try adding this line (and the variant "linklibs-armhf" instead of hd) but it did not solve the automatic building of the missing lib. I must do "linklibs-aeabi-arm-quick". Anyway after have build the aeabi lib i succefully built the toolchain (after many hours...). Smile To test I restarted from selecting option 21 (on rebuild.sh) but after many hours i get the same error of the kernel includes not found...maybe i need to modify the configure script for my case. With the toolchain built i try to build the core-linux-armhf (DEBUG) (option 22) but after a while it stopped with "cannot find -laeabi " so i made it built manually...and now i can continue compiling...i'll let you know if all goes ok. == Hardware == ===64bit=== ====BCM2712==== With the Pi5 Broadcom VideoCore 7 vc7 is an integrated GPU with 12 cores and up to 800 MHz clock. VideoCore VII is capable of OpenGL ES 3.1 and Vulkan 1.2. The driver support for the Raspberry Pi continues to build upon the [https://lore.kernel.org/dri-devel/20230928114532.167854-1-itoral@igalia.com/ open-source V3D driver] stack within [https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25450 Mesa] hopefully be merged for Mesa 23.3 *Raspberry Pi M.2 HAT+ Expansion Board *Geekworm X1001 PCIe to M.2 Key-M NVMe *Geekworm X1003 PCIe to M.2 HAT NVMe SSD PIP Board for Raspberry Pi 5 *Pineboards Pi Hut HatDrive! M.2 HAT 2024/V4 *Hat+ Gen2 Gen3 Nvme *GeeekPi 52Pi N04 for Raspberry Pi 5 NVME M.2 * *2024 RPI AI HAT - Hailo 20TOPs no LLMs *2026 RPI AI HAT+ 2 - Hailo 40TOPs slightly better? [https://www.raspberrypi.com/documentation/accessories/camera.html Cameras for Pi] *Raspberry Pi camera module, the V3 with Sony IMX708 back-illuminated CMOS 12 Megapixel sensor *Raspberry Pi Camera Module V2 – 8MP Sony IMX219 Sensor *Raspberry Pi camera Rev 1.3, 5MP 1080P OV5647 image/video module, 2592 x 1944 pixels ====BCM2711==== With the Pi4 an ARM a72 cpu is about x3 times the size of an a53 in the Pi3 the 2711b line used more power when idle, compared to the 2711c *2018 Raspberry Pi PoE-HAT Power Over Ethernet Hat *2020 Raspberry Pi PoE+HAT Power Over Ethernet Hat *[https://github.com/axizo-pi/V3DLib vc6 V3D 4.2] is derived from [https://docs.broadcom.com/doc/12358545 vc4], but it is significantly different The QPU pipeline stays mostly the same, you still have an add ALU and a multiply ALU and it can issue two ALU OPs per cycle. There is still 4 SIMD lanes, interleaved over 4 cycles. The instruction encoding for the QPUs is different, but the core instructions are the same. Instructions for packed 8 bit int math has been dropped, along with most of the pack modes. Instructions for packed 16bit float math has been added (2 floats at in a single operation) With vc5/vc6, you write two packed 16f value to the tilebuffer (or four writes of 32f, if you are using the rgba32f framebuffer). And there is a handy vfpack operation which allows you to pack two f32s into a single 32bit value in a single instruction. You can vfpack directly into the tile buffer register. the multiply ALU can now fadd, so you can issue two fadds per instruction. the add ALU has gained a bunch of new instructions the A and B register files have been merged. You still only get an A read and a B read per instruction, but they read from one big register file (which means the underlying memory block has gone from two sets of "one read port, one write port" to one "two read ports, one write port" block) The theoretical max FLOPs per QPU remains the same at two per cycle, other than the bump from 400mhz to 500mhx but it looks like a lot of effort has been put putting those theoretical FLOPs to better use. *vc4 could run one or two threads per QPU. When you ran in two thread mode, the available register file halfed to 32 registers. *vc5 added a four thread per QPU mode, with 16 registers per thread. *vc6 doubled the size of the register file. You could now use all 64 threads in two thread mode and 32 registers in for thread mode. Single thread mode was removed, you always have at least two threads. With the threading improvements, the QPUs should spent much less time idle waiting NOPs for memory requests. Most of the design changes have gone to improving the fixed function hardware around the QPUs. A fixed function blend unit has been added, which should reduce load on the QPUs when doing alpha blending. hope software blending is still possible The tile buffer can now store upto 4 render targets (up to 128bits per pixel, so if you are using 4 32bit render targets, you can't have a depth buffer) A MMU, allowing a much simpler/faster kernel driver. Many more texture formats, framebuffer formats. All the features needed for opengl es 3.0 H.265 / HEVC decoder is a HEVCv2 Main 4:4:4 10 design supporting bitstreams up to profile 5.1 HEVC hardware decode supports 4kp60, 10-bit. Audio output is pretty much unchanged, but the HDMI audio channels now support 8x192kHz bitrates Each ALU typically have 2 floating point operators, and as you pointed out in a earlier post videocore 6 is no exception, with both a multiply and additive floating point operator. Thus theoretical GFLOPs are calculated with both operators in mind. That is what the 2 in my formula represents, and is common across any modern programmable shader, whether you calculate Nvidia, AMD, Intel, Boardcom or any other company's GPUs. Total ALUs * 2 * GHz clock = GFLOPs, In the case of Raspberry Pi 3, it's 24 ALUs * 2 operators * 0.4GHz = 19.2GFLOPs If the Videocore 6 does indeed only have 16 ALUs (16 * 2 * 0.5GHz), you'd have only 16GFLOPs but they are better utilised Possible maximum performance <pre> VideoCore IV @ 250MHz: 250 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 24 Gflop/s VideoCore IV @ 300MHz: 300 [MHz] x 3 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 28.8 Gflop/s VideoCore VI @ 500MHz: 500 [MHz] x 2 [slice] x 4 [qpu/slice] x 4 [processor] x 2 [op/clock] = 32 Gflop/s </pre> Faster LPDDR4 memory. ====BCM2837==== With the Pi3 * Broadcom BCM43438 chip provides 2.4&nbsp;GHz 802.11n wireless LAN, Bluetooth Low Energy, and Bluetooth 4.1 Classic radio support, 3B+ [https://github.com/aros-development-team/AROS/commit/afa5bc0bb17d5dd06bcfdbac00853a3799ca8d76 LAN7515] The overclock ability has diminished with each chip version as the energy usage has increased. BCM2837 is one of the warmest yet and benefits from active fan cooling if all four cpu cores are in use for a short while. Video playback is not affected due to the custom support in the GPU. 5 V / 2.4 or 2.5 amp power supply recommended if all four cpu cores are running, else throttling (cpu slowdown) might occur. Dual VDP and scalable QPU in VC4 ARMv8-A has [https://developer.arm.com/documentation/102412/0100/Privilege-and-Exception-levels privilege levels] where userspace typically runs at ‘EL0’, the kernel at ‘EL1’ or ‘EL2’ and the firmware at the highest level ‘EL3’. ===32bit=== === Core Kernel === ====BCM2708(family)==== which includes the [http://elinux.org/RPi_Hardware BCM2835] (ARM1176JZF-S 700&nbsp;MHz CPU + VideoCore IV GPU + up to 1GB RAM) *Framebuffer (fb) using mailbox *IRQ scheduler, etc *Arasan based SD Card controller *Synopsis DesignWare USB 2.0 OTG controller [http://networkdirection.net/index.php?option=com_content&view=article&id=106:rasperry-pi-usb-controller&catid=45:raspberry-pi&Itemid=54 Unofficial DOCS pdf], [dwc_otg.c FreeBSD], [], [https://www.riscosopen.org/viewer/view/mixed/RiscOS/Sources/HWSupport/USB/Controllers/DWCDriver/ RiscOS USB Driver], [https://www.riscosopen.org/forum/forums/5/topics/878 RiscOS USB Discussion], [https://www.riscosopen.org/forum/forums/11/topics/1893 Other USB RiscOS], [http://plan9.bell-labs.com/plan9/index.html Plan9 Miller's usb] http://plan9.bell-labs.com/sources/contrib/miller/, [https://github.com/Chadderz121/csud CSUD driver], *[http://www.smsc.com/media/Downloads_Public/Data_Sheets/9512.pdf SMSC 9512] USB LAN/Hub chip *CMOS RAM *VCHIQ port which sends messages to the GPU e.g. for mouse, keyboard, audio on HDMI, etc *Audio Driver *Serial Peripheral Interface Bus (SPI) *[http://www.susa.net/wordpress/2012/06/raspberry-pi-pcf8563-real-time-clock-rtc/ I2C registers] *I2S *Universal Asynchronous Receiver Transmitter (UART) *[http://elinux.org/RPi_BCM2835_GPIOs GPIOs] and [http://www.adafruit.com/blog/2012/08/17/broadcom-bcm2835-peripheral-memory-map-and-gpio-alternate-use-chart-piday-raspberrypi-raspberry_pi/ Alternative view of GPIO] BCM2836 * For Pi B+, PI 2 and Pi 3 SMSC LAN9514 chip adding 10/100 Ethernet connectivity and four USB channels to the board *[http://www.andrewscheller.co.uk/rpi_pcb_modules.html PCB], [http://elinux.org/RPi_Low-level_peripherals Low level features], Implemented so far... # Modify the configure system so that it correctly builds for the arm hardware float raspi target. # Implemented the bootstrap to load the aros modules and prepare the arm to jump into them. Reworked the x86 console support so that parts can be stolen for raspi to use since t has no basic functionality to output to the display. # Implemented a kernel.resource to prepare the raspi for running aros and provide the low level api calls to expose available resources and allow exec, etc function. # Implemented serial debug support # Implemented the exec (and kernel) functionality required to make multitasking work (and interrupts, exceptions, syscalls, etc) # Implemented a timer.device to utilise the hardware timers. # Implemented a very basic gfx driver to expose the hardware's framebuffer. # Implemented an SD-Card driver for AROS which presently only supports the raspi's chipset but can easily be modified to support all sd-card hardware and media. # Fixed the fat filesystem support in AROS so that it can boot on RasPi's normal SD-Card setup. The "rom" image files needed use a different filename than the default linux, etc images so can be easily installed without harming the existing files - you only need to change the loaded images in the config file to get aros to boot. # Updated the build scripts to automatically download the necessary raspi firmware files and wrap it all up so that you can simply extract the archive to a fat formatted sdcard and boot it on the raspi without having to get anything else. # fix everything in contrib and ports to build for raspi (needs proper testing/fixes but allows every component to actually compile at least, including owb) + numerous other fixes to get things working on arm/raspi .. Improvements... # Implement a USB chipset driver "OR" finish the existing one [https://github.com/aros-development-team/AROS/commit/c07d13c724f944674be5db54fc6a71ee72a01809 usb otg] - the current code is mostly a skeleton that should initialise the chipset and then needs relevant code to support the different transfer types. It also has the "virtual" hub code in place to represent the raspi's USB port (from poseidons p.o.v) # Implement a driver for the USB NIC (a few weeks - depends on USB above) # Write an [https://github.com/aros-development-team/AROS/commit/d55d0f74d20b769bbb8c8d386e5c1d7a9154f05a audio driver] (a few weeks - independent of USB) and [https://github.com/aros-development-team/AROS/commit/e93a4c245f27a87c9c4c1d39206694b39059998a HDMI] # fix syscall bug in the current raspi kernel code # Graphics depend on having a decent "bcmdma.resource" implemented as to use the cpu's dma engine. The sd card driver needs to use it for transfers to/from the controller - and the gfx system needs to use it for "blitting". # [https://github.com/aros-development-team/AROS/commit/4019d84e4975d4dad987a12d57fe108f5ac048e6 Improve the gfx driver], [ vc4gfx HIDD] add [http://dri.freedesktop.org/wiki/VC4/ Gallium3D support] # [https://github.com/aros-development-team/AROS/commit/b13905b3e8e45b089f520b44692c81affddd066f Improve] the [https://github.com/aros-development-team/AROS/commit/3a876755c070f5c73c4f53c7f4d35b4f923088b9 sdcard] device driver - which is also pretty basic but should work with most cards, rework it to also support pci, etc. sd card interfaces on x86 # The current code using very rudimentary access to the gpio interface - so that should be implemented as some resource for other components to access, as-well as the i2c interface exposed over the gpio interface. that should have a hidd class implemented which uses the gpio resource to communicate. Boot up typical for most other OSs before the open sourcing of many binary blobs from 2017 onwards On power-up, the rpi [http://www.open.com.au/mikem/bcm2835/ BCM 2835] [https://github.com/hermanhermitage/videocoreiv VideoCore4] GPU, not the ARM CPU, is in control, and the SD card slot is the only peripheral device with power. The firmware burned into the BCM2835's VideoCoreIV GPU PROM requires a DOS-style partition table; a FAT-formatted first partition; and the freely redistributable but closed sourced Broadcom files “bootcode.bin” and “start.elf” in that partition. The boot sequence carries out several pre-boot tasks *On powering of the rpi, the GPU reads and executes bootcode.bin, which then loads start.elf *The GPU loads the “start.elf” file, eventually, into the L2 cache and then executes it *configures the memory split for the CPU and GPU *reads and parses “config.txt” from the same partition on the SD card and applies the settings (like a PC’s BIOS settings) *loads the “kernel.img” file, again from the same partition *activates the CPU to begin executing the loaded kernel image The CPU/GPU memory split is hard-coded into start.elf, so Broadcom provides three start.elf images, to give 32M, 64M, or 128M to the GPU for multimedia performance, and the remainder to the CPU. RPi uses [https://github.com/raspberrypi/firmware some closed source loaders] and at some point it loads a binary blob named "kernel.img" at 0x8000, at that point there would be a rudimentary Aros alive. If one wants to use the SD-card then there would have to be a driver for the interface and a fat filesystem handler (SD-card has to be formatted to fat filesystem) Boot code and kernel are now linked together and made into that binary blob, just for starters. Raspberry Pi uses [http://kernelnomicon.org/?p=133 u-boot] and [http://kernelnomicon.org/?p=138 UBoot] as bootloader, there's already some code in the Efika MX port for that. UBoot is a native bootloader and not just for the raspberry pi, it loads after start.elf. You can find Efika MX port from arch implementations, some hacking is needed for the mmakefile.src'es as iit dates back to before the Aros crosstool era or else you get some weird errors while building. You also need to code the bootstrap and serial handling. At the moment it seems that a fastest route for the native build would be to make one binary blob without using the package system. Raspberry's memory layout is pretty simple and if the implemented u-boot doesn't support loading other modules <pre> ? - alias for 'help' mtest - simple RAM test autoscr - run script from memory base - print or set address offset bbm - BBM sub-system bdinfo - print Board Info structure boot - boot default, i.e., run 'bootcmd' bootd - boot default, i.e., run 'bootcmd' bootm - boot application image from memory bootp - boot image via network using BootP/TFTP protocol cmp - memory compare coninfo - print console devices and information cp - memory copy crc32 - checksum calculation echo - echo args to console fatinfo - print information about filesystem fatload - load binary file from a dos filesystem fatls - list files in a directory (default /) go - start application at address 'addr' help - print online help iminfo - print header information for application image itest - return true/false on integer compare jade - loadb - load binary file over serial line (kermit mode) loads - load S-Record file over serial line loady - load binary file over serial line (ymodem mode) loop - infinite loop on address range md - memory display mm - memory modify (auto-incrementing) mtest - simple RAM test mw - memory write (fill) nfs - boot image via network using NFS protocol nm - memory modify (constant address) pci - list and access PCI Configuration Space ping - send ICMP ECHO_REQUEST to network host printenv - print environment variables rarpboot - boot image via network using RARP/TFTP protocol reset - Perform RESET of the CPU run - run commands in an environment variable saveenv - save environment variables to persistent storage saves - save S-Record file over serial line setenv - set environment variables sleep - delay execution for some time tftpboot - boot image via network using TFTP protocol USB - USB sub-system usbboot - boot from USB device version - print monitor version </pre> And there is one more thing about modular ports. In order to actually implement this, your bootstrapping environment should provide the ability to load several files. On PC this is provided by GRUB2. on CHRP you can read filesystem via OpenFirmware, and Sam's Parthenope relies on modified u-boot. If your bootstrap allows to load only a single file, then you stuck with monolithic kickstart. By the way... u-boot allows not only to boot up a single uImage or zImage, it also allows to write client programs AFAIK. With this approach, you actually can write modular bootstrap for ARM AROS using unmodified u-boot. Most used [http://www.compulab.co.il/workspace/mediawiki/index.php5/U-Boot_quick_reference uboot options] are fatls usb 0:1, the reason behind INTB_KERNEL is to allow use of the standard Exec function AddIntServer() to add interrupt handlers for hardware drivers etc. AmigaOS never used it for abstract hardware drivers. AmigaOS routed only raw hardware IRQs there. Their assignment was hardcoded. As well as number of them. Actually on AmigaOS every bus has its own interrupt subsystem. For example PCI bus. PCI interrupts on Amiga are routed to a single exec interrupt. 1:1 relationship between CPU and hardware interrupts is present only on PC. IMHO we miss things like AddInterrupt/RemInterrupt methods on our PCI subsystem's device class. PCI bus class should map these methods to whatever is appropriate. This is how it is done on AmigaOS and friends. When these are implemented, raw kernel.resource API will be needed only for several PC-specific drivers with hardwired resources. Exec IRQs are real IRQs only on Amiga hardware. On other machines they can be emulated where appropriate (VBlank is a good example). kernel.resource is meant to be different, its IRQs are hardware-agnostic, they are plain "Hardware IRQ number X, whatever this means". They are low-level actually, and meaningful only in the context of a particular system. Was that not the transition from irq.hidd to kernel.resource? No. A long time ago there was another hacky bit named INTB_TIMERTICK. It was "abstract timer interrupt", used by timer.device. It was the same as VBlank, but with larger frequency. I removed it, because kernel.resource API was a cleaner way to access this interrupt. Furthermore, there can be more than one timer in the system. Thinking about bringing back timer HIDD definitions again. hpet.resource is a bad idea. Can someone please enlighten me a little on how the scheduler is meant to work? Poseidon.library creates its "Poseidon Event Task" during RTF_COLDSTART -> then calls Wait(), and ends up in limbo because wait disables interrupts (used for the scheduler heartbeat), and basically waits forever because the sigbit is never set, since krnSwitch doesn't switch the task unless TF_SWITCH is set, and no codepath run during this seems to set it?? TF_SWITCH does not disable/enable switching. This flag just enables to run user-supplied hook when the task is being switched away. It is completely safe to call Wait() in Disable()d state. Doing this actually temporarily breaks this state. IDNestCnt gets remembered in struct Task, then next task is selected, and its IDNestCnt is restored in sysbase (see kernel_scheduler.c). If there are no other tasks, then your cpu_Dispatch() should enable interrupts on the CPU and enter idle mode. See x86 implementation for good example. You miss what happens next... 1. KrnSwitch() saves context of your task, saves IDNestCnt (core_Switch() and cpu_Switch()), then drops into cpu_Dispatch(). 2. cpu_Dispatch() calls core_Dispatch. Then two cases are possible: 2a. There is a READY task. It is picked up, its IDNestCnt is restored in SysBase, then cpu_Dispatch() needs to restore registers and exit. The next task is run. 2b. There are no READY tasks. core_Dispatch() returns NULL. In this case your cpu_Dispatch() should enter idle loop. It should just enable interrupts on the CPU and put it on halt. This allows it to process hardware interrupts. Eventually some of your interrupt handlers wakes up your task and puts it into READY list. My heartbeat interrupt has been slowed atm to help debugging - but it never actually gets a chance to fire because of the Wait() disabling interrupts. Perhaps you have forgotten to enable interrupts in your idle loop. There is a change in the format of AROS executables. Until now we were using Elf RELocable files which are usually used as intermediate object files. We had them for various reasons, one of them was how AROS files were built in the past. That days we had no real aros cross compiler and the option to embed relocation data in unix executables (or in executable files in general) was rather new and not every linux/unix system had it. Therefore we have decided to use intermediate files. Although it was somehow working (and it is still working :-)), it has some drawbacks. Therefore decided to introduce real Elf EXEC types, in first turn implemented on ARM target with option to expand in future to all other AROS architectures. The first patch was pretty easy and appeared to work somehow. It generated nice executables with embedded relocation info. Not only that, it also removed all global symbols adjusting relocation data to be relative to the beginning of the sections. That move reduced number of symbols in each executable significantly (depending on the file between 20 and 80% of all symbols could be removed). The only symbols that stayed in the file are local ones - due to the nature of the patch wasn't able to remove them since we have not seen them in the symbol hash table. The patch didn't worked though. The files were relocated, AROS kernel loaded, but it crashed very early. What happened? Well, the nature of ARM relocations happened :) Most of the relocation data on all machines is rather simple. Relocation can be absolute or pc-relative, sometimes the offset has to be bit shifted. On ARM v7 there is another one. There, when one wants to load an address of function/variable into register a combination of two instructions can be used: movw and movt. The first one loads immediate into lower 16 bits of a register while clearing upper 16 bits. The second one loads immediate into upper 16 bits without touching lower halfword. Loading of a pointer into a register looks like this: movw r0, #:lower16:label movt r0, #:upper16:label In this case there are two relocations - one for lower halfword and another for upper. If an overflow of lower 16 bits occurs during relocation process, the upper one should be updated as well. Unfortunately with current patch and with typical ARM executables there is not enough information to perform the calculations. There are two options - the first one would be to give up and go back to "fake" executables, another one would be to change from REL to RELA relocation info. The latter contains an addend, extra data which can be used to perform all the relocation calculations I need. Decided for the second option. The patch is already in the works. There is another function for the binutils' bfd backend to perform the final relocation. There can decide what to do with every reloc info, modify data and eventually strip some symbols. An advantage is - at this stage of the linking process have also full access to all local symbols so can change all relocations section relative and eventually strip all symbols from the files. === GPU === VCore developed by Alphamosaic Ltd and now owned by Broadcom. Most of start.elf runs on the GPU. Placing ALL the userland GPU code in the videocore.hidd isn't going to be a terribly big problem because the code they published is nothing more than a shim that sends data straight to the GPU to execute. The good news about this is that we only need to write our HIDD using the OpenVG API. The shim is relatively small codewise and lives in the ARM memory (the actual OpenVG code itself lives in the GPU RAM area and its loaded from start.elf). That's also the bad news. Our driver has to translate AROS video calls to OpenVG calls, for most tasks it should be easy, for some, not so much. It's still probably less difficult and less work, than controlling the GPU directly. The other good news is that anything done through OpenVG happens on the GPU, its truly accelerated. It also has some nice font functions, meaning we can lead into an accelerated text mode later. Basically, AROS resets or locks up when it tries to use AROS_ATOMIC_INC or DEC. If I comment out the byte/word operations in the header files and use non-atomic operations, the code works as expected. have read that the L1 cache needs to be enabled to use LDREX and co (which I also read is only meant to be used on multi processor systems with shared memory) - however I am certain this is correctly enabled. If you are using LREX or STREX, you should have L1 cache enabled, at least on the ARM CPU I work with at work. L1 cache is enabled by enabling the MMU *AND* setting the C and I bits in the CPU - the C bit is ignored, and the I bit only covers the 16 byte instruction pipeline if the MMU is not enabled. Can you verify that your assembly is generating LDREX/STREX? From the behavior, it almost sounds like its generating the default Semaphore locked atomics. Impossible. There are no semaphore-locked atomics. There are Disable()/Enable()-based ones instead. And there's a special #define AROS_NO_ATOMIC_OPERATIONS in this case, which tweaks Disable()/Enable() implementations not to recurse forever. I have tested this on ARMv5 which does not have ldrex/strex, it works fine. On those ARMs there's no way to have real atomics. On other OSes (like Linux) this is done by introducing things like atomic_t, which appears to be a complex structure, holding the value together with accompanying spinlock (implemented using swp). #warning "TODO: lookup optimal mmu table settings for raspi memory" /* Set up an identity-mapping for all 4GB */ for(x = 0; x < 4096; x ++) { pagetable[x] = x<<20 | (0x40002|0x80000|0x010000|0x00C00|0x04); } Shouldn't there be a second loop that sets the 'C' bit in the descriptor for the RAM pages? Currently, you have TEX=0, C=0, B=1 for all pages (Shared Device). You should have TEX=0, C=1, B=0 for RAM (Write-Through, Cached) So .. pagetable[x] = x<<20 | 2; should be enough? No, for RAM you need to change the '| 0x40' to '| 0x80' tell dosboot the correct defaults to use Please don't do this. This bootconfig.c is a deprecated legacy thing. I wanted it to go away completely with time. Instead, display drivers should auto-install themselves during own initialization phase. I. e. detect hardware=>instantiate itself. This should make things way simpler. With this approach you only need to add the driver into KS image to get the device autobooted. No hardcoded stuff. Currently VESA and VGA drivers do this, look there for examples. never rewrote ATI driver because i don't have any test system for it. they defined a smaller AROSCPUContext than the ExceptionContext - yet reference it as ExceptionContext in other places, and since it hasn't allocated enough storage for ExceptionContext, are corrupting memory/the structure (since the elements that are there don't map 1 to 1 with the exception context). AFAIK, AROS has been moving in a different direction to this in recent years. It is the job of graphics HIDDs to allocate bitmaps etc. so that they have the most suitable characteristics, including allocating them from GPU RAM where possible. The concept of chip RAM is only for legacy code, and most if not all non-68k platforms should have all system RAM marked as chip. BTW, is the video processing code you mention CPU code or GPU code? Also, IIRC we have support for "external memory allocators". Perhaps that's what we need for the allocation of GPU RAM through the mailbox. All hosted and x86 native ports should use proper context formats. trying to clarify if the vblank handler has to have run by this point to prevent this deadlock. Actually, no. Unless you have installed VBlank handler which should wake up at some point. Without VBlank there will be no quantum count. Consequently, there will be no forced preemption. But the rest will work, and multitasking will be cooperative (switch happens only when current task voluntarily gives up the CPU). Does it depend on the vblank having run before this point? and if yes what does that mean on systems where it might be able to run enough code (e.g. get to this point) before the vblank interrupt has triggered? What is it waiting for? It could wait for timer, in this case you need timer.device working. VBlank is currently needed for exec's quantum counter. In current native ports we have only a single timer, which is served by timer.device. VBlank is simulated by timer.device also. If your machine has two timers, then you can use one of them for VBlank, and another for timer.device, this will simplify things down. VBlank needs to be 50 Hz for historical reasons, many programs use it as cheap timer. I am periodically thinking about making some abstract mechanism to be able to change quantum source (and untie it from 50 Hz), but have no time to come up with something good. Additionally i started disliking timer.device hardcoded design when PC has got many timers (old 8253, APIC, HPET). Currently i think there should be some low-level entity representing tick source. timer.device should just select the most appropriate source for its units. The BCM2835 has 4 GPU based timer sources - 2 are used by the GPU, so im using Timer3 for our heartbeat and the remaining one will be free to the system. There is also the less capable ARM timer but that is dependent on the CPU frequency. Very good. You won't need any emulation. Set the heartbeat to 50 Hz and drive VBlank from it. Use other timer for MicroHZ. Can you use the 'econsole.hook' I make for debugging the Sam460 via the serial port? It provides a before-anything-else shell prompt on the serial port. You can then do 'NewCLI' to test your graphics, or use any DOS command in shellcommands.resource. You should just be able to add econsole.hook to your module list, and use 'econsole' in your bootargs. So long as you have a working Exec/RawMayGetChar and Exec/RawPutChar, it should work. Also make sure to add shell.resource and shellcommands.resource for this. That should have done it. If you set "#define DEBUG 1" in arch/all-native/econsole/econsole.c, do you get any additional serial output? have added it to the build and added econsole to the command line - and can see the bootloader picks up on the emergency bootconsole tag, but I still only get the insert bootable media display? Im assuming it exposes a fake filesystem that tricks aros into booting? The contents of which are: ECON:AROS.boot Way to handle the scheduling code? The implementations I had been following were causing problems, due to cascading interrupts which I cant handle properly in the asm stubs just now (when they break disable etc.) - since it means detecting the interrupted codes cpu mode and getting the correct sp/lr for it, and that's just too tedious for arm. To work around this ive added a system idle task which does nothing - and when the scheduling code has no task to run switches this in and lets it run, thereby allowing the interrupts etc to resume until something does need to happen. Also, by adding accounting code to cpu_Switch() and cpu_Dispatch(), it should allow the system to log idle time correctly (as well as running tasks). have thought of also adding an additional task that never runs, solely to record time spent in IRQ handlers, but I digress.. was under the impression that kernel.resource should *never* be used outside of exec.library. This is a wrong impression. Michal started designing it because portable nature of AROS does not fit well into exec's API with all its assumptions. So, he started the new, hardware-agnostic kernel API from scratch. Yes, exec sits on top of it in places. But kernel always meant to be open thing. Otherwise it would not exist. it wasn't meant to be just used willy nilly by user code - but by lower system components (e.g. exec) so that they could be implemented in a more generic fashion, and the kernel resource itself hide the systems quirks. Adding new things there perfectly keeps up with our decision to minimize AROS-specific intervention into APIs which can clash with MorphOS/OS4 extensions. We want at least source-level compatibility there. Binary compatibility on PPC would be extremely cool, but at the other hand we have no maintainer for this, as well as their ABIs are a bit weird and far from optimal, especially MorphOS one, because it aims for m68k binary compatibility. It depends on what exactly is being implemented - there's no reason we should have everything crammed into kernel.resource if it doesn't need to be (i.e. if its better suited as a separate component/subsystem in its own right) The _LE versions are for when you have endian swapping taking place. If the graphics are the same endian as the CPU, no swapping should occur. I ran into a similar terminology problem in SDL with a friend insisting that his Radeon 7000 on his PC was big-endian. It is not, it just uses the same endianness for the graphics card and the CPU so no swapping was necessary. They were both little-endian. The _LE versions are because the PixFmts refer to the bitmap data being in big endian format in memory, for which the normal version would need to do endianness conversion before applying the shifts/masks. on this platform it is in _LE in memory also so we don't need the conversion hence using the _LE version of the call). would use _LE (if it's really little endian 16 bit mode). What is the bare minimum needed to implement a framebuffer based gfx driver, with our software handling the rest? I have tried with just a gfx class that only expose new/dispose/newbitmap - and having an onscreenbitmap used only for the framebuffer itself (with all other bitmaps being chunkybm, and the framebuffer's superclass also being chunkybm), but that alone isn't enough it seems? You can use workbench/hidds/sm502/ as your example - it is as simple as I could make it. So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. I so far have -: vc_init: queries the gpus memory, and sets up a fake memory handler for it, then adds the bootmode driver and returns saying all is well vc_gfxhidd:New: sets up some fake syncmodes to test with and creates the real gfx object. vc_gfxhidd:NewBitmap: checks if its a framebuffer and uses the onbitmap class or uses the chunkybm class otherwise vc_onbitmap:New; creates a chunkybm object and then pushes the real framebuffer address into it as the buffer, So, AROS creates the framebuffer bitmap (I have verified this) -> so surely it should be capable of then rendeing into it? I don't actually create the framebuffer "bitmap object" myself - only as a result of being asked to. The code I currently have on SVN seems to create the framebuffers bitmap object fine, but then crashes in intuitions DisplayDriver callback. In particular it crashes performing the getattr on the system default pointer. don't expose MEMF_CHIP in an allocatable form so AllocSpriteData was failing (and other code later doesn't check if the values are valid == illegal memory accesses) vc4 had v8adds, v8subs, v8muld, v8min and v8max which operated on four 8bit uint values packed into a 32bit register. Multiplication was in the range 0.0 to 1.0 and addition/subtraction saturated. There were also a range unpacking/packing modes that allowed you to pack and unpack 8bit values into 32bit registers. RasPi has to speak to the "operating system" which runs on the GPU itself and request/free memory - it cant directly manage it itself, and so the managed functions were used to wrap these calls. The Arm and GPU share memory space. The framebuffer is shared. The Arm can write a pixel and it will appear on the screen (through GPU hardware) without flushing/copying being required. The GPU can composite multiple FB's in real time - so you have a number of surfaces defined which are rotated etc and composited in real time to the output. Copying can map from the address space of the Arm to the flat space of the GPU which takes some code, but I don't think whole buffers are copied. The DMA hardware can also access the whole memory space and can perform 2D fills and blits (no blending). This is documented in the peripheral spec posted. The DMA is just an Arm accessible peripheral and can be set up with low latency (e.g. microseconds). must use a 0xc0000000-based bus address to access SDRAM, yet non-DMA access should go via a 0x0-based bus address. For 2D dma, set TDMODE, and the spec says "interpret the TXFR_LEN register as YLENGTH number of transfers each of XLENGTH, and add the strides to the address after each transfer." so set STRIDE to pitch of the image, the width is XLENGTH and height is YLENGTH. You would fill by not setting the SRC_INC and point source to your fill data. The DMA cannot see the ARM's L1 cache, so you would map the framebuffer with ioremap_nocache. Depending on where the source data comes from, it may need an L1 cache flush. The DMA can see the L2 cache. Use 0xC0000000 bus addresses when L2 is disabled and 0x40000000 bus addresses when L2 is enabled. (actually just call virt_to_bus and you'll get the right address out). openGLES/openVG has high latency. Writing to framebuffer then reading it back is very inefficient (e.g. milliseconds). If you can drive it a unidirectional way, just streaming commands at then that is efficient. openVG is not implemented on top of openGLES - it uses the same hardware but as a first class interface To improve the Gfx driver, we will need a DMA resource implemented so can use to perform DMA operations. The Gfx driver will need this to perform blits. Actually MEMF_CHIP has to present, for historical reasons. This has been never fully agreed upon, but in ports i wrote i exposed the whole memory as MEMF_CHIP. The idea behind this is that CHIP is originally the memory where graphics and sound data can be put. On non-Amiga platforms there are no restrictions on this, so the whole memory is CHIP. Yes, many old software can misbehave with CHIP memory size larger than 2MB. But this actually applies only to m68k AROS which is going to run m68k binaries. In other cases it's quite logical to fix the program when porting. As to original question: yes, it's enough to have a framebuffer bitmap (one with aoHidd_BitMap_FrameBuffer set to TRUE) and PutPixel routine. It framebuffer can be served by chunky bitmap class, then you can simply create chunky bitmap with your own buffer (see how VESA driver does this). Chunky PutPixel is already there. struggling to determine what is the correct pixfmt to use for the 24/16/15 bit gfx modes on the RasPi. AFAIK it uses RGB565, for 16bit but im unsure what shifts etc should go with it? suffice to say Im getting the wrong colors so far lol. <pre> redmask: 0x0000F800 greenmask: 0x000007E0 bluemask: 0x0000001F alphamask: 0 redshift: 16 greenshift: 21 blueshift: 27 alphashift: 0 </pre> It should likely be vHidd_StdPixFmt_RGB16_LE This stuff is a bit confusing. The "names" of the stdpixfmts are based on the layout in memory, ignoring endianess. So for example: ARGB32: will be 0xAA 0xRR 0xGG 0xBB in memory on both big endian and little endian machines. The shifts and masks OTOH are based on pixel access (ULONG in this case), so differ depending on whether you run on big endian machine or little endian machine (that's why there's stdpixfmt_le.h and stdpixfmt_be.h in rom/hidds/graphics/). With the 16 bit pixel format it's even more confusing, as for example it's impossible on little endian machine to describe RGB16 with shifts/masks alone. That's why there's vHidd_PixFmt_SwapPixelBytes_Flag. (RGB16 == RRRRRGGG GGGBBBBB in memory, and for pixel (WORD) access on little endian machine it needs to be accessed as GGGBBBBBRRRRRGGGG). The shifts btw indicate how much to shift the component to the left (!) so that it is moved to the highest bit (31). The aHidd_PixFmt_StdPixFmt you specify will be ignored most of the time, because when the pixelfmt is registered, the gfx hidd checks if there's an identical pixfmt (shifts/masks/etc., but ignoring pixfmt->stdpixfmt) already in the system, and if so, it uses the already existing one and does not create a new one. In theory it would be better if gfx drivers could simply/only specify a StdPixFmt without all the shifts/masks stuff when the gfx driver uses pixfmt which matches one of the stdpixfmts exactly. Another possibility would be for gfx drivers to use HIDD_Gfx_GetPIxFmt(stdpixfmt_gfx_driver_wants_to_use) and then peek shifts/masks from it and fill out a pixfmt tag list based on that. 15bit very blue/green: Try to pass same shifts/masks/etc. as in 16 bit pixfmt (maybe you think it's using 15 bit R5G5B5 (or swapped) but it's actually still using 16 bit R5G6B5 (or swapped). aHidd_PixFmt_StdPixFmt you pass is mostly ignored. It's the shift/masks/etc. that count. But I would still pass the correct one (_LE) == whatever rom/hidds/graphics/stdpixfmts_??.h uses in the entry where you have looked up shifts/masks/etc. Use the shifts/masks/etc. from the entry in stdpixfmt_le.h (if you are running on little endian machine) or stdpixfmt_be.h (if you are running on little endian machine) that matches the pixfmt that its meant to be. 0xAA,0xRR,0xGG,0xBB on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on little endian (->entry in stdpixfmt_le.h which says vHidd_StdPixFmt_BGRA32) 0xAA,0xRR,0xGG,0xBB on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_ARGB32) 0xBB,0xGG,0xRR,0xAA on big endian (->entry in stdpixfmt_be.h which says vHidd_StdPixFmt_BGRA32) it feels like AROS trashes the alpha component, otherwise it should be 8A8R8G8B. read on the subject suggest its in 1x5r5g5b (x is ignored) to keep 16bit alignment . Suggests to me that wrong shift/mask are being applied - however going by the 16bit versions it all looks correct to me so I am really confused as to what is happening. The output image looks to have too much green/blue, and very weak red. Why did usbromstartup become HW-specific ? In the past i have done a big job separating kickstart into several parts. I have never got any responses, so i re-describe my idea. For now it loads the hs otg chipset driver .. The idea is to minimize amount of archirecture-specific modules to make user's life easier. So, the kickstart was split into 'base' (which does not contain anything machine-specific) and 'BSP' (Board Support Package) which contains all hardware-specific stuff. This way, for example, distribution makers can save up space on CD and make CDs with multiple platform support. Different configuration would load the same base with different BSP's. Next there was some part which is entirely missing on hosted. These are filesystems. Hosted ports do not need them to boot up, so on hosted they are left out. At the other hand, they are also architecture-agnostic. So i put them into 'FS' package (standing for 'filesystem'). Poseidon is one more big part. I made it into separate package in order to allow users to omit it if they don't need it (for example, to run on retro PCs without USB). Personally i have one. Again, Poseidon is hardware-agnostic (well, there are USB drivers but HCIs are pretty standard). It's mandatory on PI since there are no other interface types - so being a separate package is irrelevant/pointless. Is Raspberry's USB controller non-HCI compliant? Actually i expect it to be compliant, then wouldn't it be better to make existing drivers discovering them? AFAIK its HCI 1.0 compliant but I'm not familiar enough with poseidons drivers, nor USB, to just hack away at the existing code. Perhaps once i'm more familiar with the workings I can merge in the changes needed to get it operating but for now I will focus on getting it running. Also our drivers have known issues so perhaps a fresh set of eyes might shed some light on what is going wrong. Another interesting question is whether Poseidon can operate on device side. Is it flexible enough? How similar is being a USB host and USB device? think it will need a bit of work on Poseidon's side. Until then I will force the driver into Host/Master mode in the init code, but leave open device etc to configure the chipset for either's use - and look at trying to add support for working in Device/Slave mode & switching modes once it's up and running. Actually USBROMStartup is some kind of kludge. Can there be any alternative? Could device drivers be self-installing, like our HIDDs? This would get rid of need to list them in USBRomStartup. * Model A and B limited to 150 mA per port. * Model B+ and Pi 2 introduced configurable 600 mA to 1.2 A support over all ports - anything above that requires a powered USB hub. Implementing the hardware driver that Poseidon uses to interact with the USB components. Have code in place to (try) and initialise the USB chipset, and configure host/device mode operation (though AFAICT Poseidon doesn't support device mode). Started to get the "virtual" root hub written for the single USB port so that Poseidon should at least list it correctly in the GUI - and try to interact with it to find peripherals. The BCM2835 uses a soft IP block from Synopsys’ DesignWare library (DWC), specifically the block is called dwc_usb_2_0_hs_otg_subsystem-ahb_se (“USB 2.0 Hi-Speed OTG Controller Subsystem w/AHB Interface SE”). There is no public documentation for this, and pretty much zero chance of anyone getting hold of it even with NDA. However, there's a Linux driver written by Synopsys ([https://github.com/raspberrypi/linux dwc_usb]). Specifically directories [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_common_port] and [https://github.com/raspberrypi/linux/tree/rpi-patches/drivers/usb/host dwc_otg]. The Synopsys code is actually under a fairly permissive licence – it's not GPL, it's similar to BSD (’don't sue us if it breaks’ is pretty much the only clause). So this should not be a barrier to porting the code. The code is really well written, with a nice partition between the work done by the driver (dwc_otg, which is fairly involved, given the host does more work than a conventional EHCI driver), and the interface to Linux (dwc_common_port). Probably only need provision of relevant changes to dwc_common_port. Other things to consider.... * Provision of necessary headers to get it to compile * Provision of necessary functions (main issues are wait queues, threads, work queues, tasklets, timers, spinlocks and mutexes (multithreading) ) * Interfacing between USB stack and the driver. dwc_otg/dwc_otg_hcd_linux.c looks like the place to start. the Linux bits of the headers are only required for the dwc_common_port library. dwc_common_port includes a variety of crypto functions which are not used – it appears to also be used for ultrawideband (UWB) and wireless USB (WUSB) drivers where crypto will be an issue, but it isn't going to be for plain wired USB. Every USB driver acts as an USB hub as well in order to let Poseidon control the state of USB ports. The code there was reading status of the only USB port in Raspberry's CPU but when changing the status it erroneously deleted some of the status bits, including the port enable one. It was so because those bits in the status register are of a type Read/WriteToClear. It means, if one does not want to change their value from 1 back to 0, one has to actually write the 0 value. Very practical thing e.g. in interrupt handlers, where one reads the interrupt status register to learn what was the interrupt reason, and writes it back to the same register in order to clear the interrupts. After fixing that code it turned out that the communication was still unsuccessful. Apparently the USB device was not understanding the host for some reason. That should not happen since the request sent was one of the standard ones implemented by virtually anything with an USB connector, assumed that Poseidon clears the data caches before forwarding the work to the USB drivers but that's the responsibility of the driver itself. The USB device responded and acknowledged the transmission! But why were all the request sent after address change failing with timeout? They should not. Once again, address set is supported just by anything. Tried to contact the device at address 0 once again and there it was, still responding properly. The enlightenment came. The bus address for DMA transmissions was, as it is in many bare metal USB implementations, just the pure memory address of the buffer as seen by the ARM cpu. Have "prefixed" it with the real location of uncached RAM and booted AROS once again. Trident saw this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 and this: Product : Vendor: Vdr=0424/PID=EC00 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 255 SubClass : 0 DevProto : 1 VendorID : 1060 ProductID : 60416 DevVers : 0200 and even this: Product : Hub: Vdr=0424/PID=9514 Manufacturer: Standard Microsystems Corp. SerialNumber: n/a /Users/michal/git/AROS/rom/USB/poseidon/./poseidon.library.c:psd_20_psdEnumerateDevice/3092: USBVersion: 0200 Class : 9 SubClass : 0 DevProto : 2 VendorID : 1060 ProductID : 38164 DevVers : 0200 What are these things? The first one is USB hub built in the Raspberry. Thanks to this one the Pi machines (with exception of Pi0 and computing modules) have more than just one single USB port. The second one is the network chip in raspberry, the third one is my USB SD card reader which have just connected to see what happens. AROS tried, of course, to boot from it ;) So, the first step towards working USB is done. The control transfers are working as you can see above. Next step is to implement bulk and interrupt transfers, having the basics in place. Finally some error handling will be added and USB for Pi will be as complete as the PC version. [http://www.raspyfi.com/raspberry-pi-usb-audio-fix/ Issue with USB Audio] Audio [https://github.com/raspberrypi/linux/tree/rpi-patches/sound/arm audio] and its [https://github.com/raspberrypi/firmware/issues/2 very high speed message passing interface type of thing VCHI] The Model B+ added an additional voltage regulator for the audio output and an additional output driver to drive low-resistance loads like headphones. However it is still using pulse-width modulation (PWM), which has a major impact on sound quality the old Raspberry Pi used a linear voltage regulator to provide the 3.3V to many of the components on the board while the new one uses a switching regulator. Both can perform reasonably well. However switch mode power supplies often show higher noise figures Analogue audio Audio over HDMI rev 1.3 & 1.4 Ethernet 10/100 BaseT Ethernet RJ45 socket GPIO GPIO shouldn't be too bad but bear in mind it is already accessed in places so they would need to allocate pins etc through it (e.g. sdcard to flicker the activity light, serial debug to output data on the GPIO pins) Probably a resource rather than a device... Started an i2c driver that will need to allocate GPIO pins. Feel free to work on it if you are interested ;p GPU graphics with 2D and 3D acceleration Sadly none yet for 32bit but for 64bit... Miscellanous hdmi issues Setting the hdmi_force_hotplug=1 makes sure the Pi believes the monitor/TV is really there. You might also need to set config_hdmi_boost=4 or even higher (up to 9) if your display needs a stronger signal. If the display is a computer monitor or newer tv, use hdmi_group=1 (auto HDMI use) and if it is an older TV, try hdmi_group=2 (for DMT formats, i.e. for PC monitors) then you HAVE to "set hdmi_drive = 2 to enable HDMI output as this forces HDMI mode rather than DVI mode Do not set hdmi_safe=1 as that overrides many of the previous options. Using a shorter or better quality HDMI cable might help. Make sure your Pi's power supply delivers 1 A and not 500 mA. If you see a problem with the red colour - either absent, or interference - then try a boost composite video changing the RCA cable, then the composite port worked out of the box Boot it as you are doing, without HDMI. If you now plug in the HDMI, do you get the image? In other words, does the Pi think HDMI is connected even when it isn't? Rename all the files in the first partion of the card except bootcode.bin, start.elf and fixup.dat What's the result? Put back config.txt What's the result? for PAL mode sdtv_mode=2 dmi_ignore_hotplug Pretends HDMI hotplug signal is not asserted so it appears a HDMI display is not attached hdmi_ignore_hotplug=1 Use composite mode even if HDMI monitor is detected <pre> # NOOBS Auto-generated Settings: #hdmi_force_hotplug=1 #config_hdmi_boost=4 #overscan_left=24 #overscan_right=24 #overscan_top=16 #overscan_bottom=16 #disable_overscan=0 start_x=1 gpu_mem=128 </pre> tvservice -c "PAL 4:3" <pre> /opt/vc/bin/tvservice -s or tvservice -s state: HPD high|HDMI mode|HDCP off|composite off (0x12001a), 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m CEA Group CEA has 1 modes: (native) mode 16: 1920x1080 @ 60 Hz, progressive /opt/vc/bin/tvservice -m DMT Group DMT has 0 modes: </pre> sudo amixer cset numid=3 1 forces the audio to the headphone jack, even with the HDMI video output plugged in config.txt the hdmi_ignore_edid_audio=1 option sems relevant as it should tell ALSA that the only available audio is analog, no matter what the display says There are several different ways that these 4 pole (ring) composite analog cables can be wired up, so some work great in some applications and can be a waste of time in others. What is needed for the Raspberry Pi B+ and above, which like many camcorders needs the ring contact next to the base contact to be the ground. The wiring for the 4 pole are: TIP (LEFT AUDIO CHANNEL) RING 1 (RIGHT AUDIO CHANNEL) RING 2 (GROUND/EARTH) RING 3 BASE/SLEEVE (VIDEO) YELLOW Most Apple based Players and the Microsoft Zune (TM) are wired this way. Most analogue camcorders are wired this way as well, where the ground in on Ring 2 will work with the Pi although you may need to swap your Video plug with the Right Audio plug. Nearly all other MP3 players are not wired this way, the ground is on another ring ie the wrong one. External devices * Camera Module Omnivision ov5647 Sunny 5MP (NoIR version) V1.3 - NoIR at 850&nbsp;nm, peak at 880&nbsp;nm and trails off at 940&nbsp;nm wavelengths * Camera V2 Sony IMX219 V2.1 8mpixel 8MP 8megapixel - 3280 x 2464 pixels - video at 1080p30, 720p60 and 640x480p90 - wider field of view, 62 vs 54 degrees horizontally - * Branded WIFI usb BCM43143 dongle N.B. dreaded error after changing cameras (stupidly without turning off the power first) and lasted through several power cycles. It can be a bad 15-pin FFC ribbon cable, when swapped, camera(s) and the Pi itself are working OK. It can be an instance of a cold solder joint on the CSI connector on the pi board. the camera can be detected (that's done via I2C) but may still not be able to receive image data (done via CSI-2) if something is broken. CSI-2 is uni-directional. Control is generally done via I2C. The CSI-2 receiver always writes to memory, not direct to the ISP. That's the way the Broadcom architecture works as it allows multipass processing easily. GPU memory is accessible from the ARM. Processing using the QPU graphics processors may be possible. currently the only supported sensor is OV5647 and IMX219. The linux drivers are all in the firmware blob, else you'd be looking at at least a man-month of work in a fully fledged imaging lab to do a decent tuning of the camera modules' ISP parameters. Static electricity maybe an issue for the camera module and slightly less for the pi board. == References == [https://www.raspberrypi.com/documentation/computers/compute-module.html CM5] has the same 55mm x 40mm 2x100pin connectors form factor as the CM4 but [https://www.epdtonthenet.net/article/214508/Key-Considerations-When-Migrating-from-Raspberry-Pi-CM4-to-CM5.aspx some pins and other small things] have changed. Will need the [https://raspipcb.com/tech-blog/raspberry-pi-cm4-vs-cm5-difference-in-booting-from-sd-card/ right IO board to suit] *Green [ Raspberry Pi Compute Module 5 IO Board REV2 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1967]] - untested *Green [ RPi Compute Module 5 IO board REV1 [https://pip.raspberrypi.com/categories/1097-raspberry-pi-compute-module-5-io-board SC1751]] - untested *Black SupTronics Geekbord X1500 CM5 IO Carrier Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *Green BentoIO CMX0 - untested *[https://sipeed.com/nanocluster Sipeed NanoCluster] - untested up to 7 CM5 *Home Assistant Yellow - Kit with PoE with Raspberry Pi Compute Module 5 - untested *Blue [https://www.waveshare.com/wiki/CM5_PoE_BASE_A Waveshare CM5-PoE-BASE-A] - untested *Box Waveshare [ CM5-POE-BOX-A] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-B Waveshare CM5-IO-BASE-B] - untested *Blue [https://www.waveshare.com/wiki/CM5-IO-BASE-A Waveshare CM5-IO-BASE-A] - untested *Blue Waveshare [https://www.waveshare.com/wiki/CM5-NANO-B CM5-NANO-B] - untested *[https://carboncomputers.us/products/pi-flux piFlux] *[https://carboncomputers.us/products/ Zitaotech Hackberry] CM5 lite only - *Portable [https://www.waveshare.com/pocketterm35.htm Waveshare PocketTerm35] with Pi4B or Pi5 - untested *Box [https://www.clockworkpi.com/uconsole ClockworkPi uConsole][https://www.youtube.com/watch?v=EtI_bAahbR8 CM4 into an adapter or CM3 into so-dimm - Cyberdeck] - untested *Green RPi [https://datasheets.raspberrypi.com/cm4io/CM4IO-KiCAD.zip Compute Module 4] [https://datasheets.raspberrypi.com/cm4io/cm4io-datasheet.pdf IO board] V1.4 [https://datasheets.raspberrypi.com/cm4io/CM4IOUSB3-KiCAD.zip USB3] [https://datasheets.raspberrypi.com/cm4io/cm4iousb3-appnote.pdf CM4ISO] [https://datasheets.raspberrypi.com/cm4/cm4-datasheet.pdf Dual100pin] (2020) aka Development Platform Board - untested *Purple Pi Hut Cytron CM4 Maker Board - untested *Black DeskPi Super6C Cluster Mini-ITX Board - untested *[ KubeSail PiBox mini 2] *Home Assistant Yellow with Raspberry Pi Compute Module 4 - untested *[ Turing Pi V2] - untested CM4 with 260-pin SO-DIMM socket adapters and/or nvidia jetson nanos - untested *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-B Waveshare CM4-IO-BASE-B] - untested but binary blobs *Blue [https://www.waveshare.com/wiki/CM4-IO-BASE-A Waveshare CM4-IO-BASE-A] - untested but binary blobs CM3 has a 200 pin sodimm ddr2 connector form factor but not electrically SC0028, SC0029 *Blue [https://wiki.geekworm.com/CM_IO_Board Geekworm RPi Compute Module IO Board] [https://github.com/geekworm-com/cm-io-board CSI DSI] with CM3 in ddr2 slot underside - '''works''' if SW1 on but CM3+ '''does not''' *Green [https://cdn-shop.adafruit.com/product-files/3442/CMIO_schematic.pdf RPi V3 IO board CM3IO] and CM3 Lite - untested *Green [https://turingpi.com/ turingpi v1 cluster] - untested up to 7 cm3 7xlan9514 12V discontinued sadly, 3 x Pi4 probably better *Blue [https://www.waveshare.com/wiki/Compute_Module_PoE_Board Waveshare Compute Module PoE Board] and CM3 lite (if not lite, write files to internal eMMC fat32) '''AVOID''' bin blobs *Blue [https://www.waveshare.com/compute-module-io-board-plus.htm Waveshare Compute Module IO Board Plus] [https://www.waveshare.com/wiki/Compute_Module_IO_Board_Plus wiki] [https://forums.raspberrypi.com/viewtopic.php?t=235695 pin settings] with CM3+ Lite - '''AVOID''' binary blob *[ Pi02w on Geekworm SupTronics X305 Raspberry Pi Zero IO Baseboard] - untested *[ Spotpear Pi Zero 2w to Pi3b format-ish] - untested *[ pi-top v4] box has 128x64 oled display, micro hdmi, 19Whr battery with pi4 and 15V PD 36W min needed *[ pi-top v3] three green pieces, heatsink covers most of the base tray, pi-top hub mk1 lhs and Pi1B Pi2b Pi3b rhs secured from below, black rounded strip with pi-top above keyboard, 13.3" HD 1366 x 768 display, small touchpad, *[ pi-top Model 2.0] pi-top on bottom bezel of 14-inch green laptop, large trackpad, keyboard slide down to reveal main system hub on slide rails moved to the right, Raspberry Pi3b screws down, hub slides in, 18V 2.5A 45W charger brick, battery 11.1V 3500mAh 38.85Wh and storage PiTopOS *[ Pi-Top CEED Raspberry Pi Modular Educational Desktop with RPI3] monitor *[https://www.indiegogo.com/en/projects/jesselozano/pi-top-a-raspberry-pi-laptop-you-build-yourself Pi-Top v1] wedge laptop with RPi2 <pre> 2008 Trustees collected for Foundation 2009 Pi Foundation charity status gained 2010 2011 First Raspberry prototypes 2012 First boards go on sale at CPC and RS. The Model A and B 700 MHz Arm11 - February 29th BCM 2835 2012 First million sold - more than the 10,000 original planned and anticipated 2013 First Alpha Experimental builds of AROS Native for the 32bit Pi 2013 Pi Trading launched making grants available, providing in house educational resources and Pi Academy for teacher training 2013 Over two million sold 2014 Over three million sold 2014 Pi 1 Model B+ introduced that moved composite video to audio jack and same half gig of memory 2014 Pi Model A+ v1.1 no ethernet and 1 usb - a little smaller - 2015 Over four million first gen pis sold 2015 Pi Zero 1.2 BCM2835 first production revision released with no camera port 2016 Pi0 1.3 released with camera csi connector 2017 Pi Zero W v1.1 1GHz Pi0W, single-core 32bit CPU BCM2835 released with Cypress CYW43438 wireless 2020 Raspberry Pi Pico SC0919 with RP2040 32-bit 2Core ARM Cortex-M0+ up to 133 MHz - 264KB of SRAM and 2MB of on-board QSPI Flash - 2024 Raspberry Pi Pico 2 with RP2350 2Core 32bit Arm Cortex-M33 and 2core open-hardware [https://github.com/wren6991/hazard3 Hazard3 RISC-V] 2015 Pi 2 Model B v1.1 BCM2836 900/600 MHz ARM Cortex-A7 Armv7 quad 32bit, 32bit VideoCore IV GPU - 1Gb RAM - 5V 2A micro usb - SMSC LAN9514 chip - 2015 Over a million pi2s sold 2015 Raspberry Pi 2 Model B version 1.2 Pi2bv1.2, aka Pi2B2 has armv8 BCM2837 underclocked to 900Mhz without wifi/bluetooth module 2016 Pi 3 Model B - Broadcom BCM2837 SOC four 64bit ARMv8 Cortex-A53 1.2GHz 32bit 1080p VideoCore IV GPU - 1Gb DDR2 - bluetooth 4.1, Cypress CYW43438 wireless 802.11n - 4 x USB2.0 ports - 5.1V 2.5A - SMSC LAN9514 chip 2016 PIs total over 10 million worldwide 2017 Compute Module 3 CM3 with BCM2837B0 armv8 Quad 64-bit - small 67.6mm x 31mm board which fits DDR2 SODIMM connector but not electrically compatible which plugs into needed IO board - beware of the I2C protocol issue 1Gb LPDDR2 RAM - Lite or 4Gb Emmc storage 2017 12 million pis sold in total 2018 Pi 3 Model B+ - 4c A53 BCM2837B0 1.4Ghz - 1Gb, wireless 802.11ac, gigabit ethernet (300Mbit/s) and bluetooth 4.2 - power over ethernet - 4 x USB2.0 ports - Microchip LAN7515 chip 2019 Over 15 million sold 2019 Pi 3 Model A+ with BCM2837b0 Cortex-A53 64-bit SoC @ 1.4 GHz with 512Mb LPDDR2, 1 usb2, 1 hdmi, 1 micro usb 5V 2A - no ethernet - 2019 Raspberry Pi Compute Module 3+ CM3+ - Broadcom BCM2837B0 1.2Ghz, Cortex-A53 (ARMv8) 64-bit SoC on DDR2 SODIMM mechanically compatible only factor - IO board required 1Gb DDR2 and 8GB, 16GB, 32GB or a Lite variant without eMMC 2021 Pi zero 2 (w or no W) RP3A0 quad 1GHz Cortex-A53 64bit BCM2710A1 512mB SDRam 2025 edaTEC CM0 ED-CM0NANA with additional dev board with quad 1Ghz A53 with 512Mb Raysan RAM, 2 USB2 and 10/100 ethernet - pico castellated edge 2019 Pi 4 Model B RPI4B - BCM2711B0T quad 64bit A72 1.5GHz, 4K VideoCore VI, AC wifi, Bluetooth 5.0, GbE Broadcom BCM54213PE (PHY ID 0x600d84a2), 2 micro hdmi decode up to 4K, USB-C 5.1V 3A power, 2xVLI VL805 USB 3, 2xUSB 2.0, 2GB 9LDWW D9WHZ or 4GB 9FDWW D9WHV, 8GB 0AA47 D9ZCL ddr4 ram 2020 Silent Pi 4 v1.2 upgrade with more USB-c psu support 2020 PI400 BCM2711C0T 1.8GHz 4Gb DDR4 inside keyboard, 5.1V 5A 27W usb-c psu, 2 micro hdmi, external ide style 40pin gpio, no audio port - 2020 Raspberry Pi Compute Module 4 BCM2711B0T on new 55mm x 40mm 2x100 pin form factor with extra breakout IO board CM4101000 1Gb RAM Lite SOM CM4102000 2GB RAM Lite CM4104000 4GB RAM Lite CM4004008-4GB-RAM 8GB-EMMC SOM System on Modules CM4104032 4GB RAM 32GB emmc CM4108000 8GB RAM Lite CM4008016 8GB RAM 16Gb eMMc 2021 Raspberry Pi SC0763 Compute Module 4S CM4S with ddr2 sodimm pinouts but not electrically the same with suitable IO board extra cost - CM4S01000 1GB RAM Lite CM4S01008 1GB RAM 8GB eMMC Flash CM4S02000 2GB RAM Lite CM4S04000 4GB RAM Lite CM4S08000 8GB RAM Lite 2021 Pi 4 v1.4 BCM2711B1 upgraded power regulator, to deal with 8gig of ram being more power hungry - 2023 Pi 5 v1.0 BCM2712 Quad A76 @2.4Ghz - VideoCore VII - no audio socket - dual 4k from mini hdmi - fan connector - 5.1V 5A psu 2024 Pi 5 2GB DDR4 version uses BCM2712D0 2024 Pi-500 with 8Gb LPDDR5 and membrane keyboard 2024 Pi 5 v1.1 2024 Raspberry Pi Compute Module 5 CM5 BCM2712 55mm x 40mm form factor with additional IO board CM5004000 04GB RAM 0GB eMMC Lite CM5008000 08GB RAM 0GB eMMC Lite CM5016000 16GB RAM 0GB eMMC Lite 2025 Pi-500+ with 256GB NVMe storage, 16GB LPDDR4 RAM, and Gateron KS-33 Low Profile Blue mechanical keyboard switches 2025 Pi5 1GB DDR4 announced 2022 PiOS linux goes 64bit 2024 Pi Trading IPO stockmarket stock exchange listing 2026 April and May Aros 64bit fixed, added AHI audio, VC4 gfx started, usb functions added to rom 2026 June and July Aros 64bit usb2otg started, dma.resource, sdio.resource, bwfm.device wifi added 2026 Late July daily 64bit Pi3 LE little endian builds start 2026 August Pi 4, 400, 5 and 500 DTBs added, expanding existing support and wifi for Pi4 and Pi5 2026 August Pi5 HAT+ nvme and HDMI, AHI RPiI2S added, Pi4 HVS5 video scaler started, 2026 2027 2028 Pi 6 </pre> {{BookCat}} 92ky668g9fav1ugvy0qjvo215d5m1gq User:Melikamp 2 291080 4669006 2706601 2026-09-05T19:22:05Z ShakespeareFan00 46022 4669006 wikitext text/x-wiki Hello World! [[User:Melikamp/ma225|ma225]] is a sandbox page which may be later incorporated in [[Calculus]]. [[User:Melikamp/calc|calc]] is a sandbox page which may be later incorporated in [[Calculus]]. [[User:Melikamp/b-calc|b-calc]] is a sandbox page which may be later incorporated in [[Calculus]]. [[User:Melikamp/alg-trig|alg-trig]] is a sandbox page which may be later incorporated in a college algebra and trigonometry text. [[User:Melikamp/elementary_math|elementary math]] is a sandbox page which may be later incorporated in an appropriate elementary math textbook. [[User:Melikamp/basic_algebra|basic algebra]] is a sandbox page which may be later incorporated in an appropriate basic algebra textbook. == Mew == {{Question-answer|question=Who am I?|answer=the Question-answer template}} {{Message_box |backgroundcolor = #eee;{{text default color}}; |heading = message_box heading |message = message_box message |image = Nuvola apps edu miscellaneous.svg }} {{TextBox |1 = TextBox message |BG = #eee |W = 100% }} {{ExampleRobox|title=Robox Test title<br /><math>\frac12</math>}} Test content using Robox <math>\frac12</math> {{Robox/Close}} <div style="background: #eee;{{text default color}}; padding-top: .5em; padding-bottom: .5em; padding-left: 2em; padding-right: 2em; border-style: solid; border-width: 1px; border-color: #aaa;"> just div title </div> <div style="padding-top: .5em; padding-bottom: .5em; padding-left: 2em; padding-right: 2em; border-style: solid; border-width: 1px; border-color: #aaa; border-top-width: 0px;"> just div text </div> 5p6q6of8pftn1ye697mxbdicq8ytk20 User:Fabartus/temp1 2 292062 4668925 2542626 2026-09-05T12:29:19Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668925 wikitext text/x-wiki {{TOL-Proj-top}} =TOL Wiki project DLS fixups= {{TOCright}} This is a demo project to show how the Trainzer user community can help one another using the Project namespace of the TrainzOnline wiki. I have an unusual perspective on the whole Auran/N3V community having more time editing wiki's (since I discovered both Trainz and Wikipedia back in 2004) than I do fixing [[Trainz Errors]] under the new data model, and whilst I find N3V Games a company worthy of sympathies, there are things that we the user community can do to assist one another more easily than they with their numerically challenged and overworked staff can possibly do to help us as easily. We all know how poorly the N3V staff communicates, this wiki project is spurred by the short-sighted establishment of the DLS clean-up project and the failure of N3V to do more than make a feeble attempt to have some kind of wiki... and because it was feeble, I figure they and we in the community must be nearly as dissatisfied with the results as the other. In the last couple of weeks, I've taken {{plain link|http://online.ts2009.com/mediaWiki/index.php5?title=Special:Contributions&offset=&limit=500&tagfilter=&contribs=user&target=Fabartus&namespace=10&topOnly=1|gobs of time}} to begin fixing the wiki so all of us can be as comfortable as the typical 11 year-old with making contributory edits. Part of what I'm proposing here is an expansion of the (challenged) base DLS cleanup paradigm to incorporate a discussion of community standards&mdash;using this wiki and it's projects pages to ''have community consensus'' in how different fields in '''our content''' should be fixed up going forward. The programmers and we users have different focus. When making a route, we need different information, they merely consider whether an asset is a problem in their data model and rendering software needs. When it is, they change the model, usually with their typically poor prior announcements in advance of the new changes. Hence the establishment of this wiki to have a dynamic place where they can 'publish' (albeit with insufficient consultation or notice to the user community) changes they need to evolve the Trainz simulators. ==Welcome to our DLS fixups!== Did you know you can keep up with unheralded data model changes using this wiki? It's fairly easy. When we are looking at a page you or I can add it to our wiki '[[TOL:WATCH|Watch list]]' using the tab '[[TrainzOnline:Using the Wiki page features#Watch-list_tab|Watch tab]]' and further, can set up our [[TrainzOnline:Using the Wiki page features#preferences|Preferences]] to send us an email when a page has been changed. When and if, the Programmers change the model&mdash;when they make the change without discussing the fact with the user community first, or update the model without commenting out the older tag name with an annotation as to the last valid [["Trainz-build" tag]] tech level it was valid for, it gives us two things as users: * A way of being alerted the change is in the works or part of the (hopefully) forthcoming release; not something the geeks are back documenting. * A valid reason to gripe about the N3V staff communication to us all. Point being we're the one's likely to get burned, and their track record for [[TOL:FILT|auto-fixing assets]] with {{wp|Filter (Unix)|filters}} set up to auto-update the DLS is dismal, putting it kindly as possible. In the near future, all the Official reference pages in the TrainzOnline wiki will be tagged with {{tl|ORP-top}} and {{tl|ORP-bot}} tags, enabling one to access all programmer maintained pages from a single category: [[:Category:reference pages|Reference pages]]. When that process is complete, we'll be initiating a text page listing all the pages to watch as a text asset. Any one of us can then cut and paste that document into their own watch page editor's applet, and voila', instant watch list monitoring of all changes to the geek-speak of our programmers references. In the meantime, I invite the many to join those of us in Yesterdayz Trainz to 'dumb down' the Official reference pages. Documenting when a tag becomes invalid by commenting the line with a REM statement is and should be the standard practice in all versions of Trainz, yet according to that inexperienced Trainzer Jcitron, that most needed tag has mysteriously disappeared from the [[TrainzBaseSpec]] as did the prior ability to have "//..." end of line comments, and the defacto ability of using ';' (semi-colon) on a line to delimit a comment as was once possible back from Trainz 1.x and through in the many versions TRS2004-TRS2006. NOT PROCESSING these as comments any more is out and out creation of bugs, and putting them onto the user communities backs. The ability to comment in a text file is absolutely necessary when all the file names are 'config.txt', one standard we will propose here is a standard block of comments up in the first lines of the [[config.txt file]]s &mdash; among other possible fields, are the several just above the English language description documenting the the file kuid, region, era, and especially the '''[[username]] fields'''... the very folder name the asset should be opened for edit when viewed. An important datum when a user is fixing multiple download issues and might have ten or more Windows Explorer windows open at once. The programmers have little appreciation for that condition we all see when downloading older routes and sessions. {{-}} ==Attempting to build a searchable list== [https://www.auran.com/planetauran/dls_cleanup_list.php?CurrentPage=11&Mine=0&Search=&NoClaimed=0 source page1] KUID Name Description Repairer <KUID:104001:60532> DR_US_2H0F2A_045 DR-Bahn€ng 2-gleisig mit 5,0 m Abstand f€ amerikanische Strassensystem.I Claim for repair <KUID:104001:60533> DR_US_2H0F2A_135 DR-Bahn€ng 2-gleisig mit 5,0 m Abstand f€ amerikanische Strassensystem.I Claim for repair <KUID:104001:60551> DR_SW_2H0F4A_090 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ schwedische Strassensystem.I Claim for repair <KUID:104001:60552> DR_SW_2H0F4A_045 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ schwedische Strassensystem.I Claim for repair <KUID:104001:60553> DR_SW_2H0F4A_135 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ schwedische Strassensystem.I Claim for repair <KUID:104001:60554> DR_SW_2H0F2A_090 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ schwedische Strassensystem.I Claim for repair <KUID:104001:60555> DR_SW_2H0F2A_045 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ schwedische Strassensystem.I Claim for repair <KUID:104001:60556> DR_SW_2H0F2A_135 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ schwedische Strassensystem.I Claim for repair <KUID:104001:60557> DR_US_2H0F4A_090 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ amerikanische Strassensystem.I Claim for repair <KUID:104001:60558> DR_US_2H0F4A_045 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ amerikanische Strassensystem.I Claim for repair <KUID:104001:60559> DR_US_2H0F4A_135 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ amerikanische Strassensystem.I Claim for repair <KUID:104001:60560> DR_US_2H0F2A_090 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ amerikanische Strassensystem.I Claim for repair <KUID:104001:60561> DR_US_2H0F2A_045 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ amerikanische Strassensystem.I Claim for repair <KUID:104001:60562> DR_US_2H0F2A_135 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ amerikanische Strassensystem.I Claim for repair <KUID:104001:60581> DR_SW_2H2F4A_090 DR-Bahn€ng 1-gleisig f€ schwedische Strassensystem.onplatI Claim for repair <KUID:104001:60582> DR_SW_2H2F4A_090 DR-Bahn€ng 2-gleisig mit 4,0 m Abstand f€ schwedische Strassensystem.I Claim for repair <KUID:104001:60583> DR_SW_2H2F4A_090 DR-Bahn€ng 2-gleisig mit 5,0 m Abstand f€ schwedische Strassensystem.I Claim for repair <KUID:104001:60584> DR_SW_2H2F4A_090 DR-Bahn€ng 3-gleisig Typ A (3 Gleise nebeneinander) mit 4,0 m Abstand f€ schwedische Strassensyst... Claim for repair <KUID:104001:60585> DR_SW_2H2F4A_090 DR-Bahn€ng 3-gleisig Typ A (3 Gleise nebeneinander) mit 5,0 m Abstand f€ schwedische Strassensyst... Claim for repair <KUID:104001:60586> DR_SW_2H2F4A_090 DR-Bahn€ng 3-gleisig Typ B (2 Gleise nebeneinander, 1 Gleis frei, 1 Gleis) mit 4,0 m Abstand f€ s... Claim for repair <KUID2:104722:1042:5> Ortner 3-bay Auto MFX-2 Hopper v3 AG3 One of the most distinctive cars in service today, the Ortner 100-Ton Aggregate Cars are built fo... Claim for repair ==Pages 1-6 <kuid:-1> and (-1)== '''Pages searched by 'unclaimed' and <kuid:-1>''' &nbsp; ===group-01 (-1)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID or KUID2 !style="width:19%" |Name !style="width:40%" |Description !style="width:07%" |Repairer |- | &lt;KUID :-10:170&gt; || Gen DL500 mph rhd || (null) || |- | &lt;KUID:-10:172&gt; || Gen1960 op1 || (null) || |- | &lt;KUID:-10:173&gt; || Gen RC4 || (null) || |- | &lt;KUID:-10:221&gt; || Gen 218 || (null) || |- | &lt;KUID:-12:460&gt; || AN Guard Van || 8300 Class Guard Van Company: Australian National Length (over coupler): 10.2m Width (over... || |- | &lt;KUID:-12:505&gt; || QR PWA || PWA Company: Queensland Rail Length: 12.1m Width: 2.5m Height: 2.2m Length: 8.1m (b'... || |- | &lt;KUID:-18:1101&gt; || sw || (null) || |- | &lt;KUID:-18:1213&gt; || Flash HUD Icon || (null) || |- | &lt;KUID:-18:1214&gt; || Flash HUD Panel || (null) || |- | &lt;KUID:-18:1846763744&gt; || Banks Heath || A strict schedule keeps the traffic flowing on this picturesque countryside branch; and the peopl... || |- | &lt;KUID:-1:1&gt; || ATSF F7A || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the supr... || |- | &lt;KUID:-1:100007&gt; || V/Line S || Victorian Railways 'S' Class Clyde Engineering acquired the services of former SAR Chief M... || |- | &lt;KUID:-1:100012&gt; || CO-OP Bulk Hopper || centre flow hopper Length (over coupler): 17.5m Width (overall): 3.1m Height (overal... || |- | &lt;KUID:-1:100018&gt; || VR S blue || Victorian Railways 'S' Class Clyde Engineering acquired the services of former SAR Chief M... || |- | &lt;KUID:-1:100039&gt; || BR HST 125 || Class 43 HST The debate still rages over whether the HST should be regarded as a diesel mu... || |- | &lt;KUID:-1:100042&gt; || CN Cupola Caboose || Cupola Caboose CN Length (over coupler): 11.4m Width (overall): 3.0m Height (overall... || |- | &lt;KUID:-1:100043&gt; || B&O Cupola Caboose || Cupola Caboose B&O Length (over coupler): 11.4m Width (overall): 3.0m Height (overal... || |- | &lt;KUID:-1:100046&gt; || NYC Cupola Caboose || Cupola Caboose NYC Length (over coupler): 11.4m Width (overall): 3.0m Height (overall)... || |- | &lt;KUID:-1:100121&gt; || CP FP7A || GM-EMD FP7A In 1939 General Motors Electro - Motive Division issued a challenge to the suprema... || |- | &lt;KUID:-1:100122&gt; || CP F7B || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the supr... ||&nbsp; |} &nbsp; ===group-02 (-1)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID or KUID2 !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | &lt;KUID :-1:100127&gt; || MR F7A || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the ... || |- | &lt;KUID:-1:100128&gt; || MR F7B || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the ... || |- | &lt;KUID:-1:100131&gt; || NYC F7A || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the supr... || |- | &lt;KUID:-1:100132&gt; || NYC F7B || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the ... || |- | &lt;KUID:-1:100135&gt; || ATSF F7B || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the supr... || |- | &lt;KUID:-1:100136&gt; || Southern F7A || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the supr... || |- | &lt;KUID:-1:100137&gt; || Southern F7B || GM-EMD F7A & B In 1939 General Motors Electro - Motive Division issued a challenge to the supr... || |- | &lt;KUID:-1:100143&gt; || ER FA1 || American Locomotive Company FA-1 F - for freight, A - for A unit, 1 - the model number. AL... || |- | &lt;KUID:-1:100144&gt; || LV FA1 || American Locomotive Company FA-1 F - for freight, A - for A unit, 1 - the model number. AL... || |- | &lt;KUID:-1:100145&gt; || Rock Island FA1 || American Locomotive Company FA-1 F - for freight, A - for A unit, 1 - the model number. AL... || |- | &lt;KUID:-1:100150&gt; || CN FPA4 || American Locomotive Company FPA-4 F - for freight, A - for A unit, 1 - the model number. A... || |- | &lt;KUID:-1:100153&gt; || CP FPA2 || American Locomotive Company FPA-2 F - for freight, A - for A unit, 1 - the model number. A... || |- | &lt;KUID:-1:100159&gt; || ATSF SS Baggage Car || SUPER CHIEF The Atchison Topeka & Santa Fe railroad launched the first streamlined Super Chi... || |- | &lt;KUID:-1:100160&gt; || ATSF SS Chair Car || SUPER CHIEF The Atchison Topeka & Santa Fe railroad launched the first streamlined Super Chi... || |- | &lt;KUID:-1:100161&gt; || ATSF SS Diner || SUPER CHIEF The Atchison Topeka & Santa Fe railroad launched the first streamlined Super Chi... || |- | &lt;KUID:-1:100162&gt; || ATSF SS Pleasure Dome || SUPER CHIEF The Atchison Topeka & Santa Fe railroad launched the first streamlined Super Chi... || |- | &lt;KUID:-1:100163&gt; || ATSF SS Pullman - Pine series || SUPER CHIEF The Atchison Topeka & Santa Fe railroad launched the first streamlined Super Chi... || |- | &lt;KUID:-1:100181&gt; || sw || (null) || |- | &lt;KUID:-1:100186&gt; || f7interior || (null) || |- | &lt;KUID:-1:100382&gt; || class37 int cab || (null) ||&nbsp; |} &nbsp; ===group-03 (-1)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID or KUID2 !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | &lt;KUID :-1:100554&gt; || bb15000 || (null) || |- | &lt;KUID:-1:100611&gt; || Bridge Stone 2t || (null) || |- | &lt;KUID:-1:100725&gt; || NSWGR 48 Class || ALCo DL531 - NSWGR 48 Class The ALCo DL531 was once a common sight on Australia's railways, ... || |- | &lt;KUID:-1:100734&gt; || Silverton 48s || ALCo DL531 Silverton The ALCo DL531 was once a common sight on Australia's railways, designe... || |- | &lt;KUID:-1:100737&gt; || AN 830 Class || ALCo DL531 - AN 830 Class The ALCo DL531 was once a common sight on Australia's railways, de... || |- | &lt;KUID:-1:100754&gt; || QR 2100 Class || 2100 Class Assembed by Clyde Engineering under license from GM-EMD, the 2100 class was i... || |- | &lt;KUID:-1:100770&gt; || NSWGR NLKY louvred van || NLK Lovred van Company: New South Wales Government Railways Built: 1973-76 Tare: 27t ... || |- | &lt;KUID:-1:100778&gt; || SAR 930 Class || American Locomotive Company DL500 'World Series' Known as the 'World Series', the ALCo DL500... || |- | &lt;KUID:-1:100812&gt; || NSWGR 44 Class || American Locomotive Company DL500 'World Series' Known as the 'World Series', the ALCo DL500... || |- | &lt;KUID:-1:100814&gt; || VR-SAR Overland Club Car || Overland Club Car - Melbourne to Adelaide For over a hundred years the Overland over-night... || |- | &lt;KUID:-1:100815&gt; || VR-SAR Overland AJ || The Overland - Melbourne to Adelaide For over a hundred years the Overland over-nightly po... || |- | &lt;KUID:-1:100816&gt; || VR-SAR Overland BJ || The Overland - Melbourne to Adelaide For over a hundred years the Overland over-nightly po... || |- | &lt;KUID:-1:100817&gt; || VR-SAR Overland RoomTantini || The Overland - Melbourne to Adelaide For over a hundred years the Overland over-nightly po... || |- | &lt;KUID:-1:100820&gt; || SAR 930 Class single || American Locomotive Company DL500 'World Series' Known as the 'World Series', the ALCo DL500... || |- | &lt;KUID:-1:100825&gt; || Enafer DL500 || American Locomotive Company DL500 'World Series' Known as the 'World Series', the ALCo DL500... || |- | &lt;KUID:-1:100828&gt; || NSWGR NOD || NOD Gondola Company: New South Wales Government Railways Built: 1977-81 Length: 14.2m H... || |- | &lt;KUID:-1:100841&gt; || PRR GG1 || PRR GG1 With plans to electrify it's 2,800 track miles, the Pennsylvania Railroad required ... || |- | &lt;KUID:-1:100861&gt; || NSW SRA 44 Class || American Locomotive Company DL500 'World Series' Known as the 'World Series', the ALCo DL500... || |- | &lt;KUID:-1:100871&gt; || ATSF SD40-2 || GM-EMD SD40-2 One of the problems with the popular 'carbody' units was that the strength l... || |- | &lt;KUID:-1:101060&gt; || SS Tipper Car || Tipper Length (over coupler): 7.1m Width (overall): 3.0m Height (overall): 2.7m B... ||&nbsp; |} &nbsp; ===group-04 (-1)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID or KUID2 !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | &lt;KUID :-1:101115&gt; || Bridge 2t Steel Arch || (null) || |- | &lt;KUID:-1:101153&gt; || QR QLX Bronco || QLX Length (over coupler): 14.7m Width (overall): 3.1m Height (overall): 3.7m Bogie pi... || |- | &lt;KUID:-1:101154&gt; || QR QLX || QLX Length (over coupler): 14.7m Width (overall): 3.1m Height (overall): 3.7m Bogie pi... || |- | &lt;KUID:-1:101168&gt; || class43 interior || (null) || |- | &lt;KUID:-1:101202&gt; || f7interior mph rhd || (null) || |- | &lt;KUID:-1:101206&gt; || Bridge 2t Brick || (null) || |- | &lt;KUID:-1:101211&gt; || f7interior kph lhd || (null) || |- | &lt;KUID:-1:101212&gt; || f7interior mph lhd || (null) || |- | &lt;KUID:-1:101220&gt; || SS Foundry Car || Foundry Car Length (over coupler): 10.7m Width (overall): 2.6m Height (overall): 3.... || |- | &lt;KUID:-1:101221&gt; || BR HST MK3 TGS || Type TGS Built 1976 - 1985 Length 23m Height 3.9m Weight 33.47t Seating Capacity 63 ... || |- | &lt;KUID:-1:101222&gt; || NSWGR NOD Loaded || NOD Gondola Company: New South Wales Government Railways Built: 1977-81 Length: 14.2m H... || |- | &lt;KUID:-1:101224&gt; || IC 4 bay Hopper Loaded || 4 bay Hopper Length (over coupler): 13.4m Width (overall): 3.1m Height (overall): 3.3m ... || |- | &lt;KUID:-1:101242&gt; || IP ARL Twinette 1st || Indian Pacific ARL From 1917 it was possible to travel Trans-Australia by rail, but the trip ... || |- | &lt;KUID:-1:101246&gt; || IP BRJ Twinnette 2nd || Indian Pacific BRJ From 1917 it was possible to travel Trans-Australia by rail, but the t... || |- | &lt;KUID:-1:101248&gt; || IP DF Dining Car || Indian Pacific DF From 1917 it was possible to travel Trans-Australia by rail, but the tr... || |- | &lt;KUID:-1:101249&gt; || IP HGM Power Van || Indian Pacific HGM From 1917 it was possible to travel Trans-Australia by rail, but the t... || |- | &lt;KUID:-1:101251&gt; || IP HM Baggage Brake || Indian Pacific HM From 1917 it was possible to travel Trans-Australia by rail, but the tr... || |- | &lt;KUID:-1:101292&gt; || SAR Guard Van || 8300 Class Guard Van Company: SAR Length (over coupler): 10.2m Width (overall): 2.6m ... || |- | &lt;KUID:-1:101412&gt; || SNCF TGV SE || SNCF TGV SE Train a Grande Vitesse (high speed train) of the Societe Nationale des Chemins d... || |- | &lt;KUID:-1:101416&gt; || SNCF TGV SE Unit 2 || SNCF TGV SE Unit 2 Train a Grande Vitesse (high speed train) of the Societe Nationale des Ch... ||&nbsp; |} &nbsp; ===group-05 (-1)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID or KUID2 !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | &lt;KUID :-1:101417&gt; || SNCF TGV SE Unit 3 || SNCF TGV SE Unit 3 Train a Grande Vitesse (high speed train) of the Societe Nationale des Ch... || |- | &lt;KUID:-1:101419&gt; || SNCF TGV SE Unit 1 || SNCF TGV SE Unit 1 Train a Grande Vitesse (high speed train) of the Societe Nationale des ... || |- | &lt;KUID:-1:101420&gt; || SNCF TGV SE Unit 4 || SNCF TGV SE Unit 4 Train a Grande Vitesse (high speed train) of the Societe Nationale des Ch... || |- | &lt;KUID:-1:101472&gt; || Gen DL500 || (null) || |- | &lt;KUID:-1:101474&gt; || gen gg || (null) ||&nbsp; |} &nbsp; ===Kuid's mixing begins=== ;Interesting, search is now picking up '-1' in non-kuid fields {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" |Description !style="width:07%" |Repairer |- | &lt;KUID:109502:1000151> || EUROMED-VAGON-1 || Vagon pasajeros primera clase para el Euromed |- | &lt;KUID:109502:1000161> || AVE-2-VAGON-1 || Vagn primera clase para AVE.2 Contributors (Dependencies) ... || |- | &lt;KUID:110115:133> || DR_br132_675-1 || DR 132 675-1|| |- | &lt;KUID2:178987:1560:3> || DE-1_TRS-light || NS Blauwe Engel Length 26350 mm Width 2740 mm Height 3520 mm Model: DE 1|| |- | &lt;KUID:178987:3111> || NS_Plan-U_111-1_mBDk || NS Plan-U 111 mBDk Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1960 Lengte 24622 mm De total...|| |- | &lt;KUID:178987:3151> || NS_Plan-U_151-1_mBDk || NS Plan-U 151 mBDk Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1963 Lengte 24622 mm De total...|| |- | &lt;KUID:178987:5500> || NS_Plan-T_502-1_BK1 || NS_Plan-T_502 Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1965 Lengte 25500 mm De totale len...|| |- | &lt;KUID:178987:5510> || NS_Plan-T_529-1_BK1 || NS_Plan-T_529_BK1 Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1965 Lengte 25500 mm De totale...|| |- | &lt;KUID:189904:182134> || Virgin MkIII DVT (82134 - Sir Henry Doulton 1820-1897) || Not quite the real thing but it will do for now. Virgin MkIII DVT (82134 - Sir Henry Doulton 182...|| |- | &lt;KUID:195962:100092> || Aus-Tran HST-180 || paintshed skin|| |- | &lt;KUID:328583:3768> || JVC(V)Trees#26 Maple avenue spline low 10-15m || V.I.P. Shrub set, spline version|| |- | &lt;KUID:438196:1154> || kiha187-1502 || Japanese Diesel Car kiha187-1502, Limited Express 'Super Inaba' of West JR. Make a unit with kiha...|| |- | &lt;KUID:45588:1222> || DS4-4-10 Reading 729 || Baldwin switcher model DS-4-4-10 as used on the Reading. This unit was rebuilt with an EMD engine...|| |- | &lt;KUID:45588:1224> || DS4-4-10 Reading 38 || Baldwin switcher model DS-4-4-10 as used on the Reading. US loco sound effects by Wulf_9 enginesp...|| |- | &lt;KUID:45588:1540> || DS4-4-10 CNJ 1073 || Baldwin DS4-4-10 switcher operated by the Central Railroad of New Jersey (3 units, #1072-1074). ...|| |- |} ===group-06 (-1)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | &lt;KUID2:82412:5000048:1> || Mine-1009 || Mine-1009|| |- | &lt;KUID2:82412:5000049:1> || Mine-10010 || Mine-10010|| |- | &lt;KUID2:82412:5000051:1> || Log-Stack-Industrie-101 || Log Stack Industry. Loads TUME's Log Stack Products.|| |- | &lt;KUID2:82412:6097012:1> || MILW-Sub-HV-Connect-10m-01 || MILW-Sub-HV-Connect-10m-01|| |- | &lt;KUID2:82412:70074:1> || Bush-Spline-10m-44-DMD-BLB || David Drake's BlackBerry-spline-3 with reduced texture size especially for application within lar...|| |- | &lt;KUID2:82412:850001:1> || Messenger-MILW-Bitterroots-101 || Messenger-MILW-Bitterroots-101. Contains Videos, Session Objectives and Voice Sound|| |- | &lt;KUID2:82412:850002:1> || Messenger-MILW-Bitterroots-102 || Messenger-MILW-Bitterroots-102. Contains Pop-up Messages.|| |- | &lt;KUID2:82412:850003:1> || Messenger-NP-Bitterroots-101 || Messenger-NP-Bitterroots-101. Contains Session Objectives anf further descripions|| |- | &lt;KUID2:82412:850004:1> || Messenger-NP-Bitterroots-102 || Messenger-NP-Bitterroots-102. Contains Pop-up Messages.|| |- | &lt;KUID:93985:20001> || Britain SR 1970s-1980s || Originally based on the UTC Britain layout, this is the 2nd version of the Southern Region themed...|| |- | &lt;KUID:45588:15561> || HT Virginian 2056 H-14 || Virginian Railway had similar hoppers to this one. McClure & Plant (Morning Sun Books) 'The Virgi...|| |- | &lt;KUID:45588:1615> || DS4-4-10 WM 133 Speedlettering || Baldwin switcher model DS-4-4-10 as used on the Western Maryland. WM owned only 2 units, #133 and...|| |- | &lt;KUID2:45588:1959:1> || DS4-4-10 Monongahela 421 || Baldwin switcher model DS-4-4-10 as used on the Monongahela Railway, which operated 27 of these e...|| |- | &lt;KUID:45588:1960> || DS4-4-10 Monongahela 412 || Baldwin switcher model DS-4-4-10 as used on the Monongahela Railway, which operated 27 of these e...|| |- | &lt;KUID2:50587:1663:1> || QR 1620-1650 || The 1620 class were built from 1967 to 1969. There were a total of 34 class members. The 1620s we...|| |- | &lt;KUID2:58422:10107:4> || Pullman 12s-1d-1smk || Pullman heavyweight cars of the 1920's were to replace the old wood cars. They were built from 19...|| |- | &lt;KUID2:58422:10109:4> || Pullman 10s-1d-2c || Pullman heavyweight cars of the 1920's were to replace the old wood cars. They were built from 19...|| |- | &lt;KUID:58422:10114> || Pullman 10s-1d-2c || Pullman heavyweight cars of the 1920's were to replace the old wood cars. They were built from 19...|| |- | &lt;KUID2:58843:239:1> || CN 12-1 Sleeper || Canadian National Pullman 12-1 Sleeper. By far the most popular model of sleeping car that Pullma...|| |- | &lt;KUID:63822:9012> || GMR Alco FA-1 || paintshed skin|| |- | &lt;KUID2:69974:37022:1> || Stuetzmauer01-10M || en: Retaining Wall || |- | &lt;KUID2:69974:37034:1> || Stuetzmauer04-10M || en: Retaining Wall || |- | &lt;KUID2:69974:37035:1> || Stuetzmauer08-10M || en: Retaining Wall || |- | &lt;KUID2:82412:5000040:1> || Mine-1001 || Mine-1001|| |- | &lt;KUID2:82412:5000041:1> || Mine-1002 || Mine-1002|| |- | &lt;KUID2:82412:5000042:1> || Mine-1003 || Mine-1003|| |- | &lt;KUID2:82412:5000043:1> || Mine-1004 || Mine-1004|| |- | &lt;KUID2:82412:5000044:1> || Mine-1005 || Mine-1005|| |- | &lt;KUID2:82412:5000045:1> || Mine-1006 || Mine-1006|| |- | &lt;KUID2:82412:5000046:1> || Mine-1007 || Mine-1007|| |- |} &nbsp; ==Pages 1-6 <kuid:-2>== This search new, using <kuid:-2> and so some items are redundant. e.g. the first item below should be listed above as well. ===group-07 (-2)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- |<KUID:-1:100871> || ATSF SD40-2 || GM-EMD SD40-2 One of the problems with the popular 'carbody' units was that the strength l... || &nbsp; |- | <KUID2:104722:1042:5> || Ortner 3-bay Auto MFX-2 Hopper v3 AG3 || One of the most distinctive cars in service today, the Ortner 100-Ton Aggregate Cars are built fo... || &nbsp; |- | <KUID:104822:99001259> || L&N SD40-2 ARN 1259 || paintshed skin Contributors (Dependencies): W... || &nbsp; |- | <KUID:104822:99003554> || L&N SD40-2 3554 ARN || paintshed skin Contributors (Dependencies): W... || &nbsp; |- | <KUID:104822:99004051> || L&N GP38-2 4050 ARN || paintshed skin Contributors (Dependencies): W... || &nbsp; |- | <KUID:104822:99006011> || L&N GP38-2 6011 ARN || paintshed skin Contributors (Dependencies): W... || &nbsp; |- | <KUID:104822:99008000> || L&N SD40-2 8000 ARN || paintshed skin Contributors (Dependencies): W... || &nbsp; |- | <KUID:104822:99008133> || L&N SD40-2 8133 ARN || paintshed skin Contributors (Dependencies): W... || &nbsp; |- | <KUID:109502:1000161> || AVE-2-VAGON-1 || Vagn primera clase para AVE.2 Contributors (Dependencies): ... || &nbsp; |- | <KUID:113556:51031> || Loco UPSD40-2 #802 || UP Sd40-2 reskin #802 (Weathered) Dependencies enginesound <KUID:104722:53466> Bogey <KUID:113556:... || &nbsp; |- | <KUID2:121945:15033:4> || WR4u-28 || Vierachsiger Speisewagen Bauart 1928 Ganzstahlbauart (WR4u-28) Features: ... || &nbsp; |- | <KUID2:135744:146:1> || Detroit & Mackinac #124 4-8-2 Mountain Type || Here is a Detroit & Mackinac Railroad 4-8-2 Mountain Type locomotive #124 reskinned from Bill Sco... || &nbsp; |- | <KUID2:135744:148:1> || Pere Marquette #1224 4-8-2 Mountain Type || Here we have a Pere Marquette 4-8-2 Mountain Type loco #1224. This was reskinned from Bill Scott... || &nbsp; |- | <KUID2:135744:616:1> || NS SD40-2 Patched || This is a patched version of a Norfolk Southern SD40-2. This was reskinned from sureshot28's Nor... || &nbsp; |- | <KUID:178987:3112> || NS_Plan-U_111-2_B || NS Plan-U 111 B Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1960 Lengte 23694 mm De totale l... || &nbsp; |- | <KUID:178987:3152> || NS_Plan-U_151-2_B || NS Plan-U 151 B Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1963 Lengte 23694 mm De totale l... || &nbsp; |- | <KUID:178987:5501> || NS_Plan-T_502-2_BD || NS_Plan-T_529 Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1965 Lengte 24550 mm De totale len... || &nbsp; |- | <KUID:178987:5511> || NS_Plan-T_529-2_BD || NS_Plan-T_529_BD Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1965 Lengte 24550 mm De totale ... || &nbsp; |- | <KUID:243294:1156> || NZ Turntable-2 42in gauge || Aliased to Auran's Built-in Tside Turntable AUS 2 modified for 42in track. Suitable for TRS2... || &nbsp; |- | <KUID:328583:3766> || JVC(V)Trees#26 Maple avenue spline high 20-25m || V.I.P. Shrub set, spline version || &nbsp; |} &nbsp; ===group-08 (-2)=== &nbsp; {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- |<KUID:328583:3767> || JVC(V)Trees#26 Maple avenue spline medium 15-20m || V.I.P. Shrub set, spline version || &nbsp; |- | <KUID:440847:42003> || PKP SM42-234 PR.Gdynia || SM42 Contributors (Dependencies): makibax <li... || &nbsp; |- | <KUID:4468:225> || 4-6-2 Duchess Class Tender BR Blue || 10,000 gallon Tender for the 4-6-2 Duchess Class. || &nbsp; |- | <KUID:4468:4001> || 4-6-2 West Country Class SR || 4-6-2 West Country Class SR SR No. BR No. Name Date Built 21C101 34001 Exeter 1945 Protot... || &nbsp; |- | <KUID:4468:4002> || 4-6-2 West Country Class SR Tender || 4-6-2 West Country Class SR Tender At the end of World War II, a fast and powerful mixed traffic... || &nbsp; |- | <KUID:4468:4049> || 4-6-2 Battle of Britain Class BR Green || 4-6-2 West Country Class SR (Battle of Britain Class) SR No. BR No. Name Date Built 21C151 34... || &nbsp; |- | <KUID:4468:4050> || 4-6-2 Battle of Britain Class BR Green Tender || 4-6-2 Battle of Britain Class BR Green Tender At the end of World War II, a fast and powerful mi... || &nbsp; |- | <KUID:4468:4771> || 2-6-2 V2 LNER Green || Gresley Mixed Traffic V2 2-6-2 4771 Green Arrow 4806 Green Howard 4844 Coldstreamer (60873) 48... || &nbsp; |- | <KUID:45324:100001> || BNSF GP38-2 || Burlington Northern Santa Fe GP38-2 || &nbsp; |- | <KUID:45324:100012> || SP SD40T-2 || Southern Pacific SD40T-2 || &nbsp; |- | <KUID:45324:100013> || UP SD40T-2 || Union Pacific SD40T-2 || &nbsp; |- | <KUID:45588:10229> || Pittsburgh & West Virginia 4-6-2 Pacific 200 Tender || Pittsburgh & West Virginia 4-6-2 Pacific Tender, Coal, lettered for #200. Original tender bogey w... || &nbsp; |- | <KUID:45588:10230> || Pittsburgh & West Virginia 4-6-2 Pacific 200 || P&WV operated 3 light Pacifics, #200-202. Passenger service was discontinued before the Connelsvi... || &nbsp; |- | <KUID:45588:1162> || SD40-2 C&NW 6854 || Chicago & Northwestern owned dynamic brake-equipped SD40-2's, purchased following UP-specs for co... || &nbsp; |- | <KUID:45588:1209> || GP40-2 FEC 419 light || Florida East Coast owned 10 GP40's (#401-410) and 19 GP40-2's (#411-429) for bridge line freight ... || &nbsp; |- | <KUID:45588:1214> || GP40-2 FEC 434 new || Florida East Coast owned 10 GP40's (#401-410), 19 GP40-2's (#411-429), and 24 secondhand GP40-2's... || &nbsp; |- | <KUID:45588:1280> || GP39-2 RDG 3405 || Roger Crouch's GP39 model reskinned into Reading's best paint scheme, the final green and yellow ... || &nbsp; |- | <KUID:45588:1311> || GP38-2 NY&A 261 || Former Long Island GP38-2 working on the former LIRR freight operations, the New York & Atlantic.... || &nbsp; |- | <KUID:45588:1359> || SD38-2 Utah Railway 2053 || I read that Utah Railway had four SD38-2's on order from EMD in 1977, but cancelled them. Here th... || &nbsp; |- | <KUID:45588:1428> || SD40-2 Conrail 6358 || Conrail SD40-2. Model was created by Prjindigo, Roger Crouch and the reskin by Adam Gase. Contri... || &nbsp; |} &nbsp; ===group-09 (-2)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- |<KUID:45588:1647> || GP38-2 LV 325 || Lehigh Valley bought 12 new GP38-2's in 1972, operating them for four years before the formation ... || &nbsp; |- | <KUID:45588:1779> || Clinchfield 4-6-2 Pacific 153 || Clinchfield operated 5 light Pacifics, class P-1 #150-152 initially for passenger service and cla... || &nbsp; |- | <KUID:45588:333> || GP40-2 GTW 6413 ex-DT&I || GP40-2 GTW 6413 ex-DT&I without dynamic brakes Contributors (Dependencies) || &nbsp; |- | <KUID:45588:4022> || SD40-2 Ohio Central 4022 || Roger Crouch's SD40 model painted for the Ohio Central in their Erie-Lackawanna-style paint schem... || &nbsp; |- | <KUID:45588:4352> || GP40-2 Chessie WM 4352 || GP40-2 Chessie (WM) 4352. Western Maryland owned 35 GP40-2's, #4257-4261, 4312-4321, and 4352-437... || &nbsp; |- | <KUID:45588:4408> || GP40-2 Chessie C&O 4408 || GP40-2 Chessie (C&O) - B&O and WM notwithstanding. C&O owned 95 GP40-2's, #4165-4184, 4262-4286, ... || &nbsp; |- | <KUID:45588:455> || GP38-2 P&LE 2059 Yellow cab front || Pittsburgh & Lake Erie bought 6 new GP38-2's in 1977 and || &nbsp; |- | <KUID:45588:542> || GP38-2 Utah Belt 2016 || Auran's GP38 painted for Eric Brooman's Utah Belt. Contributors (Dependencies): || &nbsp; |- | <KUID:45588:543> || GP38-2 Utah Belt 2009 || Auran's GP38 painted for Eric Brooman's Utah Belt. Contributors (Dependencies):... || &nbsp; |- | <KUID:45588:5937> || SD40-2 GTW 5937 ex-UP || Grand Trunk Western SD40-2 5937, ex-UP, nee-Missouri Pacific, without dynamic brakes. Dynamic bra... || &nbsp; |- | <KUID:45588:842> || GP40-2 RF&P 142 || Richmond Fredericksburg & Potomac owned 7 GP40's and 7 GP40-2's for bridge line freight service b... || &nbsp; |- | <KUID:45588:844> || GP40-2 RF&P 144 || Richmond Fredericksburg & Potomac owned 7 GP40's and 7 GP40-2's for bridge line freight service b... || &nbsp; |- | <KUID:51275:1> || CSX GP 38-2 || Paint shed skin 2003 William Works || &nbsp; |- | <KUID:51275:54> || CSX GP 38-2 || Pa || &nbsp; |- | <KUID:51275:56> || CSX GP 38-2 || CSX Locomotive ver.2 needs the horn and GP38 file!!! || &nbsp; |- | <KUID:523:1094> || IR SD40-2 || GM-EMD SD40-2 One of the problems with the popular 'carbody' units was that the strength l... || &nbsp; |- | <KUID:55290:606> || Loco EMD NSSD40-2 || NS SD40-2. Model was created by Prjindigo, Roger Crouch and the paintwork was created by Phil_C, ... || &nbsp; |- | <KUID:55290:616> || LOCO NS SD40-2 wide alpha || The SD40 can be said to have been the mainstay of the rail systems through the 70s and 80s, good ... || &nbsp; |- | <KUID:55290:620> || SPGP39-2 HSH || NS GP39-2 with a high short hood.Model was created by Prjindigo, Roger Crouch and the paintwork w... || &nbsp; |- | <KUID:55290:626> || csx mow GP40-2 || CSX MOW GP40-2. Model was created by Prjindigo, Roger Crouch and the paintwork was created by Sea... || &nbsp; |} &nbsp; ===group-10 (-2)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- |<KUID:55290:632> || CHESSIE SYSTEM GP40-2 || CHESSIE SYSTEM GP40-2. Model was created by Prjindigo, Roger Crouch and the paintwork was created... || &nbsp; |- | <KUID:55290:633> || CSX GREY GP38-2 || CSX GP38-2. Model was created by Prjindigo, Roger Crouch and the paintwork was created by Sean Po... || &nbsp; |- | <KUID:55976:51012> || 4-2-2 Stirling GNR #1 Enginespec || loco || &nbsp; |- | <KUID:58377:311> || PRJX7042 SD40-2 || PRJX leasing SD40-2 || &nbsp; |- | <KUID:58377:312> || PRJX7047 SD40-2 no dynamics || PRJX leasing SD40-2 without dynamic brakes || &nbsp; |- | <KUID:58377:313> || PRJX7051 SD40-2 High Short Hood || PRJX leasing SD40-2 with a high short hood || &nbsp; |- | <KUID:58377:316> || PRJX7066 SD40-2 HSH steam no dynamics || PRJX leasing SD40-2 HSH with a steam generator without dynamic brakes || &nbsp; |- | <KUID:58377:374> || PRJX GP39-2 HSH no dynamics || PRJX leasing GP39-2 with a high short hood and no dynamic brakes || &nbsp; |- | <KUID:58377:376> || PRJX GP39-2 steam no dynamics || PRJX leasing GP39-2 with a steam generator without dynamic brakes || &nbsp; |- | <KUID:58377:393> || PRJX GP40-2 HSH || PRJX leasing GP40-2 with a high short hood || &nbsp; |- | <KUID:58377:394> || PRJX GP40-2 HSH no dynamics || PRJX leasing GP40-2 with a high short hood without dynamic brakes || &nbsp; |- | <KUID:58377:516> || SD40-2 undecorated || SD40-2 undecorated || &nbsp; |- | <KUID:58377:9997> || PRJX GP38-2 Steam || PRJX leasing GP38-2 with a steam generator || &nbsp; |- | <KUID2:58422:10109:4> || Pullman 10s-1d-2c || (null) || &nbsp; |- | <KUID:58422:10114> || Pullman 10s-1d-2c || Pullman heavyweight cars of the 1920's were to replace the old wood cars. They were built from 19... || &nbsp; |- | <KUID:58843:10052> || IC 4-4-2 Sleeper || On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... || &nbsp; |- | <KUID:61014:1776> || DT&I GP 38-2 #1776 || Delivered in this Bicentennial paint scheme in September of 1975,re-painted as DT&I #228 in 1981 || &nbsp; |- | <KUID:62456:445> || BR 101 210-2 || Model: DB 101 DB Baujahr: 1996 Hersteller: Adtranz Dauerleistung: 6400 kW Vmax: 2... || &nbsp; |- | <KUID:63822:100362> || SD40-2 CLRR || paintshed skin || &nbsp; |- | <KUID:7592:1000308> || TPR MKT SD40-2 || paintshed skin || &nbsp; |} &nbsp; ===group-11 (-2)=== &nbsp; {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- |<KUID2:7592:10175:1> || CRR #311 4-8-2 Mountain || The CRR #311 is a fictional roadnumber of the USRA Mountain Type Locomotive owned by nearly every... || &nbsp; |- | <KUID2:7592:10178:1> || GN #2507 4-8-2 Mountain || The GN #2507 is a prototypical roadnumber of the USRA Mountain Type Locomotive owned by nearly ev... || &nbsp; |- | <KUID2:7592:10180:1> || UP #7000 4-8-2 Mountain || The UP #7000 is a prototypical roadnumber of the USRA Mountain Type Locomotive owned by nearly ev... || &nbsp; |- | <KUID2:7592:10182:1> || L&N #419 4-8-2 Mountain || The L&N #419 4-8-2 Mountain is a fictional roadnumber of the USRA Mountain Type Locomotive owned ... || &nbsp; |- | <KUID2:7592:10184:1> || Southern #1409 4-8-2 Mountain || The Southern #1409 4-8-2 Mountain is a fictional roadnumber of the USRA Mountain Type Locomotive ... || &nbsp; |- | <KUID2:7592:10186:1> || GN #2512 4-8-2 Mountain || The GN #2512 is a prototypical roadnumber of the USRA Mountain Type Locomotive owned by nearly ev... || &nbsp; |- | <KUID2:7592:10187:1> || DMIR #244 4-8-2 Mountain || The UP #7000 is a prototypical roadnumber of the USRA Mountain Type Locomotive owned by nearly ev... || &nbsp; |- | <KUID:76538:100177> || GP38-2 Mohawk & Hudson 3850 || paintshed skin || &nbsp; |- | <KUID:79097:1001> || Frisco 1522 4-8-2 'Mountain Type' || The Frisco 1522 was built by the Baldwin Locomotive Company in 1925 and has a wheel arrangement o... || &nbsp; |- | <KUID:81997:51420> || SP_GS-2_Engine_Specs || Engine spec for SP GS-2 4-8-4 loco || &nbsp; |- | <KUID2:82412:4001005:1> || JVC-60-Oak-S-LO-24m-01 || JVC Oak Tree (JVC__Trees_60 Oak summer 24m) with reduced texture size especially for application ... || &nbsp; |- | <KUID2:82412:4001020:1> || JVC-9-Birch-S-LO-25m-01 || JVC Oak Tree (JVC_S1_Trees_9 Birch 25m Summer) with reduced texture size especially for applicati... || &nbsp; |- | <KUID2:82412:4001021:1> || JVC-2-Tree-LO-20m-01 || JVC Tree 2 (jvc__trees_2 20m single) with reduced texture size especially for application within ... || &nbsp; |- | <KUID2:82412:4001022:1> || JVC-49-Oak-S-LO-29m-01 || JVC Tree 2 (jvc_trees_49 oak summer lo_res 29m) with reduced texture size especially for applicat... || &nbsp; |- | <KUID2:82412:5000052:1> || Log-Stack-Industrie-201 || Log Stack Industry. Loads TUME's Log Stack Products. || &nbsp; |- | <KUID2:82412:6097013:1> || MILW-Sub-HV-Connect-20m-01 || MILW-Sub-HV-Connect-20m-01 || &nbsp; |- | <KUID:83815:100002> || SD40-2 Florida East Coast || SD40-2 Florida East Coast Contributors (Dependencies): ... || &nbsp; |- | <KUID:86105:6213> || US Army Sd40-2 4641 || paintshed skin || &nbsp; |- | <KUID:86105:6221> || Loco SD40-2 Western Pacific || Western Pacific SD40-2. Model was created be Prjindigo, Roger Crouch and the paintwork was create... || &nbsp; |- | <KUID:86105:6222> || Loco SD40-2 Southern Pacific || Southern Pacific SD40-2. Model was created be Prjindigo, Roger Crouch and the paintwork was creat... || &nbsp; |} &nbsp; ===group-12 (-2)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | <KUID:86105:6223> || Loco SD40-2 FURX || FURX SD40-2. Model was created be Prjindigo, Roger Crouch and the paintwork was created by Phil_C... || &nbsp; |- | <KUID:86105:6224> || Loco SD40-2 Grand Trunk Western || Grand Trunk Western SD40-2. Model was created by Prjindigo, Roger Crouch and the paintwork was cr... || &nbsp; |- | <KUID:86105:6225> || Loco SD40-2 Kansas City Southern || Kansas City Southern Railways SD40-2. Model was created be Prjindigo, Roger Crouch and the paintw... || &nbsp; |- | <KUID:86105:6231> || Loco SD40-2 Bessemer & Lake Erie || Bessemer & Lake Erie SD40-2. Model was created be Prjindigo, Roger Crouch and the paintwork was c... || &nbsp; |- | <KUID:86105:6232> || Loco SD40-2 Atlantic Coast Lines || Atlantic Coast Lines SD40-2. Model was created be Prjindigo, Roger Crouch and the paintwork was c... || &nbsp; |- | <KUID:86105:6233> || Loco SD40-2 Baltimore & Ohio || Baltimore & Ohio SD40-2. Model was created be Prjindigo, Roger Crouch and the paintwork was creat... || &nbsp; |- | <KUID:86105:6234> || Loco SD40-2 Chicago & North Western || Chicago & North Western SD40-2. Model was created be Prjindigo, Roger Crouch and the paintwork wa... || &nbsp; |- | <KUID:86105:6239> || Loco SD40-2 Paducah & Louisville Railway || Paducah & Louisville Railway SD40-2. Model was created be Prjindigo, Roger Crouch and the paintwo... || &nbsp; |- | <KUID:86105:6274> || Loco EMD SD40-2 CSX Bright Future || CSX SD40-2 in Bright Future paint scheme. Model was created by Prjindigo, Roger Crouch and the pa... || &nbsp; |- | <KUID:86105:6275> || Loco EMD SD40-2 CSX MaintenanceOfWay || CSX SD40-2 Maintenance Of Way. Model was created by Prjindigo, Roger Crouch and the paintwork was... || &nbsp; |- | <KUID:86105:6276> || Loco EMD SD40-2 CSX Grey || CSX SD40-2 in Grey and Blue Paint scheme. Model was created by Prjindigo, Roger Crouch and the pa... || &nbsp; |- | <KUID:86105:9904> || Loco EMD GP38-2HSH Southern Railway || GP38-2 HSH Southern Railway. Model was created by Prjindigo, Roger Crouch and the paintwork was c... || &nbsp; |- | <KUID:87051:1> || Overland3974 SD40-2 || Overland3974 SD40-2 Contributors (Dependencies): <... || &nbsp; |- | <KUID:87051:2> || Overland9928 SD40-2 || Overland9928 SD40-2 Contributors (Dependencies): <... || &nbsp; |- | <KUID:87783:1141> || SD40-2 - Midwest Central || Midwest Central's SD40-2 is a Paintshed reskin of the Auran model in the green and brown MidCen l... || &nbsp; |- | <KUID:87854:982511580> || CSX SD40-2 8808 || paintshed skin || &nbsp; |- | <KUID:87854:982511581> || CSX SD40-2 8855 || paintshed skin || &nbsp; |- | <KUID2:93502:60:1> || A10 engine 0-4-2S class engine || A10 #6 is one of the oldest steam engines still in operation in the southern hemisphere. Contrib... || &nbsp; |- | <KUID:93502:61> || 3F6I A10 engine 0-4-2S class engine || The A10 is one of the oldest steam engines still in operation in the southern hemisphere. || &nbsp; |- | <KUID:93502:72> || Emily engine 4-2-2T class engine || Emily is new engine to arrive on the happy island of sodor. || &nbsp; |- | <KUID:98966:3009> || Norfolk southern SD40-2 Booster with Steam || Norfolk southern SD40-2 Booster with Steam-unit. Many thanks to Prjindigo for the mesh and For Le... || &nbsp; |- | <KUID:98966:529786> || Norflok Southern GP38-2 HSH || Norflok Southern GP38-2 HSH , large file size do to major alterations to the secondary texture fi... || &nbsp; |} &nbsp; ==Pages 1-2 <kuid:-3>== '''All pages with <kuid:-3> and '-3' in names''' ===group-13 (-3)=== &nbsp; {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | <KUID:-3:10035> || GATX Oil Tanker || length: 37'4 width: 9'8 height: 13'9 bogie wheelbase: 5'6 bogie pivot centres: 27'2 || &nbsp; |- | <KUID:-3:10059> || Seaport || (null) || &nbsp; |- | <KUID:-3:10063> || CB Woodchips_Gondola || Woodchips Gondola Company: Chippies Bits Ltd Built: 1977-81ish Length: 14.2m Height: 2... || &nbsp; |- | <KUID:-3:100878> || NSWGR NQOX Flat Car || Container Flat Car || &nbsp; |- | <KUID:-3:10123> || Multiple Industry || (null) || &nbsp; |- | <KUID:-3:10139> || Container Station Basic || (null) || &nbsp; |- | <KUID:-3:10142> || Oil Field Basic || (null) || &nbsp; |- | <KUID:-3:10145> || Seaport Basic || (null) || &nbsp; |- | <KUID:-3:10162> || gen renfe 305 || (null) || &nbsp; |- | <KUID:-3:10165> || Multiple Industry basic || (null) || &nbsp; |- | <KUID:109502:100030> || AVE-3-CABEZA || Model: AVE-350 Manufactor: Siemens Power: 4800 bhp (compleet trainset) || &nbsp; |- | <KUID2:121945:15032:4> || B4u-30 || Vierachsiger Einheits-D-Zugwagen, 2. Klasse Bauart 1930 Ganzstahlbauart (B4u-30) ... || &nbsp; |- | <KUID:1551:10021> || SNCF TGV-PSE Unit 2-3 || TGV Paris Sud-est Unit 2 Company: SNCF || &nbsp; |- | <KUID:178987:3113> || NS_Plan-U_111-3_ABk || NS Plan-U 111 ABk Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1960 Lengte 24622 mm De totale... || &nbsp; |- | <KUID:178987:3153> || NS_Plan-U_151-3_ABk || NS Plan-U 151 ABk Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1960 Lengte 24622 mm De totale... || &nbsp; |- | <KUID:178987:5502> || NS_Plan-T_502-3_AB || NS_Plan-T_529 Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1965 Lengte 24550 mm De totale len... || &nbsp; |- | <KUID:178987:5512> || NS_Plan-T_529-3_AB || NS_Plan-T_529_AB Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1965 Lengte 24550 mm De totale ... || &nbsp; |- | <KUID:284555:100421> || Durango and silverton K-36 #485 Tender || D&RGW #485 Tender This is the Tender for the D&RGW K-36 #485. THIS IS A RESKIN OF PROWLER901'S... || &nbsp; |- | <KUID:284555:100422> || Durango & Silverton K-36 #485 || D&RGW K-36 Mikado #485 The K-36 class was built for the D&RGW by the Baldwin Locomotive Works of... || &nbsp; |- | <KUID:403674:1> || PKP_EU07-337_PKP _CARGO_ZT_Gdynia_303e || Polish electric universal locomotive EU07 class, factory type 303E Contributors (Dependencies): ... || &nbsp; |} &nbsp; ===group-14 (-3)=== &nbsp; {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | <KUID:45588:857> || SD40-3 W&LE 3016 || Roger Crouch's SD40 model painted for the (new) Wheeling & Lake Erie in their Rio Grande-style pa... || &nbsp; |- | <KUID:49267:1009> || NS ICE-3 1 || Model: NS ICE-3 Manufactor: Siemens Power: 4800 bhp (compleet trainset) Max.Speed: 330 km/h Head... || &nbsp; |- | <KUID2:67794:2001:1> || UTLX 38\' X-3 Tank Car || UTLX tank car based (somewhat) on the 38' long frame X-3 design from the 1920's. Used through out... || &nbsp; |- | <KUID2:67794:2002:1> || SHPX 38\' X-3 Tank Car || SHPX tank car based (somewhat) on the 38' long frame X-3 design from the 1920's. Used through out... || &nbsp; |- | <KUID2:82412:4001006:1> || JVC-60-Oak-S-LO-30m-01 || JVC Oak Tree (JVC__Trees_60 Oak summer 30m) with reduced texture size especially for application ... || &nbsp; |- | <KUID2:82412:4001016:1> || JVC-39-Oak-S-LO-32m-01 || JVC Oak Tree (JVC__Trees_39 Oak 32m) with reduced texture size especially for application within ... || &nbsp; |- | <KUID:83329:20521> || Ansett Douglas DC-3 || I would like to thank Minitrix for letting me reskin his Douglas DC-3 Contributors (Dependencies... || &nbsp; |- | <KUID:83329:20522> || TAA Douglas DC-3 || I would like to thank Minitrix for letting me reskin his Douglas DC-3 Contributors (Dependencies... || &nbsp; |- | <KUID:9999:10024> || OBB CAT 88-33 controll || City Airport Train Doppelstockwagen-Steuerwagen der Ö³terreichisen Bundesbahnen AG Based on the ... || &nbsp; |- | <KUID:9999:10026> || OBB Wiesel 88-33 controll || City Airport Train Doppelstockwagen-Steuerwagen der Ö³terreichisen Bundesbahnen AG Based on the ... || &nbsp; |} &nbsp; &nbsp; ==Pages 1-4 <kuid:-4>== '''Searches finding <kuid:-4> and '-4' ''' &nbsp; ===group-15 (-4)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | &lt;KUID2:113556:60000:3>||SP 8-40b #8024 ||GE B40-8 SP, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, and W... | |- |&lt;KUID2:113556:600015:2> || SSW 8-40b #8049 || GE B40-8 SSW, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, and ... | |- | &lt;KUID2:113556:60003:3> || SP 8-40b #8019 || GE B40-8 SP, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, and W... | |- | &lt;KUID2:113556:60004:2> ||SSW 8-40b #8051 ||GE B40-8 SSW, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, and ... | |- | &lt;KUID2:113556:60020:3> ||SP 8-40b #8001 ||GE B40-8 SP, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, and W... | |- | &lt;KUID2:113556:60056:3> ||BNSF 8-40b #8618 ||GE B40-8 SP, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- | &lt;KUID2:113556:60059:3> ||CSX 8-40b #5952 ||GE B40-8 CSX, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf... | |- | &lt;KUID2:113556:60060:3> ||CSX 8-40b #5942 ||GE B40-8 CSX, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf... | |- |KUID2:113556:60077:3> ||BNSF 8-40b #8603 ||GE B40-8 SP, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:113556:60080:2> ||ATSF 8-40b #7442 ||GE B40-8 ATSF mesh made by SP_OR_BUST, Thanks to CSX_sd60 for the great horn, Thanks to Weevil fo... | |- |KUID2:113556:60084:2> ||ATSF 8-40b #8615 ||GE B40-8 ATSF mesh made by SP_OR_BUST, Thanks to CSX_sd60 for the great horn, Thanks to Weevil fo... | |- |KUID2:113556:60087:2> ||ATSF 8-40b #8617 ||GE B40-8 ATSF mesh made by SP_OR_BUST, Thanks to CSX_sd60 for the great horn, Thanks to Weevil fo... | |- |KUID2:113556:70020:2> ||Susq 8-40b #4002 ||GE B40-8 Susq, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wul... | |- |KUID2:113556:70089:2> ||SP KODAK 8-40b #8151 ||GE B40-8 SP Kodachrome mesh made by SP_OR_BUST, Thanks to CSX_sd60 for the great horn, Thanks to ... | |- |KUID2:135744:2:1> ||Santa Fe Warbonnet Dash 9-44CW ||This is A Santa Fe Warbonnet scheme Dash 9 locomotive reskinned from norfolksouthern37's BNSF Das... | |- |KUID2:135744:48734:1> ||Santa Fe Warbonnet Dash 9-44CW ||This is a revision of my original Santa Fe Warbonnet Dash 9-44CW locomotive, originally reskinned... | |- |KUID:152373:9000> ||FR8Net Dash 9-44CW ||FR8Net's first Locomotive purchase's from GM on the 10th Dec 04, 8846,8847 and 8848 Working on th... | |- |KUID:178987:5503> ||NS_Plan-T_502-4_BK2 ||NS_Plan-T_502 Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1965 Lengte 25500 mm De totale len... | |- |KUID:178987:5513> ||NS_Plan-T_529-4_BK2 ||NS_Plan-T_529_BK2 Gebouwd door Werkspoor/Heemaf/Smit In dienst in 1965 Lengte 25500 mm De totale... | |- |KUID:200726:24031> ||OEBB H-40/60 Tunnel ||OEBB Lichtsignal geskripted 3-begriffiges Hauptsignal Tunnelausfuehrung | |} ===group-16 (-4)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:08%" |Repairer |- | &lt;KUID:32711:100340> ||0-4-0T Jay Street Connecting #1 ||An ALCo 0-4-0T saddle tank locomotive. This engine is based on Georgia Power #30, currently opera... | |- |KUID:32711:100353> ||0-4-0T Jay Street Connecting #2 ||An ALCo 0-4-0T saddle tank locomotive. This engine is based on Georgia Power #30, currently opera... | |- |KUID:32711:100430> ||0-4-0T Sounds ||0-4-0T sounds | |- |KUID:35848:1001> ||BNSF Dash 9-44CW ||ReSkin of the 1001 of the Elgin, Joliet & Eastern (EJE) Mesh-file by Justin Cornell (norfolksouth... | |- |KUID:45324:100015> ||BNSF Dash 9-44CW ||BNSF dash nine set | |- |KUID:45324:100018> ||BNSF Warbonnet Dash 9-44CW ||BNSF dash nine set | |- |KUID:45588:1222> ||DS4-4-10 Reading 729 ||Baldwin switcher model DS-4-4-10 as used on the Reading. This unit was rebuilt with an EMD engine... | |- |KUID:45588:1224> ||DS4-4-10 Reading 38 ||Baldwin switcher model DS-4-4-10 as used on the Reading. US loco sound effects by Wulf_9 enginesp... | |- |KUID:45588:1540> ||DS4-4-10 CNJ 1073 ||Baldwin DS4-4-10 switcher operated by the Central Railroad of New Jersey (3 units, #1072-1074). ... | |- |KUID:45588:1615> ||DS4-4-10 WM 133 Speedlettering ||Baldwin switcher model DS-4-4-10 as used on the Western Maryland. WM owned only 2 units, #133 and... | |- |KUID2:45588:1959:1> ||DS4-4-10 Monongahela 421 ||Baldwin switcher model DS-4-4-10 as used on the Monongahela Railway, which operated 27 of these e... | |- |KUID:45588:1960> ||DS4-4-10 Monongahela 412 ||Baldwin switcher model DS-4-4-10 as used on the Monongahela Railway, which operated 27 of these e... | |- |KUID:45588:4465> ||CW44-8 V&O 4460-4465 ||GE CW44-8 (Dash 9 predecessor) in Appalchian Lines (V&O) color scheme. Contributors (Dependencie... | |- |KUID:47092:15312> ||IM wellcars 1-40ft/1-48ft ||A wellcarpack! you need realsquash's bogies for these! which they can be found here at this link ... | |- |KUID:47092:15313> ||IM wellcars 1-40ft ||A wellcarpack! you need realsquash's bogies for these! which they can be found here at this link ... | |- |KUID:47092:15314> ||IM wellcars 2-40ft ||A wellcarpack! you need realsquash's bogies for these! which they can be found here at this link ... | |- |KUID:47092:15315> ||IM wellcars 2-48ft ||A wellcarpack! you need realsquash's bogies for these! which they can be found here at this link ... | |- |KUID:47092:15316> ||IM wellcars 1-48ft ||A wellcarpack! you need realsquash's bogies for these! which they can be found here at this link ... | |- |KUID:55290:100015> ||NS HORSEHEAD Dash 9-44CW ||THIS IS A NS HORSEDHEAD DASH 9 MADE BY JUSTIN AND REPAINTED BY SURESHOT28 Contributors (Dependen... | |- |KUID2:55290:60000:1> ||NS 8-40b #4800 ||GE B40-8 NS, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |} ===group-17 (-4)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:08%" |Repairer |- | &lt;KUID2:55290:60003:1> ||NS 8-40b #4804 ||GE B40-8 NS, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:55290:60005:1> ||NS 8-40b #4805 ||GE B40-8 NS, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:55290:60007:1> ||CR 8-40b #5083 ||GE B40-8 CR, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:55290:60008:1> ||CR 8-40b #4804 NS Patch ||GE B40-8 CR, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:55290:60009:1> ||CR 8-40b #5077 ||GE B40-8 CR, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:55290:60010:1> ||CR 8-40b #4808 NS PATCH ||GE B40-8 CR, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:55290:60011:1> ||CR 8-40b #5959 CSX PATCH ||GE B40-8 CR, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:55290:60012:1> ||CR 8-40b #5954 CSX Patch ||GE B40-8 CR, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID2:55290:60013:1> ||CSX 8-40b #5945 ||GE B40-8 CR, Thanks to CSX_sd60 for the great horn, Thanks to Weevil for the nice eng Spec, Wulf ... | |- |KUID:58843:10052> ||IC 4-4-2 Sleeper ||On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... | |- |KUID:58843:10054> ||IC 6-6-4 Sleeper King Coal ||On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... | |- |KUID:58843:10055> ||IC 6-6-4 Sleeper King Cotton ||On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... | |- |KUID:58843:10056> ||IC 6-6-4 Sleeper Sugarland ||On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... | |- |KUID:58843:10057> ||IC 6-6-4 Sleeper Timberland ||On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... | |- |KUID:63971:110018> ||Pilbara rail Dash 9-44CW ||GE dash-9 in pilbara rail livery Contributors (Dependencies)... | |- |KUID:63971:110019> ||BHP Dash 9-44CW ||GE dash-9 in BHP livery Contributors (Dependencies)... | |- |KUID:63971:110020> ||Hammersley Iron Dash 9-44CW ||GE dash-9 in Hammersley Iron livery Contributors (Dependencies)... | |- |KUID:63971:110021> ||GE Green Machine Dash 9-44CW ||GE dash-9 in corporate livery Contributors (Dependencies)...... | |- |KUID:74708:37003> ||raccord-4x2 ||raccord 4 Ã 2 voies | |- |KUID:74708:38007> ||pont-4voies ||pont routier 4 voies | |} ===group-18 (-4)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:08%" |Repairer |- | &lt;KUID2:82412:20115:1> ||Products-Car-C-4x4-01 ||Products-Car-C-4x4-01 | |- |KUID2:82412:4001022:1> ||JVC-49-Oak-S-LO-29m-01 ||JVC Tree 2 (jvc_trees_49 oak summer lo_res 29m) with reduced texture size especially for applicat... | |- |KUID2:82412:4001023:1> ||JVC-46-Beech-S-LO-08m-01 ||JVC Tree 2 (jvc__trees_46 beech summer lo_res 8m) with reduced texture size especially for applic... | |- |KUID2:82412:70074:1> ||Bush-Spline-10m-44-DMD-BLB ||David Drake's BlackBerry-spline-3 with reduced texture size especially for application within lar... | |- |KUID2:93502:60:1> ||A10 engine 0-4-2S class engine ||A10 #6 is one of the oldest steam engines still in operation in the southern hemisphere. Contrib... | |- |KUID:93502:61> ||3F6I A10 engine 0-4-2S class engine ||The A10 is one of the oldest steam engines still in operation in the southern hemisphere. | |- |KUID:93502:78> ||Blue A10 engine 2-4-0S class engine ||The A10 is one of the oldest steam engines sto run on the QR network, this one uses to run the No... | |- |KUID:93502:97> ||DD17 engine 4-6-4ST class engine ||DD17 #1051 is one of the last four DD17 steam tank engines still in operation in the southern hemisphere. | |- |} ==Pages 1-1 <kuid:-5>== ===group-19 (-5)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:08%" |Repairer |- |<KUID:115270:110007> || A-5 - Skrzyzowanie drog rownorzednych || A-5 - Skrzyzowanie drog rownorzednych || &nbsp; |- | <KUID2:193148:1385:1> || NSWGR D-59 class || NSWGR 59 class Locomotive 2004/2006 compatible This content is revised with the kind permission o... || &nbsp; |- | <KUID2:193148:1392:1> || NSWGR D-59 class tender || NSWGR D-59 class tender 2004/2006 compatible This content is revised with the kind permission of ... || &nbsp; |- | <KUID:438196:1151> || kiha187-502 || Japanese Diesel Car kiha187-502, Limited Express 'Super Inaba' of West JR. Make a unit with kiha1... || &nbsp; |- | <KUID:440847:42001> || PKP SU42-524 PR.Gdynia || SU42 Contributors (Dependencies): || &nbsp; |- | <KUID:62456:419> || BR 189 023-5 || Model: BR 189 Railion Baujahr: 2002 Hersteller: Siemens Dauerleistung: 6400 kW Vmax: 140 km... || &nbsp; |- | <KUID2:69974:37021:1> || Stuetzmauer-5M || || &nbsp; |- | <KUID2:69974:37029:1> || Stuetzmauer03-5M || || &nbsp; |- | <KUID2:69974:37030:1> || Stuetzmauer05-5M || || &nbsp; |- | <KUID2:69974:37031:1> || Stuetzmauer07-5M || || &nbsp; |- | <KUID2:69974:37032:1> || Stuetzmauer10-5M || || &nbsp; |- | <KUID2:82412:5000016:1> || Warehouse-Ind-50m-S2-Mullan-001 || Large warehouse for rail and truck with two rail loadingbays. Not based on any real warehouse. || &nbsp; |- | <KUID2:82412:5000019:1> || Load-Yard-50m-S2-Lucky-Friday-001 || Load-Yard-50m-S2-Lucky-Friday-001 || &nbsp; |- | <KUID2:82412:6097014:1> || MILW-Sub-HV-Connect-50m-01 || MILW-Sub-HV-Connect-50m-01 || &nbsp; |- | <KUID2:82412:6097015:1> || MILW-Sub-HV-WP-50m-003 || MILW-Sub-HV-WP-50m-003 || &nbsp; |} ==Pages 1-3 <kuid:-6&gt; and (-6)== ===group-20 (-6)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" |Description !style="width:07%" |Repairer |- | &lt;KUID:115270:110008&gt; || A-6A - Skrzyzowanie z drogami podporzadkowanymi || A-6A - Skrzyzowanie z drogami podporzadkowanymi || |- | &lt;KUID:115270:110009&gt; || A-6B - Skrzyzowanie z droga podporzadkowana R || A-6B - Skrzyzowanie z droga podporzadkowana R || |- | &lt;KUID:115270:110010&gt; || A-6C - Skrzyzowanie z droga podporzadkowana L || A-6C - Skrzyzowanie z droga podporzadkowana L || |- | &lt;KUID:115270:110011&gt; || A-6D - Skrzyzowanie z droga podporzadkowana 1kier R || A-6D - Skrzyzowanie z droga podporzadkowana 1kier R || |- | &lt;KUID:115270:110012&gt; || A-6E - Skrzyzowanie z droga podporzadkowana 1kier L || A-6E - Skrzyzowanie z droga podporzadkowana 1kier L || |- | &lt;KUID2:135744:1283:1&gt; || SP 0-6-0 Switcher #1283 || This is a Southern Pacific 0-6-0 Switcher #1283 reskinned from AltoDave's Union Pacific 0-6-0 Swi... || |- | &lt;KUID2:135744:1284:1&gt; || SP 0-6-0 Switcher #1284 || This is a Southern Pacific 0-6-0 Switcher #1284 reskinned from AltoDave's Union Pacific 0-6-0 Swi... || |- | &lt;KUID2:135744:1285:1&gt; || SP 0-6-0 Switcher #1285 || This is a Southern Pacific 0-6-0 Switcher #1285 reskinned from AltoDave's Union Pacific 0-6-0 Swi... || |- | &lt;KUID2:135744:15573:2&gt; || Detroit & Mackinac 0-6-0 Switcher Tender || This is the tender that goes with the Detroit & Mackinac 0-6-0 Switcher. It is being re-released ... || |- | &lt;KUID2:135744:6830:2&gt; || Detroit & Mackinac 0-6-0 Switcher 174 || This is an update to my original Detroit & Mackinac 0-6-0 Switcher. I have fixed many problems an... || |- | &lt;KUID2:135744:6831:2&gt; || Pere Marquette 0-6-0 Switcher 1132 || This is an update to my original Pere Marquette 0-6-0 Switcher. I have fixed many problems and bu... || |- | &lt;KUID2:135744:6832:2&gt; || Pere Marquette 0-6-0 Switcher Tender || This is the tender that goes with the Pere Marquette 0-6-0 Switcher. It is being re-released in t... || |- | &lt;KUID:136383:1000&gt; || 218 001-6 || paintshed skin || |- | &lt;KUID:208456:1025&gt; || CFL-60 DCL || Dieser Content enthält eine CFL-60 DCL welche bei der Parkeisenbahn Chemnitz im Küchwaldpark mit ... || |- | &lt;KUID:4468:225&gt; || 4-6-2 Duchess Class Tender BR Blue || 10,000 gallon Tender for the 4-6-2 Duchess Class. || |- | &lt;KUID:4468:4001&gt; || 4-6-2 West Country Class SR || 4-6-2 West Country Class SR SR No. BR No. Name Date Built 21C101 34001 Exeter 1945 Protot... || |- | &lt;KUID:4468:4002&gt; || 4-6-2 West Country Class SR Tender || 4-6-2 West Country Class SR Tender At the end of World War II, a fast and powerful mixed traffic... || |- | &lt;KUID:4468:4049&gt; || 4-6-2 Battle of Britain Class BR Green || 4-6-2 West Country Class SR (Battle of Britain Class) SR No. BR No. Name Date Built 21C151 34... || |- | &lt;KUID:4468:4050&gt; || 4-6-2 Battle of Britain Class BR Green Tender || 4-6-2 Battle of Britain Class BR Green Tender At the end of World War II, a fast and powerful mi... || |- | &lt;KUID:4468:4771&gt; || 2-6-2 V2 LNER Green || Gresley Mixed Traffic V2 2-6-2 4771 Green Arrow 4806 Green Howard 4844 Coldstreamer (60873) 48... ||&nbsp; |} &nbsp; ===group-21 (-6)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- |&lt;KUID:4468:775&gt; || BR 4-6-0 N15 King Arthur Class Tender || 5000 gallon Tender for the BR 4-6-0 N15 King Arthur Class. || |- | &lt;KUID:44797:6830&gt; || NYC-060-6825 || This is my first attempt at engine building. The engine I selected to build is NYC USRA design. T... || |- | &lt;KUID:45588:10229&gt; || Pittsburgh & West Virginia 4-6-2 Pacific 200 Tender || Pittsburgh & West Virginia 4-6-2 Pacific Tender, Coal, lettered for #200. Original tender bogey w... || |- | &lt;KUID:45588:10230&gt; || Pittsburgh & West Virginia 4-6-2 Pacific 200 || P&WV operated 3 light Pacifics, #200-202. Passenger service was discontinued before the Connelsvi... || |- | &lt;KUID:45588:1779&gt; || Clinchfield 4-6-2 Pacific 153 || Clinchfield operated 5 light Pacifics, class P-1 #150-152 initially for passenger service and cla... || |- | &lt;KUID2:46075:6930:4&gt; || UP 0-6-0 #4609 || The original NYC 0-6-0 engine was done by Bill Klene of New Lenox, IL. Rebuilt here into a late m... || |- | &lt;KUID:46219:65&gt; || GWR 94xx 0-6-0T class engine || A GWR 94xx 0-6-0T Hawksworth engine. Built at Swindon engineering works in 1947. || |- | &lt;KUID:46219:85&gt; || GWR 43xx 2-6-0 Mogul Engine || GWR 2-6-0 4300 class Mogul Locomotive || |- | &lt;KUID:58843:10054&gt; || IC 6-6-4 Sleeper King Coal || On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... || |- | &lt;KUID:58843:10055&gt; || IC 6-6-4 Sleeper King Cotton || On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... || |- | &lt;KUID:58843:10056&gt; || IC 6-6-4 Sleeper Sugarland || On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... || |- | &lt;KUID:58843:10057&gt; || IC 6-6-4 Sleeper Timberland || On February 4, 1911, The Illinois Central Railroad renamed its 'Chicago & New Orleans Limited' as... || |- | &lt;KUID:63290:2&gt; || D&RG 2-6-0 2 || Denver & Rio Grande Rail Way Class 35 3 foot gauge 2-6-0 Number 2, the Tabi-wachi. This engine is... || |- | &lt;KUID:63290:3&gt; || D&RG 2-6-0 3 || Denver & Rio Grande Rail Way Class 35 3 foot gauge 2-6-0 Number 3, the Shou-wa-no. This engine is... || |- | &lt;KUID:63290:5&gt; || D&RG 2-6-0 5 || Denver & Rio Grande Rail Way Class 35 3 foot gauge 2-6-0 Number 5, the Ouray. This engine is show... || |- | &lt;KUID:63290:8&gt; || D&RG 2-6-0 8 || Denver & Rio Grande Rail Way Class 35 3 foot gauge 2-6-0 Number 8, the Arkansas. This engine is s... || |- | &lt;KUID2:7592:10169:1&gt; || CRR 0-6-0 Tender #9049 || USRA 6000gallon/10ton Tender. Original in NYC paint by Bill Klene, relettered for CRR. This is a ... || |- | &lt;KUID2:7592:10170:1&gt; || CRR 0-6-0 #9049 || The original NYC 0-6-0 engine was done by Bill Klene of New Lenox, IL. Rebuilt here into a late m... || |- | &lt;KUID2:7592:10174:1&gt; || GN 0-6-0 #27 || The original NYC 0-6-0 engine was done by Bill Klene of New Lenox, IL. Rebuilt here into a late m... || |- | &lt;KUID2:82412:22003:1&gt; || Lamp-No-Pool-65-001 || Lamp-No-Pool-65-001 ||&nbsp; |} &nbsp; ===group-22 (-6)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | &lt;KUID2:82412:22004:1&gt; || Lamp-Wall-65-001 || Lamp-Wall-65-001 || |- | &lt;KUID2:82412:22005:1&gt; || Lamp-Wood-Pool-65-001 || Lamp-Wood-Pool-65-001 || |- | &lt;KUID2:82412:22006:1&gt; || Lamp-Wall-60-001 || Lamp-Wall-60-001 || |- | &lt;KUID2:82412:4001005:1&gt; || JVC-60-Oak-S-LO-24m-01 || JVC Oak Tree (JVC__Trees_60 Oak summer 24m) with reduced texture size especially for application ... || |- | &lt;KUID2:82412:4001006:1&gt; || JVC-60-Oak-S-LO-30m-01 || JVC Oak Tree (JVC__Trees_60 Oak summer 30m) with reduced texture size especially for application ... || |- | &lt;KUID:93502:63&gt; || PB15 engine 4-6-0S class engine || The PB15 is one of the steam engines still in operation in the southern hemisphere. || |- | &lt;KUID:93502:64&gt; || 3F6I PB15 engine 4-6-0S class engine || The PB15 is one of the steam engines still in operation in the southern hemisphere. || |- | &lt;KUID:93502:97&gt; || DD17 engine 4-6-4ST class engine || DD17 #1051 is one of the last four DD17 steam tank engines still in operation in the southern hem... ||&nbsp; |} &nbsp; ==Group-23 <kuid:-7> and (-7)== ;Pages 1-3 combined '''<big>NOTE on formats:</big>''' At this juncture, having verified the above groups can be put into a table format, revising presentation into longer combined table instead of accepting the short list pages of the https://www.auran.com/planetauran/dls_cleanup_list.php. '''Searches finding <kuid:-7> and '-7' in names:''' &nbsp; ===group-23a (-7's)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | <KUID:101340:512700> || BWL C30-7 5127 || A C30-7 for use on the Blue Water Line Contributors (Dependencies): ... | &nbsp; |- | <KUID:108523:100001> || DHI-71 || The Clyde DHI-71 was originally built for the sugar industry. The first entered service in 1954 a... || &nbsp; |- | <KUID2:135744:191:1> || Detroit & Mackinac C30-7 381 || This is a former Detroit & Mackinac C30-7 #381. You can still see this locomotive on the Lake St... || &nbsp; |- | <KUID2:135744:192:1> || LSRC C30-7 1280 || This is a loco found on the Lake State Railway Company in the former Detroit & Mackinac Railroad ... || &nbsp; |- | <KUID2:135744:8074:1> || LSRC C30-7 1195 (Weathered) || Lake State Railway Company C30-7 1195 City of East Tawas (Weathered Version) Lake State Railway ... || &nbsp; |- | <KUID2:135744:8075:1> || LSRC C30-7 1195 || Lake State Railway Company C30-7 1195 City of East Tawas Lake State Railway Company is a railroa... || &nbsp; |- | <KUID2:135744:8076:1> || LSRC C30-7 181 || Lake State Railway Company C30-7 181 City of Bay City Lake State Railway Company is a railroad c... || &nbsp; |- | <KUID2:135744:850:1> || Conrail C30-7 Patched || Here is the newest locomotive to come from the Icebreaker Locomotive Works.....a Conrail C30-7 pa... || &nbsp; |- | <KUID:136383:1001> || 218 232-7 || paintshed skin || &nbsp; |- | <KUID:138423:1042> || ln C30-7 || L&N/Family Lines C30-7 Loco Contributors (Dependencies): ... || &nbsp; |- | <KUID:142675:500790> || Ty1-76 || In 1916 railway officials had to concede that there was no heavy freight locomotive adequate to t... || &nbsp; |- | <KUID:142675:500793> || Ty1-76_cab || The Prussian freight locomotive G12.2 of 1917 was named Ty1 in PKP service. Polycounts: 12012 b... || &nbsp; |- | <KUID:1551:10014> || SNCF TGV-PSE Unit 5-7 || TGV Paris Sud-est Unit 5-7 Company: SNCF || &nbsp; |- | <KUID:1551:10023> || SNCF TGV-PSE Unit 5-7 || TGV Paris Sud-est Unit 5-7 Company: SNCF || &nbsp; |- | <KUID:35815:101> || CBQ C30-7 101 || A C30-7 In Burlington red Aliased to orignal mesh by Justin Cornell Contributors (Dependencies):... || &nbsp; |- | <KUID:35815:1550> || L&N C30-7 931 || C30-7 skinned for the L&N Original mesh by Justin Cornell Uses Auto running number script by Wulf... || &nbsp; |- | <KUID:35815:2253> || WP C30-7 2253 || Western Pacific C30-7 Aliased to original mesh by Justin Cornell Contributors (Dependencies): <u... || &nbsp; |- | <KUID:35815:3601> || Clinchfield C30-7 || Clinchfield C30-7 Aliased to original mesh by Justin Cornell Contributors (Dependencies): ... || &nbsp; |- | <KUID:35815:5001> || MILW C30-7 5001 || Aliased reskin of Justin Cornells C30-7 into Milwaukee Road #5001 Skin done in Photoshop Contrib... || &nbsp; |- | <KUID:35815:501> || MRL C30-7 501 || Alias skin for Justin Cornell's C-30-7 for Montana Ral Link Contributors (Dependencies): ... || &nbsp; |- | <KUID:35815:5127> || BN C30-7 5127 || Aliased reskin of Justin Cornells C30-7 into Burlington Northern #5127 Skin done in Photoshop Co... || &nbsp; |- | <KUID:35815:8075> || SP C30-7 || Aliased reskin of Justin Cornells C30-7 into Southern Pacific Skin done in Photoshop Contributor... || &nbsp; |- | <KUID:35815:931> || CNW C30-7 931 || A C30-7 in CNW colors Aliased to orginal mesh by Justin Cornell Painted in Photoshop Contributor... || &nbsp; |- |} &nbsp; ===group-23b (-7's)=== {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" | Description !style="width:07%" |Repairer |- | <KUID:35848:103245> || BR 103.245-7 || hochleistungs-Schnellzuglok der Deutschen Bundesbahn in orientroter ... || &nbsp; |- | <KUID:45324:100022> || ATSF C30-7 || C30-7 pack ATSF UP NS || &nbsp; |- | <KUID:45324:100023> || UP C30-7 || C30-7 pack ATSF UP NS || &nbsp; |- | <KUID:45324:100024> || Norfolk Southern C30-7 || C30-7 pack ATSF UP NS || &nbsp; |- | <KUID:45588:3304> || C30-7 C&O 3304 || Two of C&O's 13 U30C's using the C30-7 mesh as a stand-in for a real U30C. Created from photos. ... || &nbsp; |- | <KUID:45588:3310> || C30-7 C&O 3310 || Two of C&O's 13 U30C's using the C30-7 mesh as a stand-in for a real U30C. Created from photos. ... || &nbsp; |- | <KUID:45588:615> || C30-7 Lake Superior & Ishpeming 3072 || LS&I bought a number of BN U30C's and C30-7's to replace their RSD12's, RSD15's, U25C's, and U23C... || &nbsp; |- | <KUID:45588:616> || C30-7 Lake Superior & Ishpeming 3006 || LS&I bought a number of BN U30C's and C30-7's to replace their RSD12's, RSD15's, U25C's, and U23C... || &nbsp; |- | <KUID:45588:756> || C30-7 Cartier Railway 34 || QCM did not own C30-7's, but did own C630's (30-39), C636's (77-79), and M636's (41-49, 71-76, 81... || &nbsp; |- | <KUID:45588:758> || C30-7 Delaware & Hudson 758 || D&H did not own C30-7's, but swapped their 3 SD45's to EL for 3 U33C's, 751-753, then bought 9 br... || &nbsp; |- | <KUID:45588:759> || C30-7 Delaware & Hudson 759 || D&H did not own C30-7's, but swapped their 3 SD45's to EL for 3 U33C's, 751-753, then bought 9 br... || &nbsp; |- | <KUID:45588:760> || C30-7 Cartier Railway 42 || QCM did not own C30-7's, but did own C630's (30-39), C636's (77-79), and M636's (41-49, 71-76, 81... || &nbsp; |- | <KUID:45588:761> || C30-7 Cartier Railway 75 || QCM did not own C30-7's, but did own C630's (30-39), C636's (77-79), and M636's (41-49, 71-76, 81... || &nbsp; |- | <KUID:45588:762> || C30-7 Delaware & Hudson 762 || D&H did not own C30-7's, but swapped their 3 SD45's to EL for 3 U33C's, 751-753, then bought 9 br... || &nbsp; |- | <KUID:45588:792> || C30-7 Cartier Railway 81 || QCM did not own C30-7's, but did own C630's (30-39), C636's (77-79), and M636's (41-49, 71-76, 81... || &nbsp; |- | <KUID:55290:850> || CONRAIL C30-7 || THIS A REPAINT OF NORFOLKSOUTHERN37 C30-7. REPAINTED BY SURESHOT28. Contributors (Dependencies):... || &nbsp; |- | <KUID:55290:851> || B&O C30-7 || THIS A REPAINT OF NORFOLKSOUTHERN37 C30-7. REPAINTED BY SURESHOT28. Contributors (Dependencies):... || &nbsp; |- | <KUID:55290:852> || NW C30-7 || THIS IS A REPAINT OF NORFOLKSOUTHER37 C30-7A. PAINTED BY SURESHOT28 Contributors (Dependencies):... || &nbsp; |- | <KUID:55290:854> || CN C30-7 || THANKS TO NORFOLKSOUTHERN37 FOR THE MESH. REPAINTED BY SURESHOT28. Contributors (Dependencies): ... || &nbsp; |- | <KUID2:78193:923:1> || Drivable Robt E. Lee Steamboat -7m || Steamboat for 7m deep track Contributors (Dependencies): ... || &nbsp; |- | <KUID2:82412:6097035:1> || Powerline-735kV-Cable-01 || Powerline 735kV Cable, to use with Powerline-Tower's (kuid2:82412:6097031:1 and kuid2:82412:60970... || &nbsp; |- | <KUID2:82412:6097038:1> || Powerline-735kV-Cable-03 || Powerline 735kV Cable, to use with Powerline-Tower's (kuid2:82412:6097033:1). Just click the cabl... || &nbsp; |} &nbsp; ==Kuid's -8, -9 & -10== ===group-24 (-8's)=== &nbsp; {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" |Description !style="width:07%" |Repairer |- |<KUID:115270:110014> || A-8 - Skrzyzowanie ruch okrezny || A-8 - Skrzyzowanie ruch okrezny || &nbsp; |- |<KUID2:135744:146:1> || Detroit & Mackinac #124 4-8-2 Mountain Type || Here is a Detroit & Mackinac Railroad 4-8-2 Mountain Type locomotive #124 reskinned from Bill Sco... || &nbsp; |- |<KUID2:135744:148:1> || Pere Marquette #1224 4-8-2 Mountain Type || Here we have a Pere Marquette 4-8-2 Mountain Type loco #1224. This was reskinned from Bill Scott... || &nbsp; |- |<KUID:37049:1> || BCR Dash-8 40CM || BC RAIL Dash-8 40CM || &nbsp; |- |<KUID:37049:2> || BCR Dash-8 40CM || BC RAIL Dash-8 40CM || &nbsp; |- |<KUID:37049:3> || BCR Dash-8 40CM || BC RAIL Dash-8 40CM || &nbsp; |- |<KUID:45588:4465> || CW44-8 V&O 4460-4465 || GE CW44-8 (Dash 9 predecessor) in Appalchian Lines (V&O) color scheme. Contributors (Dependencie... || &nbsp; |- |<KUID:74708:37027> || carrefour-8x6 || carrefour entre route principal8m. et route secondaires 6m. || &nbsp; |- |<KUID:74708:37028> || carrefour-8x6clair || carrefour entre route principal8m. et route secondaires 6m. || &nbsp; |- |<KUID2:7592:10175:1> || CRR #311 4-8-2 Mountain || The CRR #311 is a fictional roadnumber of the USRA Mountain Type Locomotive owned by nearly every... || &nbsp; |- |<KUID2:7592:10178:1> || GN #2507 4-8-2 Mountain || The GN #2507 is a prototypical roadnumber of the USRA Mountain Type Locomotive owned by nearly ev... || &nbsp; |- |<KUID2:7592:10180:1> || UP #7000 4-8-2 Mountain || The UP #7000 is a prototypical roadnumber of the USRA Mountain Type Locomotive owned by nearly ev... || &nbsp; |- |<KUID2:7592:10182:1> || L&N #419 4-8-2 Mountain || The L&N #419 4-8-2 Mountain is a fictional roadnumber of the USRA Mountain Type Locomotive owned ... || &nbsp; |- |<KUID2:7592:10184:1> || Southern #1409 4-8-2 Mountain || The Southern #1409 4-8-2 Mountain is a fictional roadnumber of the USRA Mountain Type Locomotive ... || &nbsp; |- |<KUID2:7592:10186:1> || GN #2512 4-8-2 Mountain || The GN #2512 is a prototypical roadnumber of the USRA Mountain Type Locomotive owned by nearly ev... || &nbsp; |- |<KUID2:7592:10187:1> || DMIR #244 4-8-2 Mountain || The UP #7000 is a prototypical roadnumber of the USRA Mountain Type Locomotive owned by nearly ev... || &nbsp; |- |<KUID:79097:1001> || Frisco 1522 4-8-2 'Mountain Type' || The Frisco 1522 was built by the Baldwin Locomotive Company in 1925 and has a wheel arrangement o... || &nbsp; |- |<KUID2:82412:22002:1> || Lamp-Wall-80-001 || Lamp-Wall-80-001 || &nbsp; |- |<KUID:9999:10023> || OBB CAT 50-81 Bmpz-dl || City Airport Train Doppelstockwagen der Ö³terreichisen Bundesbahnen AG Based on the DB DBuza 747... || &nbsp; |- |<KUID:9999:10025> || OBB Wiesel 50-81 Bmpz-dl || City Airport Train Doppelstockwagen der Ö³terreichisen Bundesbahnen AG Based on the DB DBuza 747... || &nbsp; |- |} &npsp; ===Group-25 (-9's)=== &nbsp; {| style="font face: Times; font-size:10pt; width:100%; padding:3px; border:1px solid blue; " !style="width:12%" |KUID !style="width:19%" |Name !style="width:40%" |Description !style="width:07%" |Repairer |- |<KUID:113556:20000> || Loco -9 UP #5878 || General Electric Dash-9 in Union Pacific color scheme. Email fordtruc@norex.com.au for repaint re... || |- |<KUID:113556:510030> || Loco -9 UP #5840 || General Electric Dash-9 in Union Pacific color scheme. Email fordtruc@norex.com.au for repaint re... || |- |<KUID:113556:51029> || Loco SP-9 SP#245 || General Electric Dash-9 in Southern Pacific color scheme. Email fordtruc@norex.com.au for repaint... || |- |<KUID:113556:51040> || Loco SP-9 SP#211 || General Electric Dash-9 in Southern Pacific color scheme. Email fordtruc@norex.com.au for repaint... || |- |<KUID:45588:4401> || CW44-9 B&O || General Electric CW44-9 in B&O passenger (blue-black-gold-gray) color scheme normally used on E- ... || |- |<KUID:45588:4402> || CW44-9 NYS&W || GE CW44-9 as an NYS&W 'Yellow Jacket'. Contributors (Dependencies): "margin-top:0px;ma... || |- |<KUID:45588:4403> || CW44-9 B&O CSX || GEl CW44-9 in B&O passenger (blue-black-gold-gray) color scheme normally used on E- and F-units w... || |- |<KUID:45588:4404> || CW44-9 Western Maryland CSX || GE CW44-9 in Western Maryland 'what if' paint with CSX lettering (as in, 'what if' CSX got a clue... || |- |<KUID:45588:4405> || CW44-9 B&O CSX small || GEl CW44-9 in B&O passenger (blue-black-gold-gray) color scheme normally used on E- and F-units w... || |- |<KUID:45588:4406> || CW44-9 B&O Chessie Seaboard || GEl CW44-9 in B&O passenger (blue-black-gold-gray) color scheme normally used on E- and F-units w... || |- |<KUID:45588:4412> || CW44-9 Susquehanna || GE CW44-9 as an NYS&W 'Yellow Jacket'. Contributors (Dependencies): "margin-top:0px;ma... || |- |<KUID:45588:4453> || CW44-9 Western Maryland 1 || GE CW44-9 in Western Maryland 'what if' paint. Version 1 places the Fireball logo on the side of ... || |- |<KUID:45588:4457> || CW44-9 W&LE || GE CW44-9 in Wheeling & Lake Erie paint (Fictional). Contributors (Dependencies): "mar... || |- |<KUID:45588:4458> || CW44-9 NYO&W || GE CW44-9 in New York Ontario & western paint. Another 'what if'. Usess autonumbering, with three... || |- |<KUID:45588:4459> || CW44-9 Lehigh & New England || GE CW44-9 in Lehigh & New England 'what if' (fictional) paint. Contributors (Dependencies): <ul ... || |- |<KUID:45588:4460> || CW44-9 Western Maryland 2 || GE CW44-9 in Western Maryland 'what if' paint. Version 2 places the Fireball logo on the hood doo... || |- |<KUID:45588:4462> || CW44-9 Clinchfield 4401 black || GE CW44-9 in Clinchfield 'what if' paint. Contributors (Dependencies): "margin-top:0px... || |- |<KUID:45588:4463> || CW44-9 Lehigh & New England Whiskers || GE CW44-9 in Lehigh & New England 'what if' (fictional) paint matching the scheme worn by the RS2... || |- |<KUID:45588:4466> || CW44-9 Nickel Plate 4412 || GE Dash-9 in Nickel Plate Road paint scheme (Fictional). Contributors (Dependencies): ... || |- |<KUID:45588:4467> || CW44-9 Nickel Plate 4403 || GE Dash-9 in Nickel Plate Road paint scheme (Fictional). Contributors (Dependencies): ... || |- |<KUID:45588:4470> || CW44-9 Utah Belt || General Electric Dash-9 in Utah Belt color scheme. Contributors (Dependencies): "margi... || |- |<KUID:45588:4471> || CW44-9 Chessie System (B&O) || GE CW44-9 in Chessie System paint. Contributors (Dependencies): "margin-top:0px;margin... || |- |<KUID:45588:4472> || CW44-9 Chessie System (C&O) || GE CW44-9 in Chessie System paint, owned by the Chesapeake & Ohio Railway. Contributors (Depende... || |- |<KUID:45588:4473> || CW44-9 Chessie System (WM) || GE CW44-9 in Chessie System paint, owned by Western Maryland Railway. Contributors (Dependencies... || |- |<KUID:49267:15261> || Sggmrss-90' B Empty (white) || Sggmrss 90 Empty B unit (back) White Will load: - Auran's 20' and 40' Container - 20' Containers ... || |- |<KUID2:82412:300126:1> || MILW-Caboose-991265-01 || A caboose of The Milwaukee Road, originally created by Deadfred by using paintshed. The caboose t... || |- |<KUID2:82412:300127:1> || MILW-Caboose-991269-01 || A caboose of The Milwaukee Road, originally created by Deadfred by using paintshed. The caboose t... || |- |<KUID2:82412:4001020:1> || JVC-9-Birch-S-LO-25m-01 || JVC Oak Tree (JVC_S1_Trees_9 Birch 25m Summer) with reduced texture size especially for applicati... || |- |<KUID:85324:5430> || CW44-9 Jersey Central 5430 || GE CW44-9 in Central of New Jersey 'what if' paint. Colors by Jacob Newman at http://jnewman.m72e... || |- |<KUID:85324:5431> || CW44-9 Jersey Central 5431 || GE CW44-9 in Central of New Jersey 'what if' paint. Colors by Jacob Newman at http://jnewman.m72e... || |- |<KUID:-10:170> || Gen DL500 mph rhd || (null) || |- |<KUID:-10:172> || Gen1960 op1 || (null) || |- |<KUID:-10:173> || Gen RC4 || (null) || |- |<KUID:-10:221> || Gen 218 || (null) || |- |} ==Missing on DLS== The second list below is '''an add to list'''... assets called for '''''when something has been downloaded''''' that includes the asset on the route or session '''as a dependency''', but which has not been uploaded to the DLS by the asset creator. The first list is an index to those sites which provide Trainz content, and usually, host downloading services of their own. Several listings therein however make it policy to place their content on the DLS for free access by all. &nbsp; ===Content source sites=== {| style="background-color:#f9f9f9;{{Text default color}}; font face: Verdana,Garamond,Helvetica,Arial; font-size:14pt; width:100%; padding:1px; border:3px solid green; " ! <u>Table of [https://www.auran.com/TRS2004/DLS.php Alternative source sites]</u><hr/> <div style="font face:Arial;"><small>(use column one for note in Column five below)</small></div> |- | {| cellspacing="2" border="1" cellpadding="3" style="font face: Garamond,Roman,Times,Arial; font-size:12pt; width:100%; padding:3px; border:1px solid blue; text-align:left; background:lightyellow;{{Text default color}};" !style="width:12%" |Nickname !style="width:28%" |Common name !N3V-Prtr !Description !style="width:15%" |login Url !style="width:15%" |DnLd url |- | HP-Tz |HP-Trainz |yes |user group, freeware and payware assets and routes |[http://www.hp-trainz.de/html/News_EN.html website] |[http://www.hp-trainz.de/html/Geschenkt_EN.html downloads] |- | TPR |TrainzProRoutes |yes |Freeware (mainly) user group |[http://www.trainzproroutes.org/ website] |[http://www.trainzproroutes.org/tprdownloads/index.php downloads] |- | JR & J-R || Jointed Rail |yes || Mostly payware Prof. content |[http://www.jointedrail.com/ website] |[http://jointedrail.com/index.php/customer/account/login/ downloads] |- | TNG || Trainz Narrowgaugers ||yes|| User interest group | [http://www.virtualrailroader.com/TNG.html website] | none |- | Yz-Tz || Yesterdayz Trainz || n/a||User interest group training content creation and using Trainz | [http://yesterdayztrainz.federalproductions.com/ website] | [http://forums.auran.com/trainz/showthread.php?100965-Yesterdayz-Trainz-Group N3V forum]<br/>No Downloads |} |} <div>&nbsp;</div> &nbsp; <div>&nbsp;</div> &nbsp; ;Assets missing on the DLS &nbsp; This section will give new Trainzers a www-web-wide Kuid indexed searchable source page to quickly find where an asset might be located, should they have that hated '''''missing dependency'''''' after downloading a asset such as a session or route. Asset creators and users should feel to update the page reflecting a newly discovered missing asset and delete those which are no longer 'missing' on the DLS. &nbsp; {| cellspacing="3" cellpadding="2" border="2" style="font face: Garamond,Verdana,Times,Arial; font-size:12pt; width:100%; padding:3px; border:1px solid blue; " !style="width:17%" |KUID !style="width:19%" |Asset Name !style="width:40%" |Description !style="width:07%" |creator !Source |- |a |b |c |d |e |- |a |b |c |d |e |- |<kuid:45324:50203:2><br/><kuid:45324:50204:2><br/><kuid:45324:50205:2><br/><kuid:45324:50206:2><br/><kuid:37581:1221> |S-2 Trucks, various wheel diameters, {x= 100T, 70T, 125T, 50Tons} <br/>& generic sounds |p/o J-R S2 Truck pack freeware ([[traincar]]s bogey wheels, 36", 33", 38", and 28" respectively) |style="text-align:center;"|norfolksouthern<br/>"<br/>"<br/>"<br/>& therock |J-R <!-- if your kuid is a lower number put it towards the top, if larger, then towards the bottom. This is boilerplate to cut and paste. The 'stub' lines can be written over once there are more than 5-7 kuids listed herein Questions: [[User:Fabartus|Fra]]<font color="green">[[User talk:Fabartus|nkB]]</font> 01:34, 10 July 2013 (UTC) --> |- |a |b |c |d |e |- |a |b |c |d |e |- |} 87km8gw7bh2zenord5n1cuj6a1q8xgq User talk:Egmason 3 299094 4669055 2631978 2026-09-06T06:38:33Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669055 wikitext text/x-wiki == Welcome! == <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Egmason!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> <div style="text-align:right; padding:0.2em 0.5em 0.2em 0.5em;">Thanks, --[[User:Xania|ЗAНИA]] [[Image:Flag_of_Estonia.svg|15px]][[User talk:Xania|<sup>talk</sup>]] 23:41, 20 April 2014 (UTC)</div> </div> <div style="clear:both;"> </div> 680xl6f3bj7hz19bfxhgsxxzl0s1r9i User talk:Surement 3 300586 4669049 2667126 2026-09-06T06:34:50Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669049 wikitext text/x-wiki == Welcome! == <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Surement!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> <div style="text-align:right; padding:0.2em 0.5em 0.2em 0.5em;">Thanks, --[[User:Xania|ЗAНИA]] [[Image:Flag_of_Estonia.svg|15px]][[User talk:Xania|<sup>talk</sup>]] 23:03, 28 May 2014 (UTC)</div> </div> <div style="clear:both;"> </div> 1v98bj30ayowfvw9umafx7sh3fujctn User talk:46.108.136.27 3 301233 4669043 2673310 2026-09-06T06:30:34Z ShakespeareFan00 46022 4669043 wikitext text/x-wiki <div style="padding:5px; border:1px solid #A9A9A9; background-color:#FFEFD5;{{text default color}}; min-height:40px;">[[File:Stop x nuvola with clock.svg|40px|left|link=]] '''[[Wikibooks:Blocking policy|You cannot edit]] for 1 month due to disruptive editing'''. You are welcome to contribute constructively when editing privileges are restored. You may appeal this action with a reasonable argument by adding the text <!-- Copy the text as it appears on your page, not as it appears in this edit area. Do not include the "tlx" argument. -->{{tlx|unblock|Your reason here}} below. </div><!-- Template:blocked --> --[[User:Xania|ЗAНИA]] [[Image:Flag_of_the_Isle_of_Mann.svg|15px]][[User talk:Xania|<sup>talk</sup>]] 20:05, 14 June 2014 (UTC) 8p8jlrt97spwzmi3ar4g6ftj6jcn54f User talk:Richardlholmes 3 302048 4669066 2682488 2026-09-06T06:43:13Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669066 wikitext text/x-wiki == Welcome! == <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Richardlholmes!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> <div style="text-align:right; padding:0.2em 0.5em 0.2em 0.5em;">Thanks, --[[User:Xania|ЗAНИA]] [[Image:Flag_of_the_Isle_of_Mann.svg|15px]][[User talk:Xania|<sup>talk</sup>]] 16:46, 18 July 2014 (UTC)</div> </div> <div style="clear:both;"> </div> cgtcuw1j7vwiu7fkcnlfv6zqio4nasn User talk:Apogjack 3 308058 4669060 2754671 2026-09-06T06:40:32Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669060 wikitext text/x-wiki == Welcome! == <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Apogjack!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> <div style="text-align:right; padding:0.2em 0.5em 0.2em 0.5em;">Thanks, --Leaderboard 17:24, 11 January 2015 (UTC)</div> </div> <div style="clear:both;"> </div> a539cxp0e0neif3p1icgl8wf5peiaox User:Legoeric/sandbox 2 308694 4668932 4667930 2026-09-05T12:43:43Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668932 wikitext text/x-wiki {{shortcut|WP:MATH|WP:MATHS|Help:Math}} {{redirect6|WP:MATH" and "WP:MATHS|the WikiProject on mathematics|Wikipedia:WikiProject Mathematics|Wikipedia's mathematics style manual|Wikipedia:Manual of Style/Mathematics|the mathematics reference desk|Wikipedia:Reference desk/Mathematics}} [[MediaWiki]] uses a subset of [[AMS-LaTeX]] markup, a superset of [[LaTeX]] markup which is in turn a superset of [[TeX]] markup, for mathematical formulae. It generates [[Portable Network Graphics|PNG]] images by default. Alternatively, the [[MathJax]] renderer can be selected in the [[Help:Preferences|user preferences]]; this uses a combination of HTML and CSS to display the equation. Although, in all cases mentioned, TeX is generated by [[Compiler|compilation]], and not by an interpreter program, there is one essential difference between, e.g., [[Donald Knuth|Knuth]]'s [[TeX]] or [[Leslie Lamport|Lamport]]'s [[LaTeX]] and the present implementation: whereas in the first two cases the compiler typically generates an ''all-in-one'' printable output, which has the quality of a whole book with all chapters, sections and subsections, and where no line is "special", in the present case one has, typically, a mixture of TeX images (more precisely: PNG images) for the equations, embedded into usual text, and with short TeX elements usually replaced by HTML parts. As a consequence, in many cases TeX-elements, e.g. vector symbols, "stick out" below (or above) the text line. This "sticking out" is ''not''&nbsp; the case in the above-mentioned original products, and the HTML-substitutes for small TeX additions to the text are often insufficient in quality for many readers. In spite of these shortcomings, the present product characterized by "many embedded PNG-images" should be preferred for small texts, where the equations do not dominate. More precisely, MediaWiki filters the markup through [[Wikipedia:Texvc|Texvc]], which in turn passes the commands to TeX or [[MathJax]] for the actual [[Rendering (computer graphics)|render]]ing. Thus, only a limited part of the full TeX language is supported; see below for details. To have math rendered in a particular MediaWiki installation, one has to set <source lang="php" enclose="none">$wgUseTeX = true;</source> in [[mw:Manual:LocalSettings.php|LocalSettings.php]]. Conrad's == Basics == Math markup goes inside {{tag|math}}. The TeX code has to be put literally: MediaWiki templates, predefined templates, and parameters cannot be used within math tags: pairs of double braces are ignored and "#" gives an error message. However, math tags work in the then and else part of #if, etc. See {{tim|Demo of attempt to use parameters within TeX}} for more information. === LaTeX commands === LaTeX commands are case-sensitive, and take one of the following two formats: * They start with a backslash \ and then have a name consisting of letters only. Command names are terminated by a space, a number or any other "non-letter". * They consist of a backslash \ and exactly one non-letter. Some commands need an argument, which has to be given between curly braces { } after the command name. Some commands support optional parameters, which are added after the command name in square brackets []. The general syntax is: \commandname[option1,option2,...]{argument1}{argument2}... === Special characters === The following symbols are reserved characters that either have a special meaning under LaTeX or are unavailable in all the fonts. If you enter them directly in your text, they will normally not render, but rather do things you did not intend. # $ % ^ & _ { } ~ \ These characters can be entered by adding a prefix backslash: \# \$ \% \textasciicircum{} \& \_ \{ \} \~{} \textbackslash{} The other symbols and many more can be rendered with special commands in mathematical formulae or as accents. The backslash character \ can ''not'' be entered by adding another backslash in front of it (\\); this sequence is used for line breaking. For introducing a backslash in math mode, you can use \backslash instead. The command \~ produces a tilde which is placed over the next letter. For example \~n gives ñ. To produce just the character ~, use \~{} which places a ~ over an empty box. Alternatively \sim produces a large centred ~ which may be more appropriate in some situations, but may not render properly in simple expressions which are converted to HTML. Similarly, the command \^ produces a hat over the next character, for example \^{o} produces ô. If you need in text to display the ^ symbol you have to use \textasciicircum. === Spaces === "Whitespace" characters, such as blank or tab, are treated uniformly as "space" by LaTeX. Several consecutive whitespace characters are treated as one "space". See [[#Spacing|below]] for commands that produces spaces of different size. === LaTeX environments === ''Environments'' in LaTeX have a role that is quite similar to commands, but they usually have effect on a wider part of formula. Their syntax is: <source lang="latex"> \begin{environmentname} text to be influenced \end{environmentname} </source> Environments supported by Wikipedia include ''matrix'', ''align'', etc. See [[#Fractions, matrices, multilines|below]]. === Rendering === {| class="wikitable" style="float:right;" | <math>e^{i \pi} + 1 = 0\,\!</math> | style="background-color:red;{{Text default color}};" | <math>e^{i \pi} + 1 = 0\,\!</math> | style="background-color:red;{{Text default color}};" | <math>e^{i \pi} + 1 = 0\,\!</math> |} By default, the PNG images are rendered black on white, with a transparent background. On darker backgrounds, the characters may show white edges. To remove these, match the PNG background color with the background color of the page using <source lang="latex" enclose="none">\pagecolor</source>. However, black text on a dark background is hard to read and should be avoided altogether where possible. The colors, as well as font sizes and types, are independent of browser settings or CSS. Font sizes and types will often deviate from what HTML renders. Vertical alignment with the surrounding text can also be a problem (see [[bugzilla:32694|bug 32694]]); a work-around is described in the [[Help:Displaying_a_formula#Alignment with normal text flow|"Alignment with normal text flow"]] section below. The [[Help:User style#CSS selectors|css selector]] of the images is <source lang="latex" enclose="none">img.tex</source>. The [[WP:ALT|alt text]] of the PNG images, which is displayed to visually impaired and other readers who cannot see the images, and is also used when the text is selected and copied, defaults to the wikitext that produced the image, excluding the <code><nowiki><math></nowiki></code> and <code><nowiki></math></nowiki></code>. You can override this by explicitly specifying an <source lang="latex" enclose="none">alt</source> attribute for the <source lang="latex" enclose="none">math</source> element. For example, <source lang="latex" enclose="none"><math alt="Square root of pi">\sqrt{\pi}</math></source> generates an image <math alt="square root of pi">\sqrt{\pi}</math> whose alt text is "Square root of pi". This should not be confused with the ''title'' attribute that produces popup text when the hovering over the PNG image, for example <source lang="latex" enclose="none"><math title="pi">\pi</math></source> generates an image <math title="pi">\pi</math> whose popup text is "pi". Apart from function and operator names, as is customary in mathematics, variables and letters are in italics; digits are not. For other text, (like variable labels) to avoid being rendered in italics like variables, use <source lang="latex" enclose="none">\text</source>, <source lang="latex" enclose="none">\mbox</source>, or <source lang="latex" enclose="none">\mathrm</source>. You can also define new function names using <source lang="latex" enclose="none">\operatorname{...}</source>. For example, <source lang="latex" enclose="none">\text{abc}</source> gives <math>\text{abc}</math>. Latex does not have full support for Unicode characters and not all characters render. Most Latin characters with accents render correctly. However some do not, in particular those that include multiple diacritics (e.g. with Latin letters used in Vietnamese) or that cannot be precomposed into a single character (such as the uppercase Latin letter W with ring), or that use other diacritics (like the ogonek or the double grave accent, used in Central European languages like Polish, or the horn attached above some vowels in Vietnamese), or other modified letter forms (used in IPA notations, or African languages, or in medieval texts), some digram ligatures (like IJ in Dutch), or Latin letters borrowed from Greek, or small capitals, as well as superscripts and subscript letters. For example <source lang="latex" enclose="none">\text{ð}</source> or <source lang="latex" enclose="none">\mbox{ð}</source>, and <source lang="latex" enclose="none">\text{þ}</source> or <source lang="latex" enclose="none">\mbox{þ}</source> (used in Icelandic) will give errors. == TeX vs HTML == {{main|Wikipedia:Rendering math}} Before using TeX markup for producing special characters, it should be noted that, as this comparison table shows, sometimes similar results can be achieved in HTML, with [[Template:Math]] or [[Template:Bigmath]] (also see: [[Help:Special characters]]). {| class="wikitable" border=1 <!--set cell borders for MSIE browsers--> |- ! TeX syntax ! TeX rendering ! HTML syntax ! HTML rendering |- | <source lang="latex" enclose="none">\alpha\,\!</source> | <math>\alpha\,\!</math> | <source lang="html5" enclose="none">{{math|<VAR>&alpha;</VAR>}}</source> | {{math|''&alpha;''}} |- | <source lang="latex" enclose="none">f(x) = x^2\,\!</source> | <math> f(x) = x^2\,\!</math> | <source lang="html5" enclose="none">{{math|''f''(<var>x</var>) {{=}} <var>x</var><sup>2</sup>}}</source> | {{math|''f''(''x'') {{=}} ''x''<sup>2</sup>}} |- | <source lang="latex" enclose="none">\sqrt{2}</source> | <math>\sqrt{2}</math> | <source lang="html5" enclose="none">{{math|{{radical|2}}}}</source> | {{math|{{radical|2}}}} |- | <source lang="latex" enclose="none">\sqrt{1-e^2}</source> | <math>\sqrt{1-e^2}\!</math> | <source lang="html5" enclose="none">{{math|{{radical|1 &minus; ''e''<sup>2</sup>}}}}</source> | {{math|{{radical|1 &minus; ''e''<sup>2</sup>}}}} |- | <source lang="latex" enclose="none">\sqrt{1-z^3}</source> | <math>\sqrt{1-z^3}\!</math> | <source lang="html5" enclose="none">{{bigmath|{{radical|1 &minus; ''z''<sup>3</sup>}}}}</source> | {{bigmath|{{radical|1 &minus; ''z''<sup>3</sup>}} }} |} The codes on the left produce the symbols on the right, but the latter can also be put directly in the wikitext, except for ‘=’. {| class="wikitable" border=1 <!--set border for MSIE browsers--> |- ! Syntax ! Rendering |- style="vertical-align:middle" | <pre>&amp;alpha; &amp;beta; &amp;gamma; &amp;delta; &amp;epsilon; &amp;zeta; &amp;eta; &amp;theta; &amp;iota; &amp;kappa; &amp;lambda; &amp;mu; &amp;nu; &amp;xi; &amp;omicron; &amp;pi; &amp;rho; &amp;sigma; &amp;sigmaf; &amp;tau; &amp;upsilon; &amp;phi; &amp;chi; &amp;psi; &amp;omega;</pre> | α β γ δ ε ζ <br> η θ ι κ λ μ ν <br> ξ ο π ρ σ ς <br> τ υ φ χ ψ ω <br> |- style="vertical-align:middle" | <pre>&amp;Gamma; &amp;Delta; &amp;Theta; &amp;Lambda; &amp;Xi; &amp;Pi; &amp;Sigma; &amp;Phi; &amp;Psi; &amp;Omega;</pre> | Γ Δ Θ Λ Ξ Π <br> Σ Φ Ψ Ω |- style="vertical-align:middle" | <pre>&amp;int; &amp;sum; &amp;prod; &amp;radic; &amp;minus; &amp;plusmn; &amp;infin; &amp;asymp; &amp;prop; = &amp;equiv; &amp;ne; &amp;le; &amp;ge; &amp;times; &amp;middot; &amp;sdot; &amp;divide; &amp;part; &amp;prime; &amp;Prime; &amp;nabla; &amp;permil; &amp;deg; &amp;there4; &amp;empty;</pre> | ∫ ∑ ∏ √ − ± ∞<br /> ≈ ∝ = ≡ ≠ ≤ ≥<br /> × · ⋅ ÷ ∂ ′ ″<br /> ∇ ‰ ° ∴ ∅ |- style="vertical-align:middle" | <pre>&amp;isin; &amp;notin; &amp;cap; &amp;cup; &amp;sub; &amp;sup; &amp;sube; &amp;supe; &amp;not; &amp;and; &amp;or; &amp;exist; &amp;forall; &amp;rArr; &amp;hArr; &amp;rarr; &amp;harr; &amp;uarr; &amp;darr; &amp;alefsym; - &amp;ndash; &amp;mdash;</pre> | ∈ ∉ ∩ ∪ ⊂ ⊃ ⊆ ⊇<br> ¬ ∧ ∨ ∃ ∀<br /> ⇒ ⇔ → ↔ ↑ ↓<br /> ℵ - – — |} The project has settled on using both HTML and TeX because each has advantages in some situations. === Pros of HTML === # Formulas in HTML behave more like regular text. In-line HTML formulae always align properly with the rest of the HTML text and, to some degree, can be copied-and-pasted (this is not a problem if TeX is rendered using [[w:MathJax|MathJax]], and the alignment should not be a problem for PNG rendering once [[bugzilla:32694|bug 32694]] is fixed). # The formula’s background and font size match the rest of HTML contents (this can be fixed on TeX formulas by using the commands [[#Color|<source lang="latex" enclose="none">\pagecolor</source> and <source lang="latex" enclose="none">\definecolor</source>]]) and the appearance respects CSS and browser settings while the typeface is conveniently altered to help you identify formulae. # Pages using HTML code for formulae will load faster and they will create less clutter on your hard disk. # Formulae typeset with HTML code will be accessible to client-side script links (a.k.a. scriptlets). # The display of a formula entered using mathematical templates can be conveniently altered by modifying the templates involved; this modification will affect all relevant formulae without any manual intervention. # The HTML code, if entered diligently, will contain all semantic information to transform the equation back to TeX or any other code as needed. It can even contain differences TeX does not normally catch, e.g. <source lang="html5" enclose="none">{{math|''i''}}</source> for the [[w:imaginary unit|imaginary unit]] and <source lang="html5" enclose="none">{{math|<var>i</var>}}</source> for an arbitrary index variable. # Unlike generated bitmaps, HTML is not sensitive to [[w:Dots per inch|dots per inch]] variances between viewing platforms. === Pros of TeX === # TeX is semantically more precise than HTML. ## In TeX, "<source lang="latex" enclose="none">x</source>" means "mathematical variable <math>x</math>", whereas in HTML "<source lang="latex" enclose="none">x</source>" is generic and somewhat ambiguous. ## On the other hand, if you encode the same formula as "<source lang="html5" enclose="none">{{math|<var>x</var>}}</source>", you get the same visual result {{math|''x''}} and no information is lost. This requires diligence and more typing that could make the formula harder to understand as you type it. However, since there are far more readers than editors, this effort is worth considering if no other rendering options are available (such as [[w:MathJax|MathJax]], which is available to logged-in users as a [[Special:Preferences#mw-prefsection-rendering|preferences]] opt-in). # One consequence of point&nbsp;1 is that TeX code can be transformed into HTML, but not vice-versa.{{ref|dilHTML}} This means that on the server side we can always transform a formula, based on its complexity and location within the text, user preferences, type of browser, etc. Therefore, where possible, all the benefits of HTML can be retained, together with the benefits of TeX. It is true that the current situation is not ideal, but that is not a good reason to drop information or contents. It is more a reason to [[#Bug reports|help improve the situation]]. # Another consequence of point&nbsp;1 is that TeX can be converted to [[w:MathML|MathML]] (e.g. by MathJax) for browsers which support it, thus keeping its semantics and allowing the rendering to be better suited for the reader’s graphic device. # TeX is the preferred text formatting language of most professional mathematicians, scientists, and engineers. It is easier to persuade them to contribute if they can write in TeX. # TeX has been specifically designed for typesetting formulae, so input is easier and more natural if you are accustomed to it, and output is more aesthetically pleasing if you focus on a single formula rather than on the whole containing page. # Once a formula is done correctly in TeX, it will render reliably, whereas the success of HTML formulae is somewhat dependent on browsers or versions of browsers. Another aspect of this dependency is fonts: the serif font used for rendering formulae is browser-dependent and it may be missing some important glyphs. While the browser is generally capable to substitute a matching glyph from a different font family, it need not be the case for combined glyphs (compare&nbsp;‘&nbsp;''{{IPA|a&#773;}}''&nbsp;’ and&nbsp;‘&nbsp;''a̅''&nbsp;’). # When writing in TeX, editors need not worry about whether this or that version of this or that browser supports this or that HTML entity. The burden of these decisions is put on the software. This does not hold for HTML formulae, which can easily end up being rendered wrongly or differently from the editor’s intentions on a different browser.{{ref|browsupp}} # TeX formulae, by default, render larger and are usually more readable than HTML formulae and are not dependent on client-side browser resources, such as fonts, and so the results are more reliably WYSIWYG. # While TeX does not assist you in finding HTML codes or Unicode values (which you can obtain by viewing the HTML source in your browser), copying and pasting from a TeX PNG image in Wikipedia into simple text will return the LaTeX source. : <small>{{note|dilHTML}} Unless your wikitext follows the style of point&nbsp;1.2</small> : <small>{{note|entHTML}} The entity support problem is not limited to mathematical formulae though; it can be easily solved by using the corresponding characters instead of entities, as the character repertoire links do, except for cases where the corresponding glyphs are visually indiscernible (e.g. &amp;ndash; for &lsquo;&ndash;&rsquo; and &amp;minus; for &lsquo;&minus;&rsquo;).</small> In some cases it may be the best choice to use neither TeX nor the HTML substitutes, but instead the simple ASCII symbols of a standard keyboard (see hereafter, for an example). === Using MathJax === The [[MathJax]] renderer, selectable through [[Special:Preferences#mw-prefsection-rendering|My Preferences - Appearance - Math]], uses a very different system to the standard texvc renderer. Rather than rendering a static image on the server side a combination of JavaScript, HTML and CSS is used to locally construct the formula. This allows high-quality typesetting, and other problems such as font sizes not matching your browser settings or wrong baselines are fixed as well. MathJax may also reduce the download time of images but entails a small delay as the JavaScript interpreter runs to render the formulas. (After the small delay, the vertical dimension of the displayed page tends to update asynchronously—math content usually becomes taller—which can cause a disorienting jump in the document view position in some user agents; speedy mouse-wheelers might wish to check into this as part of their usability evaluation.) Alternatively to the preferences option, MathJax can also be selected using the [[User:Nageh/mathJax|mathJax]] user script. It is the basis for the global option, and hence more experimental but also more up to date. Bug reports are taken care of at the script's [[User talk:Nageh/mathJax|talk page]]. The quality of font rendering is dependent on your browser and operating system. Speed and appearance can be improved by installing the [[STIX Fonts project|STIX fonts]]; for installation details see the [http://www.mathjax.org/help/fonts/ MathJax font help] page. Further information is also available at [[User:Nageh/mathJax|this page]]. = Formatting using TeX = == Functions, symbols, special characters == <!-- Eight symbols per line seems to be optimal --> {| class="wikitable" |- !colspan="2"| === Accents/diacritics === |- | <source lang="text" enclose="none">\dot{a}, \ddot{a}, \acute{a}, \grave{a} </source> | <math>\dot{a}, \ddot{a}, \acute{a}, \grave{a} \!</math> |- | <source lang="text" enclose="none">\check{a}, \breve{a}, \tilde{a}, \bar{a} </source> | <math>\check{a}, \breve{a}, \tilde{a}, \bar{a} \!</math> |- | <source lang="text" enclose="none">\hat{a}, \widehat{a}, \vec{a} </source> | <math>\hat{a}, \widehat{a}, \vec{a} \!</math> |- !colspan="2"| === Standard numerical functions === |- | <source lang="latex" enclose="none">\exp_a b = a^b, \exp b = e^b, 10^m </source> | <math>\exp_a b = a^b, \exp b = e^b, 10^m \!</math> |- | <source lang="latex" enclose="none">\ln c, \lg d = \log e, \log_{10} f </source> | <math>\ln c, \lg d = \log e, \log_{10} f \!</math> |- | <source lang="latex" enclose="none">\sin a, \cos b, \tan c, \cot d, \sec e, \csc f</source> | <math>\sin a, \cos b, \tan c, \cot d, \sec e, \csc f\!</math> |- | <source lang="latex" enclose="none">\arcsin h, \arccos i, \arctan j </source> | <math>\arcsin h, \arccos i, \arctan j \!</math> |- | <source lang="latex" enclose="none">\sinh k, \cosh l, \tanh m, \coth n </source> | <math>\sinh k, \cosh l, \tanh m, \coth n \!</math> |- | <source lang="text" enclose="none">\operatorname{sh}\,k, \operatorname{ch}\,l, \operatorname{th}\,m, \operatorname{coth}\,n </source> | <math>\operatorname{sh}\,k, \operatorname{ch}\,l, \operatorname{th}\,m, \operatorname{coth}\,n \!</math> |- | <source lang="text" enclose="none">\operatorname{argsh}\,o, \operatorname{argch}\,p, \operatorname{argth}\,q </source> | <math>\operatorname{argsh}\,o, \operatorname{argch}\,p, \operatorname{argth}\,q \!</math> |- | <source lang="latex" enclose="none">\sgn r, \left\vert s \right\vert </source> | <math>\sgn r, \left\vert s \right\vert \!</math> |- | <source lang="latex" enclose="none">\min(x,y), \max(x,y) </source> | <math>\min(x,y), \max(x,y) \!</math> |- !colspan="2"| === Bounds === |- | <source lang="latex" enclose="none">\min x, \max y, \inf s, \sup t </source> | <math>\min x, \max y, \inf s, \sup t \!</math> |- | <source lang="latex" enclose="none">\lim u, \liminf v, \limsup w </source> | <math>\lim u, \liminf v, \limsup w \!</math> |- | <source lang="latex" enclose="none">\dim p, \deg q, \det m, \ker\phi </source> | <math>\dim p, \deg q, \det m, \ker\phi \!</math> |- !colspan="2"| === Projections === |- | <source lang="latex" enclose="none">\Pr j, \hom l, \lVert z \rVert, \arg z </source> | <math>\Pr j, \hom l, \lVert z \rVert, \arg z \!</math> |- !colspan="2"| === Differentials and derivatives === |- | <source lang="latex" enclose="none">dt, \operatorname{d}\!t, \partial t, \nabla\psi</source> | <math>dt, \operatorname{d}\!t, \partial t, \nabla\psi\!</math> |- | <source lang="text" enclose="none">dy/dx, \operatorname{d}\!y/\operatorname{d}\!x, {dy \over dx}, {\operatorname{d}\!y\over\operatorname{d}\!x}, {\partial^2\over\partial x_1\partial x_2}y </source> | <math>dy/dx, \operatorname{d}\!y/\operatorname{d}\!x, {dy \over dx}, {\operatorname{d}\!y\over\operatorname{d}\!x}, {\partial^2\over\partial x_1\partial x_2}y \!</math> |- | <source lang="latex" enclose="none">\prime, \backprime, f^\prime, f', f'', f^{(3)}, \dot y, \ddot y </source> | <math>\prime, \backprime, f^\prime, f', f'', f^{(3)} \!, \dot y, \ddot y</math> |- !colspan="2"| === Letter-like symbols or constants === |- | <source lang="latex" enclose="none">\infty, \aleph, \complement, \backepsilon, \eth, \Finv, \hbar </source> | <math>\infty, \aleph, \complement, \backepsilon, \eth, \Finv, \hbar \!</math> |- | <source lang="latex" enclose="none">\Im, \imath, \jmath, \Bbbk, \ell, \mho, \wp, \Re, \circledS </source> | <math>\Im, \imath, \jmath, \Bbbk, \ell, \mho, \wp, \Re, \circledS \!</math> |- !colspan="2"| === Modular arithmetic === |- | <source lang="latex" enclose="none">s_k \equiv 0 \pmod{m} </source> | <math>s_k \equiv 0 \pmod{m} \!</math> |- | <source lang="latex" enclose="none">a\,\bmod\,b </source> | <math>a\,\bmod\,b \!</math> |- | <source lang="latex" enclose="none">\gcd(m, n), \operatorname{lcm}(m, n)</source> | <math>\gcd(m, n), \operatorname{lcm}(m, n)</math> |- | <source lang="latex" enclose="none">\mid, \nmid, \shortmid, \nshortmid </source> | <math>\mid, \nmid, \shortmid, \nshortmid \!</math> |- !colspan="2"| === Radicals === |- | <source lang="text" enclose="none">\surd, \sqrt{2}, \sqrt[n]{}, \sqrt[3]{x^3+y^3 \over 2} </source> | <math>\surd, \sqrt{2}, \sqrt[n]{}, \sqrt[3]{x^3+y^3 \over 2} \!</math> |- !colspan="2"| === Operators === |- | <source lang="latex" enclose="none">+, -, \pm, \mp, \dotplus </source> | <math>+, -, \pm, \mp, \dotplus \!</math> |- | <source lang="latex" enclose="none">\times, \div, \divideontimes, /, \backslash </source> | <math>\times, \div, \divideontimes, /, \backslash \!</math> |- | <source lang="latex" enclose="none">\cdot, * \ast, \star, \circ, \bullet </source> | <math>\cdot, * \ast, \star, \circ, \bullet \!</math> |- | <source lang="latex" enclose="none">\boxplus, \boxminus, \boxtimes, \boxdot </source> | <math>\boxplus, \boxminus, \boxtimes, \boxdot \!</math> |- | <source lang="latex" enclose="none">\oplus, \ominus, \otimes, \oslash, \odot</source> | <math>\oplus, \ominus, \otimes, \oslash, \odot\!</math> |- | <source lang="latex" enclose="none">\circleddash, \circledcirc, \circledast </source> | <math>\circleddash, \circledcirc, \circledast \!</math> |- | <source lang="latex" enclose="none">\bigoplus, \bigotimes, \bigodot </source> | <math>\bigoplus, \bigotimes, \bigodot \!</math> |- !colspan="2"| === Sets === |- | <source lang="text" enclose="none">\{ \}, \O \empty \emptyset, \varnothing </source> | <math>\{ \}, \O \empty \emptyset, \varnothing \!</math> |- | <source lang="latex" enclose="none">\in, \notin \not\in, \ni, \not\ni </source> | <math>\in, \notin \not\in, \ni, \not\ni \!</math> |- | <source lang="latex" enclose="none">\cap, \Cap, \sqcap, \bigcap </source> | <math>\cap, \Cap, \sqcap, \bigcap \!</math> |- | <source lang="latex" enclose="none">\cup, \Cup, \sqcup, \bigcup, \bigsqcup, \uplus, \biguplus </source> | <math>\cup, \Cup, \sqcup, \bigcup, \bigsqcup, \uplus, \biguplus \!</math> |- | <source lang="latex" enclose="none">\setminus, \smallsetminus, \times </source> | <math>\setminus, \smallsetminus, \times \!</math> |- | <source lang="latex" enclose="none">\subset, \Subset, \sqsubset </source> | <math>\subset, \Subset, \sqsubset \!</math> |- | <source lang="latex" enclose="none">\supset, \Supset, \sqsupset </source> | <math>\supset, \Supset, \sqsupset \!</math> |- | <source lang="latex" enclose="none">\subseteq, \nsubseteq, \subsetneq, \varsubsetneq, \sqsubseteq </source> | <math>\subseteq, \nsubseteq, \subsetneq, \varsubsetneq, \sqsubseteq \!</math> |- | <source lang="latex" enclose="none">\supseteq, \nsupseteq, \supsetneq, \varsupsetneq, \sqsupseteq </source> | <math>\supseteq, \nsupseteq, \supsetneq, \varsupsetneq, \sqsupseteq \!</math> |- | <source lang="latex" enclose="none">\subseteqq, \nsubseteqq, \subsetneqq, \varsubsetneqq </source> | <math>\subseteqq, \nsubseteqq, \subsetneqq, \varsubsetneqq \!</math> |- | <source lang="latex" enclose="none">\supseteqq, \nsupseteqq, \supsetneqq, \varsupsetneqq </source> | <math>\supseteqq, \nsupseteqq, \supsetneqq, \varsupsetneqq \!</math> |- !colspan="2"| === Relations === |- | <source lang="latex" enclose="none">=, \ne, \neq, \equiv, \not\equiv </source> | <math>=, \ne, \neq, \equiv, \not\equiv \!</math> |- | <source lang="latex" enclose="none">\doteq, \doteqdot,</source> <source lang="text" enclose="none">\overset{\underset{\mathrm{def}}{}}{=},</source> <source lang="latex" enclose="none">:=</source> | <math>\doteq, \doteqdot, \overset{\underset{\mathrm{def}}{}}{=}, := \!</math> |- | <source lang="latex" enclose="none">\sim, \nsim, \backsim, \thicksim, \simeq, \backsimeq, \eqsim, \cong, \ncong </source> | <math>\sim, \nsim, \backsim, \thicksim, \simeq, \backsimeq, \eqsim, \cong, \ncong \!</math> |- | <source lang="latex" enclose="none">\approx, \thickapprox, \approxeq, \asymp, \propto, \varpropto </source> | <math>\approx, \thickapprox, \approxeq, \asymp, \propto, \varpropto \!</math> |- | <source lang="latex" enclose="none"><, \nless, \ll, \not\ll, \lll, \not\lll, \lessdot </source> | <math><, \nless, \ll, \not\ll, \lll, \not\lll, \lessdot \!</math> |- | <source lang="latex" enclose="none">>, \ngtr, \gg, \not\gg, \ggg, \not\ggg, \gtrdot </source> | <math>>, \ngtr, \gg, \not\gg, \ggg, \not\ggg, \gtrdot \!</math> |- | <source lang="latex" enclose="none">\le, \leq, \lneq, \leqq, \nleq, \nleqq, \lneqq, \lvertneqq </source> | <math>\le, \leq, \lneq, \leqq, \nleq, \nleqq, \lneqq, \lvertneqq \!</math> |- | <source lang="latex" enclose="none">\ge, \geq, \gneq, \geqq, \ngeq, \ngeqq, \gneqq, \gvertneqq </source> | <math>\ge, \geq, \gneq, \geqq, \ngeq, \ngeqq, \gneqq, \gvertneqq \!</math> |- | <source lang="latex" enclose="none">\lessgtr, \lesseqgtr, \lesseqqgtr, \gtrless, \gtreqless, \gtreqqless </source> | <math>\lessgtr, \lesseqgtr, \lesseqqgtr, \gtrless, \gtreqless, \gtreqqless \!</math> |- | <source lang="latex" enclose="none">\leqslant, \nleqslant, \eqslantless </source> | <math>\leqslant, \nleqslant, \eqslantless \!</math> |- | <source lang="latex" enclose="none">\geqslant, \ngeqslant, \eqslantgtr </source> | <math>\geqslant, \ngeqslant, \eqslantgtr \!</math> |- | <source lang="latex" enclose="none">\lesssim, \lnsim, \lessapprox, \lnapprox </source> | <math>\lesssim, \lnsim, \lessapprox, \lnapprox \!</math> |- | <source lang="latex" enclose="none">\gtrsim, \gnsim, \gtrapprox, \gnapprox </source> | <math>\gtrsim, \gnsim, \gtrapprox, \gnapprox \,</math> |- | <source lang="latex" enclose="none">\prec, \nprec, \preceq, \npreceq, \precneqq </source> | <math>\prec, \nprec, \preceq, \npreceq, \precneqq \!</math> |- | <source lang="latex" enclose="none">\succ, \nsucc, \succeq, \nsucceq, \succneqq </source> | <math>\succ, \nsucc, \succeq, \nsucceq, \succneqq \!</math> |- | <source lang="latex" enclose="none">\preccurlyeq, \curlyeqprec </source> | <math>\preccurlyeq, \curlyeqprec \,</math> |- | <source lang="latex" enclose="none">\succcurlyeq, \curlyeqsucc </source> | <math>\succcurlyeq, \curlyeqsucc \,</math> |- | <source lang="latex" enclose="none">\precsim, \precnsim, \precapprox, \precnapprox </source> | <math>\precsim, \precnsim, \precapprox, \precnapprox \,</math> |- | <source lang="latex" enclose="none">\succsim, \succnsim, \succapprox, \succnapprox </source> | <math>\succsim, \succnsim, \succapprox, \succnapprox \,</math> |- !colspan="2"| === Geometric === |- | <source lang="latex" enclose="none">\parallel, \nparallel, \shortparallel, \nshortparallel </source> | <math>\parallel, \nparallel, \shortparallel, \nshortparallel \!</math> |- | <source lang="latex" enclose="none">\perp, \angle, \sphericalangle, \measuredangle, 45^\circ </source> | <math>\perp, \angle, \sphericalangle, \measuredangle, 45^\circ \!</math> |- | <source lang="latex" enclose="none">\Box, \blacksquare, \diamond, \Diamond \lozenge, \blacklozenge, \bigstar </source> | <math>\Box, \blacksquare, \diamond, \Diamond \lozenge, \blacklozenge, \bigstar \!</math> |- | <source lang="latex" enclose="none">\bigcirc, \triangle \bigtriangleup, \bigtriangledown </source> | <math>\bigcirc, \triangle \bigtriangleup, \bigtriangledown \!</math> |- | <source lang="latex" enclose="none">\vartriangle, \triangledown </source> | <math>\vartriangle, \triangledown\!</math> |- | <source lang="latex" enclose="none">\blacktriangle, \blacktriangledown, \blacktriangleleft, \blacktriangleright </source> | <math>\blacktriangle, \blacktriangledown, \blacktriangleleft, \blacktriangleright \!</math> |- !colspan="2"| === Logic === |- | <source lang="latex" enclose="none">\forall, \exists, \nexists </source> | <math>\forall, \exists, \nexists \!</math> |- | <source lang="latex" enclose="none">\therefore, \because, \And </source> | <math>\therefore, \because, \And \!</math> |- | <source lang="latex" enclose="none">\or \lor \vee, \curlyvee, \bigvee </source> | <math>\or \lor \vee, \curlyvee, \bigvee \!</math> |- | <source lang="latex" enclose="none">\and \land \wedge, \curlywedge, \bigwedge </source> | <math>\and \land \wedge, \curlywedge, \bigwedge \!</math> |- | <source lang="text" enclose="none">\bar{q}, \bar{abc}, \overline{q}, \overline{abc}, </source><br /> <source lang="latex" enclose="none">\lnot \neg, \not\operatorname{R}, \bot, \top</source> | <math>\bar{q}, \bar{abc}, \overline{q}, \overline{abc}, \!</math><br /> <math>\lnot \neg, \not\operatorname{R}, \bot, \top \!</math> |- | <source lang="latex" enclose="none">\vdash \dashv, \vDash, \Vdash, \models </source> | <math>\vdash \dashv, \vDash, \Vdash, \models \!</math> |- | <source lang="latex" enclose="none">\Vvdash \nvdash \nVdash \nvDash \nVDash </source> | <math>\Vvdash \nvdash \nVdash \nvDash \nVDash \!</math> |- | <source lang="latex" enclose="none">\ulcorner \urcorner \llcorner \lrcorner </source> | <math>\ulcorner \urcorner \llcorner \lrcorner \,</math> |- !colspan="2"| === Arrows === |- | <source lang="latex" enclose="none">\Rrightarrow, \Lleftarrow </source> | <math>\Rrightarrow, \Lleftarrow \!</math> |- | <source lang="latex" enclose="none">\Rightarrow, \nRightarrow, \Longrightarrow \implies </source> | <math>\Rightarrow, \nRightarrow, \Longrightarrow \implies\!</math> |- | <source lang="latex" enclose="none">\Leftarrow, \nLeftarrow, \Longleftarrow </source> | <math>\Leftarrow, \nLeftarrow, \Longleftarrow \!</math> |- | <source lang="latex" enclose="none">\Leftrightarrow, \nLeftrightarrow, \Longleftrightarrow \iff </source> | <math>\Leftrightarrow, \nLeftrightarrow, \Longleftrightarrow \iff \!</math> |- | <source lang="latex" enclose="none">\Uparrow, \Downarrow, \Updownarrow </source> | <math>\Uparrow, \Downarrow, \Updownarrow \!</math> |- | <source lang="latex" enclose="none">\rightarrow \to, \nrightarrow, \longrightarrow </source> | <math>\rightarrow \to, \nrightarrow, \longrightarrow\!</math> |- | <source lang="latex" enclose="none">\leftarrow \gets, \nleftarrow, \longleftarrow </source> | <math>\leftarrow \gets, \nleftarrow, \longleftarrow\!</math> |- | <source lang="latex" enclose="none">\leftrightarrow, \nleftrightarrow, \longleftrightarrow </source> | <math>\leftrightarrow, \nleftrightarrow, \longleftrightarrow \!</math> |- | <source lang="latex" enclose="none">\uparrow, \downarrow, \updownarrow </source> | <math>\uparrow, \downarrow, \updownarrow \!</math> |- | <source lang="latex" enclose="none">\nearrow, \swarrow, \nwarrow, \searrow </source> | <math>\nearrow, \swarrow, \nwarrow, \searrow \!</math> |- | <source lang="latex" enclose="none">\mapsto, \longmapsto </source> | <math>\mapsto, \longmapsto \!</math> |- | <source lang="latex" enclose="none">\rightharpoonup \rightharpoondown \leftharpoonup \leftharpoondown \upharpoonleft \upharpoonright \downharpoonleft \downharpoonright \rightleftharpoons \leftrightharpoons</source> | <math>\rightharpoonup \rightharpoondown \leftharpoonup \leftharpoondown \upharpoonleft \upharpoonright \downharpoonleft \downharpoonright \rightleftharpoons \leftrightharpoons \,\!</math> |- | <source lang="latex" enclose="none">\curvearrowleft \circlearrowleft \Lsh \upuparrows \rightrightarrows \rightleftarrows \rightarrowtail \looparrowright</source> | <math>\curvearrowleft \circlearrowleft \Lsh \upuparrows \rightrightarrows \rightleftarrows \rightarrowtail \looparrowright \,\!</math> |- | <source lang="latex" enclose="none">\curvearrowright \circlearrowright \Rsh \downdownarrows \leftleftarrows \leftrightarrows \leftarrowtail \looparrowleft</source> | <math>\curvearrowright \circlearrowright \Rsh \downdownarrows \leftleftarrows \leftrightarrows \leftarrowtail \looparrowleft \,\!</math> |- | <source lang="latex" enclose="none">\hookrightarrow \hookleftarrow \multimap \leftrightsquigarrow \rightsquigarrow \twoheadrightarrow \twoheadleftarrow </source> | <math>\hookrightarrow \hookleftarrow \multimap \leftrightsquigarrow \rightsquigarrow \twoheadrightarrow \twoheadleftarrow \!</math> |- !colspan="2"| === Special === |- | <source lang="latex" enclose="none">\amalg \P \S \% \dagger \ddagger \ldots \cdots </source> | <math>\amalg \P \S \% \dagger \ddagger \ldots \cdots \!</math> |- | <source lang="latex" enclose="none">\smile \frown \wr \triangleleft \triangleright</source> | <math>\smile \frown \wr \triangleleft \triangleright\!</math> |- | <source lang="latex" enclose="none">\diamondsuit, \heartsuit, \clubsuit, \spadesuit, \Game, \flat, \natural, \sharp </source> | <math>\diamondsuit, \heartsuit, \clubsuit, \spadesuit, \Game, \flat, \natural, \sharp \!</math> |- !colspan="2"| === Unsorted (new stuff) === |- | <source lang="latex" enclose="none">\diagup \diagdown \centerdot \ltimes \rtimes \leftthreetimes \rightthreetimes </source> | <math>\diagup \diagdown \centerdot \ltimes \rtimes \leftthreetimes \rightthreetimes \!</math> |- | <source lang="latex" enclose="none">\eqcirc \circeq \triangleq \bumpeq \Bumpeq \doteqdot \risingdotseq \fallingdotseq </source> | <math>\eqcirc \circeq \triangleq \bumpeq \Bumpeq \doteqdot \risingdotseq \fallingdotseq \!</math> |- | <source lang="latex" enclose="none">\intercal \barwedge \veebar \doublebarwedge \between \pitchfork </source> | <math>\intercal \barwedge \veebar \doublebarwedge \between \pitchfork \!</math> |- | <source lang="latex" enclose="none">\vartriangleleft \ntriangleleft \vartriangleright \ntriangleright </source> | <math>\vartriangleleft \ntriangleleft \vartriangleright \ntriangleright \!</math> |- | <source lang="latex" enclose="none">\trianglelefteq \ntrianglelefteq \trianglerighteq \ntrianglerighteq </source> | <math>\trianglelefteq \ntrianglelefteq \trianglerighteq \ntrianglerighteq \!</math> |} For a little more semantics on these symbols, see the brief [http://www.math.upenn.edu/tex-stuff/cookbook.pdf TeX Cookbook]. == Larger expressions == === Subscripts, superscripts, integrals === {| class="wikitable" border="1" cellspacing="0" cellpadding="4" style="border-collapse:collapse" |- ! Feature !! Syntax !! How it looks rendered |- | Superscript | <source lang="text" enclose="none">a^2</source> || <math>a^2</math> |- | Subscript | <source lang="text" enclose="none">a_2</source> || <math>a_2</math> |- | rowspan="2"| Grouping | <source lang="text" enclose="none">10^{30} a^{2+2}</source> || <math>10^{30} a^{2+2}</math> |- | <source lang="text" enclose="none">a_{i,j} b_{f'}</source> || <math>a_{i,j} b_{f'}</math> |- | rowspan="2"| Combining sub & super without and with horizontal separation | <source lang="text" enclose="none">x_2^3</source> || <math>x_2^3</math> |- | <source lang="text" enclose="none">{x_2}^3</source> || <math>{x_2}^3 \,\!</math> |- | Super super | <source lang="text" enclose="none">10^{10^{8}}</source> || <math>10^{10^{8}}</math> |- | rowspan="2"| Preceding and/or additional sub & super | <source lang="text" enclose="none">\sideset{_1^2}{_3^4}\prod_a^b</source> || <math>\sideset{_1^2}{_3^4}\prod_a^b</math> |- | <source lang="text" enclose="none">{}_1^2\!\Omega_3^4</source> || <math>{}_1^2\!\Omega_3^4</math> |- | rowspan="4"| Stacking | <source lang="text" enclose="none">\overset{\alpha}{\omega}</source> || <math>\overset{\alpha}{\omega}</math> |- | <source lang="text" enclose="none">\underset{\alpha}{\omega}</source> || <math>\underset{\alpha}{\omega}</math> |- | <source lang="text" enclose="none">\overset{\alpha}{\underset{\gamma}{\omega}}</source> || <math>\overset{\alpha}{\underset{\gamma}{\omega}}</math> |- | <source lang="text" enclose="none">\stackrel{\alpha}{\omega}</source> || <math>\stackrel{\alpha}{\omega}</math> |- | rowspan="2"| Derivatives | <source lang="text" enclose="none">x', y'', f', f''</source> || <math>x', y'', f', f''</math> |- | <source lang="text" enclose="none">x^\prime, y^{\prime\prime}</source> || <math>x^\prime, y^{\prime\prime}</math> |- | Derivative dots | <source lang="text" enclose="none">\dot{x}, \ddot{x}</source> || <math>\dot{x}, \ddot{x}</math> |- | rowspan="3"| Underlines, overlines, vectors | <source lang="text" enclose="none">\hat a \ \bar b \ \vec c</source> || <math> \hat a \ \bar b \ \vec c</math> |- | <source lang="text" enclose="none">\overrightarrow{a b} \ \overleftarrow{c d} \ \widehat{d e f}</source> || <math> \overrightarrow{a b} \ \overleftarrow{c d} \ \widehat{d e f}</math> |- | <source lang="text" enclose="none">\overline{g h i} \ \underline{j k l}</source> || <math> \overline{g h i} \ \underline{j k l}</math> |- | Arc (workaround) | <source lang="text" enclose="none">\overset{\frown} {AB}</source> || <math>\overset{\frown} {AB}</math> |- | Arrows | <source lang="text" enclose="none"> A \xleftarrow{n+\mu-1} B \xrightarrow[T]{n\pm i-1} C</source> || <math> A \xleftarrow{n+\mu-1} B \xrightarrow[T]{n\pm i-1} C</math> |- | Overbraces | <source lang="text" enclose="none">\overbrace{ 1+2+\cdots+100 }^{5050}</source> || <math>\overbrace{ 1+2+\cdots+100 }^{5050}</math> |- | Underbraces | <source lang="text" enclose="none">\underbrace{ a+b+\cdots+z }_{26}</source> || <math>\underbrace{ a+b+\cdots+z }_{26}</math> |- | Sum | <source lang="text" enclose="none">\sum_{k=1}^N k^2</source> || <math>\sum_{k=1}^N k^2</math> |- | Sum (force&nbsp;<source lang="text" enclose="none">\textstyle</source>) | <source lang="text" enclose="none">\textstyle \sum_{k=1}^N k^2 </source> || <math>\textstyle \sum_{k=1}^N k^2</math> |- | Sum in a fraction (default <source lang="text" enclose="none">\textstyle</source>) | <source lang="text" enclose="none">\frac{\sum_{k=1}^N k^2}{a}</source> || <math>\frac{\sum_{k=1}^N k^2}{a}</math> |- | Sum in a fraction (force <source lang="text" enclose="none">\displaystyle</source>) | <source lang="text" enclose="none">\frac{\displaystyle \sum_{k=1}^N k^2}{a}</source> || <math>\frac{\displaystyle \sum_{k=1}^N k^2}{a}</math> |- | Sum in a fraction (alternative limits style) | <source lang="text" enclose="none">\frac{\sum\limits^{^N}_{k=1} k^2}{a}</source> || <math>\frac{\sum\limits^{^N}_{k=1} k^2}{a}</math> |- | Product | <source lang="text" enclose="none">\prod_{i=1}^N x_i</source> || <math>\prod_{i=1}^N x_i</math> |- | Product (force&nbsp;<source lang="text" enclose="none">\textstyle</source>) | <source lang="text" enclose="none">\textstyle \prod_{i=1}^N x_i</source> || <math>\textstyle \prod_{i=1}^N x_i</math> |- | Coproduct | <source lang="text" enclose="none">\coprod_{i=1}^N x_i</source> || <math>\coprod_{i=1}^N x_i</math> |- | Coproduct (force&nbsp;<source lang="text" enclose="none">\textstyle</source>) | <source lang="text" enclose="none">\textstyle \coprod_{i=1}^N x_i</source> || <math>\textstyle \coprod_{i=1}^N x_i</math> |- | Limit | <source lang="text" enclose="none">\lim_{n \to \infty}x_n</source> || <math>\lim_{n \to \infty}x_n</math> |- | Limit (force&nbsp;<source lang="text" enclose="none">\textstyle</source>) | <source lang="text" enclose="none">\textstyle \lim_{n \to \infty}x_n</source> || <math>\textstyle \lim_{n \to \infty}x_n</math> |- | Integral | <source lang="text" enclose="none">\int\limits_{1}^{3}\frac{e^3/x}{x^2}\, dx</source> || <math>\int\limits_{1}^{3}\frac{e^3/x}{x^2}\, dx</math> |- | Integral (alternative limits style) | <source lang="text" enclose="none">\int_{1}^{3}\frac{e^3/x}{x^2}\, dx</source> || <math>\int_{1}^{3}\frac{e^3/x}{x^2}\, dx</math> |- | Integral (force&nbsp;<source lang="text" enclose="none">\textstyle</source>) | <source lang="text" enclose="none">\textstyle \int\limits_{-N}^{N} e^x\, dx</source> || <math>\textstyle \int\limits_{-N}^{N} e^x\, dx</math> |- | Integral (force&nbsp;<source lang="text" enclose="none">\textstyle</source>, alternative limits style) | <source lang="text" enclose="none">\textstyle \int_{-N}^{N} e^x\, dx</source> || <math>\textstyle \int_{-N}^{N} e^x\, dx</math> |- | Double integral | <source lang="text" enclose="none">\iint\limits_D \, dx\,dy</source> || <math>\iint\limits_D \, dx\,dy</math> |- | Triple integral | <source lang="text" enclose="none">\iiint\limits_E \, dx\,dy\,dz</source> || <math>\iiint\limits_E \, dx\,dy\,dz</math> |- | Quadruple integral | <source lang="text" enclose="none">\iiiint\limits_F \, dx\,dy\,dz\,dt</source> || <math>\iiiint\limits_F \, dx\,dy\,dz\,dt</math> |- | Line or path integral | <source lang="text" enclose="none">\int_{(x,y)\in C} x^3\, dx + 4y^2\, dy</source> || <math>\int_{(x,y)\in C} x^3\, dx + 4y^2\, dy</math> |- | Closed line or path integral | <source lang="text" enclose="none">\oint_{(x,y)\in C} x^3\, dx + 4y^2\, dy</source> || <math>\oint_{(x,y)\in C} x^3\, dx + 4y^2\, dy</math> |- | Intersections | <source lang="text" enclose="none">\bigcap_{i=_1}^n E_i</source> || <math>\bigcap_{i=_1}^n E_i</math> |- | Unions | <source lang="text" enclose="none">\bigcup_{i=_1}^n E_i</source> || <math>\bigcup_{i=_1}^n E_i</math> |} === Fractions, matrices, multilines === {| class="wikitable" ! Feature ! Syntax ! How it looks rendered |- | Fractions | <source lang="text" enclose="none">\frac{2}{4}=0.5</source> or <source lang="text" enclose="none">{2 \over 4}=0.5</source> | <math>\frac{2}{4}=0.5</math> |- | Small fractions | <source lang="text" enclose="none">\tfrac{2}{4} = 0.5</source> | <math>\tfrac{2}{4} = 0.5</math> |- | Large (normal) fractions | <source lang="text" enclose="none">\dfrac{2}{4} = 0.5 \qquad \dfrac{2}{c + \dfrac{2}{d + \dfrac{2}{4}}} = a </source> | <math>\dfrac{2}{4} = 0.5 \qquad \dfrac{2}{c + \dfrac{2}{d + \dfrac{2}{4}}} = a</math> |- | Large (nested) fractions | <source lang="text" enclose="none">\cfrac{2}{c + \cfrac{2}{d + \cfrac{2}{4}}} = a</source> | <math>\cfrac{2}{c + \cfrac{2}{d + \cfrac{2}{4}}} = a</math> |- | Cancellations in fractions<br>Note does not work with MathJax | <source lang="text" enclose="none">\cfrac{x}{1 + \cfrac{\cancel{y}}{\cancel{y}}} = \cfrac{x}{2}</source> | <math>\cfrac{x}{1 + \cfrac{\cancel{y}}{\cancel{y}}} = \cfrac{x}{2}</math> |- | Binomial coefficients | <source lang="text" enclose="none">\binom{n}{k}</source> | <math>\binom{n}{k}</math> |- | Small binomial coefficients | <source lang="text" enclose="none">\tbinom{n}{k}</source> | <math>\tbinom{n}{k}</math> |- | Large (normal) binomial coefficients | <source lang="text" enclose="none">\dbinom{n}{k}</source> | <math>\dbinom{n}{k}</math> |- | rowspan="7" | Matrices | <source lang="latex">\begin{matrix} x & y \\ z & v \end{matrix}</source> | <math>\begin{matrix} x & y \\ z & v \end{matrix}</math> |- | <source lang="latex">\begin{vmatrix} x & y \\ z & v \end{vmatrix}</source> | <math>\begin{vmatrix} x & y \\ z & v \end{vmatrix}</math> |- | <source lang="latex">\begin{Vmatrix} x & y \\ z & v \end{Vmatrix}</source> | <math>\begin{Vmatrix} x & y \\ z & v \end{Vmatrix}</math> |- | <source lang="latex">\begin{bmatrix} 0 & \cdots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \cdots & 0 \end{bmatrix}</source> | <math>\begin{bmatrix} 0 & \cdots & 0 \\ \vdots & \ddots & \vdots \\ 0 & \cdots & 0 \end{bmatrix} </math> |- | <source lang="latex">\begin{Bmatrix} x & y \\ z & v \end{Bmatrix}</source> | <math>\begin{Bmatrix} x & y \\ z & v \end{Bmatrix}</math> |- | <source lang="latex">\begin{pmatrix} x & y \\ z & v \end{pmatrix}</source> | <math>\begin{pmatrix} x & y \\ z & v \end{pmatrix}</math> |- | <source lang="latex"> \bigl( \begin{smallmatrix} a&b\\ c&d \end{smallmatrix} \bigr) </source> | <math> \bigl( \begin{smallmatrix} a&b\\ c&d \end{smallmatrix} \bigr) </math> |- | Case distinctions | <source lang="latex"> f(n) = \begin{cases} n/2, & \text{if }n\text{ is even} \\ 3n+1, & \text{if }n\text{ is odd} \end{cases}</source> | <math>f(n) = \begin{cases} n/2, & \text{if }n\text{ is even} \\ 3n+1, & \text{if }n\text{ is odd} \end{cases}</math> |- | rowspan="2" | Multiline equations | <source lang="latex"> \begin{align} f(x) & = (a+b)^2 \\ & = a^2+2ab+b^2 \\ \end{align} </source> | <math> \begin{align} f(x) & = (a+b)^2 \\ & = a^2+2ab+b^2 \\ \end{align} </math> |- | <source lang="latex"> \begin{alignat}{2} f(x) & = (a-b)^2 \\ & = a^2-2ab+b^2 \\ \end{alignat} </source> | <math> \begin{alignat}{2} f(x) & = (a-b)^2 \\ & = a^2-2ab+b^2 \\ \end{alignat} </math> |- | Multiline equations <small>(must define number of columns used ({lcl})) (should not be used unless needed)</small> | <source lang="latex"> \begin{array}{lcl} z & = & a \\ f(x,y,z) & = & x + y + z \end{array}</source> | <math>\begin{array}{lcl} z & = & a \\ f(x,y,z) & = & x + y + z \end{array}</math> |- | Multiline equations (more) | <source lang="latex"> \begin{array}{lcr} z & = & a \\ f(x,y,z) & = & x + y + z \end{array}</source> | <math>\begin{array}{lcr} z & = & a \\ f(x,y,z) & = & x + y + z \end{array}</math> |- | Breaking up a long expression so that it wraps when necessary, at the expense of destroying correct spacing | <source lang="latex"> f(x) = \sum_{n=0}^\infty a_n x^n = a_0+a_1x+a_2x^2+\cdots </source> | <math>f(x) = \sum_{n=0}^\infty a_n x^n = a_0 +a_1x+a_2x^2+\cdots</math> |- | Simultaneous equations | <source lang="latex">\begin{cases} 3x + 5y + z \\ 7x - 2y + 4z \\ -6x + 3y + 2z \end{cases}</source> | <math>\begin{cases} 3x + 5y + z \\ 7x - 2y + 4z \\ -6x + 3y + 2z \end{cases}</math> |- | Arrays | <source lang="latex"> \begin{array}{|c|c|c|} a & b & S \\ \hline 0&0&1\\ 0&1&1\\ 1&0&1\\ 1&1&0\\ \end{array} </source> | <math> \begin{array}{|c|c|c|} a & b & S \\ \hline 0&0&1\\ 0&1&1\\ 1&0&1\\ 1&1&0\\ \end{array} </math> |} === Parenthesizing big expressions, brackets, bars === {| class="wikitable" ! Feature !! Syntax !! How it looks rendered |- | Bad | <source lang="text" enclose="none">( \frac{1}{2} )</source> | <math>( \frac{1}{2} )</math> |- | Good | <source lang="text" enclose="none">\left ( \frac{1}{2} \right )</source> | <math>\left ( \frac{1}{2} \right )</math> |} You can use various delimiters with \left and \right: {| class="wikitable" ! Feature ! Syntax ! How it looks rendered |- | Parentheses | <source lang="text" enclose="none">\left ( \frac{a}{b} \right )</source> | <math>\left ( \frac{a}{b} \right )</math> |- | Brackets | <source lang="text" enclose="none">\left [ \frac{a}{b} \right ] \quad</source><br/> <source lang="text" enclose="none">\left \lbrack \frac{a}{b} \right \rbrack</source> | <math>\left [ \frac{a}{b} \right ] \quad \left \lbrack \frac{a}{b} \right \rbrack</math> |- | Braces | <source lang="text" enclose="none">\left \{ \frac{a}{b} \right \} \quad</source><br/> <source lang="text" enclose="none">\left \lbrace \frac{a}{b} \right \rbrace</source> | <math>\left \{ \frac{a}{b} \right \} \quad \left \lbrace \frac{a}{b} \right \rbrace</math> |- | Angle brackets | <source lang="text" enclose="none">\left \langle \frac{a}{b} \right \rangle</source> | <math>\left \langle \frac{a}{b} \right \rangle</math> |- | Bars and double bars | <source lang="text" enclose="none">\left | \frac{a}{b} \right \vert \quad</source><br/> <source lang="text" enclose="none">\left \Vert \frac{c}{d} \right \|</source> | <math>\left | \frac{a}{b} \right \vert \quad \left \Vert \frac{c}{d} \right \|</math> |- | Floor and ceiling functions: | <source lang="text" enclose="none">\left \lfloor \frac{a}{b} \right \rfloor \quad</source><br/> <source lang="text" enclose="none">\left \lceil \frac{c}{d} \right \rceil</source> | <math>\left \lfloor \frac{a}{b} \right \rfloor \quad \left \lceil \frac{c}{d} \right \rceil</math> |- | Slashes and backslashes | <source lang="text" enclose="none">\left / \frac{a}{b} \right \backslash</source> | <math>\left / \frac{a}{b} \right \backslash</math> |- | Up, down, and up-down arrows | <source lang="text" enclose="none">\left \uparrow \frac{a}{b} \right \downarrow \quad</source><br/> <source lang="text" enclose="none">\left \Uparrow \frac{a}{b} \right \Downarrow \quad</source><br/> <source lang="text" enclose="none">\left \updownarrow \frac{a}{b} \right \Updownarrow</source> | <math>\left \uparrow \frac{a}{b} \right \downarrow \quad \left \Uparrow \frac{a}{b} \right \Downarrow \quad \left \updownarrow \frac{a}{b} \right \Updownarrow</math> |- | Delimiters can be mixed,<br>as long as \left and \right match | <source lang="latex" enclose="none">\left [ 0,1 \right )</source><br/> <source lang="latex" enclose="none">\left \langle \psi \right |</source> | <math>\left [ 0,1 \right )</math><br/> <math>\left \langle \psi \right |</math> |- | Use \left. and \right. if you<br/> do not want a delimiter to appear | <source lang="text" enclose="none">\left . \frac{A}{B} \right \} \to X</source> | <math>\left . \frac{A}{B} \right \} \to X</math> |- | rowspan="7" | Size of the delimiters (add "l" or "r" to indicate the side for proper spacing) | <source lang="latex" enclose="none">( \bigl( \Bigl( \biggl( \Biggl( \dots \Biggr] \biggr] \Bigr] \bigr] ]</source> | <math>( \bigl( \Bigl( \biggl( \Biggl( \dots \Biggr] \biggr] \Bigr] \bigr] ]</math> |- | <source lang="latex" enclose="none">\{ \bigl\{ \Bigl\{ \biggl\{ \Biggl\{ \dots</source><br/> <source lang="latex" enclose="none">\Biggr\rangle \biggr\rangle \Bigr\rangle \bigr\rangle \rangle</source> | <math>\{ \bigl\{ \Bigl\{ \biggl\{ \Biggl\{ \dots \Biggr\rangle \biggr\rangle \Bigr\rangle \bigr\rangle \rangle</math> |- | <source lang="latex" enclose="none">\| \big\| \Big\| \bigg\| \Bigg\| \dots \Bigg| \bigg| \Big| \big| |</source> | <math>\| \big\| \Big\| \bigg\| \Bigg\| \dots \Bigg| \bigg| \Big| \big| |</math> |- | <source lang="latex" enclose="none">\lfloor \bigl\lfloor \Bigl\lfloor \biggl\lfloor \Biggl\lfloor \dots</source><br/> <source lang="latex" enclose="none">\Biggr\rceil \biggr\rceil \Bigr\rceil \bigr\rceil \ceil</source> | <math>\lfloor \bigl\lfloor \Bigl\lfloor \biggl\lfloor \Biggl\lfloor \dots \Biggr\rceil \biggr\rceil \Bigr\rceil \bigr\rceil \rceil</math> |- | <source lang="latex" enclose="none">\uparrow \big\uparrow \Big\uparrow \bigg\uparrow \Bigg\uparrow \dots</source><br/> <source lang="latex" enclose="none">\Bigg\Downarrow \bigg\Downarrow \Big\Downarrow \big\Downarrow \Downarrow</source> | <math>\uparrow \big\uparrow \Big\uparrow \bigg\uparrow \Bigg\uparrow \dots \Bigg\Downarrow \bigg\Downarrow \Big\Downarrow \big\Downarrow \Downarrow</math> |- | <source lang="latex" enclose="none">\updownarrow \big\updownarrow \Big\updownarrow \bigg\updownarrow \Bigg\updownarrow \dots</source><br/> <source lang="latex" enclose="none">\Bigg\Updownarrow \bigg\Updownarrow \Big\Updownarrow \big\Updownarrow \Updownarrow</source> | <math>\updownarrow \big\updownarrow \Big\updownarrow \bigg\updownarrow \Bigg\updownarrow \dots \Bigg\Updownarrow \bigg\Updownarrow \Big\Updownarrow \big\Updownarrow \Updownarrow</math> |- | <source lang="latex" enclose="none">/ \big/ \Big/ \bigg/ \Bigg/ \dots</source><br/> <source lang="latex" enclose="none">\Bigg\backslash \bigg\backslash \Big\backslash \big\backslash \backslash</source> | <math>/ \big/ \Big/ \bigg/ \Bigg/ \dots \Bigg\backslash \bigg\backslash \Big\backslash \big\backslash \backslash</math> |} === Equation numbering === The templates {{tl|NumBlk}} and {{tl|EquationRef}} can be used to number equations. The template {{tl|EquationNote}} can be used to refer to a numbered equation from surrounding text. For example, the following syntax: : <code><nowiki>{{NumBlk|:|<math>x^2 + y^2 + z^2 = 1 \,</math>|{{EquationRef|1}}}}</nowiki></code> produces the following result (note the equation number in the right margin): {{NumBlk|:|<math>x^2 + y^2 + z^2 = 1 \,</math> or {{math|''x''<sup>2</sup> + ''y''<sup>2</sup> + ''z''<sup>2</sup> {{=}} 1}}|{{EquationRef|1}}}} Later on, the text can refer to this equation by its number using syntax like this: : <source lang="latex" enclose="none">As seen in equation ({{EquationNote|1}}), blah blah blah...</source> The result looks like this: : As seen in equation ({{EquationNote|1}}), blah blah blah... Note that the equation number produced by {{tl|EquationNote}} is a link that the user can click to go immediately to the cited equation. == Alphabets and typefaces == {{See also|Wikipedia:LaTeX symbols#Fonts}} [[Texvc]] cannot render arbitrary [[Unicode]] characters. Those it can handle can be entered by the expressions below. For others, such as [[Cyrillic]], they can be entered as Unicode or HTML entities in running text, but cannot be used in displayed formulas. {| class="wikitable" |- !colspan="2"| Greek alphabet |- | <source lang="latex" enclose="none">\Alpha \Beta \Gamma \Delta \Epsilon \Zeta \Eta \Theta </source> | <math>\Alpha \Beta \Gamma \Delta \Epsilon \Zeta \Eta \Theta \!</math> |- | <source lang="latex" enclose="none">\Iota \Kappa \Lambda \Mu \Nu \Xi \Pi \Rho </source> | <math>\Iota \Kappa \Lambda \Mu \Nu \Xi \Pi \Rho \!</math> |- | <source lang="latex" enclose="none">\Sigma \Tau \Upsilon \Phi \Chi \Psi \Omega </source> | <math>\Sigma \Tau \Upsilon \Phi \Chi \Psi \Omega \!</math> |- | <source lang="latex" enclose="none">\alpha \beta \gamma \delta \epsilon \zeta \eta \theta </source> | <math>\alpha \beta \gamma \delta \epsilon \zeta \eta \theta \!</math> |- | <source lang="latex" enclose="none">\iota \kappa \lambda \mu \nu \xi \pi \rho </source> | <math>\iota \kappa \lambda \mu \nu \xi \pi \rho \!</math> |- | <source lang="latex" enclose="none">\sigma \tau \upsilon \phi \chi \psi \omega </source> | <math>\sigma \tau \upsilon \phi \chi \psi \omega \!</math> |- | <source lang="latex" enclose="none">\varepsilon \digamma \varkappa \varpi </source> | <math>\varepsilon \digamma \varkappa \varpi \!</math> |- | <source lang="latex" enclose="none">\varrho \varsigma \vartheta \varphi </source> | <math>\varrho \varsigma \vartheta \varphi \!</math> |- !colspan="2"| Hebrew symbols |- | <source lang="latex" enclose="none">\aleph \beth \gimel \daleth </source> | <math>\aleph \beth \gimel \daleth \!</math> |- !colspan="2"| Blackboard bold/scripts |- | <source lang="latex" enclose="none">\mathbb{ABCDEFGHI} </source> | <math>\mathbb{ABCDEFGHI} \!</math> |- | <source lang="latex" enclose="none">\mathbb{JKLMNOPQR} </source> | <math>\mathbb{JKLMNOPQR} \!</math> |- | <source lang="latex" enclose="none">\mathbb{STUVWXYZ} </source> | <math>\mathbb{STUVWXYZ} \!</math> |- !colspan="2"| Boldface |- | <source lang="latex" enclose="none">\mathbf{ABCDEFGHI} </source> | <math>\mathbf{ABCDEFGHI} \!</math> |- | <source lang="latex" enclose="none">\mathbf{JKLMNOPQR} </source> | <math>\mathbf{JKLMNOPQR} \!</math> |- | <source lang="latex" enclose="none">\mathbf{STUVWXYZ} </source> | <math>\mathbf{STUVWXYZ} \!</math> |- | <source lang="latex" enclose="none">\mathbf{abcdefghijklm} </source> | <math>\mathbf{abcdefghijklm} \!</math> |- | <source lang="latex" enclose="none">\mathbf{nopqrstuvwxyz} </source> | <math>\mathbf{nopqrstuvwxyz} \!</math> |- | <source lang="latex" enclose="none">\mathbf{0123456789} </source> | <math>\mathbf{0123456789} \!</math> |- !colspan="2"| Boldface (Greek) |- | <source lang="latex" enclose="none">\boldsymbol{\Alpha\Beta\Gamma\Delta\Epsilon\Zeta\Eta\Theta} </source> | <math>\boldsymbol{\Alpha\Beta\Gamma\Delta\Epsilon\Zeta\Eta\Theta} \!</math> |- | <source lang="latex" enclose="none">\boldsymbol{\Iota\Kappa\Lambda\Mu\Nu\Xi\Pi\Rho} </source> | <math>\boldsymbol{\Iota\Kappa\Lambda\Mu\Nu\Xi\Pi\Rho} \!</math> |- | <source lang="latex" enclose="none">\boldsymbol{\Sigma\Tau\Upsilon\Phi\Chi\Psi\Omega} </source> | <math>\boldsymbol{\Sigma\Tau\Upsilon\Phi\Chi\Psi\Omega} \!</math> |- | <source lang="latex" enclose="none">\boldsymbol{\alpha\beta\gamma\delta\epsilon\zeta\eta\theta} </source> | <math>\boldsymbol{\alpha\beta\gamma\delta\epsilon\zeta\eta\theta} \!</math> |- | <source lang="latex" enclose="none">\boldsymbol{\iota\kappa\lambda\mu\nu\xi\pi\rho} </source> | <math>\boldsymbol{\iota\kappa\lambda\mu\nu\xi\pi\rho} \!</math> |- | <source lang="latex" enclose="none">\boldsymbol{\sigma\tau\upsilon\phi\chi\psi\omega} </source> | <math>\boldsymbol{\sigma\tau\upsilon\phi\chi\psi\omega} \!</math> |- | <source lang="latex" enclose="none">\boldsymbol{\varepsilon\digamma\varkappa\varpi} </source> | <math>\boldsymbol{\varepsilon\digamma\varkappa\varpi} \!</math> |- | <source lang="latex" enclose="none">\boldsymbol{\varrho\varsigma\vartheta\varphi} </source> | <math>\boldsymbol{\varrho\varsigma\vartheta\varphi} \!</math> |- !colspan="2"| Italics (default for Latin alphabet) |- | <source lang="latex" enclose="none">\mathit{0123456789} </source> | <math>\mathit{0123456789} \!</math> |- !colspan="2"| Greek italics (default for lowercase Greek) |- | <source lang="latex" enclose="none">\mathit{\Alpha\Beta\Gamma\Delta\Epsilon\Zeta\Eta\Theta} </source> | <math>\mathit{\Alpha\Beta\Gamma\Delta\Epsilon\Zeta\Eta\Theta} \!</math> |- | <source lang="latex" enclose="none">\mathit{\Iota\Kappa\Lambda\Mu\Nu\Xi\Pi\Rho} </source> | <math>\mathit{\Iota\Kappa\Lambda\Mu\Nu\Xi\Pi\Rho} \!</math> |- | <source lang="latex" enclose="none">\mathit{\Sigma\Tau\Upsilon\Phi\Chi\Psi\Omega} </source> | <math>\mathit{\Sigma\Tau\Upsilon\Phi\Chi\Psi\Omega} \!</math> |- !colspan="2"| Roman typeface |- | <source lang="latex" enclose="none">\mathrm{ABCDEFGHI} </source> | <math>\mathrm{ABCDEFGHI} \!</math> |- | <source lang="latex" enclose="none">\mathrm{JKLMNOPQR} </source> | <math>\mathrm{JKLMNOPQR} \!</math> |- | <source lang="latex" enclose="none">\mathrm{STUVWXYZ} </source> | <math>\mathrm{STUVWXYZ} \!</math> |- | <source lang="latex" enclose="none">\mathrm{abcdefghijklm} </source> | <math>\mathrm{abcdefghijklm} \!</math> |- | <source lang="latex" enclose="none">\mathrm{nopqrstuvwxyz} </source> | <math>\mathrm{nopqrstuvwxyz} \!</math> |- | <source lang="latex" enclose="none">\mathrm{0123456789} </source> | <math>\mathrm{0123456789} \!</math> |- !colspan="2"| Sans serif |- | <source lang="latex" enclose="none">\mathsf{ABCDEFGHI} </source> | <math>\mathsf{ABCDEFGHI} \!</math> |- | <source lang="latex" enclose="none">\mathsf{JKLMNOPQR} </source> | <math>\mathsf{JKLMNOPQR} \!</math> |- | <source lang="latex" enclose="none">\mathsf{STUVWXYZ} </source> | <math>\mathsf{STUVWXYZ} \!</math> |- | <source lang="latex" enclose="none">\mathsf{abcdefghijklm} </source> | <math>\mathsf{abcdefghijklm} \!</math> |- | <source lang="latex" enclose="none">\mathsf{nopqrstuvwxyz} </source> | <math>\mathsf{nopqrstuvwxyz} \!</math> |- | <source lang="latex" enclose="none">\mathsf{0123456789} </source> | <math>\mathsf{0123456789} \!</math> |- !colspan="2"| Sans serif Greek (capital only) |- | <source lang="latex" enclose="none">\mathsf{\Alpha \Beta \Gamma \Delta \Epsilon \Zeta \Eta \Theta} </source> | <math>\mathsf{\Alpha \Beta \Gamma \Delta \Epsilon \Zeta \Eta \Theta} \!</math> |- | <source lang="latex" enclose="none">\mathsf{\Iota \Kappa \Lambda \Mu \Nu \Xi \Pi \Rho} </source> | <math>\mathsf{\Iota \Kappa \Lambda \Mu \Nu \Xi \Pi \Rho} \!</math> |- | <source lang="latex" enclose="none">\mathsf{\Sigma \Tau \Upsilon \Phi \Chi \Psi \Omega}</source> | <math>\mathsf{\Sigma \Tau \Upsilon \Phi \Chi \Psi \Omega}\!</math> |- !colspan="2"| Calligraphy/script |- | <source lang="latex" enclose="none">\mathcal{ABCDEFGHI} </source> | <math>\mathcal{ABCDEFGHI} \!</math> |- | <source lang="latex" enclose="none">\mathcal{JKLMNOPQR} </source> | <math>\mathcal{JKLMNOPQR} \!</math> |- | <source lang="latex" enclose="none">\mathcal{STUVWXYZ} </source> | <math>\mathcal{STUVWXYZ} \!</math> |- !colspan="2"| Fraktur typeface |- | <source lang="latex" enclose="none">\mathfrak{ABCDEFGHI} </source> | <math>\mathfrak{ABCDEFGHI} \!</math> |- | <source lang="latex" enclose="none">\mathfrak{JKLMNOPQR} </source> | <math>\mathfrak{JKLMNOPQR} \!</math> |- | <source lang="latex" enclose="none">\mathfrak{STUVWXYZ} </source> | <math>\mathfrak{STUVWXYZ} \!</math> |- | <source lang="latex" enclose="none">\mathfrak{abcdefghijklm} </source> | <math>\mathfrak{abcdefghijklm} \!</math> |- | <source lang="latex" enclose="none">\mathfrak{nopqrstuvwxyz} </source> | <math>\mathfrak{nopqrstuvwxyz} \!</math> |- | <source lang="latex" enclose="none">\mathfrak{0123456789} </source> | <math>\mathfrak{0123456789} \!</math> |- |- !colspan="2"| Small scriptstyle text |- | <source lang="latex" enclose="none">{\scriptstyle\text{abcdefghijklm}}</source> | <math>{\scriptstyle\text{abcdefghijklm}}</math> |} === Mixed text faces === {| class="wikitable" |- ! Feature ! Syntax ! How it looks rendered |- | Italicised characters (spaces are ignored) | <source lang="text" enclose="none">x y z</source> | <math>x y z</math> |- | Non-italicised characters | <source lang="latex" enclose="none">\text{x y z}</source> | <math>\text{x y z}</math> |- | Mixed italics (bad) | <source lang="text" enclose="none">\text{if} n \text{is even}</source> | <math>\text{if} n \text{is even}</math> |- | Mixed italics (good) | <source lang="text" enclose="none">\text{if }n\text{ is even}</source> | <math>\text{if }n\text{ is even}</math> |- | Mixed italics (alternative: ~ or "\ " forces a space) | <source lang="text" enclose="none">\text{if}~n\ \text{is even}</source> | <math>\text{if}~n\ \text{is even}</math> |} == Color == Equations can use color with the <code>\color</code> command. The default [[Wikipedia:Texvc|Texvc]] renderer and the [[MathJax]] renderers have different syntaxes to support both use <code>{\color{Blue}{text}}</code>. For example * <source lang="text" enclose="none">{\color{Blue}{x^2}}+{\color{Orange}{2x}}-{\color{LimeGreen}{1}}</source> *: <math>{\color{Blue}{x^2}}+{\color{Orange}{2x}}-{\color{LimeGreen}{1}}</math> * <source lang="text" enclose="none">x_{1,2}=\frac{{\color{Blue}{-b}}\pm\sqrt{\color{Red}{b^2-4ac}}}{\color{Green}{2a}}</source> *: <math>x_{1,2}=\frac{{\color{Blue}{-b}}\pm\sqrt{\color{Red}{b^2-4ac}}}{\color{Green}{2a}}</math> There are several alternate notations styles * <source lang="text" enclose="none">{\color{Blue}x^2}+{\color{Orange}2x}-{\color{LimeGreen}1}</source> works with both texvc and MathJax *: <math>{\color{Blue}x^2}+{\color{Orange}2x}-{\color{LimeGreen}1}</math> * <source lang="text" enclose="none">\color{Blue}x^2\color{Black}+\color{Orange}2x\color{Black}-\color{LimeGreen}1</source> works with both texvc and MathJax *: <math>\color{Blue}x^2\color{Black}+\color{Orange}2x\color{Black}-\color{LimeGreen}1</math> * <source lang="text" enclose="none">\color{Blue}{x^2}+\color{Orange}{2x}-\color{LimeGreen}{1}</source> only works with MathJax *: <math>\color{Blue}{x^2}+\color{Orange}{2x}-\color{LimeGreen}{1}</math> Some color names are predeclared according to the following table, you can use them directly for the rendering of formulas (or for declaring the intended color of the page background). {| class="wikitable" |+ Colors supported |- | <math>\color{Apricot}{\text{Apricot}}</math> ||style="background-color: gray;{{Text default color}};"| <math>\color{Aquamarine}{\text{Aquamarine}}</math> || <math>\color{Bittersweet}{\text{Bittersweet}}</math> || <math>\color{Black}{\text{Black}}</math> |- | <math>\color{Blue}{\text{Blue}}</math> || <math>\color{BlueGreen}{\text{BlueGreen}}</math> || <math>\color{BlueViolet}{\text{BlueViolet}}</math> || <math>\color{BrickRed}{\text{BrickRed}}</math> |- | <math>\color{Brown}{\text{Brown}}</math> || <math>\color{BurntOrange}{\text{BurntOrange}}</math> || <math>\color{CadetBlue}{\text{CadetBlue}}</math> || <math>\color{CarnationPink}{\text{CarnationPink}}</math> |- | <math>\color{Cerulean}{\text{Cerulean}}</math> || <math>\color{CornflowerBlue}{\text{CornflowerBlue}}</math> ||style="background-color: gray;{{Text default color}};"| <math>\color{Cyan}{\text{Cyan}}</math> || <math>\color{Dandelion}{\text{Dandelion}}</math> |- | <math>\color{DarkOrchid}{\text{DarkOrchid}}</math> || <math>\color{Emerald}{\text{Emerald}}</math> || <math>\color{ForestGreen}{\text{ForestGreen}}</math> || <math>\color{Fuchsia}{\text{Fuchsia}}</math> |- | <math>\color{Goldenrod}{\text{Goldenrod}}</math> || <math>\color{Gray}{\text{Gray}}</math> || <math>\color{Green}{\text{Green}}</math> ||style="background-color: gray;{{Text default color}};"| <math>\color{GreenYellow}{\text{GreenYellow}}</math> |- | <math>\color{JungleGreen}{\text{JungleGreen}}</math> ||style="background-color: gray;{{Text default color}};"| <math>\color{Lavender}{\text{Lavender}}</math> || <math>\color{LimeGreen}{\text{LimeGreen}}</math> || <math>\color{Magenta}{\text{Magenta}}</math> |- | <math>\color{Mahogany}{\text{Mahogany}}</math> || <math>\color{Maroon}{\text{Maroon}}</math> || <math>\color{Melon}{\text{Melon}}</math> || <math>\color{MidnightBlue}{\text{MidnightBlue}}</math> |- | <math>\color{Mulberry}{\text{Mulberry}}</math> || <math>\color{NavyBlue}{\text{NavyBlue}}</math> || <math>\color{OliveGreen}{\text{OliveGreen}}</math> || <math>\color{Orange}{\text{Orange}}</math> |- | <math>\color{OrangeRed}{\text{OrangeRed}}</math> || <math>\color{Orchid}{\text{Orchid}}</math> || <math>\color{Peach}{\text{Peach}}</math> || <math>\color{Periwinkle}{\text{Periwinkle}}</math> |- | <math>\color{PineGreen}{\text{PineGreen}}</math> || <math>\color{Plum}{\text{Plum}}</math> || <math>\color{ProcessBlue}{\text{ProcessBlue}}</math> || <math>\color{Purple}{\text{Purple}}</math> |- | <math>\color{RawSienna}{\text{RawSienna}}</math> || <math>\color{Red}{\text{Red}}</math> || <math>\color{RedOrange}{\text{RedOrange}}</math> || <math>\color{RedViolet}{\text{RedViolet}}</math> |- | <math>\color{Rhodamine}{\text{Rhodamine}}</math> || <math>\color{RoyalBlue}{\text{RoyalBlue}}</math> || <math>\color{RoyalPurple}{\text{RoyalPurple}}</math> || <math>\color{RubineRed}{\text{RubineRed}}</math> |- | <math>\color{Salmon}{\text{Salmon}}</math> || <math>\color{SeaGreen}{\text{SeaGreen}}</math> || <math>\color{Sepia}{\text{Sepia}}</math> || <math>\color{SkyBlue}{\text{SkyBlue}}</math> |- | <math>\color{SpringGreen}{\text{SpringGreen}}</math> || <math>\color{Tan}{\text{Tan}}</math> || <math>\color{TealBlue}{\text{TealBlue}}</math> ||style="background-color: gray;{{Text default color}};"| <math>\color{Thistle}{\text{Thistle}}</math> |- | <math>\color{Turquoise}{\text{Turquoise}}</math> || <math>\color{Violet}{\text{Violet}}</math> || <math>\color{VioletRed}{\text{VioletRed}}</math> ||style="background-color: gray;{{Text default color}};"| <math>{\color{White}{\text{White}}}</math> |- | <math>\color{WildStrawberry}{\text{WildStrawberry}}</math> ||style="background-color: gray;{{Text default color}};"| <math>\color{Yellow}{\text{Yellow}}</math> || <math>\color{YellowGreen}{\text{YellowGreen}}</math> || <math>\color{YellowOrange}{\text{YellowOrange}}</math> |} Note that color should not be used as the ''only'' way to identify something, because it will become meaningless on black-and-white media or for color-blind people. See [[Wikipedia:Manual of Style (accessibility)#Color]]. Latex does not have a command for setting the background color. The most effective of setting a background color is by setting a CSS styling rules for a table cell <pre style="display: inline-block;"> {| class="wikitable" |- | style="background: gray;{{Text default color}};" | <math>x^2</math> || style="background: Goldenrod;{{Text default color}};" | <math>y^3</math> |} </pre> Rendered as {| class="wikitable" |- | style="background: grey;{{Text default color}};" | <math>x^2</math> || style="background: Goldenrod;{{Text default color}};" | <math>y^3</math> |} Custom colours can be defined using <syntaxhighlight lang="latex">\definecolor{myorange}{RGB}{255,165,100}\color{myorange}e^{i \pi}\color{Black} + 1 = 0</syntaxhighlight> :<math>\definecolor{myorange}{RGB}{255,165,100}\color{myorange}e^{i \pi}\color{Black} + 1 = 0</math> == Formatting issues == === Spacing === Note that TeX handles most spacing automatically, but you may sometimes want manual control. {| class="wikitable" ! Feature ! Syntax ! How it looks rendered |- | double quad space | <source lang="latex" enclose="none">a \qquad b</source> | <math>a \qquad b</math> |- | quad space | <source lang="latex" enclose="none">a \quad b</source> | <math>a \quad b</math> |- | text space | <source lang="latex" enclose="none">a\ b</source> | <math>a\ b</math> |- | text space without PNG conversion | <source lang="latex" enclose="none">a \mbox{ } b</source> | <math>a \mbox{ } b</math> |- | large space | <source lang="latex" enclose="none">a\;b</source> | <math>a\;b</math> |- | medium space | <source lang="latex" enclose="none">a\<b</source> | [not supported] |- | small space | <source lang="latex" enclose="none">a\,b</source> | <math>a\,b</math> |- | tiny space (use for multiplication of factors) | <source lang="latex" enclose="none">ab</source> | <math>ab</math> |- | no space (use for multi-letter variables) | <source lang="latex" enclose="none">\mathit{ab}</source> | <math>\mathit{ab}</math> |- | small negative space | <source lang="latex" enclose="none">a\!b</source> | <math>a\!b</math> |} Automatic spacing may be broken in very long expressions (because they produce an overfull hbox in TeX): : <source lang="latex" enclose="none">0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+\cdots</source> : <math>0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+\cdots</math> This can be remedied by putting a pair of braces { } around the whole expression: : <source lang="latex" enclose="none">{0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+\cdots}</source> : <math>{0+1+2+3+4+5+6+7+8+9+10+11+12+13+14+15+16+17+18+19+20+\cdots}</math> === Alignment with normal text flow === Due to the default CSS <source lang="CSS">img.tex { vertical-align: middle; }</source> an inline expression like <math>\int_{-N}^{N} e^x\, dx</math> should look good. If you need to align it otherwise, use <code><nowiki><math style="vertical-align:-100%;">...</math></nowiki></code> and play with the <source lang="latex" enclose="none">vertical-align</source> argument until you get it right; however, how it looks may depend on the browser and the browser settings. Also note that if you rely on this workaround, if/when the rendering on the server gets fixed in future releases, as a result of this extra manual offset your formulae will suddenly be aligned incorrectly. So use it sparingly, if at all. == Commutative diagrams == To make a [[commutative diagram]], there are three steps: # write the diagram in [[TeX]] # convert to [[SVG]] # [[commons:Commons:First steps/Upload form|upload the file]] to [[commons:|Wikimedia Commons]] === Diagrams in TeX === [http://www.tug.org/applications/Xy-pic/ Xy-pic] ([http://tex.loria.fr/graph-pack/doc-xypic/xyguide-html/xyguide-html.html online manual]) is the most powerful and general-purpose diagram package in [[TeX]]. Diagrams created using it can be found at [[commons:Category:Xy-pic diagrams|Commons: Category:Xy-pic diagrams]]. Simpler packages include: * [[American Mathematical Society|AMS's]] [http://www.dante.de/CTAN//help/Catalogue/entries/amscd.html amscd] * Paul Taylor's [http://www.ctan.org/tex-archive/macros/generic/diagrams/taylor/ diagrams] * François Borceux [http://www.ctan.org/tex-archive/help/Catalogue/entries/borceux.html Diagrams] The following is a template for Xy-pic, together with a [[Hack (technology)|hack]] to increase the [[Margin (typography)|margins]] in [[dvips]], so that the diagram is not truncated by over-eager cropping (suggested in [[TUGboat]]: [http://www.tug.org/TUGboat/Articles/tb17-3/tb52rahtz.pdf TUGboat, Volume 17 1996, No. 3]): <source lang=latex> \documentclass{amsart} \usepackage[all, ps, dvips]{xy} % Loading the XY-Pic package % Using postscript driver for smoother curves \usepackage{color} % For invisible frame \begin{document} \thispagestyle{empty} % No page numbers \SelectTips{eu}{} % Euler arrowheads (tips) \setlength{\fboxsep}{0pt} % Frame box margin {\color{white}\framebox{{\color{black}$$ % Frame for margin \xymatrix{ %%% Diagram goes here %%% } $$}}} % end math, end frame \end{document} </source> === Convert to SVG === Once you have produced your diagram in LaTeX (or TeX), you can convert it to an SVG file using the following sequence of commands: <source lang=bash> pdflatex file.tex pdfcrop --clip file.pdf tmp.pdf pdf2svg tmp.pdf file.svg rm tmp.pdf </source> The [http://pdfcrop.sourceforge.net pdfcrop] and [http://www.cityinthesky.co.uk/opensource/pdf2svg pdf2svg] utilities are needed for this procedure. You can alternatively use [http://www.pdftron.com/pdf2svg/ pdf2svg] from PDFTron for the last step. If you do not have [[pdfTeX]] (which is unlikely) you can use the following commands to replace the first step (TeX → PDF): <source lang=bash> latex file.tex dvipdfm file.dvi </source> In general, you will not be able to get anywhere with diagrams without TeX and Ghostscript, and the <source lang="latex" enclose="none">inkscape</source> program is a useful tool for creating or modifying your diagrams by hand. There is also a utility <source lang="latex" enclose="none">pstoedit</source> which supports direct conversion from Postscript files to many vector graphics formats, but it requires a non-free plugin to convert to SVG, and regardless of the format, [[User:Ryan Reich|this editor]] has not been successful in using it to convert diagrams with diagonal arrows from TeX-created files. These programs are: * a working TeX distribution, such as [[TeX Live]] * [[Ghostscript]] * [[pstoedit]] * [[Inkscape]] === Upload the file === {{See also|commons:Commons:First steps/Upload form}} {{See also|Help:Contents/Images and media}} As the diagram is your own work, upload it to [[commons:|Wikimedia Commons]], so that all projects (notably, all languages) can use it without having to copy it to their language's Wiki. (If you've previously uploaded a file to somewhere other than Commons, to Commons.) ; Check size: Before uploading, check that the default size of the image is neither too large nor too small by opening in an [[SVG#Support in applications|SVG application]] and viewing at default size (100% scaling), otherwise adjust the <code>-y</code> option to <code>dvips</code>. ; Name: Make sure the file has a [[Wikipedia:Naming conventions|meaningful name]]. ; Upload: [[commons:Special:Userlogin|Login to Wikimedia Commons]], then <span class=plainlinks>[http://commons.wikimedia.org/w/index.php?title=Special:Upload&uselang=ownwork upload the file]</span>; for the '''Summary''', give a brief description. Now go to the [[Help:Image page|image page]] and add a [[commons:Commons:First steps/Quality and description#Good file descriptions|description]], including the '''source code''', using this template: <nowiki>{{</nowiki>Information |description = <nowiki>{{</nowiki>en|1= '''Description <nowiki>[[</nowiki>:en:Link to WP page|topic<nowiki>]]</nowiki>''' <nowiki>}}</nowiki> |source = <nowiki>{{</nowiki>own<nowiki>}}</nowiki>, created as per: <nowiki>[[</nowiki>:en:Help:Displaying a formula#Commutative diagrams<nowiki>]]</nowiki>; source code below. |date = '''The Creation Date, like 1999-12-31''' |author = '''<nowiki>[[</nowiki>User:YourUserName|Your Real Name<nowiki>]]</nowiki>''' |permission = <nowiki>{{</nowiki>self|PD-self '''(or [[commons:Licensing#Well-known licenses|other license]])''' |author = '''<nowiki>[[</nowiki>User:YourUserName|Your Real Name<nowiki>]]</nowiki>'''<nowiki>}}</nowiki> <nowiki>}}</nowiki> <br> ==TeX source== &lt;source lang=latex> '''% TeX source here''' &lt;/source> <nowiki>[[Category:Commutative diagrams]]</nowiki> <nowiki>[[Category:Xy-pic diagrams]]</nowiki> <nowiki>[[Category:Images with LaTeX source code]]</nowiki> ; Source code: * Include the source code in the [[Help:Image page|image page]], in the <code>Source</code> section of the <code><nowiki>{{</nowiki>[[commons:Template:Information|Information]]<nowiki>}}</nowiki></code> template, so that the diagram can be edited in future. * Include the complete <code>.tex</code> file, not just the fragment, so future editors do not need to reconstruct a compilable file. * You may optionally make the source code section collapsible, using the <code><nowiki>{{</nowiki>[[commons:Template:cot|cot]]<nowiki>}}</nowiki></code>/<code><nowiki>{{</nowiki>[[commons:Template:cob|cob]]<nowiki>}}</nowiki></code> templates. * (Don't include it in the Summary section, which is just supposed to be a summary.) ; License: The most common license for commutative diagrams is <code>[[commons:Template:PD-self|PD-self]]</code>; some use <code>[[commons:Template:PD-self|PD-ineligible]]</code>, especially for simple diagrams, or other licenses. Please ''do not'' use the [http://www.gnu.org/copyleft/fdl.html GFDL], as it requires the entire text of the GFDL to be attached to any document that uses the diagram. ; Description: If possible, link to a Wikipedia page relevant to the diagram. (The <code>1=</code> is necessary if you use nest templates within the description, and harmless otherwise.) ; Category: Include <code><nowiki>[[Category:Commutative diagrams]]</nowiki></code>, so that it appears in [[commons:Category:Commutative diagrams]]. There are also subcategories, which you may choose to use. ; Include image: Now include the image on the original page via <code><nowiki>[[File:Diagram.svg]]</nowiki></code> === Examples === A sample conforming diagram is [[commons:Image:PSU-PU.svg]]. == Unimplemented elements and workarounds == === <source lang="latex" enclose="none">\oiint</source> and <source lang="latex" enclose="none">\oiiint</source> === Elements which are not yet implemented are <source lang="latex" enclose="none">\oiint</source>, a two-fold integral <source lang="latex" enclose="none">\iint</source> {{nowrap|(<math>\iint</math>)}} with a circular curve through the centre of the two integrals, and similarly <source lang="latex" enclose="none">\oiiint</source>, a circular curve through three integrals. In contrast, <source lang="latex" enclose="none">\oint</source> {{nowrap|(<math>\oint</math>)}} exists for the single dimension (integration over a curved line within a plane or any space with higher dimension). These elements appear in many contexts: <source lang="latex" enclose="none">\oiint</source> denotes a [[surface integral]] over the closed 2d boundary of a 3d region (which occurs in much of 3d [[vector calculus]] and physical applications – like [[Maxwell's equations]]), likewise <source lang="latex" enclose="none">\oiiint</source> denotes integration over the closed 3d boundary (surface volume) of a 4d region, and they would be strong candidates for the next TeX version. As such there are a lot of workarounds in the present version. :{| class="toccolours collapsible collapsed" style="width:80%;text-align:left" !<source lang="latex" enclose="none">\oiint</source> and <source lang="latex" enclose="none">\oiiint</source> using currently implemented symbols |- | <source lang="latex" enclose="none">\oiint</source> looks like: * <math>\iint\limits_{S}\!\!\!\!\!\!\!\!\!\!\!\subset\!\supset \mathbf D \cdot \mathrm{d}\mathbf A</math>, which uses <source lang="latex" enclose="none">\iint</source> along with <source lang="latex" enclose="none">\subset</source> and <source lang="latex" enclose="none">\supset</source> (overdrawn after backspacing): : <source lang="text" enclose="none">\iint\limits_{S}\!\!\!\!\!\!\!\!\!\!\!\subset\!\supset \mathbf D \cdot \mathrm{d}\mathbf A</source> * <math>\int\!\!\!\!\int_{\partial V}\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\;\;\;\bigcirc\,\,\mathbf D\cdot\mathrm{d}\mathbf A</math>, which uses <source lang="latex" enclose="none">\int</source> twice (with some backward [[Kern (typography)|kerning]]) along with <source lang="latex" enclose="none">\bigcirc</source> (also overdrawn after backpacing) to produce a more consistent circle: : <source lang="text" enclose="none">\int\!\!\!\!\int_{\partial V}\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\;\;\;\bigcirc\,\,\mathbf D\cdot\mathrm{d}\mathbf A</source> <source lang="latex" enclose="none">\oiiint</source> (should also be preferably more tightly kerned) looks more or less like: * <math>\int\!\!\!\!\!\int\!\!\!\!\!\int_{\partial V}\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\;\;\;\subset\!\supset \mathbf D\cdot\mathrm{d}\mathbf A</math> which uses three \int symbols (with more backward kerning) with \subset and \supset (overdrawn after backspacing): : <source lang="text" enclose="none">\int\!\!\!\!\!\int\!\!\!\!\!\int_{\partial V}\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\;\;\;\subset\!\supset \mathbf D\;\cdot\mathrm{d}\mathbf A</source> * <math>\int\!\!\!\!\!\int\!\!\!\!\!\int_{\partial V}\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\;\;\;\bigcirc\,\,\mathbf D\;\cdot\mathrm{d}\mathbf A</math>, which uses three <source lang="latex" enclose="none">\int</source> symbols (with more backward kerning) along with <source lang="latex" enclose="none">\bigcirc</source> (also overdrawn after backspacing): : <source lang="text" enclose="none">\int\!\!\!\!\!\int\!\!\!\!\!\int_{\partial V}\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\!\;\;\;\bigcirc\,\,\mathbf D\;\cdot\mathrm{d}\mathbf A</source> |} However, since no standardisation exists as yet, any workaround like this (which uses many <source lang="latex" enclose="none">\!</source> symbols for backspacing) should be avoided, if possible. See below for a possibility using PNG image enforcement. Note that <source lang="latex" enclose="none">\iint</source> (the double integral) and <source lang="latex" enclose="none">\iiint</source> (the triple integral) are still not kerned as they should preferably be, and are currently rendered as if they were successive <source lang="latex" enclose="none">\int</source> symbols ; this is not a major problem for reading the formulas, even if the integral symbols before the last one do not have bounds, so it's best to avoid backspacing "hacks" as they may be inconsistent with a possible future better implementation of integrals symbols (with more precisely computed kerning positions). ==== <source lang="latex" enclose="none">\oiint</source> and <source lang="latex" enclose="none">\oiiint</source> as PNG images ==== These symbols are available as PNG images which are also integrated into two templates, {{tl|oiint}} and {{tl|oiiint}}, which take care of the formatting around the symbols. The templates have three parameters: ;preintegral: the text or formula immediately before the integral ;intsubscpt: the subscript below the integral ;integrand: the text or formula immediately after the integral ===== Examples ===== * [[Stokes' theorem]]: <code><nowiki>{{oiint | intsubscpt = <math>{\scriptstyle S}</math> | integrand=<math>( \nabla \times \bold{F} ) \cdot {\rm d}\bold{S} = \oint_{\partial S} \bold{F} \cdot {\rm d}\boldsymbol{\ell} </math> }}</nowiki></code> : {{oiint | intsubscpt = <math>{\scriptstyle S}</math> | integrand=<math>( \nabla \times \mathbf{F} ) \cdot {\rm d}\mathbf{S} = \oint_{\partial S} \mathbf{F} \cdot {\rm d}\boldsymbol{\ell} </math> }} * [[Ampère's circuital law|Ampère's law]] + correction: <code><nowiki>{{oiint | preintegral=<math>\oint_C \bold{B} \cdot {\rm d} \boldsymbol{\ell} = \mu_0 </math> | intsubscpt = <math>{\scriptstyle S}</math> | integrand = <math>\left ( \bold{J} + \epsilon_0\frac{\partial \bold{E}}{\partial t} \right ) \cdot {\rm d}\bold{S}</math> }}</nowiki></code> : {{oiint | preintegral=<math>\oint_{\partial S} \mathbf{B} \cdot {\rm d} \boldsymbol{\ell} = \mu_0 </math> | intsubscpt = <math>{\scriptstyle S}</math> | integrand = <math>\left ( \mathbf{J} + \epsilon_0\frac{\partial \mathbf{E}}{\partial t} \right ) \cdot {\rm d}\mathbf{S}</math> }} * Continuity of [[4-momentum]] flux (in [[general relativity]]):<ref>{{Cite book|title=Gravitation|author=J. A. Wheeler, C. Misner, K. S. Thorne| year=1973|publisher=W. H. Freeman & Co|edition=2nd|isbn=0-7167-0344-0}}</ref><code><nowiki> {{oiiint | preintegral=<math>\bold{P} = </math> | intsubscpt = <math>{\scriptstyle \partial \Omega}</math> | integrand = <math>\bold{T} \cdot {\rm d}^3\boldsymbol{\Sigma} = 0</math> }}</nowiki></code> : {{oiiint | preintegral=<math>\mathbf{P} = </math> | intsubscpt = <math>{\scriptstyle \partial \Omega}</math> | integrand = <math>\mathbf{T} \cdot {\rm d}^3\boldsymbol{\Sigma} = 0</math> }} ==== Oriented <source lang="latex" enclose="none">\oiint</source> and <source lang="latex" enclose="none">\oiiint</source> as PNG images ==== Some variants of <source lang="latex" enclose="none">\oiint</source> and <source lang="latex" enclose="none">\oiiint</source> have arrows on them to indicate the sense of integration, such as a line integral around a closed curve in the clockwise sense, and higher dimensional analogues. These are not implemented in {{TEX}} on Wikipedia either, although the template {{tl|intorient}} is available - see link for details. === <source lang="latex" enclose="none">\overarc</source> === <source lang="latex" enclose="none">\overarc</source> is not yet implemented to display the arc notation. However, there exists a workaround: use <source lang="text" enclose="none">\overset{\frown}{AB}</source>, which gives <math>\overset{\frown}{AB}</math> === <source lang="latex" enclose="none">\dddot</source> === <source lang="latex" enclose="none">\dddot</source> is not implemented in the TexVC renderer but does work in MatkJax. For a workaround use <source lang="text" enclose="none">\overset{...}{x}</source>, which gives <math>\overset{...}{x}</math>. == Syntax to avoid == The texvc processor accepts some non-standard syntax. These should be avoided as the MathJax based renderers do not support these syntax. ====Percentages==== Texvc accepts <source lang="latex" enclose="none">%</source> for representing percentages. This cause an error with MathJax and should be replaced with <source lang="latex" enclose="none">\%</source> in all renderers. ====\textrm==== In texvc spaces need to be represented inside the \textrm environment using <source lang="latex" enclose="none">\,</source> <source lang="latex" enclose="none">\ </source> and normal spaces are ignored i.e. <source lang="latex" enclose="none">\textrm{A\,B C}</source> would render as {{math|A BC}}. In mathjax \textrm is an alias for \text which is renders its argument as normal text, hence <source lang="latex" enclose="none">\textrm{A\,B C}</source> renders as {{math|A\,B C}}. To ensure compatibility between versions alway use the \text environment: <source lang="latex" enclose="none">\text{A B C}</source>. ====unicode characters==== Unicode characters like π work in MathML, and MathJax but not in texvc so should be avoided. == Examples of implemented TeX formulas == <div style="text-align: center;"> === Quadratic polynomial === <math>ax^2 + bx + c = 0</math> <br> <source lang="latex"><math>ax^2 + bx + c = 0</math></source> === Quadratic formula === <math>x={-b\pm\sqrt{b^2-4ac} \over 2a}</math> <br> <source lang="latex"><math>x={-b\pm\sqrt{b^2-4ac} \over 2a}</math></source> === Tall parentheses and fractions === <math>2 = \left( \frac{\left(3-x\right) \times 2}{3-x} \right)</math> <br> <source lang="text"><math>2 = \left( \frac{\left(3-x\right) \times 2}{3-x} \right)</math></source> <math>S_{\text{new}} = S_{\text{old}} - \frac{ \left( 5-T \right) ^2} {2}</math> <source lang="text"> <math>S_{\text{new}} = S_{\text{old}} - \frac{ \left( 5-T \right) ^2} {2}</math> </source> === Integrals === <math>\int_a^x \!\!\!\int_a^s f(y)\,dy\,ds = \int_a^x f(y)(x-y)\,dy</math> <br> <source lang="latex"><math>\int_a^x \!\!\!\int_a^s f(y)\,dy\,ds = \int_a^x f(y)(x-y)\,dy</math></source> === Matrices and determinants === <math>\det(\mathsf{A}-\lambda\mathsf{I}) = 0</math> <br> <source lang="text"><math>\det(\mathsf{A}-\lambda\mathsf{I}) = 0</math></source> === Summation === <math>\sum_{i=0}^{n-1} i</math> <br> <source lang="text"><math>\sum_{i=0}^{n-1} i</math></source> <math>\sum_{m=1}^\infty\sum_{n=1}^\infty\frac{m^2\,n}{3^m\left(m\,3^n+n\,3^m\right)}</math> <br> <source lang="text"><math>\sum_{m=1}^\infty\sum_{n=1}^\infty\frac{m^2\,n} {3^m\left(m\,3^n+n\,3^m\right)}</math></source> === Differential equation === <math>u'' + p(x)u' + q(x)u=f(x),\quad x>a</math> <br> <source lang="latex"><math>u'' + p(x)u' + q(x)u=f(x),\quad x>a</math></source> === Complex numbers === <math>|\bar{z}| = |z|, |(\bar{z})^n| = |z|^n, \arg(z^n) = n \arg(z)</math> <br> <source lang="text"><math>|\bar{z}| = |z|, |(\bar{z})^n| = |z|^n, \arg(z^n) = n \arg(z)</math></source> === Limits === <math>\lim_{z\to z_0} f(z)=f(z_0)</math> <br> <source lang="latex"><math>\lim_{z\to z_0} f(z)=f(z_0)</math></source> === Integral equation === <math>\phi_n(\kappa) = \frac{1}{4\pi^2\kappa^2} \int_0^\infty \frac{\sin(\kappa R)}{\kappa R} \frac{\partial}{\partial R} \left[R^2\frac{\partial D_n(R)}{\partial R}\right]\,dR</math> <br> <source lang="text"><math>\phi_n(\kappa) = \frac{1}{4\pi^2\kappa^2} \int_0^\infty \frac{\sin(\kappa R)}{\kappa R} \frac{\partial}{\partial R} \left[R^2\frac{\partial D_n(R)}{\partial R}\right]\,dR</math></source> === Example === <math>\phi_n(\kappa) = 0.033C_n^2\kappa^{-11/3},\quad \frac{1}{L_0}\ll\kappa\ll\frac{1}{l_0}</math> <br> <source lang="text"><math>\phi_n(\kappa) = 0.033C_n^2\kappa^{-11/3},\quad \frac{1}{L_0}\ll\kappa\ll\frac{1}{l_0}</math></source> === Continuation and cases === <math>f(x) = \begin{cases}1 & -1 \le x < 0 \\ \frac{1}{2} & x = 0 \\ 1 - x^2 & \text{otherwise}\end{cases}</math> <br> <source lang="latex"><math> f(x) = \begin{cases} 1 & -1 \le x < 0 \\ \frac{1}{2} & x = 0 \\ 1 - x^2 & \text{otherwise} \end{cases} </math></source> === Prefixed subscript === <math>{}_pF_q(a_1,\dots,a_p;c_1,\dots,c_q;z) = \sum_{n=0}^\infty \frac{(a_1)_n\cdots(a_p)_n}{(c_1)_n\cdots(c_q)_n}\frac{z^n}{n!}</math> <br> <source lang="text"> <math>{}_pF_q(a_1,\dots,a_p;c_1,\dots,c_q;z) = \sum_{n=0}^\infty \frac{(a_1)_n\cdots(a_p)_n}{(c_1)_n\cdots(c_q)_n} \frac{z^n}{n!}</math></source> === Fraction and small fraction === <math>\frac{a}{b}\ \tfrac{a}{b}</math> <source lang="text"><math>\frac{a}{b}\ \tfrac{a}{b}</math></source> === Area of a quadrilateral === <math>S=dD\,\sin\alpha\!</math> <source lang="latex"><math>S=dD\,\sin\alpha\!</math></source> === Volume of a sphere-stand === <math>V=\frac16\pi h\left[3\left(r_1^2+r_2^2\right)+h^2\right]</math> <source lang="latex"><math>V=\frac16\pi h\left[3\left(r_1^2+r_2^2\right)+h^2\right]</math></source> === Multiple equations === <math>\begin{align} u & = \tfrac{1}{\sqrt{2}}(x+y) \qquad & x &= \tfrac{1}{\sqrt{2}}(u+v)\\ v & = \tfrac{1}{\sqrt{2}}(x-y) \qquad & y &= \tfrac{1}{\sqrt{2}}(u-v) \end{align}</math> &nbsp; <source lang="text"><math>\begin{align} u & = \tfrac{1}{\sqrt{2}}(x+y) \qquad & x &= \tfrac{1}{\sqrt{2}}(u+v) \\ v & = \tfrac{1}{\sqrt{2}}(x-y) \qquad & y &= \tfrac{1}{\sqrt{2}}(u-v) \end{align}</math></source> </div> == See also == * [[Wikipedia:Manual of Style (mathematics)#Typesetting of mathematical formulae|Typesetting of mathematical formulae]] * Proposed [[m:Music markup]] and [[Help:Musical symbols]] * [[Table of mathematical symbols]] * [[Wikipedia:Rendering math]] * [[mw:Extension:Blahtex]], or [[Wikipedia talk:WikiProject Mathematics/Archive10#blahtex: a LaTeX to MathML converter|blahtex: a LaTeX to MathML converter for Wikipedia]] * [[commons:Category:Images which should use TeX]] == References == {{reflist}} == External links == {{Wikibooks|LaTeX}} * [http://www.maths.tcd.ie/~dwilkins/LaTeXPrimer/ A LaTeX tutorial] *[http://www.codecogs.com/latex/eqneditor.php LaTex online editor] * {{Citation |last= Doob |first= Michael |title= A Gentle Introduction to TeX: A Manual for Self-study |url= http://www.ctan.org/tex-archive/info/gentle/gentle.pdf |doi= }}. A paper introducing TeX — see page 39 onwards for a good introduction to the maths side of things. * {{Citation |last= Oetiker |first= Tobias |last2= Partl |first2= Hubert |last3= Hyna |first3= Irene |last4= Schlegl |first4= Elisabeth |title= The Not So Short Introduction to LaTeX 2<sub>&epsilon;</sub> |date= December 13, 2009 |edition= 4.27 |url= http://www.ctan.org/tex-archive/info/lshort/english/lshort.pdf |doi= }}. A paper introducing LaTeX — skip to page 49 for the math section. See page 63 for a complete reference list of symbols included in LaTeX and AMS-LaTeX. * [http://tug.ctan.org/tex-archive/info/symbols/comprehensive/symbols-letter.pdf The Comprehensive LaTeX Symbol List]—symbols not found here may be documented there. * [http://www.tex.ac.uk/tex-archive/info/symbols/comprehensive/symbols-a4.pdf Long list of many symbols] * [http://amath.colorado.edu/documentation/LaTeX/Symbols.pdf short list of common symbols] * [http://milde.users.sourceforge.net/LUCR/Math/mathpackages/esint-symbols.pdf The esint package for closed double integrals] * [http://mirror.ox.ac.uk/sites/ctan.org/macros/latex/contrib/esint/esint.pdf The esint package for closed double integrals] * [http://www.math.washington.edu/tex-archive/macros/latex/contrib/cancel/cancel.pdf cancel package] * [http://www.ams.org/tex/amslatex.html AMS-LaTeX guide]. * [http://us.metamath.org/symbols/symbols.html A set of public domain fixed-size math symbol bitmaps]. * [[MathML]]: A product of the [[W3C]] [http://www.w3.org/Math/ Math working group], is a low-level specification for describing mathematics as a basis for machine to machine communication. {{Help navigation}} [[Category:Wikipedia text help]] oaveuhpcxrm5s2uqzxou87r8r0ftmyp User:PGCX864 2 362886 4668916 4414345 2026-09-05T12:06:16Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668916 wikitext text/x-wiki == Unicode versions table (Current style) == {| |- style="vertical-align:middle" | {| border="1" cellpadding="3" cellspacing="0" style="border-collapse:collapse;margin:0 0 0 4em;" |----- style="text-align:center" !colspan="4"|Legend: |----- style="text-align:center" !colspan="4" {{Yes|Released versions}} |----- style="text-align:center" {{Yes}} !1.x !2.x !3.x !4.x |----- style="text-align:center" |style="background:#f66;{{text default color}};"|[[Unicode/Versions#Unicode 1.0|Unicode&nbsp;1.0]] |style="background:#ff6;{{text default color}}"|[[Unicode/Versions#Unicode 2.0|Unicode&nbsp;2.0]] |style="background:#6f6;{{text default color}};"|[[Unicode/Versions#Unicode 3.0|Unicode&nbsp;3.0]] |style="background:#6ff;{{text default color}};"|[[Unicode/Versions#Unicode 4.0|Unicode&nbsp;4.0]] |----- style="text-align:center" |style="background:#f96;{{text default color}};"|[[Unicode/Versions#Unicode 1.1|Unicode&nbsp;1.1]] |style="background:#cf6;{{text default color}};"|[[Unicode/Versions#Unicode 2.1|Unicode&nbsp;2.1]] |style="background:#6f9;{{text default color}};"|[[Unicode/Versions#Unicode 3.1|Unicode&nbsp;3.1]] |style="background:#6cf;{{text default color}};"|[[Unicode/Versions#Unicode 4.1|Unicode&nbsp;4.1]] |----- style="text-align:center" || || |style="background:#6fc;{{text default color}};"|[[Unicode/Versions#Unicode 3.2|Unicode&nbsp;3.2]] || |----- style="text-align:center" {{Yes}} !5.x !6.x !7.x !8.x |----- style="text-align:center" |style="background:#66f;{{text default color}};"|[[Unicode/Versions#Unicode 5.0|Unicode&nbsp;5.0]] |style="background:#f6f;{{text default color}};"|[[Unicode/Versions#Unicode 6.0|Unicode&nbsp;6.0]] |style="background:#298;{{text default color}};"|[[Unicode/Versions#Unicode 7.0|Unicode&nbsp;7.0]] |style="background:#163;{{text default color}};"|[[Unicode/Versions#Unicode 8.0|Unicode&nbsp;8.0]] |----- style="text-align:center" |style="background:#96f;{{text default color}};"|[[Unicode/Versions#Unicode 5.1|Unicode&nbsp;5.1]] |style="background:#98c;{{text default color}};"|[[Unicode/Versions#Unicode 6.1|Unicode&nbsp;6.1]] || || |----- style="text-align:center" |style="background:#c6f;{{text default color}};"|[[Unicode/Versions#Unicode 5.2|Unicode&nbsp;5.2]] |style="background:#a86;{{text default color}};"|[[Unicode/Versions#Unicode 6.2|Unicode&nbsp;6.2]] || || |----- style="text-align:center" || |style="background:#892;{{text default color}};"|[[Unicode/Versions#Unicode 6.3|Unicode&nbsp;6.3]] || || |----- style="text-align:center" !colspan="4" style="background:plum;{{text default color}}"|Future versions |----- style="text-align:center" |style="background:#713;{{text default color}};"|[[Unicode/Versions#Unicode 9.0|Unicode&nbsp;9.0]] |style="background:#06f;{{text default color}}"|[[Unicode/Versions#Unicode 10.0|Unicode&nbsp;10.0]] |colspan="2" style="background:#666;color:#fff;"|Reserved |----- style="text-align:center" |colspan="2" style="background:#fff;{{text default color}}"|Private use |colspan="2" style="background:#000;color:#fff;"|Noncharacter |} |} == Unicode versions table (New style) == {| |- style="vertical-align:middle" | {| border="1" cellpadding="3" cellspacing="0" style="border-collapse:collapse;margin:0 0 0 4em;" |----- style="text-align:center" !colspan="4"|Legend: |----- style="text-align:center" !colspan="4" {{Yes|Released versions}} |----- style="text-align:center" {{Yes}} !1.x !2.x !3.x !4.x |----- style="text-align:center" |style="background:#f33;{{text default color}};"|[[Unicode/Versions#Unicode 1.0|Unicode&nbsp;1.0]] |style="background:#6ff;{{text default color}};"|[[Unicode/Versions#Unicode 2.0|Unicode&nbsp;2.0]] |style="background:#ff3;{{text default color}};"|[[Unicode/Versions#Unicode 3.0|Unicode&nbsp;3.0]] |style="background:#9f6;{{text default color}};"|[[Unicode/Versions#Unicode 4.0|Unicode&nbsp;4.0]] |----- style="text-align:center" |style="background:#f63;{{text default color}};"|[[Unicode/Versions#Unicode 1.1|Unicode&nbsp;1.1]] |style="background:#6cf;{{text default color}};"|[[Unicode/Versions#Unicode 2.1|Unicode&nbsp;2.1]] |style="background:#fc3;{{text default color}}"|[[Unicode/Versions#Unicode 3.1|Unicode&nbsp;3.1]] |style="background:#9c6;{{text default color}}"|[[Unicode/Versions#Unicode 4.1|Unicode&nbsp;4.1]] |----- style="text-align:center" || || |style="background:#f93;{{text default color}}"|[[Unicode/Versions#Unicode 3.2|Unicode&nbsp;3.2]] || |----- style="text-align:center" {{Yes}} !5.x !6.x !7.x !8.x |----- style="text-align:center" |style="background:#99f;{{text default color}}"|[[Unicode/Versions#Unicode 5.0|Unicode&nbsp;5.0]] |style="background:#f9c;{{text default color}}"|[[Unicode/Versions#Unicode 6.0|Unicode&nbsp;6.0]] |style="background:#396;{{text default color}}"|[[Unicode/Versions#Unicode 7.0|Unicode&nbsp;7.0]] |style="background:#963;{{text default color}}"|[[Unicode/Versions#Unicode 8.0|Unicode&nbsp;8.0]] |----- style="text-align:center" |style="background:#96f;{{text default color}}{{text default color}};"|[[Unicode/Versions#Unicode 5.1|Unicode&nbsp;5.1]] |style="background:#f6c;{{text default color}}"|[[Unicode/Versions#Unicode 6.1|Unicode&nbsp;6.1]] || || |----- style="text-align:center" |style="background:#93f;{{text default color}}"|[[Unicode/Versions#Unicode 5.2|Unicode&nbsp;5.2]] |style="background:#f3c;{{text default color}}"|[[Unicode/Versions#Unicode 6.2|Unicode&nbsp;6.2]] || || |----- style="text-align:center" || |style="background:#f0c;{{text default color}}"|[[Unicode/Versions#Unicode 6.3|Unicode&nbsp;6.3]] || || |----- style="text-align:center" !colspan="4" style="background:plum;{{text default color}}"|Future versions |----- style="text-align:center" |style="background:#933;{{text default color}}"|[[Unicode/Versions#Unicode 9.0|Unicode&nbsp;9.0]] |style="background:#36f;{{text default color}}"|[[Unicode/Versions#Unicode 10.0|Unicode&nbsp;10.0]] |colspan="2" style="background:#666;color:#fff;"|Reserved |----- style="text-align:center" |colspan="2" style="background:#fff;{{text default color}}"|Private use |colspan="2" style="background:#000;color:#fff;"|Noncharacter |} |} hakf93tjnge4zm6vewq7cly4ja3q8e9 User:Williammacewen2 2 367055 4668991 4668913 2026-09-05T19:04:09Z ShakespeareFan00 46022 4668991 wikitext text/x-wiki {{userpage}} <div style="padding:1em; border: ; background-color:;color:inherit;-moz-border-radius:15px; margin-left: 6px; margin-right: 6px; ; text-align: center"> [[Image:Crystal message2.png|24px]] '''[http://en.wikibooks.org/w/index.php?title=User_talk:williammacewen&action=edit&section=new Leave me a new message here]''' </div> Hi! My name is '''William MacEwen'''. == About religion == {{cquote2|Being crafty, I caught you with guile...for if the truth of God hath more abounded through my LIE unto his glory; why yet am I also adjudged a sinner?|[[w:St Paul|St Paul]]||90|90}} {{cquote2|What profit has not that fable of Jesus brought us!|[[w:Pope Leo X|Pope Leo X]]||90|90}} [[Image:Uthman Koran Taschkent a.jpg|thumb|center|250px|The Samarkand Quran [[w:carbon dating|carbon dated]] to the [[w:7th century|7th century]]]] The [[w:Early Quranic manuscripts|oldest complete Quran]] manuscript is the [[w:Samarkand Kufic Quran|Samarkand Codex]]. Based on [[w:orthography|orthographic]] and [[w:Palaeography|palaeographic]] studies, the manuscript probably dates the 8th or 9th century CE.<ref>{{cite web|title=The “Qur'ān Of ʿUthmān” At Tashkent (Samarqand), Uzbekistan, From 2nd Century Hijra|url=http://www.islamic-awareness.org/Quran/Text/Mss/samarqand.html|accessdate=5 September 2013}}</ref><ref> E. A. Rezvan, "On The Dating Of An “'Uthmanic Qur'an” From St. Petersburg", ''Manuscripta Orientalia'', 2000, Volume 6, No. 3, pp. 19-22.[http://www.kunstkamera.ru/files/lib/978-5-88431-178-7/978-5-88431-178-7_12.pdf]</ref> Radio-carbon dating showed a 95.4% probability of a date between 595 CE and 855 CE.<ref> E. A. Rezvan, "On The Dating Of An “'Uthmanic Qur'an” From St. Petersburg", ''Manuscripta Orientalia'', 2000, Volume 6, No. 3, pp. 19-22.[http://www.kunstkamera.ru/files/lib/978-5-88431-178-7/978-5-88431-178-7_12.pdf]</ref> <p align="right"><span style="font-size:250%">وتَرَى الجِبَالَ تَحسَبُها جَامِدةً وهِيَ تَمُرُّ مَرَّ السَّحَاب</span></p> <p align="left"><span style="font-size:156%">And you see the mountains thinking they are frozen but they move like the clouds.</span></p> <div align="left">– [[w:Quran|Quran]] [http://quran.com/27/88 27:88]</div> <br> <p align="right"><span style="font-size:250%">وهو الذى خَلَقَ اللَيلَ والنَهَارَ والشَمسَ والقَمَرَ كُلٌّ فِى فَلَكٍ يَسبَحُون</span></p> <p align="left"><span style="font-size:156%">And he is the one who created the night and the day and the sun and the moon all float in an orbit.</span></p> <div align="left">– Quran [http://quran.com/21/33 21:33]</div> <br> <p align="right"><span style="font-size:250%">لا الشَمسُ يَنبَغِى لهَا أَن تُدرِكَ القَمَرَ ولا الَيلُ سَابِقٌ النَهَارِ وكُلٌّ فِى فَلَكٍ يَسبَحُون</span></p> <p align="left"><span style="font-size:156%">It does not suit the sun to overtake the moon and the night does not come before the day and both [the sun and the moon] are floating in an orbit.</span></p> <div align="left">– Quran [http://quran.com/36/40 36:40]</div> <br> <p align="right"><span style="font-size:250%">والشَمسُ تَجرِى لِمُستَقَرٍّ لهَا ذلك تَقدِيرُ العَزِيزِ العَلِيم</span></p> <p align="left"><span style="font-size:156%">The sun will move until a stopping point for it, that is the measure of the powerful and knowing one.</span></p> <div align="left">– Quran [http://quran.com/36/38 36:38]</div> == How do I conjugate Arabic verbs? == === Conjugation of weak verb رَمَى ramaa to shoot === ==== first form ==== ===== active ===== {| border=1 cellpadding=7 cellspacing=1 |- bgcolor=#eeeeee ! align=left | Number ! align=left | English pronoun ! align=left | Arabic pronoun ! align=left | perfect ! align=left | indicative ! align=left | subjunctive ! align=left | jussive ! align=left | emphatic I ! align=left | emphatic II ! align=left | simple imperative ! align=left | emphatic imperative I ! align=left | emphatic imperative II ! align=left | agent noun |- |3rd masc. sing. ||he||هو|| رَمَى||يَرْمِيْ||يَرْمِيَ||يَرْمِ||يَرْمِيَنَّ||يَرْمِيَنْ||n/a||n/a||n/a||رَامٍ |- | 3rd fem. sing. ||she||هي||رَمَتْ||تَرْمِي||ترمِيَ||ترمِ||ترمِيَنَّ||تَرْمِيَنْ||n/a||n/a||n/a||رَامِيَةٌ |- |3rd masc. dual ||||هما||رَمَيَا||يَرْمِيَانِ||يَرْمِيَا||[[w:Ibid|ibid]]||يَرْمِيَانِّ||[https://en.wikipedia.org/wiki/N/a n/a]||n/a||n/a||/n/a|| |- |2nd fem. dual||||هما||رَمَتَا||تَرْمِيَانِ||تَرْمِيَا||ibid.||ترمِيَانِّ||n/a||n/a||n/a||n/a|| |- |3rd masc. plur.||they||هم||رَمَوْا||يَرْمُونَ||يرمُوا||ibid.||يَرْمُنَّ||يرمُنْ||n/a||n/a||n/a|| |- |3rd fem. plur. ||||هنّ||رَمَيْنَ||يَرْمِيْنَ||ibid.||ibid||يَرْمِيْنَانِّ||n/a||n/a||n/a||n/a|| |- |2nd masc. sing.||[https://en.wikipedia.org/wiki/Thou thou]||أنتَ||رَمَيْتَ||تَرْمِيْ||ترْمِيَ||ترْمِ||تَرْمِيَنَّ||تَرْمِيَنْ||اِرْمِ||إِرْمِيَنَّ||اِرْمِيَنْ|| |- |2nd fem. sing. ||||أنتِ||رَمَيْتِ||تَرْمِيْنَ||تَرْمِيْ||ibid||تَرْمِنَّ||تَرْمِنْ||اِرْمِيْ||اِرْمِنَّ||اِرْمِنْ|| |- |2nd dual||||أنتما||رَمَيْتُمَا||تَرْمِيَانِ||تَرْمِيَا||ibid||تَرْمِيَانِّ||n/a||اِرْمِيَا||اِرْمِيَانِّ||n/a|| |- |2nd masc. plur. ||[https://en.wikipedia.org/wiki/Ye_(pronoun) ye]||أنتم||رَمَيْتُمْ||تَرْمُوْنَ||تَرْمُوْا||ibid||تَرْمُنَّ||تَرْمُنْ||اِرْمُوْا||اِرْمُنَّ||إِرْمُنْ|| |- |2nd fem. plur. ||||أنتنّ||رَمَيْتُنَّ||تَرْمِيْنَ||ibid.||ibid||تَرْمِيْنَانِّ||n/a||إِرْمِيْنَ||اِرْمِيْنَانِّ||n/a|| |- |1st sing.||I||أنا||رَمَيْتُ||اَرْمِيْ||أَرْمِيَ||اَرْمِ||اَرْمِيَنَّ||اَرْمِيَنْ||n/a||n/a||n/a|| |- |1st plur.||we||نحن||رَمَيْنَا||نَرْمِيْ||نَرْمِيَ||نَرْمِ||نَرْمِيَنَّ||نَرْمِيَنْ||n/a||n/a||n/a|| |} === Conjugation of weak verb مَدَّ madda to extend === ==== first form ==== ===== active ===== {| border=1 cellpadding=7 cellspacing=1 |- bgcolor=#eeeeee ! align=left | Number ! align=left | English pronoun ! align=left | Arabic pronoun ! align=left | perfect ! align=left | indicative ! align=left | subjunctive ! align=left | jussive ! align=left | emphatic 1 ! align=left | emphatic 2 ! align=left | simple imperative ! align=left | imperative emphatic 1 ! align=left | imperative emphatic 2 ! align=left | agent noun |- |3rd masc. sing. ||he||هو||مَدَّ||يمُدُّ||يَمُدَّ||يَمْدُدْ||يَمُدَّنَّ||يمُدًّا||[https://en.wikipedia.org/wiki/N/a na]||na||na||مَادَّ |- | 3rd fem. sing. ||she||هی||مَدَّتْ||تمُدُّ||تمُدَّ||تَمْدُدْ||تمُدَّنَّ||تَمُدًّا||na||na||na||مَادَّة |- |3rd masc. dual ||||هما||مَدَّا~~ |- |2nd fem. dual||||هما||رَمَتَا||تَرْمِيَانِ||تَرْمِيَاتَرْمِيَا||ibid.||ترمِيَانِّ||n/a||n/a||n/a||n/a|| |- |3rd masc. plur.||they||هم||رَمَوْا||يَرْمُونَ||يرمُوا||ibid.||يَرْمُنَّ||يرمُنْ||n/a||n/a||n/a|| |- |3rd fem. plur. ||||هنّ||رَمَيْنَ||يَرْمِيْنَ||ibid.||ibid||يَرْمِيْنَانِّ||n/a||n/a||n/a||n/a|| |- |2nd masc. sing.||[https://en.wikipedia.org/wiki/Thou thou]||أنتَ||رَمَيْتَ||تَرْمِيْ||ترْمِيَ||ترْمِ||تَرْمِيَنَّ||تَرْمِيَنْ||اِرْمِ||إِرْمِيَنَّ||اِرْمِيَنْ|| |- |2nd fem. sing. ||||أنتِ||رَمَيْتِ||تَرْمِيْنَ||تَرْمِيْ||ibid||تَرْمِنَّ||تَرْمِنْ||اِرْمِيْ||اِرْمِنَّ||اِرْمِنْ|| |- |2nd dual||||أنتما||رَمَيْتُمَا||تَرْمِيَانِ||تَرْمِيَا||ibid||تَرْمِيَانِّ||n/a||اِرْمِيَا||اِرْمِيَانِّ||n/a|| |- |2nd masc. plur. ||[https://en.wikipedia.org/wiki/Ye_(pronoun) ye]||أنتم||رَمَيْتُمْ||تَرْمُوْنَ||تَرْمُوْا||ibid||تَرْمُنَّ||تَرْمُنْ||اِرْمُوْا||اِرْمُنَّ||إِرْمُنْ|| |- |2nd fem. plur. ||||أنتنّ||رَمَيْتُنَّ||تَرْمِيْنَ||ibid.||ibid||تَرْمِيْنَانِّ||n/a||إِرْمِيْنَ||اِرْمِيْنَانِّ||n/a|| |- |1st sing.||I||أنا||رَمَيْتُ||اَرْمِيْ||أَرْمِيَ||اَرْمِ||اَرْمِيَنَّ||اَرْمِيَنْ||n/a||n/a||n/a|| |- |1st plur.||we||نحن||رَمَيْنَا||نَرْمِيْ||نَرْمِيَ||نَرْمِ||نَرْمِيَنَّ||نَرْمِيَنْ||n/a||n/a||n/a|| |} == Plurals == {| border=1 cellpadding=7 cellspacing=1 |- bgcolor= #FFF8E7 ! align=left | <p align="left"><span style="font-size:222%">شكل</span></p><br>Form ! align=left | <p align="left"><span style="font-size:222%"><span style="color: #E86100;">شرط</span></span></p><br><span style="font-size:125%"><span style="color: #E86100;">Condition</span></span> ! align=left | <p align="left"><span style="font-size:222%">جمع</span></p><br>Plural ! align=left | <p align="left"><span style="font-size:222%">نادر؟</span></p><br>Rare? ! align=left | <p align="left"><span style="font-size:222%">مثال مفرد</span></p><br>example singular ! align=left | <p align="left"><span style="font-size:222%">مثال جمعه</span></p><br>example its plural ! align=left | <p align="left"><span style="font-size:222%">ثنية</span></p><br>Exception |- |<span style="font-size:222%">فُعْلَة</span>||||<span style="font-size:222%">فُعَل</span>||||تُحْفَہ<br>قُبَّہ<br>صُورَہ||تُحَف<br>قُبَب<br>صُوَر |- |<span style="font-size:222%">فُعْلَى فُعْلا</span>||fem. superl. of اَفْعَلُ||<span style="font-size:222%">فُعَل</span>||||الكُبْرَى<br>العُلْيَا<br>اُخْرَى||الكُبَرُ<br>العُلَى<br>اُخَرُ |- |<span style="font-size:222%">فَعْلَة</span>||esp. from verbs of rad و and ي|| <span style="font-size:222%">فُعَل</span>||||قَرْيَہ<br>دَوْلَہ<br>نَوْبَہ||قُرًى<br>دُوَل<br>نُوَب |- |<span style="font-size:222%">فِعْلَة</span>||from verbs of rad. و and ي||<span style="font-size:222%">فُعَل</span>||{{yes}}||لِحْيَہ<br>حِلْيَہ<br>||لُحًى<br>حُلًى |- |<span style="font-size:222%">اَفْعَلُ</span>||not comparative and superl.||فُعْلٌ||||اَعْمَى<br>اَصَمُّ<br>اَحْدَبُ<br>اَبْيَضُ<br>اَسْوَدُ||عُمْي<br>صُمّ<br>حُدْب<br>بِيْض<ref>for <span style="font-size:222%">بُيْض</span></ref><br>سُود |- |<span style="font-size:222%">فَعْلَاءُ</span>||fem. of اَفْعَلُ not comparative and superl.||فُعْل||||صفراءُ<br>عَرجَاءُ<br>بَيْدَاءُ||صُفْر<br>عُرْج<br>بِيد||جَمْعَاءُ كَتْعَاءُ بَصْعَاءُ بَتْعَاءُ fem. of اَجْمَعُ &c. make جُمَعُ كُتَعُ بُصَعُ بُتَعُ |- | فُعَال<br>فِعَال<br>فَعَال||from verbs of rad و and ي||فُعْل||||عَوَان<br>بِوَان<br>خِوَان<br>اُوَار||عُون<br>بُون<br>خُون<br>اُور||These may be contractions from original فُعُل as eg *سِوَاك has both for pl. سُوك and سُوُك |- |فَاعِل||from verbs of rad و and ي||فُعْل||||عَائِذ<br>هَائِد||عُوذ<br>هُود |- |فَاعِل||from verbs not of و and ي||فُغْل||{{yes}}||فَارِه<br>بَازِل||فُرْه<br>بُزْل||These may be contractions from فُرُه and بُزُل see also preceding. |- |فَعَال<br>فِعَال<br>فُعَال||not from verbs of rad و and ي||فُعُل||||رَدَاح<br>قَذَال<br>كِتَاب<br>فِرَاش<br>سِوَاك<br>قُرَاد||رُدُح<br>قُذُل<br>كُتُب<br>فُرُش<br>سُوُك<br>قُرُد |- | فَعِيل<br>فَعِيلَة<br>فَعُول||not from verbs of rad و and ي||فُعُل||||قَضِيب<br>كَثِيب<br>سَرِير<br>سَفِينَة<br>صَحِيفَة<br>عَمُود<br>رَسُول|| |- | فَعِيل<br>فَعُول||verbal adjectives not having a passive signification and not from verbs of rad و and ي||فُعُل||||نَذِير<br>صَبُور<br>ذَلُول<br>غَيُور<br>بَيُوض |- | فَعْل<br>فَعَل<br>فَعَلَة<br>فَعِل<br>فَعُل||||فُعُل||{{yes}}||سَقْف<br>سَحْل<br>اَسَد<br>فَلَك<br>بَدَنَة<br>خَشَبَة<br>اَجَمَة<br>نَمِر<br>خَشِن<br>ضَبُع||سُقُف<br>سُحُل<br>اُسُد<br>فُلُك<br>بُدُن<br>خ<br>اُجُم<br>نُمُر<br>خُشُن<br>ضَبُع |} <p align="right"><span style="font-size:222%">شرط</span></p> <p align="center"><span style="font-family: Serif; font-size: 20px; text-shadow: silver 0.2em 0.2em 0.1em;">[[User:williammacewen#Plurals|<span style="color=" #954535"">return to top</span>]]</span></p> == Gloss == === nouns === <div style="background: white;{{Text default color}}; border: blue; padding: 2px;"> {|class="wikitable sortable" border="1" |- </div> ! scope="col" width="150px" | en ! scope="col" width="100px" class="unsortable" | singular ! scope="col" width="100px" class="unsortable" | plural |- |[[w:cat|cat]] |<p align="right">male ~ <span style="font-size:222%">هِرّ</span></p> <p align="right">female ~ <span style="font-size:222%">هِرَّة</span></p> |<p align="right"><span style="font-size:222%">هِرَرَة</span></p> <p align="right"><span style="font-size:222%">هِرَر</span></p> |- |[[w:horse|horse]] |<p align="right"><span style="font-size:222%">فَرَس</span></p> |<p align="right"><span style="font-size:222%">أَفرَاس</span></p> <p align="right">pl of mult<ref> plural of multitude. An Arabic [[w:grammar|grammatical]] class which is used ''exclusively'' for a [[w:multitude|multitude]] of objects (viz. hundreds, thousands etc., and ''not'' six or seven for which the plural of paucity q.v., is used</ref> <span style="font-size:222%">الخَيل</span></p> |- |[[w:husband|husband]] |<p align="right"><span style="font-size:222%">بَعل</span></p> <p align="right"><span style="font-size:222%">سَيِّد</span></p> |<p align="right"><span style="font-size:222%">بُعُولَة</span></p> <p align="right"><span style="font-size:222%">سَادَة</span></p> |- |that very night <ref>that night</ref> it carried him to<ref>towards</ref> the coast of the aforementioned<ref>just now mentioned, just mentioned</ref> island |<p align="right"><span style="font-size:222%">فاحتَمَلَه مِن لَيلَتِه إلى ساحلِ الجَزِيرَةِ الأُخرَى المتقدّم ذكرها</span></p> |- | bag, receptacle, repository |<p align="right"><span style="font-size:222%">وِعَاء</span></p> |<p align="right"><span style="font-size:222%">أَوعِيَة</span></p> |- | bag, or other receptacle, (S, * Msb, K, TA,) for travelling-provisions, (S, K, TA,) or for dates, made of leather (Msb) |<p align="right"><span style="font-size:222%">مِزوَد</span></p> ||<p align="right"><span style="font-size:222%">مَزَاوِدُ</span></p> |- | leathern water bag, one of a pair which is borne by a camel or other beast |<p align="right"><span style="font-size:222%">مَزَادَةٌ</span></p> |<p align="right"><span style="font-size:222%">مَزَائِدُ</span></p> <p align="right"><span style="font-size:222%">مَزَاوِدُ</span></p> <p align="right">good <span style="font-size:222%">مَزَايِدُ</span></p> |- |age |<p align="right"><span style="font-size:222%">عمر سنوات</span></p> |<p align="right"><span style="font-size:222%">أَعْمَار</span></p> |- |age |<p align="right"><span style="font-size:222%">سنّ سنوات</span></p> |<p align="right"><span style="font-size:222%">أَسْنَان</span></p> |- |[[w:car|car]] |<p align="right"><span style="font-size:222%">عَرَبَة</span></p> |<p align="right"><span style="font-size:222%">عَرَبَات</span></p> |- |[[w:vehicle|car]], vehicle |<p align="right"><span style="font-size:222%">مَركَبَة</span></p> |<p align="right"><span style="font-size:222%">مَركَبَات</span></p> |- |[[w:car|car]], cart, carriage, wheeled [[w:carriage|carriage]] |<p align="right"><span style="font-size:222%">عَجَلَة</span></p> |<p align="right">coll. generic noun <span style="font-size:222%">عَجَل</span></p><p align="right">pl. of pauc. <span style="font-size:222%">اَعجَال</span></p><p align="right">pl of multitude <span style="font-size:222%">عِجَال</span></p> |- |coast, shore, sea-shore, sea-coast, seaboard |<p align="right"><span style="font-size:222%">سَاحِل</span></p> |<p align="right"><span style="font-size:222%">سَوَاحِلُ</span></p> |- |candlestick, lamp, chandelier, lantern |<p align="right"><span style="font-size:222%">قِندِيل</span></p><p align="right"><ref>syn. <span style="font-size:222%">مَشعَل</span></ref></p> <p align="right"><span style="font-size:222%">قَندِيل</span></p> |<p align="right"><span style="font-size:222%">قَنَادِيلُ</span></p> |- |lamp, lantern, [[w:torch|torch]], light |<p align="right"><span style="font-size:222%">مَشعَل</span></p> |<p align="right"><span style="font-size:222%">مَشَاعِلُ</span></p> |- |problem, question, conundrum |<p align="right"><span style="font-size:222%">مَسْاَلَة</span></p> |<p align="right"><span style="font-size:222%">مَسَائِلُ</span></p> |- |[[w:artery|artery]], pulsating veins, which spring from the heart |<p align="right"><span style="font-size:222%">شَِريَان</span></p> |<p align="right"><span style="font-size:222%"></span></p> |- |[[w:mule|mule]] |<p align="right"><span style="font-size:222%">بَغْل</span></p> |<p align="right">pl. of pauc. <span style="font-size:222%">#$#@</span></p><p align="right">pl of multitude <span style="font-size:222%">بِغَال</span></p> |- |he goat, male goat |<p align="right"><span style="font-size:222%">تَيْسٌ</span></p> |<p align="right">pl. of pauc. <span style="font-size:222%">#$#@</span></p><p align="right">pl of multitude <span style="font-size:222%">تُيُوس</span></p> |- |she goat, female goat |<p align="right"><span style="font-size:222%">عَنْزَة</span></p> <p align="right"><span style="font-size:222%">عَنْزٌ</span></p> |<p align="right">pl. of pauc. <span style="font-size:222%">#$#@</span></p><p align="right">pl of multitude <span style="font-size:222%">عِنَازٌ/عُنُوز</span></p> |- |} </div> <p align="center"><span style="font-family: Arial Black; font-size: 19px; text-shadow: silver 0.2em 0.2em 0.1em;">[[User:williammacewen#Gloss|<span style="color: #954535;">Return to top</span>]]</span></p> <nowiki /> === verbs === <div style="background: white;{{Text default color}}; border: blue; padding: 2px;"> {|class="wikitable sortable" border="1" |- </div> ! scope="col" width="215px" | en ! scope="col" width="190px" class="unsortable" | past ! scope="col" width="110px" class="unsortable" | present ! scope="col" width="110px" class="unsortable" | infinitive ! scope="col" width="110px" class="unsortable" | 2 ! scope="col" width="110px" class="unsortable" | 3 ! scope="col" width="110px" class="unsortable" | 6 ! scope="col" width="110px" class="unsortable" | 4 ! scope="col" width="110px" class="unsortable" | 8 ! scope="col" width="110px" class="unsortable" | 10 ! scope="col" width="110px" class="unsortable" | more |- |know trns.<ref>[[w:transitive verb|transitive]]</ref> , he knew it, |<p align="right"><span style="font-size:222%">دَرَى الشيءَ</span></p><p align="right"><span style="font-size:222%">دَرَى به</span></p> |<p align="right"><span style="font-size:222%">يدرِي</span></p> |<p align="right"><span style="font-size:222%">دَرْي</span><span style="font-size:222%">دِريَة</span><span style="font-size:222%">دِرَايَة</span><span style="font-size:222%">دَرَيَان</span><span style="font-size:222%">دُرِيّ</span></p> |- |[[w:eating|eat, consume]] trns |<p align="right"><span style="font-size:222%">A</span></p> |<p align="right"><span style="font-size:222%">U</span></p> |<p align="right"><span style="font-size:222%">اَكْل</span></p> |- |[[w:silence|silence]], he was became silent, mute, speechless<ref>used exclusively for him who has the power or faculty to speak but abstains from making use of it, ie he 'ceased or stopped speaking, he was or became silent intentionally. antonym <span style="font-size:222%">نطق</span> synonym <span style="font-size:222%">صمت</span></ref> |<p align="right"><span style="font-size:222%">A</span></p> |<p align="right"><span style="font-size:222%">U</span></p> |<p align="right"><span style="font-size:222%">سُكُوت</span><span style="font-size:222%">سُكَات</span></p> |- |[[w:bark (sound)|bark]], it (a [[w:dog|dog]]) barked, to bark على ~, at~ |<p align="right"><span style="font-size:222%">A</span></p> |<p align="right"><span style="font-size:222%">I, A<ref>lane says according to Msb. the former is more common, Steingass (and hans wehr) list A first..</ref></span></p> |<p align="right"><span style="font-size:222%">نَبْح</span><span style="font-size:222%">نُباح</span><span style="font-size:222%">نِباح</span><span style="font-size:222%">نَبِيح</span></p> |infin n. <span style="font-size:222%">تَنبَاح</span> (intensive) | |to answer each others barks (dogs at night)<br/> |4, 10 incite to barking, rouse the dogs (by imitating a bark). | | |<span style="font-size:222%">نبّاح</span> barker yelper |- |} </div> <p align="center"><span style="font-family: Arial Black; font-size: 19px; text-shadow: silver 0.2em 0.2em 0.1em;">[[User:williammacewen#Gloss|<span style="color: #954535;">Return to top</span>]]</span></p> {| border="1" |+ ! scope="col" | <span style="font-family: Andalus; font-size: 21px; text-shadow: silver 0.2em 0.2em 0.1em;color:#004225">[[user:williammacewen#Gloss]]</span> |} == Chapter 10 (yunus jonah) of the Koran revealed in mecca == === without diacritics === <p align="right"><span style="font-family: Arabic Typesetting; font-size: 50px;">الر تلك آيات الكتاب الحكيم (1) أكان للناس عجبا أن أوحينا إلى رجل منهم أن أنذر الناس وبشر الذين آمنوا أن لهم قدم صدق عند ربهم قال الكافرون إن هذا لساحر مبين (2) إن ربكم الله الذي خلق السماوات والأرض في ستة أيام ثم استوى على العرش يدبر الأمر ما من شفيع إلا من بعد إذنه ذلكم الله ربكم فاعبدوه أفلا تذكرون (3) إليه مرجعكم جميعا وعد الله حقا إنه يبدأ الخلق ثم يعيده ليجزي الذين آمنوا وعملوا الصالحات بالقسط والذين كفروا لهم شراب من حميم وعذاب أليم بما كانوا يكفرون (4) هو الذي جعل الشمس ضياء والقمر نورا وقدره منازل لتعلموا عدد السنين والحساب ما خلق الله ذلك إلا بالحق يفصل الآيات لقوم يعلمون (5) إن في اختلاف الليل والنهار وما خلق الله في السماوات والأرض لآيات لقوم يتقون (6) إن الذين لا يرجون لقاءنا ورضوا بالحياة الدنيا واطمأنوا بها والذين هم عن آياتنا غافلون (7) أولئك مأواهم النار بما كانوا يكسبون (8) إن الذين آمنوا وعملوا الصالحات يهديهم ربهم بإيمانهم تجري من تحتهم الأنهار في جنات النعيم (9) دعواهم فيها سبحانك اللهم وتحيتهم فيها سلام وآخر دعواهم أن الحمد لله رب العالمين (10) ولو يعجل الله للناس الشر استعجالهم بالخير لقضي إليهم أجلهم فنذر الذين لا يرجون لقاءنا في طغيانهم يعمهون (11) وإذا مس الإنسان الضر دعانا لجنبه أو قاعدا أو قائما فلما كشفنا عنه ضره مر كأن لم يدعنا إلى ضر مسه كذلك زين للمسرفين ما كانوا يعملون (12) ولقد أهلكنا القرون من قبلكم لما ظلموا وجاءتهم رسلهم بالبينات وما كانوا ليؤمنوا كذلك نجزي القوم المجرمين (13) ثم جعلناكم خلائف في الأرض من بعدهم لننظر كيف تعملون (14) وإذا تتلى عليهم آياتنا بينات قال الذين لا يرجون لقاءنا ائت بقرآن غير هذا أو بدله قل ما يكون لي أن أبدله من تلقاء نفسي إن أتبع إلا ما يوحى إلي إني أخاف إن عصيت ربي عذاب يوم عظيم (15) قل لو شاء الله ما تلوته عليكم ولا أدراكم به فقد لبثت فيكم عمرا من قبله أفلا تعقلون (16) فمن أظلم ممن افترى على الله كذبا أو كذب بآياته إنه لا يفلح المجرمون (17) ويعبدون من دون الله ما لا يضرهم ولا ينفعهم ويقولون هؤلاء شفعاؤنا عند الله قل أتنبئون الله بما لا يعلم في السماوات ولا في الأرض سبحانه وتعالى عما يشركون (18) وما كان الناس إلا أمة واحدة فاختلفوا ولولا كلمة سبقت من ربك لقضي بينهم فيما فيه يختلفون (19) ويقولون لولا أنزل عليه آية من ربه فقل إنما الغيب لله فانتظروا إني معكم من المنتظرين (20) وإذا أذقنا الناس رحمة من بعد ضراء مستهم إذا لهم مكر في آياتنا قل الله أسرع مكرا إن رسلنا يكتبون ما تمكرون (21) هو الذي يسيركم في البر والبحر حتى إذا كنتم في الفلك وجرين بهم بريح طيبة وفرحوا بها جاءتها ريح عاصف وجاءهم الموج من كل مكان وظنوا أنهم أحيط بهم دعوا الله مخلصين له الدين لئن أنجيتنا من هذه لنكونن من الشاكرين (22) فلما أنجاهم إذا هم يبغون في الأرض بغير الحق يا أيها الناس إنما بغيكم على أنفسكم متاع الحياة الدنيا ثم إلينا مرجعكم فننبئكم بما كنتم تعملون (23) إنما مثل الحياة الدنيا كماء أنزلناه من السماء فاختلط به نبات الأرض مما يأكل الناس والأنعام حتى إذا أخذت الأرض زخرفها وازينت وظن أهلها أنهم قادرون عليها أتاها أمرنا ليلا أو نهارا فجعلناها حصيدا كأن لم تغن بالأمس كذلك نفصل الآيات لقوم يتفكرون (24) والله يدعو إلى دار السلام ويهدي من يشاء إلى صراط مستقيم (25) للذين أحسنوا الحسنى وزيادة ولا يرهق وجوههم قتر ولا ذلة أولئك أصحاب الجنة هم فيها خالدون (26) والذين كسبوا السيئات جزاء سيئة بمثلها وترهقهم ذلة ما لهم من الله من عاصم كأنما أغشيت وجوههم قطعا من الليل مظلما أولئك أصحاب النار هم فيها خالدون (27) ويوم نحشرهم جميعا ثم نقول للذين أشركوا مكانكم أنتم وشركاؤكم فزيلنا بينهم وقال شركاؤهم ما كنتم إيانا تعبدون (28) فكفى بالله شهيدا بيننا وبينكم إن كنا عن عبادتكم لغافلين (29) هنالك تبلو كل نفس ما أسلفت وردوا إلى الله مولاهم الحق وضل عنهم ما كانوا يفترون (30) قل من يرزقكم من السماء والأرض أمن يملك السمع والأبصار ومن يخرج الحي من الميت ويخرج الميت من الحي ومن يدبر الأمر فسيقولون الله فقل أفلا تتقون (31) فذلكم الله ربكم الحق فماذا بعد الحق إلا الضلال فأنى تصرفون (32) كذلك حقت كلمت ربك على الذين فسقوا أنهم لا يؤمنون (33) قل هل من شركائكم من يبدأ الخلق ثم يعيده قل الله يبدأ الخلق ثم يعيده فأنى تؤفكون (34) قل هل من شركائكم من يهدي إلى الحق قل الله يهدي للحق أفمن يهدي إلى الحق أحق أن يتبع أمن لا يهدي إلا أن يهدى فما لكم كيف تحكمون (35) وما يتبع أكثرهم إلا ظنا إن الظن لا يغني من الحق شيئا إن الله عليم بما يفعلون (36) وما كان هذا القرآن أن يفترى من دون الله ولكن تصديق الذي بين يديه وتفصيل الكتاب لا ريب فيه من رب العالمين (37) أم يقولون افتراه قل فأتوا بسورة مثله وادعوا من استطعتم من دون الله إن كنتم صادقين (38) بل كذبوا بما لم يحيطوا بعلمه ولما يأتهم تأويله كذلك كذب الذين من قبلهم فانظر كيف كان عاقبة الظالمين (39) ومنهم من يؤمن به ومنهم من لا يؤمن به وربك أعلم بالمفسدين (40) وإن كذبوك فقل لي عملي ولكم عملكم أنتم بريئون مما أعمل وأنا بريء مما تعملون (41) ومنهم من يستمعون إليك أفأنت تسمع الصم ولو كانوا لا يعقلون (42) ومنهم من ينظر إليك أفأنت تهدي العمي ولو كانوا لا يبصرون (43) إن الله لا يظلم الناس شيئا ولكن الناس أنفسهم يظلمون (44) ويوم يحشرهم كأن لم يلبثوا إلا ساعة من النهار يتعارفون بينهم قد خسر الذين كذبوا بلقاء الله وما كانوا مهتدين (45) وإما نرينك بعض الذي نعدهم أو نتوفينك فإلينا مرجعهم ثم الله شهيد على ما يفعلون (46) ولكل أمة رسول فإذا جاء رسولهم قضي بينهم بالقسط وهم لا يظلمون (47) ويقولون متى هذا الوعد إن كنتم صادقين (48) قل لا أملك لنفسي ضرا ولا نفعا إلا ما شاء الله لكل أمة أجل إذا جاء أجلهم فلا يستأخرون ساعة ولا يستقدمون (49) قل أرأيتم إن أتاكم عذابه بياتا أو نهارا ماذا يستعجل منه المجرمون (50) أثم إذا ما وقع آمنتم به آلآن وقد كنتم به تستعجلون (51) ثم قيل للذين ظلموا ذوقوا عذاب الخلد هل تجزون إلا بما كنتم تكسبون (52) ويستنبئونك أحق هو قل إي وربي إنه لحق وما أنتم بمعجزين (53) ولو أن لكل نفس ظلمت ما في الأرض لافتدت به وأسروا الندامة لما رأوا العذاب وقضي بينهم بالقسط وهم لا يظلمون (54) ألا إن لله ما في السماوات والأرض ألا إن وعد الله حق ولكن أكثرهم لا يعلمون (55) هو يحيي ويميت وإليه ترجعون (56) يا أيها الناس قد جاءتكم موعظة من ربكم وشفاء لما في الصدور وهدى ورحمة للمؤمنين (57) قل بفضل الله وبرحمته فبذلك فليفرحوا هو خير مما يجمعون (58) قل أرأيتم ما أنزل الله لكم من رزق فجعلتم منه حراما وحلالا قل آلله أذن لكم أم على الله تفترون (59) وما ظن الذين يفترون على الله الكذب يوم القيامة إن الله لذو فضل على الناس ولكن أكثرهم لا يشكرون (60) وما تكون في شأن وما تتلو منه من قرآن ولا تعملون من عمل إلا كنا عليكم شهودا إذ تفيضون فيه وما يعزب عن ربك من مثقال ذرة في الأرض ولا في السماء ولا أصغر من ذلك ولا أكبر إلا في كتاب مبين (61) ألا إن أولياء الله لا خوف عليهم ولا هم يحزنون (62) الذين آمنوا وكانوا يتقون (63) لهم البشرى في الحياة الدنيا وفي الآخرة لا تبديل لكلمات الله ذلك هو الفوز العظيم (64) ولا يحزنك قولهم إن العزة لله جميعا هو السميع العليم (65) ألا إن لله من في السماوات ومن في الأرض وما يتبع الذين يدعون من دون الله شركاء إن يتبعون إلا الظن وإن هم إلا يخرصون (66) هو الذي جعل لكم الليل لتسكنوا فيه والنهار مبصرا إن في ذلك لآيات لقوم يسمعون (67) قالوا اتخذ الله ولدا سبحانه هو الغني له ما في السماوات وما في الأرض إن عندكم من سلطان بهذا أتقولون على الله ما لا تعلمون (68) قل إن الذين يفترون على الله الكذب لا يفلحون (69) متاع في الدنيا ثم إلينا مرجعهم ثم نذيقهم العذاب الشديد بما كانوا يكفرون (70) واتل عليهم نبأ نوح إذ قال لقومه يا قوم إن كان كبر عليكم مقامي وتذكيري بآيات الله فعلى الله توكلت فأجمعوا أمركم وشركاءكم ثم لا يكن أمركم عليكم غمة ثم اقضوا إلي ولا تنظرون (71) فإن توليتم فما سألتكم من أجر إن أجري إلا على الله وأمرت أن أكون من المسلمين (72) فكذبوه فنجيناه ومن معه في الفلك وجعلناهم خلائف وأغرقنا الذين كذبوا بآياتنا فانظر كيف كان عاقبة المنذرين (73) ثم بعثنا من بعده رسلا إلى قومهم فجاءوهم بالبينات فما كانوا ليؤمنوا بما كذبوا به من قبل كذلك نطبع على قلوب المعتدين (74) ثم بعثنا من بعدهم موسى وهارون إلى فرعون وملئه بآياتنا فاستكبروا وكانوا قوما مجرمين (75) فلما جاءهم الحق من عندنا قالوا إن هذا لسحر مبين (76) قال موسى أتقولون للحق لما جاءكم أسحر هذا ولا يفلح الساحرون (77) قالوا أجئتنا لتلفتنا عما وجدنا عليه آباءنا وتكون لكما الكبرياء في الأرض وما نحن لكما بمؤمنين (78) وقال فرعون ائتوني بكل ساحر عليم (79) فلما جاء السحرة قال لهم موسى ألقوا ما أنتم ملقون (80) فلما ألقوا قال موسى ما جئتم به السحر إن الله سيبطله إن الله لا يصلح عمل المفسدين (81) ويحق الله الحق بكلماته ولو كره المجرمون (82) فما آمن لموسى إلا ذرية من قومه على خوف من فرعون وملئهم أن يفتنهم وإن فرعون لعال في الأرض وإنه لمن المسرفين (83) وقال موسى يا قوم إن كنتم آمنتم بالله فعليه توكلوا إن كنتم مسلمين (84) فقالوا على الله توكلنا ربنا لا تجعلنا فتنة للقوم الظالمين (85) ونجنا برحمتك من القوم الكافرين (86) وأوحينا إلى موسى وأخيه أن تبوآ لقومكما بمصر بيوتا واجعلوا بيوتكم قبلة وأقيموا الصلاة وبشر المؤمنين (87) وقال موسى ربنا إنك آتيت فرعون وملأه زينة وأموالا في الحياة الدنيا ربنا ليضلوا عن سبيلك ربنا اطمس على أموالهم واشدد على قلوبهم فلا يؤمنوا حتى يروا العذاب الأليم (88) قال قد أجيبت دعوتكما فاستقيما ولا تتبعان سبيل الذين لا يعلمون (89) وجاوزنا ببني إسرائيل البحر فأتبعهم فرعون وجنوده بغيا وعدوا حتى إذا أدركه الغرق قال آمنت أنه لا إله إلا الذي آمنت به بنو إسرائيل وأنا من المسلمين (90) آلآن وقد عصيت قبل وكنت من المفسدين (91) فاليوم ننجيك ببدنك لتكون لمن خلفك آية وإن كثيرا من الناس عن آياتنا لغافلون (92) ولقد بوأنا بني إسرائيل مبوأ صدق ورزقناهم من الطيبات فما اختلفوا حتى جاءهم العلم إن ربك يقضي بينهم يوم القيامة فيما كانوا فيه يختلفون (93) فإن كنت في شك مما أنزلنا إليك فاسأل الذين يقرءون الكتاب من قبلك لقد جاءك الحق من ربك فلا تكونن من الممترين (94) ولا تكونن من الذين كذبوا بآيات الله فتكون من الخاسرين (95) إن الذين حقت عليهم كلمت ربك لا يؤمنون (96) ولو جاءتهم كل آية حتى يروا العذاب الأليم (97) فلولا كانت قرية آمنت فنفعها إيمانها إلا قوم يونس لما آمنوا كشفنا عنهم عذاب الخزي في الحياة الدنيا ومتعناهم إلى حين (98) ولو شاء ربك لآمن من في الأرض كلهم جميعا أفأنت تكره الناس حتى يكونوا مؤمنين (99) وما كان لنفس أن تؤمن إلا بإذن الله ويجعل الرجس على الذين لا يعقلون (100) قل انظروا ماذا في السماوات والأرض وما تغني الآيات والنذر عن قوم لا يؤمنون (101) فهل ينتظرون إلا مثل أيام الذين خلوا من قبلهم قل فانتظروا إني معكم من المنتظرين (102) ثم ننجي رسلنا والذين آمنوا كذلك حقا علينا ننج المؤمنين (103) قل يا أيها الناس إن كنتم في شك من ديني فلا أعبد الذين تعبدون من دون الله ولكن أعبد الله الذي يتوفاكم وأمرت أن أكون من المؤمنين (104) وأن أقم وجهك للدين حنيفا ولا تكونن من المشركين (105) ولا تدع من دون الله ما لا ينفعك ولا يضرك فإن فعلت فإنك إذا من الظالمين (106) وإن يمسسك الله بضر فلا كاشف له إلا هو وإن يردك بخير فلا راد لفضله يصيب به من يشاء من عباده وهو الغفور الرحيم (107) قل يا أيها الناس قد جاءكم الحق من ربكم فمن اهتدى فإنما يهتدي لنفسه ومن ضل فإنما يضل عليها وما أنا عليكم بوكيل (108) واتبع ما يوحى إليك واصبر حتى يحكم الله وهو خير الحاكمين (109</span></p> <p align="center"><span style="font-family: Serif; font-size: 20px; text-shadow: silver 0.2em 0.2em 0.1em;">[[User:williammacewen#without diacritics|<span style="color=" #954535"">return to top</span>]]</span></p> === with diacritics === <p align="right"><span style="font-family: Arabic Typesetting; font-size: 50px;">الر تِلْكَ آيَاتُ الْكِتَابِ الْحَكِيمِ (1) أَكَانَ لِلنَّاسِ عَجَبًا أَنْ أَوْحَيْنَا إِلَى رَجُلٍ مِنْهُمْ أَنْ أَنْذِرِ النَّاسَ وَبَشِّرِ الَّذِينَ آمَنُوا أَنَّ لَهُمْ قَدَمَ صِدْقٍ عِنْدَ رَبِّهِمْ قَالَ الْكَافِرُونَ إِنَّ هَذَا لَسَاحِرٌ مُبِينٌ (2) إِنَّ رَبَّكُمُ اللَّهُ الَّذِي خَلَقَ السَّمَاوَاتِ وَالْأَرْضَ فِي سِتَّةِ أَيَّامٍ ثُمَّ اسْتَوَى عَلَى الْعَرْشِ يُدَبِّرُ الْأَمْرَ مَا مِنْ شَفِيعٍ إِلَّا مِنْ بَعْدِ إِذْنِهِ ذَلِكُمُ اللَّهُ رَبُّكُمْ فَاعْبُدُوهُ أَفَلَا تَذَكَّرُونَ (3) إِلَيْهِ مَرْجِعُكُمْ جَمِيعًا وَعْدَ اللَّهِ حَقًّا إِنَّهُ يَبْدَأُ الْخَلْقَ ثُمَّ يُعِيدُهُ لِيَجْزِيَ الَّذِينَ آمَنُوا وَعَمِلُوا الصَّالِحَاتِ بِالْقِسْطِ وَالَّذِينَ كَفَرُوا لَهُمْ شَرَابٌ مِنْ حَمِيمٍ وَعَذَابٌ أَلِيمٌ بِمَا كَانُوا يَكْفُرُونَ (4) هُوَ الَّذِي جَعَلَ الشَّمْسَ ضِيَاءً وَالْقَمَرَ نُورًا وَقَدَّرَهُ مَنَازِلَ لِتَعْلَمُوا عَدَدَ السِّنِينَ وَالْحِسَابَ مَا خَلَقَ اللَّهُ ذَلِكَ إِلَّا بِالْحَقِّ يُفَصِّلُ الْآيَاتِ لِقَوْمٍ يَعْلَمُونَ (5) إِنَّ فِي اخْتِلَافِ اللَّيْلِ وَالنَّهَارِ وَمَا خَلَقَ اللَّهُ فِي السَّمَاوَاتِ وَالْأَرْضِ لَآيَاتٍ لِقَوْمٍ يَتَّقُونَ (6) إِنَّ الَّذِينَ لَا يَرْجُونَ لِقَاءَنَا وَرَضُوا بِالْحَيَاةِ الدُّنْيَا وَاطْمَأَنُّوا بِهَا وَالَّذِينَ هُمْ عَنْ آيَاتِنَا غَافِلُونَ (7) أُولَئِكَ مَأْوَاهُمُ النَّارُ بِمَا كَانُوا يَكْسِبُونَ (8) إِنَّ الَّذِينَ آمَنُوا وَعَمِلُوا الصَّالِحَاتِ يَهْدِيهِمْ رَبُّهُمْ بِإِيمَانِهِمْ تَجْرِي مِنْ تَحْتِهِمُ الْأَنْهَارُ فِي جَنَّاتِ النَّعِيمِ (9) دَعْوَاهُمْ فِيهَا سُبْحَانَكَ اللَّهُمَّ وَتَحِيَّتُهُمْ فِيهَا سَلَامٌ وَآخِرُ دَعْوَاهُمْ أَنِ الْحَمْدُ لِلَّهِ رَبِّ الْعَالَمِينَ (10) وَلَوْ يُعَجِّلُ اللَّهُ لِلنَّاسِ الشَّرَّ اسْتِعْجَالَهُمْ بِالْخَيْرِ لَقُضِيَ إِلَيْهِمْ أَجَلُهُمْ فَنَذَرُ الَّذِينَ لَا يَرْجُونَ لِقَاءَنَا فِي طُغْيَانِهِمْ يَعْمَهُونَ (11) وَإِذَا مَسَّ الْإِنْسَانَ الضُّرُّ دَعَانَا لِجَنْبِهِ أَوْ قَاعِدًا أَوْ قَائِمًا فَلَمَّا كَشَفْنَا عَنْهُ ضُرَّهُ مَرَّ كَأَنْ لَمْ يَدْعُنَا إِلَى ضُرٍّ مَسَّهُ كَذَلِكَ زُيِّنَ لِلْمُسْرِفِينَ مَا كَانُوا يَعْمَلُونَ (12) وَلَقَدْ أَهْلَكْنَا الْقُرُونَ مِنْ قَبْلِكُمْ لَمَّا ظَلَمُوا وَجَاءَتْهُمْ رُسُلُهُمْ بِالْبَيِّنَاتِ وَمَا كَانُوا لِيُؤْمِنُوا كَذَلِكَ نَجْزِي الْقَوْمَ الْمُجْرِمِينَ (13) ثُمَّ جَعَلْنَاكُمْ خَلَائِفَ فِي الْأَرْضِ مِنْ بَعْدِهِمْ لِنَنْظُرَ كَيْفَ تَعْمَلُونَ (14) وَإِذَا تُتْلَى عَلَيْهِمْ آيَاتُنَا بَيِّنَاتٍ قَالَ الَّذِينَ لَا يَرْجُونَ لِقَاءَنَا ائْتِ بِقُرْآنٍ غَيْرِ هَذَا أَوْ بَدِّلْهُ قُلْ مَا يَكُونُ لِي أَنْ أُبَدِّلَهُ مِنْ تِلْقَاءِ نَفْسِي إِنْ أَتَّبِعُ إِلَّا مَا يُوحَى إِلَيَّ إِنِّي أَخَافُ إِنْ عَصَيْتُ رَبِّي عَذَابَ يَوْمٍ عَظِيمٍ (15) قُلْ لَوْ شَاءَ اللَّهُ مَا تَلَوْتُهُ عَلَيْكُمْ وَلَا أَدْرَاكُمْ بِهِ فَقَدْ لَبِثْتُ فِيكُمْ عُمُرًا مِنْ قَبْلِهِ أَفَلَا تَعْقِلُونَ (16) فَمَنْ أَظْلَمُ مِمَّنِ افْتَرَى عَلَى اللَّهِ كَذِبًا أَوْ كَذَّبَ بِآيَاتِهِ إِنَّهُ لَا يُفْلِحُ الْمُجْرِمُونَ (17) وَيَعْبُدُونَ مِنْ دُونِ اللَّهِ مَا لَا يَضُرُّهُمْ وَلَا يَنْفَعُهُمْ وَيَقُولُونَ هَؤُلَاءِ شُفَعَاؤُنَا عِنْدَ اللَّهِ قُلْ أَتُنَبِّئُونَ اللَّهَ بِمَا لَا يَعْلَمُ فِي السَّمَاوَاتِ وَلَا فِي الْأَرْضِ سُبْحَانَهُ وَتَعَالَى عَمَّا يُشْرِكُونَ (18) وَمَا كَانَ النَّاسُ إِلَّا أُمَّةً وَاحِدَةً فَاخْتَلَفُوا وَلَوْلَا كَلِمَةٌ سَبَقَتْ مِنْ رَبِّكَ لَقُضِيَ بَيْنَهُمْ فِيمَا فِيهِ يَخْتَلِفُونَ (19) وَيَقُولُونَ لَوْلَا أُنْزِلَ عَلَيْهِ آيَةٌ مِنْ رَبِّهِ فَقُلْ إِنَّمَا الْغَيْبُ لِلَّهِ فَانْتَظِرُوا إِنِّي مَعَكُمْ مِنَ الْمُنْتَظِرِينَ (20) وَإِذَا أَذَقْنَا النَّاسَ رَحْمَةً مِنْ بَعْدِ ضَرَّاءَ مَسَّتْهُمْ إِذَا لَهُمْ مَكْرٌ فِي آيَاتِنَا قُلِ اللَّهُ أَسْرَعُ مَكْرًا إِنَّ رُسُلَنَا يَكْتُبُونَ مَا تَمْكُرُونَ (21) هُوَ الَّذِي يُسَيِّرُكُمْ فِي الْبَرِّ وَالْبَحْرِ حَتَّى إِذَا كُنْتُمْ فِي الْفُلْكِ وَجَرَيْنَ بِهِمْ بِرِيحٍ طَيِّبَةٍ وَفَرِحُوا بِهَا جَاءَتْهَا رِيحٌ عَاصِفٌ وَجَاءَهُمُ الْمَوْجُ مِنْ كُلِّ مَكَانٍ وَظَنُّوا أَنَّهُمْ أُحِيطَ بِهِمْ دَعَوُا اللَّهَ مُخْلِصِينَ لَهُ الدِّينَ لَئِنْ أَنْجَيْتَنَا مِنْ هَذِهِ لَنَكُونَنَّ مِنَ الشَّاكِرِينَ (22) فَلَمَّا أَنْجَاهُمْ إِذَا هُمْ يَبْغُونَ فِي الْأَرْضِ بِغَيْرِ الْحَقِّ يَا أَيُّهَا النَّاسُ إِنَّمَا بَغْيُكُمْ عَلَى أَنْفُسِكُمْ مَتَاعَ الْحَيَاةِ الدُّنْيَا ثُمَّ إِلَيْنَا مَرْجِعُكُمْ فَنُنَبِّئُكُمْ بِمَا كُنْتُمْ تَعْمَلُونَ (23) إِنَّمَا مَثَلُ الْحَيَاةِ الدُّنْيَا كَمَاءٍ أَنْزَلْنَاهُ مِنَ السَّمَاءِ فَاخْتَلَطَ بِهِ نَبَاتُ الْأَرْضِ مِمَّا يَأْكُلُ النَّاسُ وَالْأَنْعَامُ حَتَّى إِذَا أَخَذَتِ الْأَرْضُ زُخْرُفَهَا وَازَّيَّنَتْ وَظَنَّ أَهْلُهَا أَنَّهُمْ قَادِرُونَ عَلَيْهَا أَتَاهَا أَمْرُنَا لَيْلًا أَوْ نَهَارًا فَجَعَلْنَاهَا حَصِيدًا كَأَنْ لَمْ تَغْنَ بِالْأَمْسِ كَذَلِكَ نُفَصِّلُ الْآيَاتِ لِقَوْمٍ يَتَفَكَّرُونَ (24) وَاللَّهُ يَدْعُو إِلَى دَارِ السَّلَامِ وَيَهْدِي مَنْ يَشَاءُ إِلَى صِرَاطٍ مُسْتَقِيمٍ (25) لِلَّذِينَ أَحْسَنُوا الْحُسْنَى وَزِيَادَةٌ وَلَا يَرْهَقُ وُجُوهَهُمْ قَتَرٌ وَلَا ذِلَّةٌ أُولَئِكَ أَصْحَابُ الْجَنَّةِ هُمْ فِيهَا خَالِدُونَ (26) وَالَّذِينَ كَسَبُوا السَّيِّئَاتِ جَزَاءُ سَيِّئَةٍ بِمِثْلِهَا وَتَرْهَقُهُمْ ذِلَّةٌ مَا لَهُمْ مِنَ اللَّهِ مِنْ عَاصِمٍ كَأَنَّمَا أُغْشِيَتْ وُجُوهُهُمْ قِطَعًا مِنَ اللَّيْلِ مُظْلِمًا أُولَئِكَ أَصْحَابُ النَّارِ هُمْ فِيهَا خَالِدُونَ (27) وَيَوْمَ نَحْشُرُهُمْ جَمِيعًا ثُمَّ نَقُولُ لِلَّذِينَ أَشْرَكُوا مَكَانَكُمْ أَنْتُمْ وَشُرَكَاؤُكُمْ فَزَيَّلْنَا بَيْنَهُمْ وَقَالَ شُرَكَاؤُهُمْ مَا كُنْتُمْ إِيَّانَا تَعْبُدُونَ (28) فَكَفَى بِاللَّهِ شَهِيدًا بَيْنَنَا وَبَيْنَكُمْ إِنْ كُنَّا عَنْ عِبَادَتِكُمْ لَغَافِلِينَ (29) هُنَالِكَ تَبْلُو كُلُّ نَفْسٍ مَا أَسْلَفَتْ وَرُدُّوا إِلَى اللَّهِ مَوْلَاهُمُ الْحَقِّ وَضَلَّ عَنْهُمْ مَا كَانُوا يَفْتَرُونَ (30) قُلْ مَنْ يَرْزُقُكُمْ مِنَ السَّمَاءِ وَالْأَرْضِ أَمَّنْ يَمْلِكُ السَّمْعَ وَالْأَبْصَارَ وَمَنْ يُخْرِجُ الْحَيَّ مِنَ الْمَيِّتِ وَيُخْرِجُ الْمَيِّتَ مِنَ الْحَيِّ وَمَنْ يُدَبِّرُ الْأَمْرَ فَسَيَقُولُونَ اللَّهُ فَقُلْ أَفَلَا تَتَّقُونَ (31) فَذَلِكُمُ اللَّهُ رَبُّكُمُ الْحَقُّ فَمَاذَا بَعْدَ الْحَقِّ إِلَّا الضَّلَالُ فَأَنَّى تُصْرَفُونَ (32) كَذَلِكَ حَقَّتْ كَلِمَتُ رَبِّكَ عَلَى الَّذِينَ فَسَقُوا أَنَّهُمْ لَا يُؤْمِنُونَ (33) قُلْ هَلْ مِنْ شُرَكَائِكُمْ مَنْ يَبْدَأُ الْخَلْقَ ثُمَّ يُعِيدُهُ قُلِ اللَّهُ يَبْدَأُ الْخَلْقَ ثُمَّ يُعِيدُهُ فَأَنَّى تُؤْفَكُونَ (34) قُلْ هَلْ مِنْ شُرَكَائِكُمْ مَنْ يَهْدِي إِلَى الْحَقِّ قُلِ اللَّهُ يَهْدِي لِلْحَقِّ أَفَمَنْ يَهْدِي إِلَى الْحَقِّ أَحَقُّ أَنْ يُتَّبَعَ أَمَّنْ لَا يَهِدِّي إِلَّا أَنْ يُهْدَى فَمَا لَكُمْ كَيْفَ تَحْكُمُونَ (35) وَمَا يَتَّبِعُ أَكْثَرُهُمْ إِلَّا ظَنًّا إِنَّ الظَّنَّ لَا يُغْنِي مِنَ الْحَقِّ شَيْئًا إِنَّ اللَّهَ عَلِيمٌ بِمَا يَفْعَلُونَ (36) وَمَا كَانَ هَذَا الْقُرْآنُ أَنْ يُفْتَرَى مِنْ دُونِ اللَّهِ وَلَكِنْ تَصْدِيقَ الَّذِي بَيْنَ يَدَيْهِ وَتَفْصِيلَ الْكِتَابِ لَا رَيْبَ فِيهِ مِنْ رَبِّ الْعَالَمِينَ (37) أَمْ يَقُولُونَ افْتَرَاهُ قُلْ فَأْتُوا بِسُورَةٍ مِثْلِهِ وَادْعُوا مَنِ اسْتَطَعْتُمْ مِنْ دُونِ اللَّهِ إِنْ كُنْتُمْ صَادِقِينَ (38) بَلْ كَذَّبُوا بِمَا لَمْ يُحِيطُوا بِعِلْمِهِ وَلَمَّا يَأْتِهِمْ تَأْوِيلُهُ كَذَلِكَ كَذَّبَ الَّذِينَ مِنْ قَبْلِهِمْ فَانْظُرْ كَيْفَ كَانَ عَاقِبَةُ الظَّالِمِينَ (39) وَمِنْهُمْ مَنْ يُؤْمِنُ بِهِ وَمِنْهُمْ مَنْ لَا يُؤْمِنُ بِهِ وَرَبُّكَ أَعْلَمُ بِالْمُفْسِدِينَ (40) وَإِنْ كَذَّبُوكَ فَقُلْ لِي عَمَلِي وَلَكُمْ عَمَلُكُمْ أَنْتُمْ بَرِيئُونَ مِمَّا أَعْمَلُ وَأَنَا بَرِيءٌ مِمَّا تَعْمَلُونَ (41) وَمِنْهُمْ مَنْ يَسْتَمِعُونَ إِلَيْكَ أَفَأَنْتَ تُسْمِعُ الصُّمَّ وَلَوْ كَانُوا لَا يَعْقِلُونَ (42) وَمِنْهُمْ مَنْ يَنْظُرُ إِلَيْكَ أَفَأَنْتَ تَهْدِي الْعُمْيَ وَلَوْ كَانُوا لَا يُبْصِرُونَ (43) إِنَّ اللَّهَ لَا يَظْلِمُ النَّاسَ شَيْئًا وَلَكِنَّ النَّاسَ أَنْفُسَهُمْ يَظْلِمُونَ (44) وَيَوْمَ يَحْشُرُهُمْ كَأَنْ لَمْ يَلْبَثُوا إِلَّا سَاعَةً مِنَ النَّهَارِ يَتَعَارَفُونَ بَيْنَهُمْ قَدْ خَسِرَ الَّذِينَ كَذَّبُوا بِلِقَاءِ اللَّهِ وَمَا كَانُوا مُهْتَدِينَ (45) وَإِمَّا نُرِيَنَّكَ بَعْضَ الَّذِي نَعِدُهُمْ أَوْ نَتَوَفَّيَنَّكَ فَإِلَيْنَا مَرْجِعُهُمْ ثُمَّ اللَّهُ شَهِيدٌ عَلَى مَا يَفْعَلُونَ (46) وَلِكُلِّ أُمَّةٍ رَسُولٌ فَإِذَا جَاءَ رَسُولُهُمْ قُضِيَ بَيْنَهُمْ بِالْقِسْطِ وَهُمْ لَا يُظْلَمُونَ (47) وَيَقُولُونَ مَتَى هَذَا الْوَعْدُ إِنْ كُنْتُمْ صَادِقِينَ (48) قُلْ لَا أَمْلِكُ لِنَفْسِي ضَرًّا وَلَا نَفْعًا إِلَّا مَا شَاءَ اللَّهُ لِكُلِّ أُمَّةٍ أَجَلٌ إِذَا جَاءَ أَجَلُهُمْ فَلَا يَسْتَأْخِرُونَ سَاعَةً وَلَا يَسْتَقْدِمُونَ (49) قُلْ أَرَأَيْتُمْ إِنْ أَتَاكُمْ عَذَابُهُ بَيَاتًا أَوْ نَهَارًا مَاذَا يَسْتَعْجِلُ مِنْهُ الْمُجْرِمُونَ (50) أَثُمَّ إِذَا مَا وَقَعَ آمَنْتُمْ بِهِ آلْآنَ وَقَدْ كُنْتُمْ بِهِ تَسْتَعْجِلُونَ (51) ثُمَّ قِيلَ لِلَّذِينَ ظَلَمُوا ذُوقُوا عَذَابَ الْخُلْدِ هَلْ تُجْزَوْنَ إِلَّا بِمَا كُنْتُمْ تَكْسِبُونَ (52) وَيَسْتَنْبِئُونَكَ أَحَقٌّ هُوَ قُلْ إِي وَرَبِّي إِنَّهُ لَحَقٌّ وَمَا أَنْتُمْ بِمُعْجِزِينَ (53) وَلَوْ أَنَّ لِكُلِّ نَفْسٍ ظَلَمَتْ مَا فِي الْأَرْضِ لَافْتَدَتْ بِهِ وَأَسَرُّوا النَّدَامَةَ لَمَّا رَأَوُا الْعَذَابَ وَقُضِيَ بَيْنَهُمْ بِالْقِسْطِ وَهُمْ لَا يُظْلَمُونَ (54) أَلَا إِنَّ لِلَّهِ مَا فِي السَّمَاوَاتِ وَالْأَرْضِ أَلَا إِنَّ وَعْدَ اللَّهِ حَقٌّ وَلَكِنَّ أَكْثَرَهُمْ لَا يَعْلَمُونَ (55) هُوَ يُحْيِي وَيُمِيتُ وَإِلَيْهِ تُرْجَعُونَ (56) يَا أَيُّهَا النَّاسُ قَدْ جَاءَتْكُمْ مَوْعِظَةٌ مِنْ رَبِّكُمْ وَشِفَاءٌ لِمَا فِي الصُّدُورِ وَهُدًى وَرَحْمَةٌ لِلْمُؤْمِنِينَ (57) قُلْ بِفَضْلِ اللَّهِ وَبِرَحْمَتِهِ فَبِذَلِكَ فَلْيَفْرَحُوا هُوَ خَيْرٌ مِمَّا يَجْمَعُونَ (58) قُلْ أَرَأَيْتُمْ مَا أَنْزَلَ اللَّهُ لَكُمْ مِنْ رِزْقٍ فَجَعَلْتُمْ مِنْهُ حَرَامًا وَحَلَالًا قُلْ آللَّهُ أَذِنَ لَكُمْ أَمْ عَلَى اللَّهِ تَفْتَرُونَ (59) وَمَا ظَنُّ الَّذِينَ يَفْتَرُونَ عَلَى اللَّهِ الْكَذِبَ يَوْمَ الْقِيَامَةِ إِنَّ اللَّهَ لَذُو فَضْلٍ عَلَى النَّاسِ وَلَكِنَّ أَكْثَرَهُمْ لَا يَشْكُرُونَ (60) وَمَا تَكُونُ فِي شَأْنٍ وَمَا تَتْلُو مِنْهُ مِنْ قُرْآنٍ وَلَا تَعْمَلُونَ مِنْ عَمَلٍ إِلَّا كُنَّا عَلَيْكُمْ شُهُودًا إِذْ تُفِيضُونَ فِيهِ وَمَا يَعْزُبُ عَنْ رَبِّكَ مِنْ مِثْقَالِ ذَرَّةٍ فِي الْأَرْضِ وَلَا فِي السَّمَاءِ وَلَا أَصْغَرَ مِنْ ذَلِكَ وَلَا أَكْبَرَ إِلَّا فِي كِتَابٍ مُبِينٍ (61) أَلَا إِنَّ أَوْلِيَاءَ اللَّهِ لَا خَوْفٌ عَلَيْهِمْ وَلَا هُمْ يَحْزَنُونَ (62) الَّذِينَ آمَنُوا وَكَانُوا يَتَّقُونَ (63) لَهُمُ الْبُشْرَى فِي الْحَيَاةِ الدُّنْيَا وَفِي الْآخِرَةِ لَا تَبْدِيلَ لِكَلِمَاتِ اللَّهِ ذَلِكَ هُوَ الْفَوْزُ الْعَظِيمُ (64) وَلَا يَحْزُنْكَ قَوْلُهُمْ إِنَّ الْعِزَّةَ لِلَّهِ جَمِيعًا هُوَ السَّمِيعُ الْعَلِيمُ (65) أَلَا إِنَّ لِلَّهِ مَنْ فِي السَّمَاوَاتِ وَمَنْ فِي الْأَرْضِ وَمَا يَتَّبِعُ الَّذِينَ يَدْعُونَ مِنْ دُونِ اللَّهِ شُرَكَاءَ إِنْ يَتَّبِعُونَ إِلَّا الظَّنَّ وَإِنْ هُمْ إِلَّا يَخْرُصُونَ (66) هُوَ الَّذِي جَعَلَ لَكُمُ اللَّيْلَ لِتَسْكُنُوا فِيهِ وَالنَّهَارَ مُبْصِرًا إِنَّ فِي ذَلِكَ لَآيَاتٍ لِقَوْمٍ يَسْمَعُونَ (67) قَالُوا اتَّخَذَ اللَّهُ وَلَدًا سُبْحَانَهُ هُوَ الْغَنِيُّ لَهُ مَا فِي السَّمَاوَاتِ وَمَا فِي الْأَرْضِ إِنْ عِنْدَكُمْ مِنْ سُلْطَانٍ بِهَذَا أَتَقُولُونَ عَلَى اللَّهِ مَا لَا تَعْلَمُونَ (68) قُلْ إِنَّ الَّذِينَ يَفْتَرُونَ عَلَى اللَّهِ الْكَذِبَ لَا يُفْلِحُونَ (69) مَتَاعٌ فِي الدُّنْيَا ثُمَّ إِلَيْنَا مَرْجِعُهُمْ ثُمَّ نُذِيقُهُمُ الْعَذَابَ الشَّدِيدَ بِمَا كَانُوا يَكْفُرُونَ (70) وَاتْلُ عَلَيْهِمْ نَبَأَ نُوحٍ إِذْ قَالَ لِقَوْمِهِ يَا قَوْمِ إِنْ كَانَ كَبُرَ عَلَيْكُمْ مَقَامِي وَتَذْكِيرِي بِآيَاتِ اللَّهِ فَعَلَى اللَّهِ تَوَكَّلْتُ فَأَجْمِعُوا أَمْرَكُمْ وَشُرَكَاءَكُمْ ثُمَّ لَا يَكُنْ أَمْرُكُمْ عَلَيْكُمْ غُمَّةً ثُمَّ اقْضُوا إِلَيَّ وَلَا تُنْظِرُونِ (71) فَإِنْ تَوَلَّيْتُمْ فَمَا سَأَلْتُكُمْ مِنْ أَجْرٍ إِنْ أَجْرِيَ إِلَّا عَلَى اللَّهِ وَأُمِرْتُ أَنْ أَكُونَ مِنَ الْمُسْلِمِينَ (72) فَكَذَّبُوهُ فَنَجَّيْنَاهُ وَمَنْ مَعَهُ فِي الْفُلْكِ وَجَعَلْنَاهُمْ خَلَائِفَ وَأَغْرَقْنَا الَّذِينَ كَذَّبُوا بِآيَاتِنَا فَانْظُرْ كَيْفَ كَانَ عَاقِبَةُ الْمُنْذَرِينَ (73) ثُمَّ بَعَثْنَا مِنْ بَعْدِهِ رُسُلًا إِلَى قَوْمِهِمْ فَجَاءُوهُمْ بِالْبَيِّنَاتِ فَمَا كَانُوا لِيُؤْمِنُوا بِمَا كَذَّبُوا بِهِ مِنْ قَبْلُ كَذَلِكَ نَطْبَعُ عَلَى قُلُوبِ الْمُعْتَدِينَ (74) ثُمَّ بَعَثْنَا مِنْ بَعْدِهِمْ مُوسَى وَهَارُونَ إِلَى فِرْعَوْنَ وَمَلَئِهِ بِآيَاتِنَا فَاسْتَكْبَرُوا وَكَانُوا قَوْمًا مُجْرِمِينَ (75) فَلَمَّا جَاءَهُمُ الْحَقُّ مِنْ عِنْدِنَا قَالُوا إِنَّ هَذَا لَسِحْرٌ مُبِينٌ (76) قَالَ مُوسَى أَتَقُولُونَ لِلْحَقِّ لَمَّا جَاءَكُمْ أَسِحْرٌ هَذَا وَلَا يُفْلِحُ السَّاحِرُونَ (77) قَالُوا أَجِئْتَنَا لِتَلْفِتَنَا عَمَّا وَجَدْنَا عَلَيْهِ آبَاءَنَا وَتَكُونَ لَكُمَا الْكِبْرِيَاءُ فِي الْأَرْضِ وَمَا نَحْنُ لَكُمَا بِمُؤْمِنِينَ (78) وَقَالَ فِرْعَوْنُ ائْتُونِي بِكُلِّ سَاحِرٍ عَلِيمٍ (79) فَلَمَّا جَاءَ السَّحَرَةُ قَالَ لَهُمْ مُوسَى أَلْقُوا مَا أَنْتُمْ مُلْقُونَ (80) فَلَمَّا أَلْقَوْا قَالَ مُوسَى مَا جِئْتُمْ بِهِ السِّحْرُ إِنَّ اللَّهَ سَيُبْطِلُهُ إِنَّ اللَّهَ لَا يُصْلِحُ عَمَلَ الْمُفْسِدِينَ (81) وَيُحِقُّ اللَّهُ الْحَقَّ بِكَلِمَاتِهِ وَلَوْ كَرِهَ الْمُجْرِمُونَ (82) فَمَا آمَنَ لِمُوسَى إِلَّا ذُرِّيَّةٌ مِنْ قَوْمِهِ عَلَى خَوْفٍ مِنْ فِرْعَوْنَ وَمَلَئِهِمْ أَنْ يَفْتِنَهُمْ وَإِنَّ فِرْعَوْنَ لَعَالٍ فِي الْأَرْضِ وَإِنَّهُ لَمِنَ الْمُسْرِفِينَ (83) وَقَالَ مُوسَى يَا قَوْمِ إِنْ كُنْتُمْ آمَنْتُمْ بِاللَّهِ فَعَلَيْهِ تَوَكَّلُوا إِنْ كُنْتُمْ مُسْلِمِينَ (84) فَقَالُوا عَلَى اللَّهِ تَوَكَّلْنَا رَبَّنَا لَا تَجْعَلْنَا فِتْنَةً لِلْقَوْمِ الظَّالِمِينَ (85) وَنَجِّنَا بِرَحْمَتِكَ مِنَ الْقَوْمِ الْكَافِرِينَ (86) وَأَوْحَيْنَا إِلَى مُوسَى وَأَخِيهِ أَنْ تَبَوَّآ لِقَوْمِكُمَا بِمِصْرَ بُيُوتًا وَاجْعَلُوا بُيُوتَكُمْ قِبْلَةً وَأَقِيمُوا الصَّلَاةَ وَبَشِّرِ الْمُؤْمِنِينَ (87) وَقَالَ مُوسَى رَبَّنَا إِنَّكَ آتَيْتَ فِرْعَوْنَ وَمَلَأَهُ زِينَةً وَأَمْوَالًا فِي الْحَيَاةِ الدُّنْيَا رَبَّنَا لِيُضِلُّوا عَنْ سَبِيلِكَ رَبَّنَا اطْمِسْ عَلَى أَمْوَالِهِمْ وَاشْدُدْ عَلَى قُلُوبِهِمْ فَلَا يُؤْمِنُوا حَتَّى يَرَوُا الْعَذَابَ الْأَلِيمَ (88) قَالَ قَدْ أُجِيبَتْ دَعْوَتُكُمَا فَاسْتَقِيمَا وَلَا تَتَّبِعَانِّ سَبِيلَ الَّذِينَ لَا يَعْلَمُونَ (89) وَجَاوَزْنَا بِبَنِي إِسْرَائِيلَ الْبَحْرَ فَأَتْبَعَهُمْ فِرْعَوْنُ وَجُنُودُهُ بَغْيًا وَعَدْوًا حَتَّى إِذَا أَدْرَكَهُ الْغَرَقُ قَالَ آمَنْتُ أَنَّهُ لَا إِلَهَ إِلَّا الَّذِي آمَنَتْ بِهِ بَنُو إِسْرَائِيلَ وَأَنَا مِنَ الْمُسْلِمِينَ (90) آلْآنَ وَقَدْ عَصَيْتَ قَبْلُ وَكُنْتَ مِنَ الْمُفْسِدِينَ (91) فَالْيَوْمَ نُنَجِّيكَ بِبَدَنِكَ لِتَكُونَ لِمَنْ خَلْفَكَ آيَةً وَإِنَّ كَثِيرًا مِنَ النَّاسِ عَنْ آيَاتِنَا لَغَافِلُونَ (92) وَلَقَدْ بَوَّأْنَا بَنِي إِسْرَائِيلَ مُبَوَّأَ صِدْقٍ وَرَزَقْنَاهُمْ مِنَ الطَّيِّبَاتِ فَمَا اخْتَلَفُوا حَتَّى جَاءَهُمُ الْعِلْمُ إِنَّ رَبَّكَ يَقْضِي بَيْنَهُمْ يَوْمَ الْقِيَامَةِ فِيمَا كَانُوا فِيهِ يَخْتَلِفُونَ (93) فَإِنْ كُنْتَ فِي شَكٍّ مِمَّا أَنْزَلْنَا إِلَيْكَ فَاسْأَلِ الَّذِينَ يَقْرَءُونَ الْكِتَابَ مِنْ قَبْلِكَ لَقَدْ جَاءَكَ الْحَقُّ مِنْ رَبِّكَ فَلَا تَكُونَنَّ مِنَ الْمُمْتَرِينَ (94) وَلَا تَكُونَنَّ مِنَ الَّذِينَ كَذَّبُوا بِآيَاتِ اللَّهِ فَتَكُونَ مِنَ الْخَاسِرِينَ (95) إِنَّ الَّذِينَ حَقَّتْ عَلَيْهِمْ كَلِمَتُ رَبِّكَ لَا يُؤْمِنُونَ (96) وَلَوْ جَاءَتْهُمْ كُلُّ آيَةٍ حَتَّى يَرَوُا الْعَذَابَ الْأَلِيمَ (97) فَلَوْلَا كَانَتْ قَرْيَةٌ آمَنَتْ فَنَفَعَهَا إِيمَانُهَا إِلَّا قَوْمَ يُونُسَ لَمَّا آمَنُوا كَشَفْنَا عَنْهُمْ عَذَابَ الْخِزْيِ فِي الْحَيَاةِ الدُّنْيَا وَمَتَّعْنَاهُمْ إِلَى حِينٍ (98) وَلَوْ شَاءَ رَبُّكَ لَآمَنَ مَنْ فِي الْأَرْضِ كُلُّهُمْ جَمِيعًا أَفَأَنْتَ تُكْرِهُ النَّاسَ حَتَّى يَكُونُوا مُؤْمِنِينَ (99) وَمَا كَانَ لِنَفْسٍ أَنْ تُؤْمِنَ إِلَّا بِإِذْنِ اللَّهِ وَيَجْعَلُ الرِّجْسَ عَلَى الَّذِينَ لَا يَعْقِلُونَ (100) قُلِ انْظُرُوا مَاذَا فِي السَّمَاوَاتِ وَالْأَرْضِ وَمَا تُغْنِي الْآيَاتُ وَالنُّذُرُ عَنْ قَوْمٍ لَا يُؤْمِنُونَ (101) فَهَلْ يَنْتَظِرُونَ إِلَّا مِثْلَ أَيَّامِ الَّذِينَ خَلَوْا مِنْ قَبْلِهِمْ قُلْ فَانْتَظِرُوا إِنِّي مَعَكُمْ مِنَ الْمُنْتَظِرِينَ (102) ثُمَّ نُنَجِّي رُسُلَنَا وَالَّذِينَ آمَنُوا كَذَلِكَ حَقًّا عَلَيْنَا نُنْجِ الْمُؤْمِنِينَ (103) قُلْ يَا أَيُّهَا النَّاسُ إِنْ كُنْتُمْ فِي شَكٍّ مِنْ دِينِي فَلَا أَعْبُدُ الَّذِينَ تَعْبُدُونَ مِنْ دُونِ اللَّهِ وَلَكِنْ أَعْبُدُ اللَّهَ الَّذِي يَتَوَفَّاكُمْ وَأُمِرْتُ أَنْ أَكُونَ مِنَ الْمُؤْمِنِينَ (104) وَأَنْ أَقِمْ وَجْهَكَ لِلدِّينِ حَنِيفًا وَلَا تَكُونَنَّ مِنَ الْمُشْرِFكِينَ (105) وَلَا تَدْعُ مِنْ دُونِ اللَّهِ مَا لَا يَنْفَعُكَ وَلَا يَضُرُّكَ فَإِنْ فَعَلْتَ فَإِنَّكَ إِذًا مِنَ الظَّالِمِينَ (106) وَإِنْ يَمْسَسْكَ اللَّهُ بِضُرٍّ فَلَا كَاشِفَ لَهُ إِلَّا هُوَ وَإِنْ يُرِدْكَ بِخَيْرٍ فَلَا رَادَّ لِفَضْلِهِ يُصِيبُ بِهِ مَنْ يَشَاءُ مِنْ عِبَادِهِ وَهُوَ الْغَفُورُ الرَّحِيمُ (107) قُلْ يَا أَيُّهَا النَّاسُ قَدْ جَاءَكُمُ الْحَقُّ مِنْ رَبِّكُمْ فَمَنِ اهْتَدَى فَإِنَّمَا يَهْتَدِي لِنَفْسِهِ وَمَنْ ضَلَّ فَإِنَّمَا يَضِلُّ عَلَيْهَا وَمَا أَنَا عَلَيْكُمْ بِوَكِيلٍ (108) وَاتَّبِعْ مَا يُوحَى إِلَيْكَ وَاصْبِرْ حَتَّى يَحْكُمَ اللَّهُ وَهُوَ خَيْرُ الْحَاكِمِينَ (109</span></p> <p align="center"><span style="font-family: Serif; font-size: 20px; text-shadow: silver 0.2em 0.2em 0.1em;">[[User:williammacewen#with diacritics|<span style="color=" #954535"">return to top</span>]]</span></p> == References == {{reflist}} nv6juvoblfp9niysvchg0vllf389auv User:Broter/The Church of Jesus Christ of Latter-day Saints 2 367379 4668921 4414351 2026-09-05T12:15:08Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668921 wikitext text/x-wiki __NOTOC__ {| border="0" cellspacing="5" cellpadding="8" |colspan="2" style="background-color:#fcfcfc;{{Text default color}};border:1px solid #ccc;margin-top:.7em;"| {|style="width:100%;background-color:#fcfcfc;{{Text default color}};" border="0" |style="width:100%;color:#000"| {|style="width:100%;border:solid 0px;background:none;color:inherit;" |- |style="padding-left: 12px;text-align:center;white-space:nowrap;color:#000" | [[Image:Saltlaketemplehighsmith13507u.jpg|thumb|right|[[:W:en:Temple Square|Temple Square]]]] <div style="font-size:162%;border:none;margin: 0;padding:.1em;color:#000"> The Church of Jesus Christ of Latter-day Saints </div> <div style="top:+0.2em;font-size: 110%"> A book about The Church of Jesus Christ of Latter-day Saints </div> |} {|style="border-spacing:8px;margin:0px -8px" |class="MainPageBG" style="width:55%;border:1px solid #cef2e0;background-color:#f5fffa;{{Text default color}};vertical-align:top;color:#000"| {| cellpadding="2" cellspacing="5" style="width:100%;vertical-align:top;background-color:#ffffff;{{Text default color}};" |<h2 style="margin:0;background-color:#cef2e0;{{Text default color}};font-family:sans-serif;font-size:120%;font-weight:bold;border:1px solid #a3bfb1;text-align:left;color:#000;padding:0.2em 0.4em;">The Church of Jesus Christ of Latter-day Saints</h2> |- |style="color:#000"| According to LDS Church teachings, there was a Great Apostasy, which means that all churches fell away from the true gospel and teach today false doctrines. Thus the only true church on earth needed to be restored by the Prophet Joseph Smith. His successors, who are appointed by God, lead now this one true church. This is the reason for the existence of the LDS Church.<ref name = Faust>{{Citation |last= Faust |first= James E. |author-link= James E. Faust |title= The Restoration of All Things |url= http://lds.org/liahona/2006/05/the-restoration-of-all-things |journal= [[Liahona (magazine)|Liahona]] |publisher= LDS Church |pages= 61–62, 67–68 |date=May 2006 }}</ref> <ref name = Eyring>{{Citation |last= Eyring |first= Henry B. |author-link= Henry B. Eyring |title= The True and Living Church |url= http://www.lds.org/ensign/2008/05/the-true-and-living-church |journal= [[Ensign (LDS magazine)|Ensign]] |publisher= LDS Church |pages= 20–24 |date= May 2008 }}</ref> |} |class="MainPageBG" style="width:55%;border:1px solid #cef2e0;background-color:#f5fffa;vertical-align:top;color:#000"| {| cellpadding="2" cellspacing="5" style="width:100%;vertical-align:top;background-color:#ffffff;{{Text default color}};" |<h2 style="margin:0;background-color:#cef2e0;{{Text default color}};font-family:sans-serif;font-size:120%;font-weight:bold;border:1px solid #a3bfb1;text-align:left;color:#000;padding:0.2em 0.4em;">Contents</h2> |- |style="color:#000"| #[[/The Gospel of Jesus Christ/]] #[[/The Great Apostasy/]] #[[/Joseph Smith/]] #[[/Prophets and Apostles/]] #[[/Scriptures/]] #[[/Priesthood/]] #[[/Relief Society/]] #[[/Families/]] #[[/Temples/]] #[[/Tithing/]] #[[/Law of Chastity/]] #[[/Temporal Welfare/]] #[[/Missionary Work/]] #[[/Church Service/]] #[[/Church Buildings/]] #[[/Church Meetings/]] |} |} {|style="border-spacing:8px;margin:-8px -8px;width:100%" |class="MainPageBG" style="width:100%;border:1px solid #cef2e0;background-color:#ffffff;vertical-align:top;color:#000"| {|cellpadding="2" cellspacing="5" style="width:100%;vertical-align:top;background-color:#ffffff;color:#000" ! <h2 style="margin:0;background-color:#cef2e0;font-size:120%;font-weight:bold;border:1px solid #a3bfb1;text-align:left;color:#000;padding:0.2em 0.4em;">Summary of the Teachings of The Church of Jesus Christ of Latter-day Saints</h2> |- |style="color:#000"| |} The teachings of the LDS Church are best summarized by a quote by [[:W:en:Joseph Smith|Joseph Smith]]: {{cquote|The fundamental principles of our religion are the testimony of the Apostles and Prophets, concerning Jesus Christ, that He died, was buried, and rose again the third day, and ascended into heaven; and all other things which pertain to our religion are only appendages to it.<ref>p. 121</ref>}} |} |} |} ==Notes== {{sisterlinks|species=no}} {{Reflist}} ==Bibliography== *{{Citation | editor-last = Smith | editor-first = Joseph Fielding | author-link = Joseph Fielding Smith | title = [[:W:en:Teachings of the Prophet Joseph Smith|Teachings of the Prophet Joseph Smith]] | publisher = [[:W:en:Deseret Book Company|Deseret Book Company]] | year = 1976 | isbn = 0-87747-665-9 | others = (index and concordance by [[:W:en:Robert J. Matthews|Robert J. Matthews]]) }} {{Subjects|Abrahamic religions}} {{alphabetical|T}} qbxn7woq24qx8hakcphi09jwfdzpyvb Users Guide to Hartshorne Algebraic Geometry/Chapter 0 0 384578 4669085 3427705 2026-09-06T07:25:03Z ShakespeareFan00 46022 4669085 wikitext text/x-wiki == References == # Algebraic Geometry - Hartshorne # Arithmetic - Serre # https://people.ucsc.edu/~weissman/Math222A/SerreAnn.pdf # http://web.mit.edu/18.705/www/12Nts-2up.pdf (for basic commutative algebra) # https://arxiv.org/pdf/1605.04832.pdf (for more advanced commutative algebra) # [http://wstein.org/books/ant/ant.pdf Algebraic Number Theory, A Computational Approach] - Stein == Basic Commutative Algebra == ===Categories of Commutative Rings and Algebras=== The starting point for this section is the definition of a '''commutative ring''': a unital ring with commutative multiplication. In this book you can assume that all rings are commutative, so we will omit the 'commutative' adjective. The most basic rings include * <math>\mathbb{Z}</math> * <math>\mathbb{Z}/n</math> * Fields <math>\mathbb{F}</math> * Polynomial rings <math>R[x_1,\ldots,x_n]</math> We can relate rings to one another using a '''morphism''' of rings. A function <math>\phi: R \to S</math> between rings is a morphism of rings if the following two axioms are satisfied # <math>\phi(a + b) = \phi(a) + \phi(b)</math> (Additivity) # <math>\phi(ab) = \phi(a)\phi(b)</math> (Multiplicativity) we could have stated this succinctly as a function which respects the ring structure. It turns out that rings with ring morphisms form a category <math>\textbf{CRing}</math>. As an important technical note, there is no zero-ring given by a single element in our category. This category has an initial object given by the ring of integers because given a ring morphisms : <math>\phi:\mathbb{Z} \to R</math> the ring morphism axioms forces :<math>\phi(1) = 1_R</math>, <math>\phi(-1) = -1_R</math>, and <math>\phi(n) = \phi\left(\sum_n 1\right) = \sum_n \phi(1)</math> Recall that the category of <math>R</math>-algebras has objects given by ring morphisms <math>R \to S</math> and morphisms given by commutative diagrams <blockquote><math>\begin{matrix} && S \\ & \nearrow\\ R && \downarrow \phi \\ & \searrow \\ && S' \end{matrix}</math></blockquote>If we consider only algebras, the category <math>\mathbb{Z}-\textbf{CAlg}</math> is equivalent to the category <math>\textbf{CRing}</math>. Note that it is common to consider the categories <math>\mathbb{F}_q-\textbf{CAlg}</math>, <math>\mathbb{C}-\textbf{CAlg}</math>, <math>\mathbb{Q}_p-\textbf{CAlg}</math>. The motivation for why will be readily apparent when considering categories of schemes. ===Ideals=== One of the ways to construct new rings is by taking quotient rings. An ideal of a ring is a subset <math>I \subset R</math> which is # An abelian group under addition # <math>R\cdot I \subset R</math> Then, we can take the quotient of abelian groups <math>R/I</math> and use the multiplicative structure on <math>R</math> to construct one on <math>R/I</math>. The second axiom of ideals guarantees that this is well-defined. This is called a '''quotient ring'''. Some typical examples of quotient rings are given by * <math>\mathbb{Z}/(p)</math> * <math>\mathbb{Z}[x]/(x^2 - 5) \cong \mathbb{Z}[\sqrt{5}]</math> * <math>\mathbb{Q}[x]/(x^p-1)</math> * <math> \frac{\mathbb{Z}[x_1,\ldots,x_n]}{(f_1,\ldots,f_k)} </math> ===Playing with Presentations=== As we have seen, there are many ways to construct polynomial ring; but, another interesting technique for creating new polynomial rings is to attach variables which have relations between them. For example, consider <math>\mathbb{Z}[x,x^2,x^3]</math>. We can relabel the elements we've attached, so we consider the ring <math>\mathbb{Z}[X,Y,Z]</math>, but there are a couple relations between these variables: :<math>X^2 - Y, XY - Z</math> note that these two relations can be used to show others such as <math>XZ - Y^2</math> and <math>X^3 - Z</math>. Hence :<math>\mathbb{Z}[x,x^2,x^3] \cong \frac{\mathbb{Z}[X,Y,Z]}{(X^2 - Y, XY - Z)}</math> Some other examples include *<math>\mathbb{Z}[x,x^{3/2}] \cong \frac{\mathbb{Z}[X,Y]}{(Y^2 - X^3)} </math> *<math>\mathbb{Z}[x^2,xy,y^2] \cong \frac{\mathbb{Z}[X,Y,Z]}{(XZ - Y^2)}</math> *<math>\mathbb{Z}[x^3,x^2y,xy^2,y^3] \cong \frac{\mathbb{Z}[X,Y,Z,W]}{(XW - YZ, XZ - Y^2, YW - Z^2)}</math> ===Prime Ideals=== There are a special class of ideals called '''prime ideals''': an ideal <math>\mathfrak{p}</math> in a UFD <math>R</math> is prime if :<math>xy \in \mathfrak{p} \Leftrightarrow x \in \mathfrak{p} \text{ or } y \in \mathfrak{p}</math> For example, <math>(p) \subset \mathbb{Z}</math> is the first known example of a prime ideal. It should be apparent that <math>(6)</math> is not a prime ideal since <math> 2\cdot 3 \in (6)</math> but <math>2,3 \not\in (6)</math>. Now, given an irreducible polynomial <math>f \in S[x_1,\ldots,x_n]</math> the ideal <math>(f)</math> will be prime. A simple non-example of a prime ideal is given by <math>(xy) \subset \mathbb{C}[x,y]</math>. This can be generalized to <math>(fg) \subset S[x_1,\ldots,x_n]</math>. Some other examples of prime ideals include :<math>(x^2 + 1) \subset \mathbb{Q}[x]</math> :<math>(x-\alpha) \subset \mathbb{C}[x]</math> :<math>(y^2 - x^3 + 1) \subset \mathbb{C}[x,y]</math> If you take the quotient ring of a prime ideal in a UFD <math>R</math> you get an '''integral domain'''. This means your ring has the following multiplicative property: :<math>xy = 0</math> if <math>x=0</math> or <math>y=0</math> For example, in :<math> \frac{\mathbb{C}[x,y]}{(y^2 - x^3)}</math> you will never be able to multiply two non-zero elements together to get zero. The two key non-examples of a ring being an integral domain are :<math>\mathbb{C}[x,y]/(xy)</math> since <math>xy = 0</math> :<math>\mathbb{C}[x]/(x^2)</math> since <math> x \cdot x = 0</math> ''In general'', an ideal <math>\mathfrak{p}</math> of a ring <math>R</math> is called '''prime''' if <math>R/\mathfrak{p}</math> is an integral domain. If <math>R/\mathfrak{m}</math> is also a field, then we call <math>\mathfrak{m}</math> a '''maximal ideal'''. One useful exercise is to check that for a morphism <math>f:R \to S</math> and a prime ideal <math>\mathfrak{p}\subset S</math> the inverse image <math>f^{-1}(\mathfrak{p})</math> is a prime ideal. The second example motivates the operation of taking radicals of an ideal. Given an ideal <math>I\subseteq R</math> we define its radical as<blockquote><math>\sqrt{I} = \{ f \in R : f^k \in I \text{ for some } r \in \mathbb{N} \}</math></blockquote>For example, the radical of the ideal <math>((x^2 - y + z)^4(xyz - z^2)^5)\subset \mathbb{Z}[x,y,z]</math> is <math>((x^2 - y + z)(xyz - z^2))</math>. Given a quotient ring <math>R/I</math> we call the ring <math>R/\sqrt{I}</math> its reduction; sometimes this is denoted <math>(R/I)_{\text{red}}</math>. We define the '''nilradical''' of a ring <math>R</math> as <math>\sqrt{(0)}</math>. The nonzero elements in the nilradical are called '''nilpotents'''. ===Eisenstein's Criterion and Constructing Prime Ideals=== There is a generalization of Eisenstein's criterion for integral domains: given a ring <math>R</math> and a polynomial <math>f(x) \in R[x]</math> which can be written as :<math>f(x) = a_nx^n + a_{n-1}x^{n-1} + \cdots + a_1x + a_0</math> then it cannot be written as a product of polynomials if the following conditions are satisfied: Suppose there exists a prime ideal <math>\mathfrak{p}\subset R</math> such that :<math> \begin{align} a_i \in \mathfrak{p} \text{ for } i \neq n \\ a_n \not\in \mathfrak{p} \\ a_0 \not\in \mathfrak{p}^2 \end{align} </math> then <math>f(x)</math> cannot be written as a product of polynomials <math>g_1(x)\cdots g_k(x)</math>. For example, consider the integral domain <math>\mathbb{C}[x]</math> and the polynomial <math>f \in \mathbb{C}[x][y]</math> given by :<math>f(x,y) = 1\cdot y^3 + 0\cdot y^2 + 0\cdot y + x^3\cdot y^0 = y^3 + x^3</math> Using the prime ideal <math>(x-1)\subset \mathbb{C}[x]</math> we have that <math>a_1,a_2=0 \in (x-1)</math>, <math>a_3 = 1 \not\in (x-1)</math>, and <math>a_0 = x^3 \not\in (x-1)^2</math>. Hence :<math>(x^3 + y^3) \subset \mathbb{C}[x,y]</math> is a prime ideal. This example can be extended to show that :<math>x_1^{k_1} + \cdots + x_n^{k_n} \in \mathbb{C}[x_1,\ldots,x_n]</math> generates a prime ideal. ===Nullstellensatz=== Now we are in the right place to discuss the foundational theorem of algebraic geometry: '''Hilbert's nullstellensatz'''. Here we fix <math>k</math> as an algebraically closed field. '''Theorem:''' The maximal ideals of <math>\mathfrak{m}\subset k[x_1,\ldots,x_n]</math> are in bijection with the set <math>k^n</math>. For example, the kernel of <math>\text{ev}_{(1,2)}:\mathbb{C}[x,y] \to \mathbb{C}</math> is the ideal <math>(x-1,y-2)</math>. This allows one to interpret quotient rings give by ideals <math>I \subset k[x_1,\ldots,x_n]</math> as algebraic subsets of <math>k^n</math> because an evaluation morphism<blockquote><math>\text{ev}_{(\alpha_1,\ldots,\alpha_n)}:\mathbb{C}[x_1,\ldots,x_n]/I \to \mathbb{C}</math></blockquote>is well-defined only if <math>(x_1-\alpha_1,\ldots,x_n-\alpha_n) \subset k[x_1,\ldots,x_n]/I</math> is a maximal ideal. For example, consider the following example and non-example: * <math>\text{ev}_{(1,1)}:\mathbb{C}[x,y]/(y-x^2) \to \mathbb{C}</math> is a well defined morphism since<math>(x-1,y-1,y^2 - x) = (x-1,y-1,1^2 - 1) = (x-1,y-1)</math>This implies that <math>(1,1) \in \{ (a,b) \in \mathbb{C}^2 : b^2 - a\}</math> * <math>\text{ev}_{(1,2)}:\mathbb{C}[x,y]/(y-x^2) \to \mathbb{C}</math> is not a well-defined morphism because <math>(x-1,y-2,y^2-x) = (x-1,y-2,4-1) = (1)</math>; there is no quotient ring <math>R/(1)</math>. Hence <math>(1,2) \not\in \{ (a,b) \in \mathbb{C}^2 : b^2 - a\}</math> Now we can interpret rings which are not integral. For example, we saw that <math>\mathbb{C}[x,y]/(xy)</math> is not an integral domain. Geometrically, this is the union of the <math>x</math> and <math>y</math> axes. The other main case of a non-integral ring is a non-reduced ring. For example, <math>\mathbb{C}[x,y]/(y^3)</math> is the <math>x</math>-axis but there is extra algebraic information from the <math>y,y^2</math> left over. The way you should interpret this ring as is a '''fat''' line. === Basic Scheme Theory === We can now ''confidently'' define an affine scheme: it is a functor<blockquote><math>\text{Hom}_\mathbf{CRing}(R,-): \mathbf{CRing} \to \textbf{Sets}</math></blockquote>for some fixed commutative ring <math>R</math>. === Localization === The next basic construction in commutative ring theory is '''localization'''. This defines a generalization of inverting the non-zero integers and getting the rational numbers. Let <math>S\subset R</math> be a multiplicatively closed subset with unity, meaning <math>1 \in S</math> and <math> s,s' \in S \Rightarrow ss' \in S</math>. For example, for a fixed element <math>f \in R</math> consider the subset <math>\{1,s,s^2,s^3,\ldots\}</math>. We define a commutative ring <math>R[S^{-1}]</math> as follows. First, consider the set <math>R\times S / \sim</math> where<blockquote><math>(r,s) \sim (r',s') \text{ if there exists } u \in S \text{ such that } u(rs' - r's) =0</math></blockquote>(don't worry, we will given a motivating example for this seemingly random <math>u</math>). It is an exercise to verify that this indeed defines an equivalence relation — it is standard to write these equivalence classes as <math>r/s</math>. These equivalence classes have a well-define commutative ring structure given by<blockquote><math>\frac{r}{s} \cdot \frac{r'}{s'} = \frac{rr'}{ss'} \text{ and } \frac{r}{s} + \frac{r'}{s'} = \frac{rs' + r's}{ss'}</math></blockquote>Some basic examples of localization include * The subset <math>S = \{1,p,p^2,p^3,\ldots\} \subset \mathbb{Z}</math> gives the ring <math>\mathbb{Z}[S^{-1}] = \mathbb{Z}[1/p]</math>. Notice that if we localized by the set <math>T = \{1,p^3,p^6,p^9,\ldots\} \subset \mathbb{Z}</math> then this gives the ring <math>\mathbb{Z}[1/p^3]</math>. But, because we could write <math>1/p</math> as <math>p^2/p^3</math>, these two rings are isomorphic. For brevity, we could just say that we localized <math>\mathbb{Z}</math> by <math>p</math>. Try localizing by some other non-zero integers and see why you find. * An important geometric example is given by localizing by some non-zero polynomial <math>f = f_1^{i_1}\cdots f_k^{i_k} \in \mathbb{C}[x_1,\ldots,x_n]</math>. * Given an integral domain <math>R</math>, we can take the set <math>S = R-\{0\}</math>. Then, <math>R[S^{-1}]</math> is called the '''field of fractions''' of the integral domain. (It is an exercise to check that this is a field) * Given a ring <math>R</math> and a prime ideal <math>\mathfrak{p}</math>, we can consider the set <math>S = R -\mathfrak{p}</math>. This is multiplicatively closed because of the properties of primality of an ideal. The localization of <math>R</math> by <math>S</math> is typically denoted <math>R_\mathfrak{p}</math>. For example, consider <math>(x,y) \subset \mathbb{C}[x,y]</math>. The localization can be described as <blockquote><math>\mathbb{C}[x,y][S^{-1}] = \mathbb{C}[x,y]_{\mathfrak{p}} = \left\{ \frac{f(x,y)}{g(x,y)} : f,g \in \mathbb{C}[x,y] \text{ and } g(0,0) \neq 0 \right\}</math></blockquote>The last example is special because it motivates a definition: a ring is '''local''' if it has a unique maximal ideal. The pair <math>(R_\mathfrak{p},\mathfrak{p})</math> is a local ring. ===Basic Module Theory=== A <math>R</math>-module is defined as an abelian group <math>M</math> with a fixed ring morphism <math>\phi:R \to \text{End}_{\textbf{Ab}}(M)</math>. We will use the notation :<math>r\cdot m := \phi(r)(m)</math> where <math>r\in R, m \in M</math> for the ring action on <math>M</math>. A morphism of <math>R</math>-modules <math>\psi:M\to M'</math> is defined by a commutative diagram <blockquote><math>\begin{matrix} && \text{End}_{\textbf{Ab}}(M) \\ & \nearrow\\ R && \downarrow \psi \\ & \searrow \\ && \text{End}_{\textbf{Ab}}(M') \end{matrix}</math></blockquote> We can use this construction to build a category of <math>R</math>-modules which is '''abelian'''. This means that it has a zero object, kernels and cokernels, products and coproducts, and images/co-images agree. Please note that we've had to enlarge our category of commutative rings to all rings since the endomorphism ring of an abelian group is generally non-commutative; This is one of the only cases where we use non-commutative unital rings in this book. Typical examples of <math>R</math>-modules includes * the zero object <math>0</math> * ideals <math>I\subset R</math> * direct sums, such as <math>M_1\oplus \cdots \oplus M_k</math> * a morphism <math>\phi:R\to S</math> of rings gives the structure of an <math>R</math>-module on the underlying abelian group of <math>S</math> Another useful technique for constructing new modules is taking the cokernel of a morphism <math>\psi:R^n \to R^m</math>. For example, the cokernel of<blockquote><math>\mathbb{C}[x,y,z]^{\oplus 2} \xrightarrow{\cdot (x^4 + y^4 + z^4 - 1)\oplus \cdot (x^4 - y^2 + z^2 + 1)} \mathbb{C}[x,y,z]</math></blockquote>is <math>\mathbb{C}[x,y,z]/(x^4 + y^4 + z^4 - 1,x^4 - y^2 + z^2 + 1)</math>. We can generalize this example using '''exact sequences'''. A sequence of objects in an abelian category <blockquote><math> M_1\xrightarrow{\phi_1}M_2 \xrightarrow{\phi_2} \to \cdots \xrightarrow{\phi_{n-1}} M_n </math> </blockquote>is called exact if each :<math>\frac{\text{Ker}(\phi_i)}{\text{Ker}(\phi_{i-1})} \cong 0</math> in the last example, we had the exact sequence :<math> R^{\oplus2} \to R \to M \to 0</math> In general, if there is an exact sequence :<math>R^n \to R^m \to M \to 0</math> for finite integers <math>m,n</math>, then we say that the module is '''of finite-type'''. If there is just a sequence :<math>R^n \to M \to 0</math> then we say that the module is '''finite'''. For example, the module :<math>k[x_1,x_2,\ldots] \to k \to 0</math> is finite but not finite-type since the kernel of the non-trivial morphism is the ideal :<math>(x_1,x_2,\ldots) \cong \bigoplus_{i=1}^\infty R\cdot x_i</math> ===Tensor Products=== * construct tensor products for modules * construct tensor products of algebras ** show that tensor products of integral domains are integral *** show that <math>k[\underline{x}]/(f(\underline{x})\otimes_k k[\underline{y}]/(g(\underline{y})) \cong k[\underline{x},\underline{y}]/(f(\underline{x}, g(\underline{y}))</math> *** show <math>k[\underline{x}]/(f(\underline{x}))\otimes_{k[\underline{x}]}k[\underline{x}]/(g(\underline{x})) \cong k[\underline{x}]/(f(\underline{x}),g(\underline{x}))</math> ===Finiteness, Chain Conditions=== If we have an <math>R</math>-algebra <math>R \to S</math> we say that <math>S</math> it is a '''finite''' if it is finite as a module. We say that it is '''of finite-type''' if there exists a surjective morphism <math>R[x_1,\ldots,x_n] \to S</math>, implying that :<math>S \cong \frac{R[x_1,\ldots,x_n]}{(f_1,\ldots,f_k)}</math> There are a couple other notions of "finiteness" which appear in commutative algebra called '''chain conditions'''. We say call a sequence of <math>R</math>-modules :<math>M_1\subseteq M_2\subseteq \cdots</math> an '''ascending chain''' and :<math> N_1\supseteq N_2 \supseteq \cdots</math> a '''descending chain'''. They satisfy the '''ascending chain condition''' or '''descending chain condition''' if there is some <math>k</math> such that <math>M_k=M_{k+1}=\cdots</math>, <math>N_k=N_{k+1}=N_{k+2}=\cdots</math>. If there exist chains :<math>M_1\subseteq M_2 \subseteq \cdots</math> where <math> \cup^\infty_{i=1}M_i = R</math> or :<math>R\supseteq N_2 \supseteq \cdots</math> then we say <math>R</math> is '''Noetherian''' or '''Artinian''', respectively. One can show that every Artinian ring is Noetherian. The basic examples of Noetherian rings include * Fields * <math>\mathbb{Z}</math> * Finite algebras over fields * Quotients of Noetherian rings. A simple non-example is given by the ring <math>k[x_1,x_2,x_3,\ldots]</math> where <math>k</math> is a field. There is a fundamental theorem in algebra called '''Hilbert's Basis Theorem''' stating:<blockquote>'''Theorem:''' If <math>R</math> is Noetherian, then <math>R[x_1,\ldots,x_n]</math> is Noetherian</blockquote>Hence all rings of the form<blockquote><math>\frac{R[x_1,\ldots,x_n]}{(f_1,\ldots,f_k)}</math></blockquote>are Noetherian. Artinian rings are much simpler than Noetherian rings:<blockquote>'''Theorem:''' Every Artin ring is a finite product of Artin local rings.</blockquote>All we have to analyze is the structure of an Artin local ring <math>(R,\mathfrak{m})</math>. Notice that we have a descending chain<blockquote><math>R \supseteq \mathfrak{m} \supseteq \mathfrak{m}^2 \supseteq \mathfrak{m}^3 \supseteq \cdots</math></blockquote>which eventually stabilizes at some <math>\mathfrak{m}^k</math>; this is the zero ideal <math>(0)</math>. We can use this to show the underlying <math>R/\mathfrak{m}</math>-vector space of <math>R</math> is finite dimensional. Some examples of artin local rings are * <math>(\mathbb{C}[x]/(x^5), (x))</math> * <math>(\mathbb{Q}[x,y]/((x-1)^3,(x-1)^2(y-2),(y-2)^5)), (x-1,y-2))</math> === Integrality === Given a morphism of commutative rings <math>R \to R'</math> we say an element <math>x \in R'</math> is '''integral''' over <math>R</math> if there is a monic polynomial <math>f(t) = t^n + a_{n-1}t^{n-1} +\cdot + a_1t + a_0 \in R[t] </math>and a morphism<blockquote><math>\frac{R[t]}{f(t)} \to R'</math></blockquote>sending <math>t \mapsto x</math>. For example, <math>\sqrt{-5} \in \mathbb{Z}[\sqrt{-5}]</math> is integral over <math>\mathbb{Z}</math> since<blockquote><math>\frac{\mathbb{Z}[t]}{(t^2 + 5)} \cong \mathbb{Z}[\sqrt{-5}]</math></blockquote>Adjoining all of the integral elements <math>\{x_i\}</math> <math>R</math> is called the '''integral closure of <math>R</math> in <math>R'</math>'''. An integral domain <math>R</math> is called '''integrally closed''' if every element in its fraction field is integral over <math>R</math>. For example, we can compute the integral closure of<blockquote><math>R = \frac{\mathbb{C}[x,y]}{(x^2 - y^3)}</math></blockquote>fairly easily. Since it is isomorphic to the ring <math>\mathbb{C}[x,x^{3/2}]</math> we should see immediately that <math>x^{1/2}</math> is not contained in <math>R</math>. Adjoining this element to <math>R</math> gives a ring isomorphic to <math>\mathbb{C}[s]</math>. As an exercise, try and unpack<blockquote><math>\frac{\mathbb{C}[x,y,z,w]}{(x^2 - y^5 - y^3, z^3 - w^4)}</math></blockquote>TODO: - hyperelliptic curves - quotient fields of curves - https://math.stackexchange.com/questions/2304521/why-is-this-coordinate-ring-integral-over-kx - rings of integers == Chapter 0 == === Basic Commutative Algebra === ==== Structures ==== * tensor products of modules/algebras... localization of modules * categories of commutative algebras * support of modules * graded rings * colimits and stalks * limits, completions, p-adics * valuations - https://en.wikipedia.org/wiki/Valuation_(algebra)#P-adic_valuation_on_a_Dedekind_domain * dimension * transcendence degree * functor formalism * categorical structures such as pullbacks and pushforwards * kahler differentials/ basic differential algebra * smooth algebras/smooth morphisms * complete intersection/local complete intersection morphisms * etale algebras/etale morphisms * galois theory with useful terminology... * same w/ algebraic number theory terminology... * basic homological algebra, ext, tor * koszul complexes * derived categories * grothendieck group * hilbert polynomial * grobner bases/elimination theory - https://mathoverflow.net/questions/60957/how-to-determine-whether-an-ideal-is-prime-or-not-by-an-algorithm ==== Theorems ==== * Eisenstein's Criterion * Primary Decomposition * Noether Normalization * Going up and down === Basic Differential/Complex Geometry === ==== Constructions ==== * Smooth manifolds * Morphisms * Vector Bundles * Topological K-theory * de-Rham Cohomology * Complex manifolds and sheaves * hodge decomposition of complex manifolds === Theorems === * Whitney embedding theorem * Submersion theorem * Sard's theorem {{BookCat}} 2iq34ygwtdxtig9vkhje2tyuffo4j91 4669086 4669085 2026-09-06T07:27:06Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669086 wikitext text/x-wiki == References == # Algebraic Geometry - Hartshorne # Arithmetic - Serre # https://people.ucsc.edu/~weissman/Math222A/SerreAnn.pdf # http://web.mit.edu/18.705/www/12Nts-2up.pdf (for basic commutative algebra) # https://arxiv.org/pdf/1605.04832.pdf (for more advanced commutative algebra) # [http://wstein.org/books/ant/ant.pdf Algebraic Number Theory, A Computational Approach] - Stein == Basic Commutative Algebra == ===Categories of Commutative Rings and Algebras=== The starting point for this section is the definition of a '''commutative ring''': a unital ring with commutative multiplication. In this book you can assume that all rings are commutative, so we will omit the 'commutative' adjective. The most basic rings include * <math>\mathbb{Z}</math> * <math>\mathbb{Z}/n</math> * Fields <math>\mathbb{F}</math> * Polynomial rings <math>R[x_1,\ldots,x_n]</math> We can relate rings to one another using a '''morphism''' of rings. A function <math>\phi: R \to S</math> between rings is a morphism of rings if the following two axioms are satisfied # <math>\phi(a + b) = \phi(a) + \phi(b)</math> (Additivity) # <math>\phi(ab) = \phi(a)\phi(b)</math> (Multiplicativity) we could have stated this succinctly as a function which respects the ring structure. It turns out that rings with ring morphisms form a category <math>\textbf{CRing}</math>. As an important technical note, there is no zero-ring given by a single element in our category. This category has an initial object given by the ring of integers because given a ring morphisms : <math>\phi:\mathbb{Z} \to R</math> the ring morphism axioms forces :<math>\phi(1) = 1_R</math>, <math>\phi(-1) = -1_R</math>, and <math>\phi(n) = \phi\left(\sum_n 1\right) = \sum_n \phi(1)</math> Recall that the category of <math>R</math>-algebras has objects given by ring morphisms <math>R \to S</math> and morphisms given by commutative diagrams <blockquote><math>\begin{matrix} && S \\ & \nearrow\\ R && \downarrow \phi \\ & \searrow \\ && S' \end{matrix}</math></blockquote>If we consider only algebras, the category <math>\mathbb{Z}-\textbf{CAlg}</math> is equivalent to the category <math>\textbf{CRing}</math>. Note that it is common to consider the categories <math>\mathbb{F}_q-\textbf{CAlg}</math>, <math>\mathbb{C}-\textbf{CAlg}</math>, <math>\mathbb{Q}_p-\textbf{CAlg}</math>. The motivation for why will be readily apparent when considering categories of schemes. ===Ideals=== One of the ways to construct new rings is by taking quotient rings. An ideal of a ring is a subset <math>I \subset R</math> which is # An abelian group under addition # <math>R\cdot I \subset R</math> Then, we can take the quotient of abelian groups <math>R/I</math> and use the multiplicative structure on <math>R</math> to construct one on <math>R/I</math>. The second axiom of ideals guarantees that this is well-defined. This is called a '''quotient ring'''. Some typical examples of quotient rings are given by * <math>\mathbb{Z}/(p)</math> * <math>\mathbb{Z}[x]/(x^2 - 5) \cong \mathbb{Z}[\sqrt{5}]</math> * <math>\mathbb{Q}[x]/(x^p-1)</math> * <math> \frac{\mathbb{Z}[x_1,\ldots,x_n]}{(f_1,\ldots,f_k)} </math> ===Playing with Presentations=== As we have seen, there are many ways to construct polynomial ring; but, another interesting technique for creating new polynomial rings is to attach variables which have relations between them. For example, consider <math>\mathbb{Z}[x,x^2,x^3]</math>. We can relabel the elements we've attached, so we consider the ring <math>\mathbb{Z}[X,Y,Z]</math>, but there are a couple relations between these variables: :<math>X^2 - Y, XY - Z</math> note that these two relations can be used to show others such as <math>XZ - Y^2</math> and <math>X^3 - Z</math>. Hence :<math>\mathbb{Z}[x,x^2,x^3] \cong \frac{\mathbb{Z}[X,Y,Z]}{(X^2 - Y, XY - Z)}</math> Some other examples include *<math>\mathbb{Z}[x,x^{3/2}] \cong \frac{\mathbb{Z}[X,Y]}{(Y^2 - X^3)} </math> *<math>\mathbb{Z}[x^2,xy,y^2] \cong \frac{\mathbb{Z}[X,Y,Z]}{(XZ - Y^2)}</math> *<math>\mathbb{Z}[x^3,x^2y,xy^2,y^3] \cong \frac{\mathbb{Z}[X,Y,Z,W]}{(XW - YZ, XZ - Y^2, YW - Z^2)}</math> ===Prime Ideals=== There are a special class of ideals called '''prime ideals''': an ideal <math>\mathfrak{p}</math> in a UFD <math>R</math> is prime if :<math>xy \in \mathfrak{p} \Leftrightarrow x \in \mathfrak{p} \text{ or } y \in \mathfrak{p}</math> For example, <math>(p) \subset \mathbb{Z}</math> is the first known example of a prime ideal. It should be apparent that <math>(6)</math> is not a prime ideal since <math> 2\cdot 3 \in (6)</math> but <math>2,3 \not\in (6)</math>. Now, given an irreducible polynomial <math>f \in S[x_1,\ldots,x_n]</math> the ideal <math>(f)</math> will be prime. A simple non-example of a prime ideal is given by <math>(xy) \subset \mathbb{C}[x,y]</math>. This can be generalized to <math>(fg) \subset S[x_1,\ldots,x_n]</math>. Some other examples of prime ideals include :<math>(x^2 + 1) \subset \mathbb{Q}[x]</math> :<math>(x-\alpha) \subset \mathbb{C}[x]</math> :<math>(y^2 - x^3 + 1) \subset \mathbb{C}[x,y]</math> If you take the quotient ring of a prime ideal in a UFD <math>R</math> you get an '''integral domain'''. This means your ring has the following multiplicative property: :<math>xy = 0</math> if <math>x=0</math> or <math>y=0</math> For example, in :<math> \frac{\mathbb{C}[x,y]}{(y^2 - x^3)}</math> you will never be able to multiply two non-zero elements together to get zero. The two key non-examples of a ring being an integral domain are :<math>\mathbb{C}[x,y]/(xy)</math> since <math>xy = 0</math> :<math>\mathbb{C}[x]/(x^2)</math> since <math> x \cdot x = 0</math> ''In general'', an ideal <math>\mathfrak{p}</math> of a ring <math>R</math> is called '''prime''' if <math>R/\mathfrak{p}</math> is an integral domain. If <math>R/\mathfrak{m}</math> is also a field, then we call <math>\mathfrak{m}</math> a '''maximal ideal'''. One useful exercise is to check that for a morphism <math>f:R \to S</math> and a prime ideal <math>\mathfrak{p}\subset S</math> the inverse image <math>f^{-1}(\mathfrak{p})</math> is a prime ideal. The second example motivates the operation of taking radicals of an ideal. Given an ideal <math>I\subseteq R</math> we define its radical as<blockquote><math>\sqrt{I} = \{ f \in R : f^k \in I \text{ for some } r \in \mathbb{N} \}</math></blockquote>For example, the radical of the ideal <math>((x^2 - y + z)^4(xyz - z^2)^5)\subset \mathbb{Z}[x,y,z]</math> is <math>((x^2 - y + z)(xyz - z^2))</math>. Given a quotient ring <math>R/I</math> we call the ring <math>R/\sqrt{I}</math> its reduction; sometimes this is denoted <math>(R/I)_{\text{red}}</math>. We define the '''nilradical''' of a ring <math>R</math> as <math>\sqrt{(0)}</math>. The nonzero elements in the nilradical are called '''nilpotents'''. ===Eisenstein's Criterion and Constructing Prime Ideals=== There is a generalization of Eisenstein's criterion for integral domains: given a ring <math>R</math> and a polynomial <math>f(x) \in R[x]</math> which can be written as :<math>f(x) = a_nx^n + a_{n-1}x^{n-1} + \cdots + a_1x + a_0</math> then it cannot be written as a product of polynomials if the following conditions are satisfied: Suppose there exists a prime ideal <math>\mathfrak{p}\subset R</math> such that :<math> \begin{align} a_i \in \mathfrak{p} \text{ for } i \neq n \\ a_n \not\in \mathfrak{p} \\ a_0 \not\in \mathfrak{p}^2 \end{align} </math> then <math>f(x)</math> cannot be written as a product of polynomials <math>g_1(x)\cdots g_k(x)</math>. For example, consider the integral domain <math>\mathbb{C}[x]</math> and the polynomial <math>f \in \mathbb{C}[x][y]</math> given by :<math>f(x,y) = 1\cdot y^3 + 0\cdot y^2 + 0\cdot y + x^3\cdot y^0 = y^3 + x^3</math> Using the prime ideal <math>(x-1)\subset \mathbb{C}[x]</math> we have that <math>a_1,a_2=0 \in (x-1)</math>, <math>a_3 = 1 \not\in (x-1)</math>, and <math>a_0 = x^3 \not\in (x-1)^2</math>. Hence :<math>(x^3 + y^3) \subset \mathbb{C}[x,y]</math> is a prime ideal. This example can be extended to show that :<math>x_1^{k_1} + \cdots + x_n^{k_n} \in \mathbb{C}[x_1,\ldots,x_n]</math> generates a prime ideal. ===Nullstellensatz=== Now we are in the right place to discuss the foundational theorem of algebraic geometry: '''Hilbert's nullstellensatz'''. Here we fix <math>k</math> as an algebraically closed field. '''Theorem:''' The maximal ideals of <math>\mathfrak{m}\subset k[x_1,\ldots,x_n]</math> are in bijection with the set <math>k^n</math>. For example, the kernel of <math>\text{ev}_{(1,2)}:\mathbb{C}[x,y] \to \mathbb{C}</math> is the ideal <math>(x-1,y-2)</math>. This allows one to interpret quotient rings give by ideals <math>I \subset k[x_1,\ldots,x_n]</math> as algebraic subsets of <math>k^n</math> because an evaluation morphism<blockquote><math>\text{ev}_{(\alpha_1,\ldots,\alpha_n)}:\mathbb{C}[x_1,\ldots,x_n]/I \to \mathbb{C}</math></blockquote>is well-defined only if <math>(x_1-\alpha_1,\ldots,x_n-\alpha_n) \subset k[x_1,\ldots,x_n]/I</math> is a maximal ideal. For example, consider the following example and non-example: * <math>\text{ev}_{(1,1)}:\mathbb{C}[x,y]/(y-x^2) \to \mathbb{C}</math> is a well defined morphism since<math>(x-1,y-1,y^2 - x) = (x-1,y-1,1^2 - 1) = (x-1,y-1)</math>This implies that <math>(1,1) \in \{ (a,b) \in \mathbb{C}^2 : b^2 - a\}</math> * <math>\text{ev}_{(1,2)}:\mathbb{C}[x,y]/(y-x^2) \to \mathbb{C}</math> is not a well-defined morphism because <math>(x-1,y-2,y^2-x) = (x-1,y-2,4-1) = (1)</math>; there is no quotient ring <math>R/(1)</math>. Hence <math>(1,2) \not\in \{ (a,b) \in \mathbb{C}^2 : b^2 - a\}</math> Now we can interpret rings which are not integral. For example, we saw that <math>\mathbb{C}[x,y]/(xy)</math> is not an integral domain. Geometrically, this is the union of the <math>x</math> and <math>y</math> axes. The other main case of a non-integral ring is a non-reduced ring. For example, <math>\mathbb{C}[x,y]/(y^3)</math> is the <math>x</math>-axis but there is extra algebraic information from the <math>y,y^2</math> left over. The way you should interpret this ring as is a '''fat''' line. === Basic Scheme Theory === We can now ''confidently'' define an affine scheme: it is a functor<blockquote><math>\text{Hom}_\mathbf{CRing}(R,-): \mathbf{CRing} \to \textbf{Sets}</math></blockquote>for some fixed commutative ring <math>R</math>. === Localization === The next basic construction in commutative ring theory is '''localization'''. This defines a generalization of inverting the non-zero integers and getting the rational numbers. Let <math>S\subset R</math> be a multiplicatively closed subset with unity, meaning <math>1 \in S</math> and <math> s,s' \in S \Rightarrow ss' \in S</math>. For example, for a fixed element <math>f \in R</math> consider the subset <math>\{1,s,s^2,s^3,\ldots\}</math>. We define a commutative ring <math>R[S^{-1}]</math> as follows. First, consider the set <math>R\times S / \sim</math> where<blockquote><math>(r,s) \sim (r',s') \text{ if there exists } u \in S \text{ such that } u(rs' - r's) =0</math></blockquote>(don't worry, we will given a motivating example for this seemingly random <math>u</math>). It is an exercise to verify that this indeed defines an equivalence relation — it is standard to write these equivalence classes as <math>r/s</math>. These equivalence classes have a well-define commutative ring structure given by<blockquote><math>\frac{r}{s} \cdot \frac{r'}{s'} = \frac{rr'}{ss'} \text{ and } \frac{r}{s} + \frac{r'}{s'} = \frac{rs' + r's}{ss'}</math></blockquote>Some basic examples of localization include * The subset <math>S = \{1,p,p^2,p^3,\ldots\} \subset \mathbb{Z}</math> gives the ring <math>\mathbb{Z}[S^{-1}] = \mathbb{Z}[1/p]</math>. Notice that if we localized by the set <math>T = \{1,p^3,p^6,p^9,\ldots\} \subset \mathbb{Z}</math> then this gives the ring <math>\mathbb{Z}[1/p^3]</math>. But, because we could write <math>1/p</math> as <math>p^2/p^3</math>, these two rings are isomorphic. For brevity, we could just say that we localized <math>\mathbb{Z}</math> by <math>p</math>. Try localizing by some other non-zero integers and see why you find. * An important geometric example is given by localizing by some non-zero polynomial <math>f = f_1^{i_1}\cdots f_k^{i_k} \in \mathbb{C}[x_1,\ldots,x_n]</math>. * Given an integral domain <math>R</math>, we can take the set <math>S = R-\{0\}</math>. Then, <math>R[S^{-1}]</math> is called the '''field of fractions''' of the integral domain. (It is an exercise to check that this is a field) * Given a ring <math>R</math> and a prime ideal <math>\mathfrak{p}</math>, we can consider the set <math>S = R -\mathfrak{p}</math>. This is multiplicatively closed because of the properties of primality of an ideal. The localization of <math>R</math> by <math>S</math> is typically denoted <math>R_\mathfrak{p}</math>. For example, consider <math>(x,y) \subset \mathbb{C}[x,y]</math>. The localization can be described as <blockquote><math>\mathbb{C}[x,y][S^{-1}] = \mathbb{C}[x,y]_{\mathfrak{p}} = \left\{ \frac{f(x,y)}{g(x,y)} : f,g \in \mathbb{C}[x,y] \text{ and } g(0,0) \neq 0 \right\}</math></blockquote>The last example is special because it motivates a definition: a ring is '''local''' if it has a unique maximal ideal. The pair <math>(R_\mathfrak{p},\mathfrak{p})</math> is a local ring. ===Basic Module Theory=== A <math>R</math>-module is defined as an abelian group <math>M</math> with a fixed ring morphism <math>\phi:R \to \text{End}_{\textbf{Ab}}(M)</math>. We will use the notation :<math>r\cdot m := \phi(r)(m)</math> where <math>r\in R, m \in M</math> for the ring action on <math>M</math>. A morphism of <math>R</math>-modules <math>\psi:M\to M'</math> is defined by a commutative diagram <blockquote><math>\begin{matrix} && \text{End}_{\textbf{Ab}}(M) \\ & \nearrow\\ R && \downarrow \psi \\ & \searrow \\ && \text{End}_{\textbf{Ab}}(M') \end{matrix}</math></blockquote> We can use this construction to build a category of <math>R</math>-modules which is '''abelian'''. This means that it has a zero object, kernels and cokernels, products and coproducts, and images/co-images agree. Please note that we've had to enlarge our category of commutative rings to all rings since the endomorphism ring of an abelian group is generally non-commutative; This is one of the only cases where we use non-commutative unital rings in this book. Typical examples of <math>R</math>-modules includes * the zero object <math>0</math> * ideals <math>I\subset R</math> * direct sums, such as <math>M_1\oplus \cdots \oplus M_k</math> * a morphism <math>\phi:R\to S</math> of rings gives the structure of an <math>R</math>-module on the underlying abelian group of <math>S</math> Another useful technique for constructing new modules is taking the cokernel of a morphism <math>\psi:R^n \to R^m</math>. For example, the cokernel of<blockquote><math>\mathbb{C}[x,y,z]^{\oplus 2} \xrightarrow{\cdot (x^4 + y^4 + z^4 - 1)\oplus \cdot (x^4 - y^2 + z^2 + 1)} \mathbb{C}[x,y,z]</math></blockquote>is <math>\mathbb{C}[x,y,z]/(x^4 + y^4 + z^4 - 1,x^4 - y^2 + z^2 + 1)</math>. We can generalize this example using '''exact sequences'''. A sequence of objects in an abelian category <blockquote><math> M_1\xrightarrow{\phi_1}M_2 \xrightarrow{\phi_2} \to \cdots \xrightarrow{\phi_{n-1}} M_n </math> </blockquote>is called exact if each :<math>\frac{\text{Ker}(\phi_i)}{\text{Ker}(\phi_{i-1})} \cong 0</math> in the last example, we had the exact sequence :<math> R^{\oplus2} \to R \to M \to 0</math> In general, if there is an exact sequence :<math>R^n \to R^m \to M \to 0</math> for finite integers <math>m,n</math>, then we say that the module is '''of finite-type'''. If there is just a sequence :<math>R^n \to M \to 0</math> then we say that the module is '''finite'''. For example, the module :<math>k[x_1,x_2,\ldots] \to k \to 0</math> is finite but not finite-type since the kernel of the non-trivial morphism is the ideal :<math>(x_1,x_2,\ldots) \cong \bigoplus_{i=1}^\infty R\cdot x_i</math> ===Tensor Products=== * construct tensor products for modules * construct tensor products of algebras ** show that tensor products of integral domains are integral *** show that <math>k[\underline{x}]/(f(\underline{x})\otimes_k k[\underline{y}]/(g(\underline{y})) \cong k[\underline{x},\underline{y}]/(f(\underline{x}, g(\underline{y}))</math> *** show <math>k[\underline{x}]/(f(\underline{x}))\otimes_{k[\underline{x}]}k[\underline{x}]/(g(\underline{x})) \cong k[\underline{x}]/(f(\underline{x}),g(\underline{x}))</math> ===Finiteness, Chain Conditions=== If we have an <math>R</math>-algebra <math>R \to S</math> we say that <math>S</math> it is a '''finite''' if it is finite as a module. We say that it is '''of finite-type''' if there exists a surjective morphism <math>R[x_1,\ldots,x_n] \to S</math>, implying that :<math>S \cong \frac{R[x_1,\ldots,x_n]}{(f_1,\ldots,f_k)}</math> There are a couple other notions of "finiteness" which appear in commutative algebra called '''chain conditions'''. We say call a sequence of <math>R</math>-modules :<math>M_1\subseteq M_2\subseteq \cdots</math> an '''ascending chain''' and :<math> N_1\supseteq N_2 \supseteq \cdots</math> a '''descending chain'''. They satisfy the '''ascending chain condition''' or '''descending chain condition''' if there is some <math>k</math> such that <math>M_k=M_{k+1}=\cdots</math>, <math>N_k=N_{k+1}=N_{k+2}=\cdots</math>. If there exist chains :<math>M_1\subseteq M_2 \subseteq \cdots</math> where <math> \cup^\infty_{i=1}M_i = R</math> or :<math>R\supseteq N_2 \supseteq \cdots</math> then we say <math>R</math> is '''Noetherian''' or '''Artinian''', respectively. One can show that every Artinian ring is Noetherian. The basic examples of Noetherian rings include * Fields * <math>\mathbb{Z}</math> * Finite algebras over fields * Quotients of Noetherian rings. A simple non-example is given by the ring <math>k[x_1,x_2,x_3,\ldots]</math> where <math>k</math> is a field. There is a fundamental theorem in algebra called '''Hilbert's Basis Theorem''' stating:<blockquote>'''Theorem:''' If <math>R</math> is Noetherian, then <math>R[x_1,\ldots,x_n]</math> is Noetherian</blockquote>Hence all rings of the form<blockquote><math>\frac{R[x_1,\ldots,x_n]}{(f_1,\ldots,f_k)}</math></blockquote>are Noetherian. Artinian rings are much simpler than Noetherian rings:<blockquote>'''Theorem:''' Every Artin ring is a finite product of Artin local rings.</blockquote>All we have to analyze is the structure of an Artin local ring <math>(R,\mathfrak{m})</math>. Notice that we have a descending chain<blockquote><math>R \supseteq \mathfrak{m} \supseteq \mathfrak{m}^2 \supseteq \mathfrak{m}^3 \supseteq \cdots</math></blockquote>which eventually stabilizes at some <math>\mathfrak{m}^k</math>; this is the zero ideal <math>(0)</math>. We can use this to show the underlying <math>R/\mathfrak{m}</math>-vector space of <math>R</math> is finite dimensional. Some examples of artin local rings are * <math>(\mathbb{C}[x]/(x^5), (x))</math> * <math>(\mathbb{Q}[x,y]/((x-1)^3,(x-1)^2(y-2),(y-2)^5)), (x-1,y-2))</math> === Integrality === Given a morphism of commutative rings <math>R \to R'</math> we say an element <math>x \in R'</math> is '''integral''' over <math>R</math> if there is a monic polynomial <math>f(t) = t^n + a_{n-1}t^{n-1} +\cdot + a_1t + a_0 \in R[t] </math>and a morphism<blockquote><math>\frac{R[t]}{f(t)} \to R'</math></blockquote>sending <math>t \mapsto x</math>. For example, <math>\sqrt{-5} \in \mathbb{Z}[\sqrt{-5}]</math> is integral over <math>\mathbb{Z}</math> since<blockquote><math>\frac{\mathbb{Z}[t]}{(t^2 + 5)} \cong \mathbb{Z}[\sqrt{-5}]</math></blockquote>Adjoining all of the integral elements <math>\{x_i\}</math> <math>R</math> is called the '''integral closure of''' <math>R</math> '''in''' <math>R'</math>. An integral domain <math>R</math> is called '''integrally closed''' if every element in its fraction field is integral over <math>R</math>. For example, we can compute the integral closure of<blockquote><math>R = \frac{\mathbb{C}[x,y]}{(x^2 - y^3)}</math></blockquote>fairly easily. Since it is isomorphic to the ring <math>\mathbb{C}[x,x^{3/2}]</math> we should see immediately that <math>x^{1/2}</math> is not contained in <math>R</math>. Adjoining this element to <math>R</math> gives a ring isomorphic to <math>\mathbb{C}[s]</math>. As an exercise, try and unpack<blockquote><math>\frac{\mathbb{C}[x,y,z,w]}{(x^2 - y^5 - y^3, z^3 - w^4)}</math></blockquote>TODO: - hyperelliptic curves - quotient fields of curves - https://math.stackexchange.com/questions/2304521/why-is-this-coordinate-ring-integral-over-kx - rings of integers == Chapter 0 == === Basic Commutative Algebra === ==== Structures ==== * tensor products of modules/algebras... localization of modules * categories of commutative algebras * support of modules * graded rings * colimits and stalks * limits, completions, p-adics * valuations - https://en.wikipedia.org/wiki/Valuation_(algebra)#P-adic_valuation_on_a_Dedekind_domain * dimension * transcendence degree * functor formalism * categorical structures such as pullbacks and pushforwards * kahler differentials/ basic differential algebra * smooth algebras/smooth morphisms * complete intersection/local complete intersection morphisms * etale algebras/etale morphisms * galois theory with useful terminology... * same w/ algebraic number theory terminology... * basic homological algebra, ext, tor * koszul complexes * derived categories * grothendieck group * hilbert polynomial * grobner bases/elimination theory - https://mathoverflow.net/questions/60957/how-to-determine-whether-an-ideal-is-prime-or-not-by-an-algorithm ==== Theorems ==== * Eisenstein's Criterion * Primary Decomposition * Noether Normalization * Going up and down === Basic Differential/Complex Geometry === ==== Constructions ==== * Smooth manifolds * Morphisms * Vector Bundles * Topological K-theory * de-Rham Cohomology * Complex manifolds and sheaves * hodge decomposition of complex manifolds === Theorems === * Whitney embedding theorem * Submersion theorem * Sard's theorem {{BookCat}} ar92so9tv1lvcz247phreutf04dhkms User:Kaliru/Barnstars 2 407387 4669015 3547213 2026-09-05T19:30:59Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669015 wikitext text/x-wiki {{User:Kaliru/navbar}} == Thank you for being one of Wikipedia's top medical contributors! == <div lang="en" dir="ltr" class="mw-content-ltr"> :''please help translate this message into your local language via [https://meta.wikimedia.org/wiki/Wiki_Project_Med/The_Cure_Award meta]'' {| style="background-color: #fdffe7;{{Text default color}}; border: 1px solid #fceb92;" |rowspan="2" style="vertical-align: middle; padding: 5px;" | [[File:Wiki Project Med Foundation logo.svg|100px]] |style="font-size: x-large; padding: 3px 3px 0 3px; height: 1.5em;" |'''The 2018 Cure Award''' |- | style="vertical-align: middle; padding: 3px;" |In 2018 you were one of the [[W:EN:Wikipedia:WikiProject Medicine/Stats/Top medical editors 2018 (all)|top ~250 medical editors]] across any language of Wikipedia. Thank you from [[m:WikiProject_Med|Wiki Project Med Foundation]] for helping bring free, complete, accurate, up-to-date health information to the public. We really appreciate you and the vital work you do! Wiki Project Med Foundation is a [[meta:user group|user group]] whose mission is to improve our health content. Consider joining '''[[meta:Wiki_Project_Med#People_interested|here]]''', there are no associated costs. |} Thanks again :-) -- [[W:EN:User:Doc James|<span style="color:#0000f1">'''Doc James'''</span>]] along with the rest of the team at '''[[m:WikiProject_Med|Wiki Project Med Foundation]]''' 17:55, 28 சனவரி 2019 (UTC) </div> <!-- Message sent by User:Doc James@metawiki using the list at https://meta.wikimedia.org/w/index.php?title=Global_message_delivery/Targets/Top_Medical_Editors_2018/other&oldid=18822373 --> 3uziq77769hw4hujqhgypnftm82jirf Baroque Macedonia and the Macedonian Revolts/Chapter 3 : The gathering of troops 0 408710 4669096 4532896 2026-09-06T10:54:46Z WereSpielChequers 248949 typo 4669096 wikitext text/x-wiki === Chapter 3 === '''The gathering of troops''' The Macedonians had also attempted a revolt back in the mid-16th century and this was one of the very first revolts ever to occur. The local uprising took place in 1564, it began in the [[wikipedia:Mariovo|Mariovo]] region and spread to the Prilep plains and from there to the town of [[wikipedia:Prilep|Prilep]]. Known as the Mariovo and Prilep revolt, it is unknown why this revolt began, but it is clear that three peasants and two priests from the Mariovo district started it. No sooner had the trouble started when the Sultan, through a [[wikipedia:decree|decree]] dated October 3, 1564, ordered that the leaders of the revolt be put to death while the followers were to be sent to serve as oarsmen on Turkish galleys. Before the decree could be enforced, however the perpetrators fled causing the Sultan to order another decree for their capture. The [[wikipedia:Mariovo and Prilep rebellion|Mariovo and Prilep rebellion]] was one that was unsuccessful and the rebellion was suppressed by the Ottoman troops. Prilep soon became a place known for demonstrations, when the Ottoman court ruled in favour of a Pasha in a dispute with the peasants. According to a document dated December 1565 a revolt broke out inside the town of Prilep. The situation began when the Prilep court, in settling a dispute between the peasants and Mustafa Pasha, ruled in favour of the Pasha. Later the news hit the streets and more than a thousand rebels from the surrounding villages, armed with garden shovels, and long barrelled muskets assembled and stormed the court. It is unknown how this situation or incident ended. As explained previously the peasants eventually had no chance in further causing trouble as the large Ottoman forces greatly enforced order upon the peasant rebels. According to historical sources General Piccolomini was currently in the town of [[wikipedia:Nis|Nis]], Ottoman Serbia, he arrived there on the 24th of September, 1689 in the early hours of the morning. With him was also the Austrian commander, [[wikipedia:Louis William, Margrave of Baden-Baden|Louis William, Margrave of Baden-Baden]]. Accompanying the two commanders was Pavle Nestorović who was a Serbian commander that assisted Piccolomini, during the capture of Nis. Nis was a quite town located in the southern part of Ottoman Serbia, it had a [[wikipedia:garrison|garrison]] of approximately 40,000 soldiers or most likely over 40,000. Louis William had a total of about 16,000 troops, most of them were Austrian however there were also Serbian troops. When Louis William learned that there were no Ottoman defence positions on Vinik he ordered Pavle to attack. Eventually Pavle was successful and the Battle of Nis ended with an Austrian victory. Pavle was promoted and later Louis William had decided to leave for [[wikipedia:Vidin|Vidin]] while Piccolomini was left to keep an eye on Nis. The next month Piccolomini left for Ottoman Macedonia, and when this happened the Ottoman troops once again gained possession of the Sanjak of Nis. [[File:Musket01.jpg|thumb|A Macedonian soldier or rebel holding a heavy musket, circa 1610.]] [[File:Maps 09.jpg|thumb|A cartographic map of Central Europe, circa 1806.]] On the right we see a photo of a Macedonian rebel holding a heavy musket. These types of guns were very popular during the first half of the 17th century. A musket is a muzzle-loaded long gun that appeared as a smoothbore weapon in the early 16th century, at first as a heavier variant of the [[wikipedia:arquebus|arquebus]] capable of penetrating heavy armor if fired correctly. Distinguished features of a heavy musket was a very long barrel, the reason for this extremely long barrel was to gain a good or reasonable range. Evidence of the musket as a type of firearm does not appear until 1521, the long-barreled, musket-caliber weapons had been in use as wall-defense weapons in Europe and in other continents. By 1650 the heavy musket eventually become obsolete due to its size and weight, as a result of this the musket was improved. By 1690 the wearing of knights armor dramatically decreased, this was probably due to the increased power of certain types of guns. There are two sources regarding the arrival of Silvio Piccolomini to the city of Uskup (Skopje). General Piccolomini arrived in Uskup in late October, 1689. One historical source explains that when General Piccolomini entered Uskup he was greeted by the people of Uskup, and there was also a fanfare playing at the time, while the other historical source explains that when he arrived to the city, the city was most likely abandoned and there was only a few people. When General Piccolomini set out from the Habsburg Empire he had a total of 4,000 soldiers most of them were cavalry, after the battle of Nis, his armies were reduced as some of them were killed in action or were injured and had to remain behind. Overall his armies now were a small number, and this greatly affected his abilities to guard or even defend a large city such as Uskup. With General Piccolomini in Uskup, what happened to the Ottoman garrison that was stationed in Uskup ? Did they withdraw from the city of Uskup after witnessing the Austrian armies entering the city, or was the city unguarded and no Ottoman troops were positioned within the streets of Uskup ? These are just some questions that have puzzled the Macedonian historians. The answer to this question is that there were no Ottoman soldiers stationed within Uskup (Skopje) at the time, because if there was then a fierce battle would break out. There was no armed conflict between the Ottoman troops and the Austrian cavalry units within Uskup. While staying in Skopje, Piccolomini started feeling very ill. He was unaware that he had contracted some form of disease. According to historical accounts, Piccolomini had [[wikipedia:cholera|cholera]] and his health was beginning to deteriorate. Piccolomini had the following symptoms : diarrhea, vomiting, dehydration, and discoloration of the skin. It is unclear how Piccolomini contracted cholera, it was most likely through the drinking of contaminated water or the eating of food that was contaminated with the bacterium. Back in the late 17th Century (1601-1700) the medical knowledge relating to cholera was limited, doctors were uncertain as to what caused the disease, and their current medicines provided no relief or prevention from the bacterium. Piccolomini was beginning to feel very weak due to the cholera, on the 26th of October, 1689 he ordered his armies to burn the city of Skopje. His troops placed gunpowder all around some of the buildings within the centre of Skopje and a fire was started. The [[wikipedia:Skopje fire of 1689|Skopje fire of 1689]] lasted two whole days, burning much of the wooden structures and buildings. The fire later spread towards the Jewish quarter of the city, the Jewish synagogue and a Jewish church was completely destroyed in the fire. However many of the stone buildings remained, but were blackened by the raging fire. Due to General Piccolomini's health he had decided to disband from his armies, heading to Ottoman Albania. General Piccolomini's reason for going to Ottoman Albania was so that he can board a ship and head back to Austria. In the cartographic map of Europe which is shown on the right, the Habsburg Empire also known as the Imperial Austrian Empire had access to the [[wikipedia:adriatic sea|adriatic sea]]. It was a small region just north of Ottoman Bosnia where Austria had a number of ports, here the galleons would arrive and unload. The prospects for Austrian arms in Macedonia and Albania looked promising, but a few days later Piccolomini died of the plague and his successor duke Georg Christian Von Holstein was unable to capitalize on the so called " Karposh Uprising " of the Christian peasantry which broke out in Macedonia at about this time.<ref> Atlas of Southeast Europe : Geopolitics and History. Volume 1: 1521-1699, Author : Hans H.A Hotte. p.15 2015</ref> Eventually assistance from the Austrian armies ended and the continuation of the Karposh uprising went until December, 1689. {{bookcat}} jq75jpomr5ep9yj43fh98ahqzllk9o2 User talk:Benjamin Shepard 3 424053 4669062 3821111 2026-09-06T06:41:10Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669062 wikitext text/x-wiki == Welcome! == <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Benjamin Shepard!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> </div> <div style="clear:both;"> </div> --[[User:Mrjulesd|<span style="color:orange;">Jules</span>]]&nbsp;[[User talk:Mrjulesd|(Mrjulesd)]] 09:21, 26 March 2021 (UTC) sadzlv4eazpvdy82xoup3fvdwbqzxyj Template:Unichar/main 10 425117 4669091 3839290 2026-09-06T10:06:05Z Warudo 3310627 Passed the na parameter to /glyph. 4669091 wikitext text/x-wiki {{#ifexpr:({{{dval|-1}}}=0) and ({{#ifeq:X{{{hval}}}|X0000 |0 |1}}) |<!--(error triggered if X{{{hval}}} ≠ X0000:)-->{{Error |tag=span |Error using {{tl|unichar}}: Input "{{{hvalinput|}}}" is not a [[hexadecimal]] value.}} | {{nowrap|{{{{#ifeq:{{{sans|}}}|y|sans-serif|mono}}|{{Unichar/ulink |ulink={{{ulink|<#salted#>}}} |ulinkdefault=Unicode}}{{{hval|}}}}}&#x20;}}<!-- -->{{Unichar/glyph |hval={{{hval|}}} |gc={{{gc|<#not a Unicode code point#>}}} |size={{{size}}} |use={{{use|}}} |use2={{{use2|}}} |cwith={{{cwith|}}} |image={{{image|}}} |br={{{br|}}} |na={{{na|}}} }} <!-- -->{{Unichar/name |na={{{na|}}} |nlink={{{nlink|<#salted#>}}} |gc={{{gc|}}} }} <!-- -->{{Unichar/notes |dval={{{dval|}}} |dec={{{dec|}}} |html={{{html|}}} |char_entity={{#ifeq:{{{html|+}}}|{{{html|-}}} |{{#invoke:LoadData|Numcr2namecr|{{{dval|}}}}}}} |note={{{note|}}} |finaltext={{{finaltext|NOTEXT}}} }} }}<!-- --><noinclude>{{Documentation|1=Template:Unichar/doc}}</noinclude> gl3feks5qj98q4f5bxop6t5swl9hei0 Writing Adolescent Fiction/Character names/Congolese 0 434722 4669090 4612863 2026-09-06T10:02:27Z ~2026-48191-33 3625303 added the name Tshibenji (luba, 178) 4669090 wikitext text/x-wiki Like many other African countries, the Congos have many tribes, each of those tribes having their own unique names. kongo names Mavinga, Malanda, Mambwene, Tulunga, Masamba, Luyeye, Teholo, Mambweni, Mambu,Fimpa, Mateta, Tuzolana, Matumona, Matunwene, Malangi, Wasewa, Bukaka ,Mayala, Masukidi, Diawaku, Diakanua, Ndongala, Ndombele, Matondo, Mampasi, Sita, Luzolo, Nsimba, Nzuzi, Landu, Nsakala, Nsukula, Diyamona, Biyavanga, Zola, Nkiluku, Kimwina, Kukiele, Kuyela, Kuma, Kimbangu, Kisolokele, Diasivi, Mamona, Zolana, Batukweme, Wasewa, Nseyila, Nkembo, Nsambu, Siluvagi, Vangu, Nzumba, Nsukula, Mavoka, Bwene, Mbala, Mbunba, Sala, Diasivi, Dialungana, Banzola, Mbala, Mbemba, Bisala, Nsiluvangu, Bueyasa, Makiadi, Makiese, Bukaka, Mayenda, Kiala, Malanga, Manzambi, Ntunga, Mbambi, sela, Mavoka, Sumpi, Mabiala, Makiadi, Lengi, Tezo, Tekasala, Tangi, Kamwanako, Nseka, Manduakila, Teholo, Tezangi, Mbutu, Nsinsani, Maviokele, Diambuana, Lukombo, Lusikila, Luyeye, Nzazi, Vayemba, Yengo, Kiambukuta, Tulunga, Dilu, Kiamwangana, Diwete, Nzomuisi, Senga, Mpaka, Ntalu. ==Kongo First names== The kongo tribe makes a difference between first and last names. Most first names are gender neutral. #Angola #Angolo #Kimpa #Longi #Luzolo #Manzambi #Masa #Matondo #Mawete #Maza #Mbuetete #Mfumu #Mfulutoma #Miezi #Muanda #Mvemba #Mvembaur #Namibi #N'semi #Ntangu #Ntinu #Nzinga #Nzola #Sema #Vita #Wasakumunua #Yulu #Zayi #Zulu ==Luba names == #Babanya #Badiambila #Badibanga #Badila #Bakika #Bakaji #Bakatupenda #Bajikijayi #Balela #Baloji #Bambi #Batubenga #Beleshayi #Bende(a) #Biakabutuka #Biakupa #Bikuta #Bintu #Bitumba #Biuma #Bolayi #Bulembi #Buloba #Diba #Dibuba #Dibwe(a) #Dikasa #Dikoba #Ditu #Ilonda #Ilunda #Ilunga #Kabange(a) #Kabasele #Kabasubabo #Kabatuswila #Kabedi #Kabeya #Kabishi #Kaboko #Kabongo (boy's name) #Kabose #Kabudi #Kabula #Kabundi #Kabungama #Kadima #Kakona #Kalala #Kalambayi #Kalengayi #Kalombo #Kalonda #Kalonji #Kalwanda #Kamanda #Kamudimba #Kamwanya #Kambuji #Kande(a) #Kanjinga (girl's name) #Kapela #Kapeta #Kapinga #Kantu #Kanubantu #Kapuku #Kasanda #Kasanji #Kasenda #Kashala #Kashama #Kasukupa #Kasumpata #Kasusula #Katanda (boy's name) #Katuku #Katuma #Katumbi #Kayembe #Kazadi #Kazambu #Kidiaba #Kimba #Kitambala #Kongolo #Konji #Luboya #Lukoji #Lukusa #Lusamba #Lwakanwanga #Kasanda #Mambuyi #Mampuya #Mbelu #Mbuyi #Mbwaya #Meji Mwamba #Mfuni/Mfunyi #Midibu / Midjibu #Mikalayi #Misenga #Mpoku #Mputu #Mpyana #Mubiala #Muboyayi #Muci #Mudiayi #Mudimbe #Mudingayi #Mufuta #Mujanayi #Mujinga (girl's name) #Mukeba #Mukebayi #Mukendi #Mukenge #Mukengeshayi #Mukinayi #Mukoka #Mukuna #Mukunayi #Mukunyi #Mukuta #Mulamba #Mulanga #Mulenda #Mulondo #Mulongo #Mulowa #Mulowayi #Mulumba #Mulumbu #Mulume #Mumengi #Muntu/Bantu #Musanda #Mushiya #Musungayi #Muswama #Muswamba (wa ba Mbuyi) #Muteba #Mutoke #Mutombo #Mutshipayi #Mvidiakuumpa #Mwambi #Mwepu #Mwipatayi #Ndala #Ndaye(a) #Ndomba #Ndombela #Nga(lu)lamulume #Ngalula(mukaji) #Ngandu #Ngondu #Ngoyi #Nkala #Nkashama #Nsanga (Diboko) #Nsanza #Ntambwe #Ntumba #Ntumpula #Nzadi #Shambuyi #Tshamba #Tshambwe #Tshiabu #Tshianza #Tshibamba #Tshibanda #Tshibangu #Tshibelu #Tshibenji #Tshibuabua #Tshidinda Kasapa #Tshiela (Makasa) #Tshiende(a) #Tshika #Tshikala #Tshikudimena #Tshikuta #Tshikuatakuata #Tshilanda #Tshilemba #Tshilobo #Tshilombo #Tshilonga #Tshimankinda #Tshimanga #Tshimpaka #Tshinabu wa Munda #Tshintu #Tshingombe #Tshinyama Tshiolola #Tshiomba ou Tshomba #Tshiowa (Mashi) #Tshiowela #Tshipamba #Tshisekedi #Tshiswabantu #Tshiswaka #Tshituka #Tshomba #Tumbishayi #Tunda wa Munda #Waku Menga {{BookCat}} tvihmvq25ss4p0pv67j3srrnaewbuab Maxima/Data structures 0 438298 4668961 4668764 2026-09-05T17:26:51Z Idavidmiller 3577687 Work in progress. Saving Changes. 4668961 wikitext text/x-wiki == Maxima Aggregate Data Structures == === Introduction === This book is intended to present some of the essentials of what is called Maxima aggregate data structures. By this it is meant the data types that can be used to refer to the values of expressions using a means of indexing of a single identifier (name) that refers to an aggregate (collection) of expressions as values. Built-in aggregate data types include: * lists * hashed arrays * declared arrays * structures Each of these has a means of indexing an identifier that names an instance of these data types. Please note that it is the case that this means of indexing an identifier for an aggregate data type may be referred to as involving "subscripts" or "sub-scripted variables" or "keys" as used by various computer programming languages, as well as in the context of Maxima documentation and commentary. In this book terms such as "index" or "indices" or "indexed identifiers"  are used instead. Also all built-in Maxima functions (including packages) for these data types are referred to as ''"operators"'' and not ''"functions"'' as this latter term in general serves better to refer to Maxima function expressions defined by the user -- as in <code>f(x) :=</code>, <code>g[s] :=</code> and <code>define ()</code> as examples. This section is not intended to be exhaustive. It is intended to provide familiarity with aggregate data types. What is included has been gleaned from various sources, and only a few attributions are provided. Therefore, there is no claim of originality implied. === Lists === ==== Introduction to Lists ==== Lists are one of the basic buildings block for Maxima and Lisp. Maxima expressions are in general represented as Lisp lists. For example, consider the Maxima expression:<syntaxhighlight lang="maxima"> (%i1) e+3; (%o1) e+3 </syntaxhighlight>This expression has the form of a Lisp list:<syntaxhighlight lang="maxima"> (%i2) :lisp #$[e+3]$ ((MLIST SIMP) ((MPLUS SIMP) 3 $E)) </syntaxhighlight>An expression in the form of a Lisp list can also be be displayed as a Maxima expression:<syntaxhighlight lang="maxima"> (%i2) :lisp (displa '((MLIST SIMP) ((MPLUS SIMP) 3 $E))); [e+3] NIL </syntaxhighlight>Note that the value of this expression using <code>displa '()</code> is <code>NIL</code>, and <code>[e+3]</code> is simply displayed in Maxima list object form. It is not necessary for the typical uses of Maxima to utilize this insight into the role Lisp lists have as one of the building blocks for Maxima, but it may be useful to have a familiarity with that role. Lists are often used as arguments to many operators, and the values of expressions are often in the form of lists. ==== Some Operators for Lists ==== Lists are created explicitly and list elements referenced using <code>[</code> and <code>]</code> to mark the beginning and end, respectively, of an instance of a list object, or to reference the expressions of an existing list object.<syntaxhighlight lang="maxima"> (%i3) [2,3,4]; (%o3) [2,3,4] </syntaxhighlight>The expression <code>[2,3,4]</code> creates a Maxima list object. In this case the object itself is not accessible as it was not assigned an identifier unless referenced by the <code>%</code> , <code>%i</code> or <code>%o</code> label.<syntaxhighlight lang="maxima"> (%i4) %; (%o4) [2,3,4] (%i5) %o4[2]; /* second expression of list object referenced by index */ (%o5) 3 </syntaxhighlight>That [2,3,4] is a list object can be tested using the <code>listp()</code> operator:<syntaxhighlight lang="maxima"> (%i6) listp ([2,3,4]); (%o6) true </syntaxhighlight>A list object can be assigned an identifier:<syntaxhighlight lang="maxima">(%i7) s:[%pi,%e,%phi]; (s) [%pi,%e,%phi] (%i8) listp (s); (%o8) true</syntaxhighlight> The value of an element of a list can be accessed using the list identifier and brackets with a index value.<syntaxhighlight lang="maxima"> (%i9) s[1]; (%o9) %pi (%i10) s[2]; (%o10) %e (%i11) s[3]; (%o11) %phi </syntaxhighlight> Invalid index values returns an error:<syntaxhighlight lang="maxima"> (%i12) s[4]; inpart: invalid index 4 of list or matrix. -- an error. To debug this try: debugmode(true); </syntaxhighlight> Consider the following relatively long list of integer atoms created explicitly and identified as <code>List_1</code>:<syntaxhighlight lang="maxima">(%i13) List_1:[1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582,145,2, 118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118, 30,3,484,51,3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32,4, 484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484, 49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177]; (List_1) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203,2,1582,203 ,3,118,30,3,484,51,3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582, 214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177]</syntaxhighlight> The number of values of this list can be returned using the <code>length()</code> operator:<syntaxhighlight lang="maxima"> (%i14) length (List_1); (%o14) 105 </syntaxhighlight> Create another list identified as <code>List_2</code>:<syntaxhighlight lang="maxima"> (%i15) List_2 : [6,1455,200,6,1607,205]; (List_2) [6,1455,200,6,1607,205] (%i16) length (List_2); (%o16) 6 </syntaxhighlight> Create a third list identified as <code>List_3</code>:<syntaxhighlight lang="maxima"> (%i17) List_3 : append (List_1, List_2)$ (%i18) length (List_3); (%o19) 111 </syntaxhighlight> Note that the <code>'''append ()'''</code> operator does not affect either of the list arguments <code>List_1</code> or <code>List</code>_2. It merely appends <code>List_2</code> to <code>List_1</code> and returns a new list, in this case assigned the identifier <code>List_3</code>.<syntaxhighlight lang="maxima">(%i20) length (List_1); (%o20) 105 (%i21) length (List_2); (%o21) 6 (%i22) length (List_3); (%o22) 111 (%i23) List_3; (%o23) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607,205]</syntaxhighlight> Values (the last one in this example) can be deleted from a list:<syntaxhighlight lang="maxima">(%i24) last (List_3); (%o24) 205 (%i25) delete (last (List_3), List_3); (%o25) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607]</syntaxhighlight> The <code>delete (List_3)</code> expression creates a new list object using <code>List_3</code>. <code>List_3</code> itself is not affected by the <code>'''delete ()'''</code> operator. Only the resulting list is affected. This is often the case with list operators. An identifier could be used to save the above resulting list if necessary:<syntaxhighlight lang="maxima">/* List_3 is the same length */ (%i26) length(List_3); (%o26) 111 /* The last value of List_3 is the same */ (%i27) List_3[111]; (%o27) 205 (%i28) last(List_3); (%o28) 205</syntaxhighlight>There was only one instance of <code>205</code> in <code>List_3</code>, so only that value was deleted from the list of <code>%o25</code>. If there are more than one value then the <code>delete ()</code> operator will remove all of those values from the returned list expression:<syntaxhighlight lang="maxima"> (%i29) NewList_3 : delete(118, List_3)$ /* all five instances of 118 removed from List_3 as NewList_3 */ (%i30) length(NewList_3); (%o30) 106 </syntaxhighlight>There are operators to refer to instances of list expressions by ordinal number:<syntaxhighlight lang="maxima"> (%i30) FirstThreeList_3:[first(List_3), second(List_3), third(List_3)]; (FirstThreeList_3) [1,118,30] </syntaxhighlight>Expressions of list objects can e referenced to create a new list object from the first n expressions of a list, the last n expressions of a list, or the rest remaining after n expressions from the beginning or -n expressions from the end of a list:<syntaxhighlight lang="maxima">/* first three expressions of List_3 */ (%i31) firstn(List_3,3); (%o31) [1,118,30] /* same three expressions of List_3 using the rest operator with -108 */ (%i32) rest(List_3, -108); (%o32) [1,118,30] /* last three expressions of List_3 */ (%i33) lastn(List_3,3); (%o33) [6,1607,205] /* same three expressions of List_3 using the rest operator with 108 */ (%i34) rest(List_3, 108); (%o34) [6,1607,205]</syntaxhighlight>Some further examples of the <code>'''firstn ()'''</code>, <code>'''lastn ()'''</code> and <code>'''rest ()'''</code> list operators:<syntaxhighlight lang="maxima"> /* first 63 expressions of List_3 */ (%i35) firstn (List_3, 63); (%o35) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108,3, 1231,115,3,1372,139,3,1582,140] /* last 63 expressions of List_3 */ (%i36) lastn (List_3, 63); (%o36) [3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5, 1582,177,6,1455,200,6,1607,205] /* first expressions of List_3 after removing the last 63*/ (%i37) rest (List_3, -63); (%o37) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51] </syntaxhighlight>Maxima programming expressions can be used with list operators to reference list expressions in various ways. For example, the expression which follows accesses the expressions of a list as lists of three each:<syntaxhighlight lang="maxima"> (%i38) (L4 : List_4, for i:(-length (List_4)) + 3 thru 0 step 3 do (disp (rest (L4, i)), L4 : rest (L4, 3)), "")$ [1,118,30] [1,484,58] [1,664,87] [1,1004,115] [1,1231,120] [1,1372,142] [1,1582,145] [2,118,33] [2,484,69] [2,664,111] [2,1004,156] [2,1231,172] [2,1372,203] [2,1582,203] [3,118,30] [3,484,51] [3,664,75] </syntaxhighlight>List operators can be used as arguments other list operators:<syntaxhighlight lang="maxima"> /* create a new empty list */ (%i39) newList4 : []; (newList4) [] /* append the first six & last six expressions of List_4 to the new list */ (%i40) newList4 : append (newList4, firstn (List_4, 6), lastn (List_4, 6))$ /* the new list now has the 12 appended expressions from List_4 */ (%i41) newList4; (%o41) [1,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> Maxima programming expressions can be used to step through the expressions of lists using list operators to reference "slices" of different lengths:<syntaxhighlight lang="maxima">(%i42) L4 : List_4; (L4) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582 145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203, 2,1582,203,3,118,30,3,484,51,3,664,75] (%i43) length (L4); (%o43) 51 (%i44) (L4 : List_4, for i : 21 thru 3 step -3 do print (L4 : lastn (L4, i)," ", length (L4)), "")$ [2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 21 [2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 18 [2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 15 [2,1582,203,3,118,30,3,484,51,3,664,75] 12 [3,118,30,3,484,51,3,664,75] 9 [3,484,51,3,664,75] 6 [3,664,75] 3</syntaxhighlight> ==== Using the <code>copylist</code> Operator ==== When an existing list object is assigned to an identifier, a reference to the memory location of the list object is used. This reference to the memory location is transparent from the point of view of the user. However,if this is not accounted for unintended side effects may occur when assigning another identifier to an existing one that references a list object. For example, in the expression <code>L4 : List_4</code> it might be assumed that this results in the list object referenced by <code>List_4</code> to simply be copied to a new memory location and reference for <code>L4</code>. This is not the case. Both <code>L4</code> and <code>List_4</code> refer to the same list object in memory. Consequently changes to the same list object can be effected by referencing the object using either alias.<syntaxhighlight lang="maxima"> (%i45) newList4; (%o45) [1,118,30,1,484,58,3,484,51,3,664,75] /* The identifier newList4 refers to a location in memory. The colon (:) assignment operator simply creates an alias using that same memory reference*/ (%i46) newList5 : newList4; (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Two different identifiers for the same memory location and therefore the same object. Changes to expressions of the list object using either identifier changes the same object in memory */ (%i47) newList5[1] : 99; (newList5[1]) 99 (%i48) newList4[1]; (%o48) 99 (%i49) newList4; (%o49) [99,118,30,1,484,58,3,484,51,3,664,75] (%i50) newList5; (%o50) [99,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> This "side effect" is often unwanted. The way to avoid this is by using the <code>copylist ()</code> operator instead of the assignment operator:<syntaxhighlight lang="maxima"> (%i51) newList4 : [1,118,30,1,484,58,3,484,51,3,664,75] ; (newList4) [1,118,30,1,484,58,3,484,51,3,664,75] (%i52) newList5 : copylist (newList4); (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Same list object expressions, but a different memory reference */ (%i53) newList5[1] : 99; (newList5[1]) 99 (%i54) newList4[1]; (%o54) 1 </syntaxhighlight> Changes to the values of either list will not affect the other list. {| class="wikitable" |+List Object Operators |[ |fourth |rreduce |- |] |fullsetify |second |- |append |join |setify |- |assoc |last |seventh |- |cons |length |sixth |- |copylist |listarith |some |- |create_list |listp |sort |- |delete |lmax |sublist |- |eighth |lmin |sublist_indices |- |endcons |lreduce |tenth |- |fifth |makelist |third |- |first |member |tree_reduce |- |flatten |reverse |xreduce |} Refer to the Maximal Manual<ref>{{Cite web |title=Maxima Manual Section 7.4.2 Functions and Variables for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref> for more complete description of operators and variables for Maxima lists. ==== Performance Considerations for Lists ==== <blockquote>''"Lists provide efficient ways of appending and removing elements. They can be created without knowing their final dimensions. Lisp provides efficient means of copying and handling lists. Also nested lists do not need to be strictly rectangular. These advantages over declared arrays come with the drawback that the amount of time needed for accessing a random element within a list may be roughly proportional to the element’s distance from its beginning."''<ref>{{Cite web |title=Maxima Manual Section 7.4.3 Performance considerations for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref></blockquote>Maxima list objects have many operators for creating, accessing, and changing the expressions of lists. Evaluation times of expressions that involve lists can vary significantly depending on the length of the list objects involved, as well as the nature of any operators used to compose the expressions. This fact might have an influence on the choice of using arrays rather than lists in some cases if evaluation time is a factor to consider. The example expressions that follow involve a list object (identified as <code>s</code> ) of complex number expressions that has a length of 10,000 and two different user-defined functions:<pre>(%i55) P1(s) := rectform (product(s[i], i, 1, length (s)))$ (%i56) P2(s) := xreduce (lambda ([a, b], rectform (a * b)), s)$ (%i57) s : makelist (random (1.0) + %i*random (1.0), 10^4)$ (%i58) showtime : true$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes. (%i59) P1(s); Evaluation took 32.3080 seconds (32.3860 elapsed) using 17944.301 MB. (%o59) 0.0 (%i60) P2(s); Evaluation took 0.0620 seconds (0.0620 elapsed) using 8.343 MB. (%o60) 0.0 (%i61) showtime : false$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.</pre> ==Arrays == <blockquote>"Maxima's current array/matrix semantics are a mess, I must say, with at least four different kinds of object (hash arrays, explicit lists, explicit matrices, Lisp arrays) supporting subscripting with varying semantics." <ref>[http://comments.gmane.org/gmane.comp.mathematics.maxima.general/21829 Maxima: Syntax improvements by Stavros Macrakis ]</ref> – Stavros Macrakis "Maxima's concept of arrays, lists, and matrices is pretty confused, since various ideas have accreted in the many years of the project... Yes, this is a mess. Sorry about that. These are all interesting ideas, but there is no unifying framework."<ref>[http://stackoverflow.com/a/29926692 Maxima: what does Maxima call an “array”? - answer by Robert Dodier]</ref> – Robert Dodier</blockquote> The various terminology used in the context of arrays undoubtedly can be confusing. For the sake of simplicity and clarity the following categories of array objects are referred to in this book: Maxima has three array categories :<ref>[http://permalink.gmane.org/gmane.comp.mathematics.maxima.general/13588 the Maxima mailing list <nowiki>: [Maxima] array and matrix? - answer by Robert Dodier</nowiki>]</ref> * Declared arrays * Undeclared (hashed) arrays * Lisp arrays '''''Declared arrays''''' are explicitly created using the <code>array()</code> operator, and unlike lists, which have only one index and are one-dimensional, declared arrays can be multi-dimensional – having one to five indices. The indices for declared array dimensions need not be equal. Indices for each dimension may be between 0 and the respective declared dimension. Each declared array may be for expressions of a specified type, which can be ''fixnum'' for integers or ''flonum'' for floating-point numbers. '''''Undeclared (hashed) arrays''''' are created implicitly by assigning an expression to an indexed identifier that does not name an existing list object. An undeclared array (hashed array) can grow dynamically as there is no fixed dimension limit for each index as there is with declared arrays Another difference is that numbers, identifiers, expressions and strings may be used for indices. Also, there is no fixed limit on the number of dimensions. The only real limitation is practical – the available computer memory and the underlying Lisp environment of the Maxima session. Hashed arrays with only one dimension may be confused with a list object. It is essential to keep in mind that list objects must always be created before values are assigned or referenced. Assigning an expression to a one-dimensional indexed identifier, that does not reference an existing list, implicitly creates a hashed array. '''''Lisp arrays''''' are created using the <code>'''make_array ()'''</code> operator. The array type may be specified as ''any'', ''flonum'', ''fixnum'', or ''hashed''. Lisp array objects may be created as one-dimensional or multi-dimensional as specified by the number of dimension size values used with the <code>'''make_array ()'''</code> operator. For each dimension value specified, the associated index value can be a number between 0 to 1 less than the respective dimension value. The same or different values may be used for each specified dimension. the ''hashed'' type does not require any dimensions. Lisp arrays may be used in cases where memory usage and garbage collection are factors. Examples of use and elaboration upon the technical details for each of these categories of array object types follows. {| class="wikitable" |+Array Operators and Flags |array |arraysetapply |rearray |- |arrayapply |has_key |remarray |- |arrayinfo |fillarray |subvar |- |arraymake |listarray |subvarp |- |arrays |make_array |use_fast_arrays |- | | |translate_fast_arrays |} === Declared Arrays === Declared arrays must be created before being referenced and are of fixed dimensions.<syntaxhighlight lang="maxima"> (%i1) array(A1, fixnum, 34,2); (%o1) A1 (%i2) array(A2, flonum, 35,2); (%o2) A2 (%i3) array(A3, 14,3); (%o3) A3 (%i4) arrayinfo (A1); (%o4) [complete,2,[34,2]] (%i5) arrayinfo (A2); (%o5) [complete,2,[35,2]] (%i6) arrayinfo (A3); (%o6) [declared,2,[14,3]] </syntaxhighlight> The first expression <code>%i1</code> creates a declared array object named using the identifier <code>A1</code>. This array is two-dimensional – the first index may have values from 0 to 34 and the second index may have values from 0 to 2. This array therefore is 35 by 3 in extent. The array type is declared to be <code>fixnum</code>. As it is, <code>A1</code> is an not empty array – it has values to reference as will be exemplified below. Similarly the second expression <code>%i2</code> creates a declared array object named using the identifier <code>A2</code>. This array is also two-dimensional – the first index may have values from 0 to 35 and the second index may have values from 0 to 2. This array therefore is 36 by 3 in extent. The array type is declared to be <code>flonum</code>. As it is, <code>A2</code> is not an empty array – it also has values to reference as will be exemplified below. The third expression <code>%i3</code> creates a declared array object named using the identifier <code>A3</code>. This array is also two-dimensional – the first index may have values from 0 to 13 and the second index may have values from 0 to 3. This array therefore is 15 by 4 in extent. The array type is not declared. As it is, <code>A3</code> is an empty array – it has no values to reference as will be exemplified below. The <code>'''arrayinfo ()'''</code> operator can be used to return a list object that has values reflecting information about an array. Note that arrays declared without a type will have <code>declared</code> as a value of the list. Arrays declared with <code>fixnum</code> or <code>flonum</code> as the type will have <code>complete</code> as a value of the list. This technical detail is not well-documented. The returned information list also shows a value for the dimension of the array ( 2 in these examples ) and an inner list with values for the maximum index for each dimension. A look inside each of these declared arrays provides a clue as to why <code>complete</code> is returned instead of <code>declared</code> when the type is specified as <code>fixnum</code> or <code>flonum</code>:<syntaxhighlight lang="maxima">/* This array reference has a value of 0 */ (%i7) A1[0,0]; (%o7) 0 /* This array reference has a value of 0.0 */ (%i8) A2[0,0]; (%o8) 0.0 /* This array reference has a value of itself */ (%i9) A3[0,0]; (%o9) A3[0,0]</syntaxhighlight> In fact, ''all'' values of the array <code>A1</code> have been assigned 0, and ''all'' values of the array <code>A2</code> have beenassigned 0.0. However, ''all'' values of the array <code>A3</code> have been not been assigned any value.<syntaxhighlight lang="maxima">(%i10) listarray(A1); (%o10) [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0] (%i11) listarray(A2); (%o11) [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] (%i12) listarray(A3); (%o12) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####]</syntaxhighlight> Thus, arrays <code>A1</code> and <code>A2</code> are <code>complete</code> in this sense, and array <code>A3</code> is simply <code>declared</code>. It might seem reasonable, that Maxima would complain if a value was assigned to an array that is at odds with the declared type. Such is not the case however. Once an array is declared with a type, Maxima does not enforce any type checking of values assigned to the array. The effect of the type (if any) in the declaration is simply to fill the array with values of #####, 0 or 0.0. Subsequently, those values can be replaced by the assignment of different values that will not be checked for the type of value. One way to enforce type checking is by using predicate operators to check values at the point in time of assignment to arrays. For example, using one or more of: * numberp (expr) * floatnump (expr) * integerp (expr) * ratnump (expr) * stringp (obj) * listp (expr) * featurep (a, f) and possibly others.<syntaxhighlight lang="maxima"> /* A1 was declared as type fixnum */ (%i13) A1[5,2]:3.14159; (%o13) 3.14159 /* A2 was declared as type flonum */ (%i14) A2[3,0]:7129; (%o14) 7129 /* A1 which was declared as type fixnum assigned a string */ (%i15) A1[4,1]:"a string"; (%o15) "a string" /* A2 which was declared as type flonum assigned a math expression*/ (%i16) A2[6,1]:3*x^2 + 4*x +10; (%o16) 3*x^2+4*x+10 </syntaxhighlight> There are other ways to assign values to an array. One way is to read the values from a comma separated (CSV) file using the <code>'''read_array ()'''</code> operator from the ''numericalio'' package.<syntaxhighlight lang="maxima"> (%i17) load(numericalio); (%o17) "/app/plugins/maxima/share/maxima/5.50.0/share/numericalio/numericalio.mac" </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data_nh.csv</code> :<syntaxhighlight lang="text"> 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight> Note that the following expression assumes that the CSV file is located in the Maxima working directory.<syntaxhighlight lang="maxima"> (%i18) read_array("tree_data_nh.csv", A1, ","); (%o18) done (%i19) listarray(A1); (%o19) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142, 1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172, 2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108, 3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112, 4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484,49, 5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177] </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data.csv</code> which has a header row, but is otherwise the same as <code>tree_data_nh.csv</code>:<syntaxhighlight lang="text"> "Tree","age","circumference" 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight><syntaxhighlight lang="maxima">(%i20) read_array("tree_data.csv", A2, ","); (%o20) done (%i21) listarray(A2); (%o21) ["Tree","age","circumference",1,118,30,1,484,58,1,664,87,1,1004, 115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111, 2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51, 3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174, 5,1582,177]</syntaxhighlight>The previous values of 0 and 0,0 as well as the assigned values of <code>A1</code> and <code>A2</code> have been replaced with the values from the CSV files. The third array A3 can be used with values from the dataset.csv file below:<syntaxhighlight lang="text">"Last Name","Sales","Country","Quarter" "Smith",16753.00,"UK","Qtr 3" "Johnson",14808.00,"USA","Qtr 4" "Williams",10644.00,"UK","Qtr 2" "Jones",1390.00,"USA","Qtr 3" "Brown",4865.00,"USA","Qtr 4" "Williams",12438.00,"UK","Qtr 1" "Johnson",9339.00,"UK","Qtr 2" "Smith",18919.00,"USA","Qtr 3" "Jones",9213.00,"USA","Qtr 4" "Jones",7433.00,"UK","Qtr 1" "Brown",3255.00,"USA","Qtr 2" "Williams",14867.00,"USA","Qtr 3" "Williams",19302.00,"UK","Qtr 4" "Smith",9698.00,"USA","Qtr 1"</syntaxhighlight><syntaxhighlight lang="maxima">(%i22) read_array("dataset.csv", A3, ","); (%o22) done (%i23) listarray(A3); (%o23) ["Last Name","Sales","Country","Quarter", "Smith",16753.0,"UK","Qtr 3", "Johnson",14808.0,"USA","Qtr 4", "Williams",10644.0,"UK","Qtr 2", "Jones",1390.0,"USA","Qtr 3", "Brown",4865.0,"USA","Qtr 4", "Williams",12438.0,"UK","Qtr 1", "Johnson",9339.0,"UK","Qtr 2", "Smith",18919.0,"USA","Qtr 3", "Jones",9213.0,"USA","Qtr 4", "Jones",7433.0,"UK","Qtr 1", "Brown",3255.0,"USA","Qtr 2", "Williams",14867.0,"USA","Qtr 3", "Williams",19302.0,"UK","Qtr 4", "Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> Values of the array can be referenced by indices as required for some purpose:<syntaxhighlight lang="maxima"> (%i24) A3[0,0]; (%o24) "Last Name" (%i25) A3[4,2]; (%o25) "USA" </syntaxhighlight> A row list object can be created using the <code>'''makelist ()'''</code> operator:<syntaxhighlight lang="maxima"> (%i26) row1A3: makelist(A3[0, j], j, 0, 3)$ (%i27) row1A3; (%o27) ["Last Name","Sales","Country","Quarter"] (%i28) row1A3[1]; (%o28) "Last Name" (%i29) row15A3: makelist(A3[14, j], j, 0, 3)$ (%i30) row15A3; (%o30) ["Smith",9698.0,"USA","Qtr 1"] (%i31) row15A3[2]; (%o31) 9698.0 </syntaxhighlight> A list of the indices of the array can be created:<syntaxhighlight lang="maxima"> (%i32) indices_A3 : arrayinfo(A3)[3]; (indices_A3) [14,3] </syntaxhighlight> The number of indices of array <code>A3</code> can also be referenced using the <code>'''length (''')</code> operator:<syntaxhighlight lang="maxima"> (%i33) length(arrayinfo(A3)[3]); (%o33) 2 </syntaxhighlight>The number of values of the array <code>A3</code> can be returned using the '''<code>length ()</code>''' operator:<syntaxhighlight lang="maxima"> (%i34) length(listarray(A3)); (%o34) 60 </syntaxhighlight> The values of the array <code>A3</code> can be printed as output using the list of values with a loop programming expression:<syntaxhighlight lang="maxima"> (%i35) for i:1 thru length (listarray(A3)) do print('A3[i] ," = ", listarray(A3)[i])$ A3[1]" = ""Last Name" A3[2]" = ""Sales" A3[3]" = ""County" A3[4]" = ""Quarter" A3[5]" = ""Smith" A3[6]" = "16753.0 A3[7]" = ""UK" A3[8]" = ""Qtr 3" A3[9]" = ""Johnson" A3[10]" = "14808.0 A3[11]" = ""USA" A3[12]" = ""Qtr 4" A3[13]" = ""Williams" A3[14]" = "10644.0 A3[15]" = ""UK" A3[16]" = ""Qtr 2" A3[17]" = ""Jones" A3[18]" = "1390.0 A3[19]" = ""USA" A3[20]" = ""Qtr 3" A3[21]" = ""Brown" A3[22]" = "4865.0 A3[23]" = ""USA" A3[24]" = ""Qtr 4" A3[25]" = ""Williams" A3[26]" = "12438.0 A3[27]" = ""UK" A3[28]" = ""Qtr 1" A3[29]" = ""Johnson" A3[30]" = "9339.0 A3[31]" = ""UK" A3[32]" = ""Qtr 2" A3[33]" = ""Smith" A3[34]" = "18919.0 A3[35]" = ""USA" A3[36]" = ""Qtr 3" A3[37]" = ""Jones" A3[38]" = "9213.0 A3[39]" = ""USA" A3[40]" = ""Qtr 4" A3[41]" = ""Jones" A3[42]" = "7433.0 A3[43]" = ""UK" A3[44]" = ""Qtr 1" A3[45]" = ""Brown" A3[46]" = "3255.0 A3[47]" = ""USA" A3[48]" = ""Qtr 2" A3[49]" = ""Williams" A3[50]" = "14867.0 A3[51]" = ""USA" A3[52]" = ""Qtr 3" A3[53]" = ""Williams" A3[54]" = "19302.0 A3[55]" = ""UK" A3[56]" = ""Qtr 4" A3[57]" = ""Smith" A3[58]" = "9698.0 A3[59]" = ""USA" A3[60]" = ""Qtr 1" </syntaxhighlight> Maxima treats declared arrays as fixed-sized, and individual values are accessed via indices. There is no built-in "row" object — rows must be extracted manually using the <code>'''makelist ()'''</code> operator or by looping through values of an array.<syntaxhighlight lang="maxima"> (%i36) array(rowsA3,15); (%o36) rowsA3 (%i37) arrayinfo(rowsA3); (%o37) [declared,1,[15]] (%i38) for i:0 thru 14 do (rowsA3[i+1]:makelist(A3[i, j], j, 0, 3), print("Row ",i+1,": ",rowsA3[i+1]))$; "Row "1": "["Last Name","Sales","Country","Quarter"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"] </syntaxhighlight> Maxima does not have a built-in function like <code>delete</code> or <code>unset</code> for removing individual values from arrays using indices. Existing values of an array can be changed by assignment however:<syntaxhighlight lang="maxima">(%i52) rowsA3[1]:["Solomon",1045.0,"USA","Qtr 4"]$ (%i53) for i:1 thru 15 do (newRowsA3[i]:rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$; "Row "1": "["Solomon",1045.0,"USA","Qtr 4"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> The <code>'''arrayapply ()'''</code> operator can be used a follows to reference values of a declared array:<syntaxhighlight lang="maxima"> (%i39) arrayapply(rowsA3,[5]); (%o39) ["Jones",1390.0,"USA","Qtr 3"] (%i40) arrayapply(A3, [5,1]); (%o40) 4865.0 </syntaxhighlight>The operator <code>'''fillarray (A, B)'''</code> assigns values to array <code>A</code> from <code>B</code>, which can be a list or an array.The dimensions of the arrays <code>A</code> and <code>B</code> may not be the same. In that case, array <code>A</code> is filled in "row-major" order. There may not be enough values in <code>B</code> compared to <code>A</code>. In that case, the last value of <code>B</code> is used to for the remaining values of <code>A</code>. There may be too many values of <code>B</code> compared to array <code>A</code>. In that case, the remaining values of <code>B</code> once <code>A</code> is filled are not used. The return value of <code>'''fillarray ()'''</code> is not the filled array <code>A</code>, but it is the first argument.<syntaxhighlight lang="maxima">/* Create a declared array B of type fixnum */ (%i41) array (B, fixnum, 9); (%o41) B /* list the values of array B */ (%i42) listarray (B); (%o42) [0,0,0,0,0,0,0,0,0,0] /* fill array B with the values of the list */ (%i43) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9.0]); (%o43) B /* list the values of array B */ (%i44) listarray (B); (%o44) [0,1,2,3,4,5,6,7,8,9.0] /* fill array B with the value 1.0 */ (%i45) fillarray (B, [1.0]); (%o45) B /* list the values of array B */ (%i46) listarray (B); (%o46) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* fill array B with the first 9 values of the list */ (%i47) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12]); (%o47) B /* list the values of array B */ (%i48) listarray (B); (%o48) [0,1,2,3,4,5,6,7,8,9] /* Create a declared array D of no type */ (%i49) array (D, 9); (%o49) D /* list the values of array D */ (%i50) listarray (D); (%o50) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####] /* fill array D with the value 1.0 */ (%i51) fillarray (D, [1.0]); (%o51) D /* list the values of array D */ (%i52) listarray (D); (%o52) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* Create a declared array E of no type */ (%i53) array (E, 15); (%o53) E /* fill array E with the values from the newRowsA3 list */ (%i54) fillarray (E, listarray (newRowsA3)); (%o54) E /* list the values of array D */ (%i55) listarray (E); (%o55) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"], ["Smith",9698.0,"USA","Qtr 1"]] /* remove array E */ (%i56) remarray (E); (%o56) [E] /* D is no longer an array */ (%i57) arrayinfo (E); arrayinfo: E is not an array. -- an error. To debug this try: debugmode(true);</syntaxhighlight> If you need to keep the array but remove only one value, you must reconstruct it without that value. The operator <code>'''remarray ()'''</code> is the typical way to completely remove an array. The <code>'''rearray (A, dim<sub>1</sub>, dim<sub>2</sub> ,…, dim<sub>n</sub>)'''</code> operator is used to change the dimensions of an array. The changed array will be filled with the elements of the existing array in row-major order. If the existing array has one or more smaller dimensions, the additional dimension values of the changed array are assigned with a value that depends on the type of the array. If the existing array has one or more larger dimensions, the deficient dimension values of the changed array are lost. The type of the array cannot be changed using this operator. <syntaxhighlight lang="maxima"> /* list with the values of array B */ (%i58) listarray(B); (%o58) [0,1,2,3,4,5,6,7,8,9] /* list with information about array B */ (%i59) arrayinfo(B); (%o59) [complete,1,[9]] /* increase the dimension of array B */ (%i60) rearray (B, 12); (%o60) \#\{Lisp array \[13\]\} /* list with information about array B with increased dimension */ (%i61) arrayinfo(B); (%o61) [complete,1,[12]] /* list with the values of array B */ (%i62) listarray(B); (%o62) [0,1,2,3,4,5,6,7,8,9,0,0,0] /* decrease the dimension of array B */ (%i63) rearray (B, 6); (%o63) \#\{Lisp array \[7\]\} /* list with information about array B with decreased dimension */ (%i64) arrayinfo(B); (%o64) [complete,1,[6]] /* list with the values of array B */ (%i65) listarray(B); (%o65) [0,1,2,3,4,5,6] </syntaxhighlight> The <code>'''arraymake ()'''</code> operator returns a value that is an array reference without evaluation. This operator, in spite of the name, does not "make" an array. It returns this reference as a value whether or not an array exists as an object:<syntaxhighlight lang="maxima"> /* the arraymake operator returns the unevaluated reference to A */ (%i66) arraymake (A, [i,j]); (%o66) A[i,j] /* however array A is not an array object*/ (%i67) arrayinfo (A); arrayinfo: A is not an array. -- an error. To debug this try: debugmode(true); /* Maxima sees A[j,k] as a reference to an undefined memoizing function */ (%i68) op (arraymake (A, [i,j])); (%o68) A </syntaxhighlight> However, from a practical point of view, this operator is used with existing arrays:<syntaxhighlight lang="maxima"> (%i69) listarray (newRowsA3); (%o69) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"]] (%i70) arraymake (newRowsA3, [4]); (%o70) newRowsA3[4] (%i71) ''%; (%o71) ["Williams",10644.0,"UK","Qtr 2"] (%i72) arraymake (newRowsA3, [i]); (%o72) newRowsA3[i] (%i73) ''%, i = 6; (%o73) ["Brown",4865.0,"USA","Qtr 4"] </syntaxhighlight> The operator <code>arraymake (x, [i])</code> constructs the expression <code>x[i]</code>, but does not evaluate it. The operator <code>'''subvar'''</code> <code>'''(x, i)'''</code> evaluates the indexed expression <code>x[i]</code>, and evaluates its arguments. <syntaxhighlight lang="maxima"> (%i74) listarray(B); (%o174) [0,1,2,3,4,5,6] (%i75) x : B; (x) B (%i76) i : 4; (i) 4 (%i77) subvar (x, i); (%o77) 4 </syntaxhighlight> The operator <code>'''subvarp (expr)'''</code> returns a value of <code>true</code> if <code>expr</code> is a indexed identifier, and <code>false</code> otherwise. This operator evaluates the argument <code>expr</code>. <syntaxhighlight lang="maxima"> (%i78) z[p]; (%o78) z[p] (%i79) subvarp (z[p]); (%o79) true (%i80) x[i]; (%o80) 4 (%i81) subvar (x, i) (%o81) 4 (%i82) w : z[p]; (w) z[p] (%i83) subvarp (w); (%o83) true </syntaxhighlight> The expression <code>'''arrays'''</code> returns a list of allocated arrays: <syntaxhighlight lang="maxima">(%i84) arrays; (%o84) [A3,A2,A1,rowsA3,newRowsA3,B,D]</syntaxhighlight> The operator <code>'''arraysetapply (A, [i<sub>1</sub>,i<sub>2,</sub>…,i<sub>n</sub>], x)'''</code> assigns the value of expression <code>x</code> to <code>A</code><code>[i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub>]</code>, where <code>A</code> is an array and <code>i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub></code> are integers.<syntaxhighlight lang="maxima">(%i85) arraysetapply (newRowsA3, [8], ["George",20818.0,"UK","Qtr 4"]); (%o85) ["George",20818.0,"UK","Qtr 4"]</syntaxhighlight> === Undeclared Arrays === Maxima declared arrays and Maxima undeclared arrays will likely be the two types of data structures used by most users. Maxima undeclared arrays are also referred to as '''''hashed arrays'''''. For both of these two array types, memory allocation and structure occur "behind the curtain" of the Maxima user level, and "the man behind the curtain" is Lisp. Of these two types, hashed arrays are the most flexible from the user point of view, all other factors being equal: * The indices allowed for hashed arrays can be expressions, * The dimensions of a hashed array are dynamic and not fixed, and * Hashed arrays are relatively easier to create. In fact, hashed arrays can be somewhat too easy to create. In the examples of the previous section involving declared arrays, identifiers were used as names for arrays. here is the list of allocated arrays:<syntaxhighlight lang="maxima">(%i86) arrays; (%o86) [A3,A2,A1,rowsA3,newRowsA3,B,D,my_list,h]</syntaxhighlight>The array information for array <code>newRowsA3</code> is shown below:<syntaxhighlight lang="maxima"> (%i87) arrayinfo(newRowsA3); (%o87) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15]] </syntaxhighlight>So the array <code>newRowsA3</code> is not a declared array. it was created as part of a loop programming expression repeated below:<syntaxhighlight lang="maxima">(%i53) for i : 1 thru 15 do (newRowsA3[i] : rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$;</syntaxhighlight>When the first loop block was executed with i : 1, the assignment expression: <code>newRowsA3[i] : rowsA3[i]</code> created a hashed array named <code>newRowsA3</code> and assigned <code>newRowsA3[1]</code> the value of <code>rowsA3[1]</code> automatically without any declaration. After that the hashed array dynamically allocated memory for values of the loop identifier i from 2 through 15 with each successive pass in the loop expression. Since hashed arrays are undeclared, and their associated dimensions are not fixed, but rather increase dynamically, expressions can be added to hashed arrays without creating a error message. These added values can be can be any valid Maxima expression, and the value of the indices used are not limited to zero and nonzero integers: <syntaxhighlight lang="maxima"> (%i88) newRowsA3[16] : ["Maisel",12785.0,"USA","Qtr 2"]; (newRowsA3[16]) ["Maisel",12785.0,"USA","Qtr 2"] (%i89 arrayinfo(newRowsA3); (%o89) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16]] (%i90) newRowsA3[z] : 2*sin(y) ^2 + 3*sin(x)^3; (newRowsA3[z]) 2*sin(y)^2+3*sin(B)^3 (%i91) arrayinfo(newRowsA3); (%o91) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[z]] </syntaxhighlight>So one point to glean from this example is that all that is required to create a hashed array is an assignment expression to an indexed identifier, but it does require this assignment. If for some reason, a declared array is intended, but not declared using the <code>array</code> operator (as in the instance of <code>newRowsA3</code>), then a hashed array will be created at the first assignment of an expression to an indexed identifier. This issue can also occur in cases where reference to a list value is intended, but the list has not been created. Lists are one-dimensional objects by definition. A reference using an identifier with a single index intended to be a list with no list existing named by that identifier, can inadvertently create a hashed array.<syntaxhighlight lang="maxima"> (%i91) Alist[2] : 2*sin(y) ^2 + 3*sin(s)^3; (Alist[2]) 2*sin(y)^2+3*sin(s)^3 (%i92) listp(Alist); (%o92) false (%i93) arrayinfo(Alist); (%o93) [hashed,1,[2]] </syntaxhighlight>The identifier <code>Alist</code> is a name for a hashed array and not a list. However, hashed arrays, like declared arrays can, be multi-dimensional: <syntaxhighlight lang="maxima"> (%i94) a_hashed_array [j,k,l] : [12,s^(1/3), %i]; (%o94) [12,s^(1/3),%i] (%i95) arrayinfo(a_hashed_array); (%o95) [hashed,3,[j,k,l]] </syntaxhighlight>The <code>array</code> operator can be used to transform a hashed array into a declared array:<syntaxhighlight lang="maxima"> (%i96) another_hashed_array[ 0, 2, 3] : 55; (%o96) 55 (%i97) array (another_hashed_array, 2, 4, 5); (%o97) another_hashed_array (%i98) arrayinfo(another_hashed_array); (%o98) [declared,3,[2,4,5]] </syntaxhighlight>From the user point of view, hashed arrays and declared arrays typically can be used for the same purpose. If dynamic dimensions or index expression flexibility are factors, then hashed arrays are likely to be a better choice. Many of the operators that can use declared arrays as arguments, may also be used with hashed arrays. However, it should be noted at this point, that merely using a indexed identifier alone without an assignment, will not create a hashed array. Instead, Maxima interprets an expression so composed as an identifier for an undefined memoizing function, which is the topic of the next section. ==== Memoizing Functions ==== Assignment using an indexed identifier implicitly creates an undeclared (hashed) array. However, entering an expression that is an unassigned indexed identifier, from the point of view of Maxima, creates the identifier of a "memoizing" function. Memoizing functions are technically not an array topic, as these functions fall under the category of function definition. These functions have one foot in the function category and the other foot in the array category. Memoizing functions are defined in a manner similar to other user-defined functions, for example: <code>f(x, y, z) := x^2 + y^2 + z^2;</code> But instead of the arguments being enclosed in parentheses, they are enclosed using brackets: <code>f[x, y, z] := x^2 + y^2 + z^2;</code> However, memoizing functions may be referred to as ''array functions,'' and it is the case that these functions from the point of view of aggregate data structures are hashed arrays. So these are mentioned and exemplified here for that reason:<syntaxhighlight lang="maxima">/* reference an indexed identifier h without assignment */ (%i99) h[x]; (%o99) h[x] /* check identifier h as an array */ (%i100) arrayinfo (h); arrayinfo: h is not an array. -- an error. To debug this try: debugmode(true); /* check identifier h as a function */ (%i101) op(h[x]); (%o101) h /* define h[x] as a function */ (%i102) h[x] := 5*x^3 + sin(x); (h[x]) h[x]:=5*x^3+sin(x) /* check identifier h[x] as a function */ (%i103) op(h[x]); (%o103) "+" /* check identifier h as an array */ (%i104) arrayinfo (h); (%o104) [hashed,1,[x]] /* check the value of identifier h[x] */ (%i105) h[x]; (%o105) sin(x)+5*x^3 /* evaluate identifier h[x] with the argument 3*%pi */ (%i106) h[3*%pi]; (%o106) 135*%pi^3 /* list the values of identifier h as an array */ (%i107) listarray(h); (%o107) [135*%pi^3,sin(x)+5*x^3] /* check identifier h as an array */ (%i108) arrayinfo (h); (%o108) [hashed,1,[3*%pi],[x]]</syntaxhighlight>A defined memoizing function stores its value the ''first time'' it is referenced with arguments, and returns the stored value, without evaluation, when the same arguments are used with that function subsequently. The stored value is "frozen" after the initial evaluation. Thus, it behaves like a hashed array. The arguments of a memoizing function also serve as indices of the associated hashed array. === Lisp Arrays === Lisp arrays are created using the <code>make_array (type, dim<sub>1</sub>, dim<sub>2</sub>, …, dim<sub>n</sub>)</code> operator. Perhaps a better name for this operator would be <code>make_lisp_array ()</code>, which admittedly is a longer name. This operator creates and has a return value of a Lisp array. The array type may be <code>any</code>, <code>flonum</code>, <code>fixnum</code>, or <code>hashed</code> . The <code>functional</code> type referred to in the Maxima Manual appears to have been deprecated, and may result in an error message if used. There can be ''n'' indices, and where the associated indices can be a value from ''0'' to ''dim<sub>i</sub> -1'', and ''i'' can have a value of one of 1 to n inclusive. This operator can be used as an alternative to the <code>array ()</code> operator. The advantage of using <code>make_array()</code> is that the return value of <code>make_array()</code> ''does not have a name''. Once the Maxima identifier that is assigned to the array return value is no longer assigned, the array memory allocation is released, and the allocated memory can be garbage collected. What it is being referred to that Lisp arrays created using <code>make_array()</code> do not have names? <syntaxhighlight lang="maxima"> /* create a undeclared Maxima hashed array */ (%i109) arrayA1 [1] : 55; (%o109) 55 /* check the information about this undeclared Maxima hashed array */ (%i110) arrayinfo (arrayA1); (%o110) [hashed,1,[1]] /* check the value of this undeclared Maxima hashed array */ (%i111) arrayA1; (%o111) arrayA1 /* the name */ /* create a Lisp hashed array */ (%i112) arrayA2 : make_array (hashed); (arrayA2) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* check the information about this Lisp hashed array */ (%i113) arrayinfo (arrayA2); (%o113) [hash_table,1] /* check the value of this Lisp hashed array */ (%i114) arrayA2; (%o114) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* no name */ (%i115) listarray (arrayA2); (%o115) [] /* this hashed array is empty */ </syntaxhighlight>So Lisp arrays do not have a name as a value. So, Maxima identifiers assigned to a Lisp array have no name for the array as a value. These identifiers have the reference to the array itself as a value, Lisp hashed arrays created using <code>make_array()</code> with the hashed type specified, do not use dimensions. Lisp hashed arrays are often referred to as '''''hashed tables''''', and their indices are called '''''keys'''''. An example of a Lisp array with the type <code>any</code> follows: <syntaxhighlight lang="maxima"> /* make a Lisp 3 by 4 array of type any */ (%i116) arrayA3 : make_array (any, 3,4); (arrayA3) \#\{Lisp array \[3\\,4\]\} (%i117) arrayinfo (arrayA3); (%o117) [declared,2,[2,3]] (%i118) listarray(arrayA3); (%o118) [false,false,false,false,false,false,false,false,false,false,false,false] (%i119) arrayA3[1,1] : "a string" ; (%o119) "a string" (%i120) listarray(arrayA3); (%o120) [false,false,false,false,false,"a string", false,false,false,false,false,false] </syntaxhighlight>Contrary to statements made in some sources, type checking is is not accomplished automatically, and will not cause Maxima to return an error message, as the Lisp array with the type <code>fixnum</code> which follows is an exemplifies:<syntaxhighlight lang="maxima">(%i121) arrayA4 : make_array (fixnum, 3,4); (arrayA4) \#\{Lisp array \[3\\,4\]\} (%i122) arrayinfo (arrayA4); (%o122) [declared,2,[2,3]] (%i123) listarray (arrayA4); (%o123) [0,0,0,0,0,0,0,0,0,0,0,0] (%i124) arrayA4[0,2] : 3.14159; (%o124) 3.14159 (%i125) arrayA4[0,0] : "a string"; (%o125) "a string" /* value types not checked and no error message */ (%i126) listarray (arrayA4); (%o126) ["a string",0,3.14159,0,0,0,0,0,0,0,0,0]</syntaxhighlight>As was the case with declared arrays, there is no type checking and no error messages associated with assigned values of the array based on the declared type. The declared array type simply determines initial fill values, if any. Hashed arrays and Lisp hash tables have an operator in common: <code>has_key</code> <code>(A, L)</code> This expression has a a value of <code>true</code>, if the hashed array or Lisp hash table <code>A</code> has the key (index) or keys (indices) of the list object <code>L</code>. Otherwise the expression has a value of <code>false</code>. The array <code>A</code> must be a hashed (undeclared) array, a Lisp hash table value returned by the <code>make_array</code> operator, or created as an undeclared array with <code>use_fast_arrays</code> assigned the value <code>true</code>. If array A has only one key, that key must be the value of a list.<syntaxhighlight lang="maxima"> (%i127) arrayinfo (newRowsA3); (%o127) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10], [11],[12],[13],[14],[15],[16],[z]] (%i128) has_key (newRowsA3, [z]); (%o128) true (%i129) has_key (newRowsA3, [3]); (%o129) true (%i130) has_key(newRowsA3, [0]); (%o130) false (%i131) lisp_Array_1 [x]; (%o131) 3*x^2 (%i132) arrayinfo (lisp_Array_1); (%o132) [hash_table,1,x] (%i133) has_key (lisp_Array_1, [x]); (%o133) true (%i134) has_key (lisp_Array_1, [y]); (%o134) false </syntaxhighlight> === Arrays and Features === Maxima arrays can be assigned features in a manner similar to other identifiers:<syntaxhighlight lang="maxima"> (%i135) array (a6,fixnum, 5); (%o135) a6 (%i136) arrayinfo (a6); (%o136) [complete,1,[5]] (%i137) declare (a6, [real, noninteger]); (%o137) done (%i138) featurep (a6, real); (%o138) true (%i139) featurep (a6, noninteger); (%o139) true (%i140) a6[2] : 2; (a6[2]) 2 (%i141) listarray (a6); (%o141) [0,0,2,0,0,0] </syntaxhighlight>However, once again, declaring an array to have one or more features does not result in type checking of values assigned to an array. Perhaps the best way to ensure types of values assigned to arrays is type-checking of expressions using predicate operators prior to assignment to arrays. === Array Memory Storage Considerations === The following from the Maxima Manual<ref>{{Cite web |title=Maxima Manual Section 7.5.1 - Functions and Variables for Arrays |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Functions-and-Variables-for-Arrays}}</ref> is quoted here for the purpose of establishing the context of that which follows:<blockquote>''"Option variable: use_fast_arrays ¶'' ''Default value: false'' ''When use_fast_arrays is true, arrays declared by array are values instead of properties, and undeclared arrays (hashed arrays) are implemented as Lisp hashed arrays.'' ''When use_fast_arrays is false, arrays declared by array are properties, and undeclared arrays are implemented with Maxima’s own hashed array implementation.'' ''Note that the code use_fast_arrays switches to is not necessarily faster than the default one; Arrays created by make_array are not affected by use_fast_arrays."''</blockquote> This Maxima Manual entry requires some elaboration in order to have a sufficient understanding of the effect of the <code>'''use_fast_arrays'''</code> "flag" – referred to as an "Option Variable" in the above quotation. The first point to note is that the default value of this flag is <code>false</code>. So, if users take no action to assign this flag to the value <code>true</code>, then declared arrays created using the <code>array()</code> operator are treated as ''properties'' bound to a symbol, and behave in the manner previously described. Likewise undeclared arrays are a Maxima array implementation, and behave as legacy property hash tables, and these also behave as previously described. If action is taken to enter an expression that assigns the value <code>true</code> to this flag, then Maxima treat arrays as standard Lisp ''values'' rather than object properties:<syntaxhighlight lang="maxima"> (%i142) use_fast_arrays; (%o142) false (%i143) array (A1,fixnum, 10); (%o143) A1 (%i144) arrayinfo (A1); (%o144) [complete,1,[10]] (%i145) H1[1] : 1729; (H1[1]) 1729 (%i146) arrayinfo (H1); (%o146) [hashed,1,[1]] (%i147) use_fast_arrays : true; (use_fast_arrays) true (%i148) array (A2, fixnum, 10); (%o148) \#\{Lisp array \[11\]\} (%i149) A2; (%o149) \#\{Lisp array \[11\]\} (%i150) H2[1] : 1729; (H2[1]) 1729 (%i151) H2; (%o151) "#<HASH-TABLE :TEST EQUAL :COUNT 2 {1203AD15A3}>" (%i152) arrayinfo (H2); (%o152) [hash_table,1,1] </syntaxhighlight> The <code>use_fast_arrays</code> flag has no effect on arrays created using the <code>make_array ()</code> operator. Note the following: * Assigning <code>use_fast_arrays</code> <code>: true</code> does not speed up execution for all operations. It primarily optimizes memory footprint by minimizing cell allocations. The main benefit is optimization of memory footprints and structural representation inside Lisp. * If compiling Maxima expressions to native Lisp using the <code>translate</code> <code>()</code> operator, pair this flag with <code>translate_fast_arrays</code> <code>: true</code>. This flag instructs the translator to compile arrays as value-based. === Structures === Structures, although not an array data type is an aggregation data type.  By "aggregation" it is meant a data type that references other data types by reference to a name and some method of accessing individual values of instances of that aggregation by means of indices used to reference values individually. Thus, as has been previously described for example lists, hashed arrays, Lisp arrays, and declared arrays are all aggregation data types with syntactical means to refer to individual values of a named aggregation instance by way of indices, which are sometimes also referred to as subscripts or keys. As examples: * An existing '''list''' named <code>L1</code> has values that can be accessed as <code>L1[1]</code>, <code>L[2]</code>, <code>L[3]</code>, and so forth * An existing '''hashed array''' with two indices ("2D") named <code>ha</code> has values that can accessed as <code>ha[1,1</code>], <code>ha[1,2]</code>,..., <code>ha[2,1]</code>, <code>ha[2,2]</code>, and  so forth. * An existing '''declared array''' with three indices ("3D") named <code>da</code> has values that can be accessed as <code>da[1,1,1]</code>, <code>da[1,1,2]</code>,...,<code>da [2,1,1]</code>, ..., <code>da[3,1,1]</code>, and so forth. What makes the Maxima structure data type different from these array data types is the form of definition used and the means of accessing values of an instance of this type of aggregation. The Maxima structure data type seems to be the closest type of data that resembles an object in some other general-purpose programming languages. The structure type of data allows the creation of named entities with attributes, and named instances of those entities and the assignment of values to those attributes. Thus the Maxima structure data type is used to define custom, named composite data types that group related fields together under a single identifier. Structures enhance code organization and readability, especially when modeling real-world entities in symbolic computations. They are useful for managing complex data in programs involving algebraic manipulations, simulations, or data modeling. Structures are created using the <code>defstruct</code> operator, which defines a template with named attributes. Once defined, instances of the structure are created using the <code>new</code> operator, and attributes are accessed via the <code>@</code> operator. So in the interest of taking advantage of this information, consider a well-defined set of people. The people of this set may have many diverse attributes that might be of interest - name, age ,and city of residence as examples. A class of people of the set of interest with these attributes can be defined as follows: <syntaxhighlight lang="maxima">(%i153) defstruct (person (name, age, city)); (%o153) [person(name,age,city)] (%i54) structures; (%o154) [person(name, age, city)] (%i155) p : new (person ("Alice", 30, "New York")); (p) person(name="Alice",age=30,city="New York") (%i156) p@name; (%o156) "Alice" (%i157) p@city; (%o157) "New York" (%i158) kill(p@city); (%o158) done /* If the attribute a in x has not been assigned a value, or the value has been "killed," then x@a evaluates to itself */ (%i159) p@city; (%o159) p@city (%i160) p; (%o160) person(name="Alice",age=30,city) (%i161) p@city : "Rochester"; (%o161) "Rochester" (%i162) p; (%o162) person(name="Alice",age=30,city="Rochester") (%i163) defstruct (sales(LastName, Sales , Country , Quarter) ); (%o163) [sales(LastName, Sales, Country, Quarter)] (%i164) structures; (%o164) [person(name, age, city), sales(LastName, Sales, Country, Quarter)] (%i165) s : new (sales ("Smith",16753.00,"UK","Qtr 3")); (%o165) sales(LastName=Smith, Sales=16753.0, Country=UK, Quarter=Qtr 3) (%i166) s@Sales; (%o166) 16753.0 (%i167) s@Sales : 17375.0; (%o167) 17375.0 (%i168) s; (%o168) sales(LastName=Smith, Sales=17375.0, Country=UK, Quarter=Qtr 3)</syntaxhighlight>{{Bookcat}} pk4i72rglnjn7148qknkvxch5hjzmdb 4668963 4668961 2026-09-05T17:31:26Z Idavidmiller 3577687 /* Introduction */ 4668963 wikitext text/x-wiki == Maxima Aggregate Data Structures == === Introduction === This section is intended to present some of the essentials of what is called Maxima aggregate data structures. By this it is meant the data types that can be used to refer to the values of expressions using a means of indexing of a single identifier (name) that refers to an aggregate (collection) of expressions as values. Built-in aggregate data types include: * lists * hashed arrays * declared arrays * structures Each of these has a means of indexing an identifier that names an instance of these data types. Please note that it is the case that this means of indexing an identifier for an aggregate data type may be referred to as involving "subscripts" or "sub-scripted variables" or "keys" as used by various computer programming languages, as well as in the context of Maxima documentation and commentary. In this book terms such as "index" or "indices" or "indexed identifiers"  are used instead. Also all built-in Maxima functions (including packages) for these data types are referred to as ''"operators"'' and not ''"functions"'' as this latter term in general serves better to refer to Maxima function expressions defined by the user -- as in <code>f(x) :=</code>, <code>g[s] :=</code> and <code>define ()</code> as examples. This section is not intended to be exhaustive. It is intended to provide familiarity with aggregate data types. What is included has been gleaned from various sources, and only a few attributions are provided. Therefore, there is no claim of originality implied. === Lists === ==== Introduction to Lists ==== Lists are one of the basic buildings block for Maxima and Lisp. Maxima expressions are in general represented as Lisp lists. For example, consider the Maxima expression:<syntaxhighlight lang="maxima"> (%i1) e+3; (%o1) e+3 </syntaxhighlight>This expression has the form of a Lisp list:<syntaxhighlight lang="maxima"> (%i2) :lisp #$[e+3]$ ((MLIST SIMP) ((MPLUS SIMP) 3 $E)) </syntaxhighlight>An expression in the form of a Lisp list can also be be displayed as a Maxima expression:<syntaxhighlight lang="maxima"> (%i2) :lisp (displa '((MLIST SIMP) ((MPLUS SIMP) 3 $E))); [e+3] NIL </syntaxhighlight>Note that the value of this expression using <code>displa '()</code> is <code>NIL</code>, and <code>[e+3]</code> is simply displayed in Maxima list object form. It is not necessary for the typical uses of Maxima to utilize this insight into the role Lisp lists have as one of the building blocks for Maxima, but it may be useful to have a familiarity with that role. Lists are often used as arguments to many operators, and the values of expressions are often in the form of lists. ==== Some Operators for Lists ==== Lists are created explicitly and list elements referenced using <code>[</code> and <code>]</code> to mark the beginning and end, respectively, of an instance of a list object, or to reference the expressions of an existing list object.<syntaxhighlight lang="maxima"> (%i3) [2,3,4]; (%o3) [2,3,4] </syntaxhighlight>The expression <code>[2,3,4]</code> creates a Maxima list object. In this case the object itself is not accessible as it was not assigned an identifier unless referenced by the <code>%</code> , <code>%i</code> or <code>%o</code> label.<syntaxhighlight lang="maxima"> (%i4) %; (%o4) [2,3,4] (%i5) %o4[2]; /* second expression of list object referenced by index */ (%o5) 3 </syntaxhighlight>That [2,3,4] is a list object can be tested using the <code>listp()</code> operator:<syntaxhighlight lang="maxima"> (%i6) listp ([2,3,4]); (%o6) true </syntaxhighlight>A list object can be assigned an identifier:<syntaxhighlight lang="maxima">(%i7) s:[%pi,%e,%phi]; (s) [%pi,%e,%phi] (%i8) listp (s); (%o8) true</syntaxhighlight> The value of an element of a list can be accessed using the list identifier and brackets with a index value.<syntaxhighlight lang="maxima"> (%i9) s[1]; (%o9) %pi (%i10) s[2]; (%o10) %e (%i11) s[3]; (%o11) %phi </syntaxhighlight> Invalid index values returns an error:<syntaxhighlight lang="maxima"> (%i12) s[4]; inpart: invalid index 4 of list or matrix. -- an error. To debug this try: debugmode(true); </syntaxhighlight> Consider the following relatively long list of integer atoms created explicitly and identified as <code>List_1</code>:<syntaxhighlight lang="maxima">(%i13) List_1:[1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582,145,2, 118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118, 30,3,484,51,3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32,4, 484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484, 49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177]; (List_1) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203,2,1582,203 ,3,118,30,3,484,51,3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582, 214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177]</syntaxhighlight> The number of values of this list can be returned using the <code>length()</code> operator:<syntaxhighlight lang="maxima"> (%i14) length (List_1); (%o14) 105 </syntaxhighlight> Create another list identified as <code>List_2</code>:<syntaxhighlight lang="maxima"> (%i15) List_2 : [6,1455,200,6,1607,205]; (List_2) [6,1455,200,6,1607,205] (%i16) length (List_2); (%o16) 6 </syntaxhighlight> Create a third list identified as <code>List_3</code>:<syntaxhighlight lang="maxima"> (%i17) List_3 : append (List_1, List_2)$ (%i18) length (List_3); (%o19) 111 </syntaxhighlight> Note that the <code>'''append ()'''</code> operator does not affect either of the list arguments <code>List_1</code> or <code>List</code>_2. It merely appends <code>List_2</code> to <code>List_1</code> and returns a new list, in this case assigned the identifier <code>List_3</code>.<syntaxhighlight lang="maxima">(%i20) length (List_1); (%o20) 105 (%i21) length (List_2); (%o21) 6 (%i22) length (List_3); (%o22) 111 (%i23) List_3; (%o23) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607,205]</syntaxhighlight> Values (the last one in this example) can be deleted from a list:<syntaxhighlight lang="maxima">(%i24) last (List_3); (%o24) 205 (%i25) delete (last (List_3), List_3); (%o25) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607]</syntaxhighlight> The <code>delete (List_3)</code> expression creates a new list object using <code>List_3</code>. <code>List_3</code> itself is not affected by the <code>'''delete ()'''</code> operator. Only the resulting list is affected. This is often the case with list operators. An identifier could be used to save the above resulting list if necessary:<syntaxhighlight lang="maxima">/* List_3 is the same length */ (%i26) length(List_3); (%o26) 111 /* The last value of List_3 is the same */ (%i27) List_3[111]; (%o27) 205 (%i28) last(List_3); (%o28) 205</syntaxhighlight>There was only one instance of <code>205</code> in <code>List_3</code>, so only that value was deleted from the list of <code>%o25</code>. If there are more than one value then the <code>delete ()</code> operator will remove all of those values from the returned list expression:<syntaxhighlight lang="maxima"> (%i29) NewList_3 : delete(118, List_3)$ /* all five instances of 118 removed from List_3 as NewList_3 */ (%i30) length(NewList_3); (%o30) 106 </syntaxhighlight>There are operators to refer to instances of list expressions by ordinal number:<syntaxhighlight lang="maxima"> (%i30) FirstThreeList_3:[first(List_3), second(List_3), third(List_3)]; (FirstThreeList_3) [1,118,30] </syntaxhighlight>Expressions of list objects can e referenced to create a new list object from the first n expressions of a list, the last n expressions of a list, or the rest remaining after n expressions from the beginning or -n expressions from the end of a list:<syntaxhighlight lang="maxima">/* first three expressions of List_3 */ (%i31) firstn(List_3,3); (%o31) [1,118,30] /* same three expressions of List_3 using the rest operator with -108 */ (%i32) rest(List_3, -108); (%o32) [1,118,30] /* last three expressions of List_3 */ (%i33) lastn(List_3,3); (%o33) [6,1607,205] /* same three expressions of List_3 using the rest operator with 108 */ (%i34) rest(List_3, 108); (%o34) [6,1607,205]</syntaxhighlight>Some further examples of the <code>'''firstn ()'''</code>, <code>'''lastn ()'''</code> and <code>'''rest ()'''</code> list operators:<syntaxhighlight lang="maxima"> /* first 63 expressions of List_3 */ (%i35) firstn (List_3, 63); (%o35) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108,3, 1231,115,3,1372,139,3,1582,140] /* last 63 expressions of List_3 */ (%i36) lastn (List_3, 63); (%o36) [3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5, 1582,177,6,1455,200,6,1607,205] /* first expressions of List_3 after removing the last 63*/ (%i37) rest (List_3, -63); (%o37) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51] </syntaxhighlight>Maxima programming expressions can be used with list operators to reference list expressions in various ways. For example, the expression which follows accesses the expressions of a list as lists of three each:<syntaxhighlight lang="maxima"> (%i38) (L4 : List_4, for i:(-length (List_4)) + 3 thru 0 step 3 do (disp (rest (L4, i)), L4 : rest (L4, 3)), "")$ [1,118,30] [1,484,58] [1,664,87] [1,1004,115] [1,1231,120] [1,1372,142] [1,1582,145] [2,118,33] [2,484,69] [2,664,111] [2,1004,156] [2,1231,172] [2,1372,203] [2,1582,203] [3,118,30] [3,484,51] [3,664,75] </syntaxhighlight>List operators can be used as arguments other list operators:<syntaxhighlight lang="maxima"> /* create a new empty list */ (%i39) newList4 : []; (newList4) [] /* append the first six & last six expressions of List_4 to the new list */ (%i40) newList4 : append (newList4, firstn (List_4, 6), lastn (List_4, 6))$ /* the new list now has the 12 appended expressions from List_4 */ (%i41) newList4; (%o41) [1,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> Maxima programming expressions can be used to step through the expressions of lists using list operators to reference "slices" of different lengths:<syntaxhighlight lang="maxima">(%i42) L4 : List_4; (L4) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582 145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203, 2,1582,203,3,118,30,3,484,51,3,664,75] (%i43) length (L4); (%o43) 51 (%i44) (L4 : List_4, for i : 21 thru 3 step -3 do print (L4 : lastn (L4, i)," ", length (L4)), "")$ [2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 21 [2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 18 [2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 15 [2,1582,203,3,118,30,3,484,51,3,664,75] 12 [3,118,30,3,484,51,3,664,75] 9 [3,484,51,3,664,75] 6 [3,664,75] 3</syntaxhighlight> ==== Using the <code>copylist</code> Operator ==== When an existing list object is assigned to an identifier, a reference to the memory location of the list object is used. This reference to the memory location is transparent from the point of view of the user. However,if this is not accounted for unintended side effects may occur when assigning another identifier to an existing one that references a list object. For example, in the expression <code>L4 : List_4</code> it might be assumed that this results in the list object referenced by <code>List_4</code> to simply be copied to a new memory location and reference for <code>L4</code>. This is not the case. Both <code>L4</code> and <code>List_4</code> refer to the same list object in memory. Consequently changes to the same list object can be effected by referencing the object using either alias.<syntaxhighlight lang="maxima"> (%i45) newList4; (%o45) [1,118,30,1,484,58,3,484,51,3,664,75] /* The identifier newList4 refers to a location in memory. The colon (:) assignment operator simply creates an alias using that same memory reference*/ (%i46) newList5 : newList4; (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Two different identifiers for the same memory location and therefore the same object. Changes to expressions of the list object using either identifier changes the same object in memory */ (%i47) newList5[1] : 99; (newList5[1]) 99 (%i48) newList4[1]; (%o48) 99 (%i49) newList4; (%o49) [99,118,30,1,484,58,3,484,51,3,664,75] (%i50) newList5; (%o50) [99,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> This "side effect" is often unwanted. The way to avoid this is by using the <code>copylist ()</code> operator instead of the assignment operator:<syntaxhighlight lang="maxima"> (%i51) newList4 : [1,118,30,1,484,58,3,484,51,3,664,75] ; (newList4) [1,118,30,1,484,58,3,484,51,3,664,75] (%i52) newList5 : copylist (newList4); (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Same list object expressions, but a different memory reference */ (%i53) newList5[1] : 99; (newList5[1]) 99 (%i54) newList4[1]; (%o54) 1 </syntaxhighlight> Changes to the values of either list will not affect the other list. {| class="wikitable" |+List Object Operators |[ |fourth |rreduce |- |] |fullsetify |second |- |append |join |setify |- |assoc |last |seventh |- |cons |length |sixth |- |copylist |listarith |some |- |create_list |listp |sort |- |delete |lmax |sublist |- |eighth |lmin |sublist_indices |- |endcons |lreduce |tenth |- |fifth |makelist |third |- |first |member |tree_reduce |- |flatten |reverse |xreduce |} Refer to the Maximal Manual<ref>{{Cite web |title=Maxima Manual Section 7.4.2 Functions and Variables for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref> for more complete description of operators and variables for Maxima lists. ==== Performance Considerations for Lists ==== <blockquote>''"Lists provide efficient ways of appending and removing elements. They can be created without knowing their final dimensions. Lisp provides efficient means of copying and handling lists. Also nested lists do not need to be strictly rectangular. These advantages over declared arrays come with the drawback that the amount of time needed for accessing a random element within a list may be roughly proportional to the element’s distance from its beginning."''<ref>{{Cite web |title=Maxima Manual Section 7.4.3 Performance considerations for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref></blockquote>Maxima list objects have many operators for creating, accessing, and changing the expressions of lists. Evaluation times of expressions that involve lists can vary significantly depending on the length of the list objects involved, as well as the nature of any operators used to compose the expressions. This fact might have an influence on the choice of using arrays rather than lists in some cases if evaluation time is a factor to consider. The example expressions that follow involve a list object (identified as <code>s</code> ) of complex number expressions that has a length of 10,000 and two different user-defined functions:<pre>(%i55) P1(s) := rectform (product(s[i], i, 1, length (s)))$ (%i56) P2(s) := xreduce (lambda ([a, b], rectform (a * b)), s)$ (%i57) s : makelist (random (1.0) + %i*random (1.0), 10^4)$ (%i58) showtime : true$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes. (%i59) P1(s); Evaluation took 32.3080 seconds (32.3860 elapsed) using 17944.301 MB. (%o59) 0.0 (%i60) P2(s); Evaluation took 0.0620 seconds (0.0620 elapsed) using 8.343 MB. (%o60) 0.0 (%i61) showtime : false$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.</pre> ==Arrays == <blockquote>"Maxima's current array/matrix semantics are a mess, I must say, with at least four different kinds of object (hash arrays, explicit lists, explicit matrices, Lisp arrays) supporting subscripting with varying semantics." <ref>[http://comments.gmane.org/gmane.comp.mathematics.maxima.general/21829 Maxima: Syntax improvements by Stavros Macrakis ]</ref> – Stavros Macrakis "Maxima's concept of arrays, lists, and matrices is pretty confused, since various ideas have accreted in the many years of the project... Yes, this is a mess. Sorry about that. These are all interesting ideas, but there is no unifying framework."<ref>[http://stackoverflow.com/a/29926692 Maxima: what does Maxima call an “array”? - answer by Robert Dodier]</ref> – Robert Dodier</blockquote> The various terminology used in the context of arrays undoubtedly can be confusing. For the sake of simplicity and clarity the following categories of array objects are referred to in this book: Maxima has three array categories :<ref>[http://permalink.gmane.org/gmane.comp.mathematics.maxima.general/13588 the Maxima mailing list <nowiki>: [Maxima] array and matrix? - answer by Robert Dodier</nowiki>]</ref> * Declared arrays * Undeclared (hashed) arrays * Lisp arrays '''''Declared arrays''''' are explicitly created using the <code>array()</code> operator, and unlike lists, which have only one index and are one-dimensional, declared arrays can be multi-dimensional – having one to five indices. The indices for declared array dimensions need not be equal. Indices for each dimension may be between 0 and the respective declared dimension. Each declared array may be for expressions of a specified type, which can be ''fixnum'' for integers or ''flonum'' for floating-point numbers. '''''Undeclared (hashed) arrays''''' are created implicitly by assigning an expression to an indexed identifier that does not name an existing list object. An undeclared array (hashed array) can grow dynamically as there is no fixed dimension limit for each index as there is with declared arrays Another difference is that numbers, identifiers, expressions and strings may be used for indices. Also, there is no fixed limit on the number of dimensions. The only real limitation is practical – the available computer memory and the underlying Lisp environment of the Maxima session. Hashed arrays with only one dimension may be confused with a list object. It is essential to keep in mind that list objects must always be created before values are assigned or referenced. Assigning an expression to a one-dimensional indexed identifier, that does not reference an existing list, implicitly creates a hashed array. '''''Lisp arrays''''' are created using the <code>'''make_array ()'''</code> operator. The array type may be specified as ''any'', ''flonum'', ''fixnum'', or ''hashed''. Lisp array objects may be created as one-dimensional or multi-dimensional as specified by the number of dimension size values used with the <code>'''make_array ()'''</code> operator. For each dimension value specified, the associated index value can be a number between 0 to 1 less than the respective dimension value. The same or different values may be used for each specified dimension. the ''hashed'' type does not require any dimensions. Lisp arrays may be used in cases where memory usage and garbage collection are factors. Examples of use and elaboration upon the technical details for each of these categories of array object types follows. {| class="wikitable" |+Array Operators and Flags |array |arraysetapply |rearray |- |arrayapply |has_key |remarray |- |arrayinfo |fillarray |subvar |- |arraymake |listarray |subvarp |- |arrays |make_array |use_fast_arrays |- | | |translate_fast_arrays |} === Declared Arrays === Declared arrays must be created before being referenced and are of fixed dimensions.<syntaxhighlight lang="maxima"> (%i1) array(A1, fixnum, 34,2); (%o1) A1 (%i2) array(A2, flonum, 35,2); (%o2) A2 (%i3) array(A3, 14,3); (%o3) A3 (%i4) arrayinfo (A1); (%o4) [complete,2,[34,2]] (%i5) arrayinfo (A2); (%o5) [complete,2,[35,2]] (%i6) arrayinfo (A3); (%o6) [declared,2,[14,3]] </syntaxhighlight> The first expression <code>%i1</code> creates a declared array object named using the identifier <code>A1</code>. This array is two-dimensional – the first index may have values from 0 to 34 and the second index may have values from 0 to 2. This array therefore is 35 by 3 in extent. The array type is declared to be <code>fixnum</code>. As it is, <code>A1</code> is an not empty array – it has values to reference as will be exemplified below. Similarly the second expression <code>%i2</code> creates a declared array object named using the identifier <code>A2</code>. This array is also two-dimensional – the first index may have values from 0 to 35 and the second index may have values from 0 to 2. This array therefore is 36 by 3 in extent. The array type is declared to be <code>flonum</code>. As it is, <code>A2</code> is not an empty array – it also has values to reference as will be exemplified below. The third expression <code>%i3</code> creates a declared array object named using the identifier <code>A3</code>. This array is also two-dimensional – the first index may have values from 0 to 13 and the second index may have values from 0 to 3. This array therefore is 15 by 4 in extent. The array type is not declared. As it is, <code>A3</code> is an empty array – it has no values to reference as will be exemplified below. The <code>'''arrayinfo ()'''</code> operator can be used to return a list object that has values reflecting information about an array. Note that arrays declared without a type will have <code>declared</code> as a value of the list. Arrays declared with <code>fixnum</code> or <code>flonum</code> as the type will have <code>complete</code> as a value of the list. This technical detail is not well-documented. The returned information list also shows a value for the dimension of the array ( 2 in these examples ) and an inner list with values for the maximum index for each dimension. A look inside each of these declared arrays provides a clue as to why <code>complete</code> is returned instead of <code>declared</code> when the type is specified as <code>fixnum</code> or <code>flonum</code>:<syntaxhighlight lang="maxima">/* This array reference has a value of 0 */ (%i7) A1[0,0]; (%o7) 0 /* This array reference has a value of 0.0 */ (%i8) A2[0,0]; (%o8) 0.0 /* This array reference has a value of itself */ (%i9) A3[0,0]; (%o9) A3[0,0]</syntaxhighlight> In fact, ''all'' values of the array <code>A1</code> have been assigned 0, and ''all'' values of the array <code>A2</code> have beenassigned 0.0. However, ''all'' values of the array <code>A3</code> have been not been assigned any value.<syntaxhighlight lang="maxima">(%i10) listarray(A1); (%o10) [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0] (%i11) listarray(A2); (%o11) [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] (%i12) listarray(A3); (%o12) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####]</syntaxhighlight> Thus, arrays <code>A1</code> and <code>A2</code> are <code>complete</code> in this sense, and array <code>A3</code> is simply <code>declared</code>. It might seem reasonable, that Maxima would complain if a value was assigned to an array that is at odds with the declared type. Such is not the case however. Once an array is declared with a type, Maxima does not enforce any type checking of values assigned to the array. The effect of the type (if any) in the declaration is simply to fill the array with values of #####, 0 or 0.0. Subsequently, those values can be replaced by the assignment of different values that will not be checked for the type of value. One way to enforce type checking is by using predicate operators to check values at the point in time of assignment to arrays. For example, using one or more of: * numberp (expr) * floatnump (expr) * integerp (expr) * ratnump (expr) * stringp (obj) * listp (expr) * featurep (a, f) and possibly others.<syntaxhighlight lang="maxima"> /* A1 was declared as type fixnum */ (%i13) A1[5,2]:3.14159; (%o13) 3.14159 /* A2 was declared as type flonum */ (%i14) A2[3,0]:7129; (%o14) 7129 /* A1 which was declared as type fixnum assigned a string */ (%i15) A1[4,1]:"a string"; (%o15) "a string" /* A2 which was declared as type flonum assigned a math expression*/ (%i16) A2[6,1]:3*x^2 + 4*x +10; (%o16) 3*x^2+4*x+10 </syntaxhighlight> There are other ways to assign values to an array. One way is to read the values from a comma separated (CSV) file using the <code>'''read_array ()'''</code> operator from the ''numericalio'' package.<syntaxhighlight lang="maxima"> (%i17) load(numericalio); (%o17) "/app/plugins/maxima/share/maxima/5.50.0/share/numericalio/numericalio.mac" </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data_nh.csv</code> :<syntaxhighlight lang="text"> 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight> Note that the following expression assumes that the CSV file is located in the Maxima working directory.<syntaxhighlight lang="maxima"> (%i18) read_array("tree_data_nh.csv", A1, ","); (%o18) done (%i19) listarray(A1); (%o19) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142, 1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172, 2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108, 3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112, 4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484,49, 5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177] </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data.csv</code> which has a header row, but is otherwise the same as <code>tree_data_nh.csv</code>:<syntaxhighlight lang="text"> "Tree","age","circumference" 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight><syntaxhighlight lang="maxima">(%i20) read_array("tree_data.csv", A2, ","); (%o20) done (%i21) listarray(A2); (%o21) ["Tree","age","circumference",1,118,30,1,484,58,1,664,87,1,1004, 115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111, 2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51, 3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174, 5,1582,177]</syntaxhighlight>The previous values of 0 and 0,0 as well as the assigned values of <code>A1</code> and <code>A2</code> have been replaced with the values from the CSV files. The third array A3 can be used with values from the dataset.csv file below:<syntaxhighlight lang="text">"Last Name","Sales","Country","Quarter" "Smith",16753.00,"UK","Qtr 3" "Johnson",14808.00,"USA","Qtr 4" "Williams",10644.00,"UK","Qtr 2" "Jones",1390.00,"USA","Qtr 3" "Brown",4865.00,"USA","Qtr 4" "Williams",12438.00,"UK","Qtr 1" "Johnson",9339.00,"UK","Qtr 2" "Smith",18919.00,"USA","Qtr 3" "Jones",9213.00,"USA","Qtr 4" "Jones",7433.00,"UK","Qtr 1" "Brown",3255.00,"USA","Qtr 2" "Williams",14867.00,"USA","Qtr 3" "Williams",19302.00,"UK","Qtr 4" "Smith",9698.00,"USA","Qtr 1"</syntaxhighlight><syntaxhighlight lang="maxima">(%i22) read_array("dataset.csv", A3, ","); (%o22) done (%i23) listarray(A3); (%o23) ["Last Name","Sales","Country","Quarter", "Smith",16753.0,"UK","Qtr 3", "Johnson",14808.0,"USA","Qtr 4", "Williams",10644.0,"UK","Qtr 2", "Jones",1390.0,"USA","Qtr 3", "Brown",4865.0,"USA","Qtr 4", "Williams",12438.0,"UK","Qtr 1", "Johnson",9339.0,"UK","Qtr 2", "Smith",18919.0,"USA","Qtr 3", "Jones",9213.0,"USA","Qtr 4", "Jones",7433.0,"UK","Qtr 1", "Brown",3255.0,"USA","Qtr 2", "Williams",14867.0,"USA","Qtr 3", "Williams",19302.0,"UK","Qtr 4", "Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> Values of the array can be referenced by indices as required for some purpose:<syntaxhighlight lang="maxima"> (%i24) A3[0,0]; (%o24) "Last Name" (%i25) A3[4,2]; (%o25) "USA" </syntaxhighlight> A row list object can be created using the <code>'''makelist ()'''</code> operator:<syntaxhighlight lang="maxima"> (%i26) row1A3: makelist(A3[0, j], j, 0, 3)$ (%i27) row1A3; (%o27) ["Last Name","Sales","Country","Quarter"] (%i28) row1A3[1]; (%o28) "Last Name" (%i29) row15A3: makelist(A3[14, j], j, 0, 3)$ (%i30) row15A3; (%o30) ["Smith",9698.0,"USA","Qtr 1"] (%i31) row15A3[2]; (%o31) 9698.0 </syntaxhighlight> A list of the indices of the array can be created:<syntaxhighlight lang="maxima"> (%i32) indices_A3 : arrayinfo(A3)[3]; (indices_A3) [14,3] </syntaxhighlight> The number of indices of array <code>A3</code> can also be referenced using the <code>'''length (''')</code> operator:<syntaxhighlight lang="maxima"> (%i33) length(arrayinfo(A3)[3]); (%o33) 2 </syntaxhighlight>The number of values of the array <code>A3</code> can be returned using the '''<code>length ()</code>''' operator:<syntaxhighlight lang="maxima"> (%i34) length(listarray(A3)); (%o34) 60 </syntaxhighlight> The values of the array <code>A3</code> can be printed as output using the list of values with a loop programming expression:<syntaxhighlight lang="maxima"> (%i35) for i:1 thru length (listarray(A3)) do print('A3[i] ," = ", listarray(A3)[i])$ A3[1]" = ""Last Name" A3[2]" = ""Sales" A3[3]" = ""County" A3[4]" = ""Quarter" A3[5]" = ""Smith" A3[6]" = "16753.0 A3[7]" = ""UK" A3[8]" = ""Qtr 3" A3[9]" = ""Johnson" A3[10]" = "14808.0 A3[11]" = ""USA" A3[12]" = ""Qtr 4" A3[13]" = ""Williams" A3[14]" = "10644.0 A3[15]" = ""UK" A3[16]" = ""Qtr 2" A3[17]" = ""Jones" A3[18]" = "1390.0 A3[19]" = ""USA" A3[20]" = ""Qtr 3" A3[21]" = ""Brown" A3[22]" = "4865.0 A3[23]" = ""USA" A3[24]" = ""Qtr 4" A3[25]" = ""Williams" A3[26]" = "12438.0 A3[27]" = ""UK" A3[28]" = ""Qtr 1" A3[29]" = ""Johnson" A3[30]" = "9339.0 A3[31]" = ""UK" A3[32]" = ""Qtr 2" A3[33]" = ""Smith" A3[34]" = "18919.0 A3[35]" = ""USA" A3[36]" = ""Qtr 3" A3[37]" = ""Jones" A3[38]" = "9213.0 A3[39]" = ""USA" A3[40]" = ""Qtr 4" A3[41]" = ""Jones" A3[42]" = "7433.0 A3[43]" = ""UK" A3[44]" = ""Qtr 1" A3[45]" = ""Brown" A3[46]" = "3255.0 A3[47]" = ""USA" A3[48]" = ""Qtr 2" A3[49]" = ""Williams" A3[50]" = "14867.0 A3[51]" = ""USA" A3[52]" = ""Qtr 3" A3[53]" = ""Williams" A3[54]" = "19302.0 A3[55]" = ""UK" A3[56]" = ""Qtr 4" A3[57]" = ""Smith" A3[58]" = "9698.0 A3[59]" = ""USA" A3[60]" = ""Qtr 1" </syntaxhighlight> Maxima treats declared arrays as fixed-sized, and individual values are accessed via indices. There is no built-in "row" object — rows must be extracted manually using the <code>'''makelist ()'''</code> operator or by looping through values of an array.<syntaxhighlight lang="maxima"> (%i36) array(rowsA3,15); (%o36) rowsA3 (%i37) arrayinfo(rowsA3); (%o37) [declared,1,[15]] (%i38) for i:0 thru 14 do (rowsA3[i+1]:makelist(A3[i, j], j, 0, 3), print("Row ",i+1,": ",rowsA3[i+1]))$; "Row "1": "["Last Name","Sales","Country","Quarter"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"] </syntaxhighlight> Maxima does not have a built-in function like <code>delete</code> or <code>unset</code> for removing individual values from arrays using indices. Existing values of an array can be changed by assignment however:<syntaxhighlight lang="maxima">(%i52) rowsA3[1]:["Solomon",1045.0,"USA","Qtr 4"]$ (%i53) for i:1 thru 15 do (newRowsA3[i]:rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$; "Row "1": "["Solomon",1045.0,"USA","Qtr 4"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> The <code>'''arrayapply ()'''</code> operator can be used a follows to reference values of a declared array:<syntaxhighlight lang="maxima"> (%i39) arrayapply(rowsA3,[5]); (%o39) ["Jones",1390.0,"USA","Qtr 3"] (%i40) arrayapply(A3, [5,1]); (%o40) 4865.0 </syntaxhighlight>The operator <code>'''fillarray (A, B)'''</code> assigns values to array <code>A</code> from <code>B</code>, which can be a list or an array.The dimensions of the arrays <code>A</code> and <code>B</code> may not be the same. In that case, array <code>A</code> is filled in "row-major" order. There may not be enough values in <code>B</code> compared to <code>A</code>. In that case, the last value of <code>B</code> is used to for the remaining values of <code>A</code>. There may be too many values of <code>B</code> compared to array <code>A</code>. In that case, the remaining values of <code>B</code> once <code>A</code> is filled are not used. The return value of <code>'''fillarray ()'''</code> is not the filled array <code>A</code>, but it is the first argument.<syntaxhighlight lang="maxima">/* Create a declared array B of type fixnum */ (%i41) array (B, fixnum, 9); (%o41) B /* list the values of array B */ (%i42) listarray (B); (%o42) [0,0,0,0,0,0,0,0,0,0] /* fill array B with the values of the list */ (%i43) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9.0]); (%o43) B /* list the values of array B */ (%i44) listarray (B); (%o44) [0,1,2,3,4,5,6,7,8,9.0] /* fill array B with the value 1.0 */ (%i45) fillarray (B, [1.0]); (%o45) B /* list the values of array B */ (%i46) listarray (B); (%o46) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* fill array B with the first 9 values of the list */ (%i47) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12]); (%o47) B /* list the values of array B */ (%i48) listarray (B); (%o48) [0,1,2,3,4,5,6,7,8,9] /* Create a declared array D of no type */ (%i49) array (D, 9); (%o49) D /* list the values of array D */ (%i50) listarray (D); (%o50) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####] /* fill array D with the value 1.0 */ (%i51) fillarray (D, [1.0]); (%o51) D /* list the values of array D */ (%i52) listarray (D); (%o52) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* Create a declared array E of no type */ (%i53) array (E, 15); (%o53) E /* fill array E with the values from the newRowsA3 list */ (%i54) fillarray (E, listarray (newRowsA3)); (%o54) E /* list the values of array D */ (%i55) listarray (E); (%o55) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"], ["Smith",9698.0,"USA","Qtr 1"]] /* remove array E */ (%i56) remarray (E); (%o56) [E] /* D is no longer an array */ (%i57) arrayinfo (E); arrayinfo: E is not an array. -- an error. To debug this try: debugmode(true);</syntaxhighlight> If you need to keep the array but remove only one value, you must reconstruct it without that value. The operator <code>'''remarray ()'''</code> is the typical way to completely remove an array. The <code>'''rearray (A, dim<sub>1</sub>, dim<sub>2</sub> ,…, dim<sub>n</sub>)'''</code> operator is used to change the dimensions of an array. The changed array will be filled with the elements of the existing array in row-major order. If the existing array has one or more smaller dimensions, the additional dimension values of the changed array are assigned with a value that depends on the type of the array. If the existing array has one or more larger dimensions, the deficient dimension values of the changed array are lost. The type of the array cannot be changed using this operator. <syntaxhighlight lang="maxima"> /* list with the values of array B */ (%i58) listarray(B); (%o58) [0,1,2,3,4,5,6,7,8,9] /* list with information about array B */ (%i59) arrayinfo(B); (%o59) [complete,1,[9]] /* increase the dimension of array B */ (%i60) rearray (B, 12); (%o60) \#\{Lisp array \[13\]\} /* list with information about array B with increased dimension */ (%i61) arrayinfo(B); (%o61) [complete,1,[12]] /* list with the values of array B */ (%i62) listarray(B); (%o62) [0,1,2,3,4,5,6,7,8,9,0,0,0] /* decrease the dimension of array B */ (%i63) rearray (B, 6); (%o63) \#\{Lisp array \[7\]\} /* list with information about array B with decreased dimension */ (%i64) arrayinfo(B); (%o64) [complete,1,[6]] /* list with the values of array B */ (%i65) listarray(B); (%o65) [0,1,2,3,4,5,6] </syntaxhighlight> The <code>'''arraymake ()'''</code> operator returns a value that is an array reference without evaluation. This operator, in spite of the name, does not "make" an array. It returns this reference as a value whether or not an array exists as an object:<syntaxhighlight lang="maxima"> /* the arraymake operator returns the unevaluated reference to A */ (%i66) arraymake (A, [i,j]); (%o66) A[i,j] /* however array A is not an array object*/ (%i67) arrayinfo (A); arrayinfo: A is not an array. -- an error. To debug this try: debugmode(true); /* Maxima sees A[j,k] as a reference to an undefined memoizing function */ (%i68) op (arraymake (A, [i,j])); (%o68) A </syntaxhighlight> However, from a practical point of view, this operator is used with existing arrays:<syntaxhighlight lang="maxima"> (%i69) listarray (newRowsA3); (%o69) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"]] (%i70) arraymake (newRowsA3, [4]); (%o70) newRowsA3[4] (%i71) ''%; (%o71) ["Williams",10644.0,"UK","Qtr 2"] (%i72) arraymake (newRowsA3, [i]); (%o72) newRowsA3[i] (%i73) ''%, i = 6; (%o73) ["Brown",4865.0,"USA","Qtr 4"] </syntaxhighlight> The operator <code>arraymake (x, [i])</code> constructs the expression <code>x[i]</code>, but does not evaluate it. The operator <code>'''subvar'''</code> <code>'''(x, i)'''</code> evaluates the indexed expression <code>x[i]</code>, and evaluates its arguments. <syntaxhighlight lang="maxima"> (%i74) listarray(B); (%o174) [0,1,2,3,4,5,6] (%i75) x : B; (x) B (%i76) i : 4; (i) 4 (%i77) subvar (x, i); (%o77) 4 </syntaxhighlight> The operator <code>'''subvarp (expr)'''</code> returns a value of <code>true</code> if <code>expr</code> is a indexed identifier, and <code>false</code> otherwise. This operator evaluates the argument <code>expr</code>. <syntaxhighlight lang="maxima"> (%i78) z[p]; (%o78) z[p] (%i79) subvarp (z[p]); (%o79) true (%i80) x[i]; (%o80) 4 (%i81) subvar (x, i) (%o81) 4 (%i82) w : z[p]; (w) z[p] (%i83) subvarp (w); (%o83) true </syntaxhighlight> The expression <code>'''arrays'''</code> returns a list of allocated arrays: <syntaxhighlight lang="maxima">(%i84) arrays; (%o84) [A3,A2,A1,rowsA3,newRowsA3,B,D]</syntaxhighlight> The operator <code>'''arraysetapply (A, [i<sub>1</sub>,i<sub>2,</sub>…,i<sub>n</sub>], x)'''</code> assigns the value of expression <code>x</code> to <code>A</code><code>[i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub>]</code>, where <code>A</code> is an array and <code>i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub></code> are integers.<syntaxhighlight lang="maxima">(%i85) arraysetapply (newRowsA3, [8], ["George",20818.0,"UK","Qtr 4"]); (%o85) ["George",20818.0,"UK","Qtr 4"]</syntaxhighlight> === Undeclared Arrays === Maxima declared arrays and Maxima undeclared arrays will likely be the two types of data structures used by most users. Maxima undeclared arrays are also referred to as '''''hashed arrays'''''. For both of these two array types, memory allocation and structure occur "behind the curtain" of the Maxima user level, and "the man behind the curtain" is Lisp. Of these two types, hashed arrays are the most flexible from the user point of view, all other factors being equal: * The indices allowed for hashed arrays can be expressions, * The dimensions of a hashed array are dynamic and not fixed, and * Hashed arrays are relatively easier to create. In fact, hashed arrays can be somewhat too easy to create. In the examples of the previous section involving declared arrays, identifiers were used as names for arrays. here is the list of allocated arrays:<syntaxhighlight lang="maxima">(%i86) arrays; (%o86) [A3,A2,A1,rowsA3,newRowsA3,B,D,my_list,h]</syntaxhighlight>The array information for array <code>newRowsA3</code> is shown below:<syntaxhighlight lang="maxima"> (%i87) arrayinfo(newRowsA3); (%o87) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15]] </syntaxhighlight>So the array <code>newRowsA3</code> is not a declared array. it was created as part of a loop programming expression repeated below:<syntaxhighlight lang="maxima">(%i53) for i : 1 thru 15 do (newRowsA3[i] : rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$;</syntaxhighlight>When the first loop block was executed with i : 1, the assignment expression: <code>newRowsA3[i] : rowsA3[i]</code> created a hashed array named <code>newRowsA3</code> and assigned <code>newRowsA3[1]</code> the value of <code>rowsA3[1]</code> automatically without any declaration. After that the hashed array dynamically allocated memory for values of the loop identifier i from 2 through 15 with each successive pass in the loop expression. Since hashed arrays are undeclared, and their associated dimensions are not fixed, but rather increase dynamically, expressions can be added to hashed arrays without creating a error message. These added values can be can be any valid Maxima expression, and the value of the indices used are not limited to zero and nonzero integers: <syntaxhighlight lang="maxima"> (%i88) newRowsA3[16] : ["Maisel",12785.0,"USA","Qtr 2"]; (newRowsA3[16]) ["Maisel",12785.0,"USA","Qtr 2"] (%i89 arrayinfo(newRowsA3); (%o89) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16]] (%i90) newRowsA3[z] : 2*sin(y) ^2 + 3*sin(x)^3; (newRowsA3[z]) 2*sin(y)^2+3*sin(B)^3 (%i91) arrayinfo(newRowsA3); (%o91) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[z]] </syntaxhighlight>So one point to glean from this example is that all that is required to create a hashed array is an assignment expression to an indexed identifier, but it does require this assignment. If for some reason, a declared array is intended, but not declared using the <code>array</code> operator (as in the instance of <code>newRowsA3</code>), then a hashed array will be created at the first assignment of an expression to an indexed identifier. This issue can also occur in cases where reference to a list value is intended, but the list has not been created. Lists are one-dimensional objects by definition. A reference using an identifier with a single index intended to be a list with no list existing named by that identifier, can inadvertently create a hashed array.<syntaxhighlight lang="maxima"> (%i91) Alist[2] : 2*sin(y) ^2 + 3*sin(s)^3; (Alist[2]) 2*sin(y)^2+3*sin(s)^3 (%i92) listp(Alist); (%o92) false (%i93) arrayinfo(Alist); (%o93) [hashed,1,[2]] </syntaxhighlight>The identifier <code>Alist</code> is a name for a hashed array and not a list. However, hashed arrays, like declared arrays can, be multi-dimensional: <syntaxhighlight lang="maxima"> (%i94) a_hashed_array [j,k,l] : [12,s^(1/3), %i]; (%o94) [12,s^(1/3),%i] (%i95) arrayinfo(a_hashed_array); (%o95) [hashed,3,[j,k,l]] </syntaxhighlight>The <code>array</code> operator can be used to transform a hashed array into a declared array:<syntaxhighlight lang="maxima"> (%i96) another_hashed_array[ 0, 2, 3] : 55; (%o96) 55 (%i97) array (another_hashed_array, 2, 4, 5); (%o97) another_hashed_array (%i98) arrayinfo(another_hashed_array); (%o98) [declared,3,[2,4,5]] </syntaxhighlight>From the user point of view, hashed arrays and declared arrays typically can be used for the same purpose. If dynamic dimensions or index expression flexibility are factors, then hashed arrays are likely to be a better choice. Many of the operators that can use declared arrays as arguments, may also be used with hashed arrays. However, it should be noted at this point, that merely using a indexed identifier alone without an assignment, will not create a hashed array. Instead, Maxima interprets an expression so composed as an identifier for an undefined memoizing function, which is the topic of the next section. ==== Memoizing Functions ==== Assignment using an indexed identifier implicitly creates an undeclared (hashed) array. However, entering an expression that is an unassigned indexed identifier, from the point of view of Maxima, creates the identifier of a "memoizing" function. Memoizing functions are technically not an array topic, as these functions fall under the category of function definition. These functions have one foot in the function category and the other foot in the array category. Memoizing functions are defined in a manner similar to other user-defined functions, for example: <code>f(x, y, z) := x^2 + y^2 + z^2;</code> But instead of the arguments being enclosed in parentheses, they are enclosed using brackets: <code>f[x, y, z] := x^2 + y^2 + z^2;</code> However, memoizing functions may be referred to as ''array functions,'' and it is the case that these functions from the point of view of aggregate data structures are hashed arrays. So these are mentioned and exemplified here for that reason:<syntaxhighlight lang="maxima">/* reference an indexed identifier h without assignment */ (%i99) h[x]; (%o99) h[x] /* check identifier h as an array */ (%i100) arrayinfo (h); arrayinfo: h is not an array. -- an error. To debug this try: debugmode(true); /* check identifier h as a function */ (%i101) op(h[x]); (%o101) h /* define h[x] as a function */ (%i102) h[x] := 5*x^3 + sin(x); (h[x]) h[x]:=5*x^3+sin(x) /* check identifier h[x] as a function */ (%i103) op(h[x]); (%o103) "+" /* check identifier h as an array */ (%i104) arrayinfo (h); (%o104) [hashed,1,[x]] /* check the value of identifier h[x] */ (%i105) h[x]; (%o105) sin(x)+5*x^3 /* evaluate identifier h[x] with the argument 3*%pi */ (%i106) h[3*%pi]; (%o106) 135*%pi^3 /* list the values of identifier h as an array */ (%i107) listarray(h); (%o107) [135*%pi^3,sin(x)+5*x^3] /* check identifier h as an array */ (%i108) arrayinfo (h); (%o108) [hashed,1,[3*%pi],[x]]</syntaxhighlight>A defined memoizing function stores its value the ''first time'' it is referenced with arguments, and returns the stored value, without evaluation, when the same arguments are used with that function subsequently. The stored value is "frozen" after the initial evaluation. Thus, it behaves like a hashed array. The arguments of a memoizing function also serve as indices of the associated hashed array. === Lisp Arrays === Lisp arrays are created using the <code>make_array (type, dim<sub>1</sub>, dim<sub>2</sub>, …, dim<sub>n</sub>)</code> operator. Perhaps a better name for this operator would be <code>make_lisp_array ()</code>, which admittedly is a longer name. This operator creates and has a return value of a Lisp array. The array type may be <code>any</code>, <code>flonum</code>, <code>fixnum</code>, or <code>hashed</code> . The <code>functional</code> type referred to in the Maxima Manual appears to have been deprecated, and may result in an error message if used. There can be ''n'' indices, and where the associated indices can be a value from ''0'' to ''dim<sub>i</sub> -1'', and ''i'' can have a value of one of 1 to n inclusive. This operator can be used as an alternative to the <code>array ()</code> operator. The advantage of using <code>make_array()</code> is that the return value of <code>make_array()</code> ''does not have a name''. Once the Maxima identifier that is assigned to the array return value is no longer assigned, the array memory allocation is released, and the allocated memory can be garbage collected. What it is being referred to that Lisp arrays created using <code>make_array()</code> do not have names? <syntaxhighlight lang="maxima"> /* create a undeclared Maxima hashed array */ (%i109) arrayA1 [1] : 55; (%o109) 55 /* check the information about this undeclared Maxima hashed array */ (%i110) arrayinfo (arrayA1); (%o110) [hashed,1,[1]] /* check the value of this undeclared Maxima hashed array */ (%i111) arrayA1; (%o111) arrayA1 /* the name */ /* create a Lisp hashed array */ (%i112) arrayA2 : make_array (hashed); (arrayA2) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* check the information about this Lisp hashed array */ (%i113) arrayinfo (arrayA2); (%o113) [hash_table,1] /* check the value of this Lisp hashed array */ (%i114) arrayA2; (%o114) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* no name */ (%i115) listarray (arrayA2); (%o115) [] /* this hashed array is empty */ </syntaxhighlight>So Lisp arrays do not have a name as a value. So, Maxima identifiers assigned to a Lisp array have no name for the array as a value. These identifiers have the reference to the array itself as a value, Lisp hashed arrays created using <code>make_array()</code> with the hashed type specified, do not use dimensions. Lisp hashed arrays are often referred to as '''''hashed tables''''', and their indices are called '''''keys'''''. An example of a Lisp array with the type <code>any</code> follows: <syntaxhighlight lang="maxima"> /* make a Lisp 3 by 4 array of type any */ (%i116) arrayA3 : make_array (any, 3,4); (arrayA3) \#\{Lisp array \[3\\,4\]\} (%i117) arrayinfo (arrayA3); (%o117) [declared,2,[2,3]] (%i118) listarray(arrayA3); (%o118) [false,false,false,false,false,false,false,false,false,false,false,false] (%i119) arrayA3[1,1] : "a string" ; (%o119) "a string" (%i120) listarray(arrayA3); (%o120) [false,false,false,false,false,"a string", false,false,false,false,false,false] </syntaxhighlight>Contrary to statements made in some sources, type checking is is not accomplished automatically, and will not cause Maxima to return an error message, as the Lisp array with the type <code>fixnum</code> which follows is an exemplifies:<syntaxhighlight lang="maxima">(%i121) arrayA4 : make_array (fixnum, 3,4); (arrayA4) \#\{Lisp array \[3\\,4\]\} (%i122) arrayinfo (arrayA4); (%o122) [declared,2,[2,3]] (%i123) listarray (arrayA4); (%o123) [0,0,0,0,0,0,0,0,0,0,0,0] (%i124) arrayA4[0,2] : 3.14159; (%o124) 3.14159 (%i125) arrayA4[0,0] : "a string"; (%o125) "a string" /* value types not checked and no error message */ (%i126) listarray (arrayA4); (%o126) ["a string",0,3.14159,0,0,0,0,0,0,0,0,0]</syntaxhighlight>As was the case with declared arrays, there is no type checking and no error messages associated with assigned values of the array based on the declared type. The declared array type simply determines initial fill values, if any. Hashed arrays and Lisp hash tables have an operator in common: <code>has_key</code> <code>(A, L)</code> This expression has a a value of <code>true</code>, if the hashed array or Lisp hash table <code>A</code> has the key (index) or keys (indices) of the list object <code>L</code>. Otherwise the expression has a value of <code>false</code>. The array <code>A</code> must be a hashed (undeclared) array, a Lisp hash table value returned by the <code>make_array</code> operator, or created as an undeclared array with <code>use_fast_arrays</code> assigned the value <code>true</code>. If array A has only one key, that key must be the value of a list.<syntaxhighlight lang="maxima"> (%i127) arrayinfo (newRowsA3); (%o127) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10], [11],[12],[13],[14],[15],[16],[z]] (%i128) has_key (newRowsA3, [z]); (%o128) true (%i129) has_key (newRowsA3, [3]); (%o129) true (%i130) has_key(newRowsA3, [0]); (%o130) false (%i131) lisp_Array_1 [x]; (%o131) 3*x^2 (%i132) arrayinfo (lisp_Array_1); (%o132) [hash_table,1,x] (%i133) has_key (lisp_Array_1, [x]); (%o133) true (%i134) has_key (lisp_Array_1, [y]); (%o134) false </syntaxhighlight> === Arrays and Features === Maxima arrays can be assigned features in a manner similar to other identifiers:<syntaxhighlight lang="maxima"> (%i135) array (a6,fixnum, 5); (%o135) a6 (%i136) arrayinfo (a6); (%o136) [complete,1,[5]] (%i137) declare (a6, [real, noninteger]); (%o137) done (%i138) featurep (a6, real); (%o138) true (%i139) featurep (a6, noninteger); (%o139) true (%i140) a6[2] : 2; (a6[2]) 2 (%i141) listarray (a6); (%o141) [0,0,2,0,0,0] </syntaxhighlight>However, once again, declaring an array to have one or more features does not result in type checking of values assigned to an array. Perhaps the best way to ensure types of values assigned to arrays is type-checking of expressions using predicate operators prior to assignment to arrays. === Array Memory Storage Considerations === The following from the Maxima Manual<ref>{{Cite web |title=Maxima Manual Section 7.5.1 - Functions and Variables for Arrays |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Functions-and-Variables-for-Arrays}}</ref> is quoted here for the purpose of establishing the context of that which follows:<blockquote>''"Option variable: use_fast_arrays ¶'' ''Default value: false'' ''When use_fast_arrays is true, arrays declared by array are values instead of properties, and undeclared arrays (hashed arrays) are implemented as Lisp hashed arrays.'' ''When use_fast_arrays is false, arrays declared by array are properties, and undeclared arrays are implemented with Maxima’s own hashed array implementation.'' ''Note that the code use_fast_arrays switches to is not necessarily faster than the default one; Arrays created by make_array are not affected by use_fast_arrays."''</blockquote> This Maxima Manual entry requires some elaboration in order to have a sufficient understanding of the effect of the <code>'''use_fast_arrays'''</code> "flag" – referred to as an "Option Variable" in the above quotation. The first point to note is that the default value of this flag is <code>false</code>. So, if users take no action to assign this flag to the value <code>true</code>, then declared arrays created using the <code>array()</code> operator are treated as ''properties'' bound to a symbol, and behave in the manner previously described. Likewise undeclared arrays are a Maxima array implementation, and behave as legacy property hash tables, and these also behave as previously described. If action is taken to enter an expression that assigns the value <code>true</code> to this flag, then Maxima treat arrays as standard Lisp ''values'' rather than object properties:<syntaxhighlight lang="maxima"> (%i142) use_fast_arrays; (%o142) false (%i143) array (A1,fixnum, 10); (%o143) A1 (%i144) arrayinfo (A1); (%o144) [complete,1,[10]] (%i145) H1[1] : 1729; (H1[1]) 1729 (%i146) arrayinfo (H1); (%o146) [hashed,1,[1]] (%i147) use_fast_arrays : true; (use_fast_arrays) true (%i148) array (A2, fixnum, 10); (%o148) \#\{Lisp array \[11\]\} (%i149) A2; (%o149) \#\{Lisp array \[11\]\} (%i150) H2[1] : 1729; (H2[1]) 1729 (%i151) H2; (%o151) "#<HASH-TABLE :TEST EQUAL :COUNT 2 {1203AD15A3}>" (%i152) arrayinfo (H2); (%o152) [hash_table,1,1] </syntaxhighlight> The <code>use_fast_arrays</code> flag has no effect on arrays created using the <code>make_array ()</code> operator. Note the following: * Assigning <code>use_fast_arrays</code> <code>: true</code> does not speed up execution for all operations. It primarily optimizes memory footprint by minimizing cell allocations. The main benefit is optimization of memory footprints and structural representation inside Lisp. * If compiling Maxima expressions to native Lisp using the <code>translate</code> <code>()</code> operator, pair this flag with <code>translate_fast_arrays</code> <code>: true</code>. This flag instructs the translator to compile arrays as value-based. === Structures === Structures, although not an array data type is an aggregation data type.  By "aggregation" it is meant a data type that references other data types by reference to a name and some method of accessing individual values of instances of that aggregation by means of indices used to reference values individually. Thus, as has been previously described for example lists, hashed arrays, Lisp arrays, and declared arrays are all aggregation data types with syntactical means to refer to individual values of a named aggregation instance by way of indices, which are sometimes also referred to as subscripts or keys. As examples: * An existing '''list''' named <code>L1</code> has values that can be accessed as <code>L1[1]</code>, <code>L[2]</code>, <code>L[3]</code>, and so forth * An existing '''hashed array''' with two indices ("2D") named <code>ha</code> has values that can accessed as <code>ha[1,1</code>], <code>ha[1,2]</code>,..., <code>ha[2,1]</code>, <code>ha[2,2]</code>, and  so forth. * An existing '''declared array''' with three indices ("3D") named <code>da</code> has values that can be accessed as <code>da[1,1,1]</code>, <code>da[1,1,2]</code>,...,<code>da [2,1,1]</code>, ..., <code>da[3,1,1]</code>, and so forth. What makes the Maxima structure data type different from these array data types is the form of definition used and the means of accessing values of an instance of this type of aggregation. The Maxima structure data type seems to be the closest type of data that resembles an object in some other general-purpose programming languages. The structure type of data allows the creation of named entities with attributes, and named instances of those entities and the assignment of values to those attributes. Thus the Maxima structure data type is used to define custom, named composite data types that group related fields together under a single identifier. Structures enhance code organization and readability, especially when modeling real-world entities in symbolic computations. They are useful for managing complex data in programs involving algebraic manipulations, simulations, or data modeling. Structures are created using the <code>defstruct</code> operator, which defines a template with named attributes. Once defined, instances of the structure are created using the <code>new</code> operator, and attributes are accessed via the <code>@</code> operator. So in the interest of taking advantage of this information, consider a well-defined set of people. The people of this set may have many diverse attributes that might be of interest - name, age ,and city of residence as examples. A class of people of the set of interest with these attributes can be defined as follows: <syntaxhighlight lang="maxima">(%i153) defstruct (person (name, age, city)); (%o153) [person(name,age,city)] (%i54) structures; (%o154) [person(name, age, city)] (%i155) p : new (person ("Alice", 30, "New York")); (p) person(name="Alice",age=30,city="New York") (%i156) p@name; (%o156) "Alice" (%i157) p@city; (%o157) "New York" (%i158) kill(p@city); (%o158) done /* If the attribute a in x has not been assigned a value, or the value has been "killed," then x@a evaluates to itself */ (%i159) p@city; (%o159) p@city (%i160) p; (%o160) person(name="Alice",age=30,city) (%i161) p@city : "Rochester"; (%o161) "Rochester" (%i162) p; (%o162) person(name="Alice",age=30,city="Rochester") (%i163) defstruct (sales(LastName, Sales , Country , Quarter) ); (%o163) [sales(LastName, Sales, Country, Quarter)] (%i164) structures; (%o164) [person(name, age, city), sales(LastName, Sales, Country, Quarter)] (%i165) s : new (sales ("Smith",16753.00,"UK","Qtr 3")); (%o165) sales(LastName=Smith, Sales=16753.0, Country=UK, Quarter=Qtr 3) (%i166) s@Sales; (%o166) 16753.0 (%i167) s@Sales : 17375.0; (%o167) 17375.0 (%i168) s; (%o168) sales(LastName=Smith, Sales=17375.0, Country=UK, Quarter=Qtr 3)</syntaxhighlight>{{Bookcat}} plwzzicy0cex5uj57qssmeqzbudm74e 4668964 4668963 2026-09-05T17:31:50Z Idavidmiller 3577687 /* Introduction */ 4668964 wikitext text/x-wiki == Maxima Aggregate Data Structures == === Introduction === This section is intended to present some of the essentials of what are called Maxima aggregate data structures. By this it is meant the data types that can be used to refer to the values of expressions using a means of indexing of a single identifier (name) that refers to an aggregate (collection) of expressions as values. Built-in aggregate data types include: * lists * hashed arrays * declared arrays * structures Each of these has a means of indexing an identifier that names an instance of these data types. Please note that it is the case that this means of indexing an identifier for an aggregate data type may be referred to as involving "subscripts" or "sub-scripted variables" or "keys" as used by various computer programming languages, as well as in the context of Maxima documentation and commentary. In this book terms such as "index" or "indices" or "indexed identifiers"  are used instead. Also all built-in Maxima functions (including packages) for these data types are referred to as ''"operators"'' and not ''"functions"'' as this latter term in general serves better to refer to Maxima function expressions defined by the user -- as in <code>f(x) :=</code>, <code>g[s] :=</code> and <code>define ()</code> as examples. This section is not intended to be exhaustive. It is intended to provide familiarity with aggregate data types. What is included has been gleaned from various sources, and only a few attributions are provided. Therefore, there is no claim of originality implied. === Lists === ==== Introduction to Lists ==== Lists are one of the basic buildings block for Maxima and Lisp. Maxima expressions are in general represented as Lisp lists. For example, consider the Maxima expression:<syntaxhighlight lang="maxima"> (%i1) e+3; (%o1) e+3 </syntaxhighlight>This expression has the form of a Lisp list:<syntaxhighlight lang="maxima"> (%i2) :lisp #$[e+3]$ ((MLIST SIMP) ((MPLUS SIMP) 3 $E)) </syntaxhighlight>An expression in the form of a Lisp list can also be be displayed as a Maxima expression:<syntaxhighlight lang="maxima"> (%i2) :lisp (displa '((MLIST SIMP) ((MPLUS SIMP) 3 $E))); [e+3] NIL </syntaxhighlight>Note that the value of this expression using <code>displa '()</code> is <code>NIL</code>, and <code>[e+3]</code> is simply displayed in Maxima list object form. It is not necessary for the typical uses of Maxima to utilize this insight into the role Lisp lists have as one of the building blocks for Maxima, but it may be useful to have a familiarity with that role. Lists are often used as arguments to many operators, and the values of expressions are often in the form of lists. ==== Some Operators for Lists ==== Lists are created explicitly and list elements referenced using <code>[</code> and <code>]</code> to mark the beginning and end, respectively, of an instance of a list object, or to reference the expressions of an existing list object.<syntaxhighlight lang="maxima"> (%i3) [2,3,4]; (%o3) [2,3,4] </syntaxhighlight>The expression <code>[2,3,4]</code> creates a Maxima list object. In this case the object itself is not accessible as it was not assigned an identifier unless referenced by the <code>%</code> , <code>%i</code> or <code>%o</code> label.<syntaxhighlight lang="maxima"> (%i4) %; (%o4) [2,3,4] (%i5) %o4[2]; /* second expression of list object referenced by index */ (%o5) 3 </syntaxhighlight>That [2,3,4] is a list object can be tested using the <code>listp()</code> operator:<syntaxhighlight lang="maxima"> (%i6) listp ([2,3,4]); (%o6) true </syntaxhighlight>A list object can be assigned an identifier:<syntaxhighlight lang="maxima">(%i7) s:[%pi,%e,%phi]; (s) [%pi,%e,%phi] (%i8) listp (s); (%o8) true</syntaxhighlight> The value of an element of a list can be accessed using the list identifier and brackets with a index value.<syntaxhighlight lang="maxima"> (%i9) s[1]; (%o9) %pi (%i10) s[2]; (%o10) %e (%i11) s[3]; (%o11) %phi </syntaxhighlight> Invalid index values returns an error:<syntaxhighlight lang="maxima"> (%i12) s[4]; inpart: invalid index 4 of list or matrix. -- an error. To debug this try: debugmode(true); </syntaxhighlight> Consider the following relatively long list of integer atoms created explicitly and identified as <code>List_1</code>:<syntaxhighlight lang="maxima">(%i13) List_1:[1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582,145,2, 118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118, 30,3,484,51,3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32,4, 484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484, 49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177]; (List_1) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203,2,1582,203 ,3,118,30,3,484,51,3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582, 214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177]</syntaxhighlight> The number of values of this list can be returned using the <code>length()</code> operator:<syntaxhighlight lang="maxima"> (%i14) length (List_1); (%o14) 105 </syntaxhighlight> Create another list identified as <code>List_2</code>:<syntaxhighlight lang="maxima"> (%i15) List_2 : [6,1455,200,6,1607,205]; (List_2) [6,1455,200,6,1607,205] (%i16) length (List_2); (%o16) 6 </syntaxhighlight> Create a third list identified as <code>List_3</code>:<syntaxhighlight lang="maxima"> (%i17) List_3 : append (List_1, List_2)$ (%i18) length (List_3); (%o19) 111 </syntaxhighlight> Note that the <code>'''append ()'''</code> operator does not affect either of the list arguments <code>List_1</code> or <code>List</code>_2. It merely appends <code>List_2</code> to <code>List_1</code> and returns a new list, in this case assigned the identifier <code>List_3</code>.<syntaxhighlight lang="maxima">(%i20) length (List_1); (%o20) 105 (%i21) length (List_2); (%o21) 6 (%i22) length (List_3); (%o22) 111 (%i23) List_3; (%o23) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607,205]</syntaxhighlight> Values (the last one in this example) can be deleted from a list:<syntaxhighlight lang="maxima">(%i24) last (List_3); (%o24) 205 (%i25) delete (last (List_3), List_3); (%o25) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607]</syntaxhighlight> The <code>delete (List_3)</code> expression creates a new list object using <code>List_3</code>. <code>List_3</code> itself is not affected by the <code>'''delete ()'''</code> operator. Only the resulting list is affected. This is often the case with list operators. An identifier could be used to save the above resulting list if necessary:<syntaxhighlight lang="maxima">/* List_3 is the same length */ (%i26) length(List_3); (%o26) 111 /* The last value of List_3 is the same */ (%i27) List_3[111]; (%o27) 205 (%i28) last(List_3); (%o28) 205</syntaxhighlight>There was only one instance of <code>205</code> in <code>List_3</code>, so only that value was deleted from the list of <code>%o25</code>. If there are more than one value then the <code>delete ()</code> operator will remove all of those values from the returned list expression:<syntaxhighlight lang="maxima"> (%i29) NewList_3 : delete(118, List_3)$ /* all five instances of 118 removed from List_3 as NewList_3 */ (%i30) length(NewList_3); (%o30) 106 </syntaxhighlight>There are operators to refer to instances of list expressions by ordinal number:<syntaxhighlight lang="maxima"> (%i30) FirstThreeList_3:[first(List_3), second(List_3), third(List_3)]; (FirstThreeList_3) [1,118,30] </syntaxhighlight>Expressions of list objects can e referenced to create a new list object from the first n expressions of a list, the last n expressions of a list, or the rest remaining after n expressions from the beginning or -n expressions from the end of a list:<syntaxhighlight lang="maxima">/* first three expressions of List_3 */ (%i31) firstn(List_3,3); (%o31) [1,118,30] /* same three expressions of List_3 using the rest operator with -108 */ (%i32) rest(List_3, -108); (%o32) [1,118,30] /* last three expressions of List_3 */ (%i33) lastn(List_3,3); (%o33) [6,1607,205] /* same three expressions of List_3 using the rest operator with 108 */ (%i34) rest(List_3, 108); (%o34) [6,1607,205]</syntaxhighlight>Some further examples of the <code>'''firstn ()'''</code>, <code>'''lastn ()'''</code> and <code>'''rest ()'''</code> list operators:<syntaxhighlight lang="maxima"> /* first 63 expressions of List_3 */ (%i35) firstn (List_3, 63); (%o35) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108,3, 1231,115,3,1372,139,3,1582,140] /* last 63 expressions of List_3 */ (%i36) lastn (List_3, 63); (%o36) [3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5, 1582,177,6,1455,200,6,1607,205] /* first expressions of List_3 after removing the last 63*/ (%i37) rest (List_3, -63); (%o37) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51] </syntaxhighlight>Maxima programming expressions can be used with list operators to reference list expressions in various ways. For example, the expression which follows accesses the expressions of a list as lists of three each:<syntaxhighlight lang="maxima"> (%i38) (L4 : List_4, for i:(-length (List_4)) + 3 thru 0 step 3 do (disp (rest (L4, i)), L4 : rest (L4, 3)), "")$ [1,118,30] [1,484,58] [1,664,87] [1,1004,115] [1,1231,120] [1,1372,142] [1,1582,145] [2,118,33] [2,484,69] [2,664,111] [2,1004,156] [2,1231,172] [2,1372,203] [2,1582,203] [3,118,30] [3,484,51] [3,664,75] </syntaxhighlight>List operators can be used as arguments other list operators:<syntaxhighlight lang="maxima"> /* create a new empty list */ (%i39) newList4 : []; (newList4) [] /* append the first six & last six expressions of List_4 to the new list */ (%i40) newList4 : append (newList4, firstn (List_4, 6), lastn (List_4, 6))$ /* the new list now has the 12 appended expressions from List_4 */ (%i41) newList4; (%o41) [1,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> Maxima programming expressions can be used to step through the expressions of lists using list operators to reference "slices" of different lengths:<syntaxhighlight lang="maxima">(%i42) L4 : List_4; (L4) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582 145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203, 2,1582,203,3,118,30,3,484,51,3,664,75] (%i43) length (L4); (%o43) 51 (%i44) (L4 : List_4, for i : 21 thru 3 step -3 do print (L4 : lastn (L4, i)," ", length (L4)), "")$ [2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 21 [2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 18 [2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 15 [2,1582,203,3,118,30,3,484,51,3,664,75] 12 [3,118,30,3,484,51,3,664,75] 9 [3,484,51,3,664,75] 6 [3,664,75] 3</syntaxhighlight> ==== Using the <code>copylist</code> Operator ==== When an existing list object is assigned to an identifier, a reference to the memory location of the list object is used. This reference to the memory location is transparent from the point of view of the user. However,if this is not accounted for unintended side effects may occur when assigning another identifier to an existing one that references a list object. For example, in the expression <code>L4 : List_4</code> it might be assumed that this results in the list object referenced by <code>List_4</code> to simply be copied to a new memory location and reference for <code>L4</code>. This is not the case. Both <code>L4</code> and <code>List_4</code> refer to the same list object in memory. Consequently changes to the same list object can be effected by referencing the object using either alias.<syntaxhighlight lang="maxima"> (%i45) newList4; (%o45) [1,118,30,1,484,58,3,484,51,3,664,75] /* The identifier newList4 refers to a location in memory. The colon (:) assignment operator simply creates an alias using that same memory reference*/ (%i46) newList5 : newList4; (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Two different identifiers for the same memory location and therefore the same object. Changes to expressions of the list object using either identifier changes the same object in memory */ (%i47) newList5[1] : 99; (newList5[1]) 99 (%i48) newList4[1]; (%o48) 99 (%i49) newList4; (%o49) [99,118,30,1,484,58,3,484,51,3,664,75] (%i50) newList5; (%o50) [99,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> This "side effect" is often unwanted. The way to avoid this is by using the <code>copylist ()</code> operator instead of the assignment operator:<syntaxhighlight lang="maxima"> (%i51) newList4 : [1,118,30,1,484,58,3,484,51,3,664,75] ; (newList4) [1,118,30,1,484,58,3,484,51,3,664,75] (%i52) newList5 : copylist (newList4); (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Same list object expressions, but a different memory reference */ (%i53) newList5[1] : 99; (newList5[1]) 99 (%i54) newList4[1]; (%o54) 1 </syntaxhighlight> Changes to the values of either list will not affect the other list. {| class="wikitable" |+List Object Operators |[ |fourth |rreduce |- |] |fullsetify |second |- |append |join |setify |- |assoc |last |seventh |- |cons |length |sixth |- |copylist |listarith |some |- |create_list |listp |sort |- |delete |lmax |sublist |- |eighth |lmin |sublist_indices |- |endcons |lreduce |tenth |- |fifth |makelist |third |- |first |member |tree_reduce |- |flatten |reverse |xreduce |} Refer to the Maximal Manual<ref>{{Cite web |title=Maxima Manual Section 7.4.2 Functions and Variables for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref> for more complete description of operators and variables for Maxima lists. ==== Performance Considerations for Lists ==== <blockquote>''"Lists provide efficient ways of appending and removing elements. They can be created without knowing their final dimensions. Lisp provides efficient means of copying and handling lists. Also nested lists do not need to be strictly rectangular. These advantages over declared arrays come with the drawback that the amount of time needed for accessing a random element within a list may be roughly proportional to the element’s distance from its beginning."''<ref>{{Cite web |title=Maxima Manual Section 7.4.3 Performance considerations for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref></blockquote>Maxima list objects have many operators for creating, accessing, and changing the expressions of lists. Evaluation times of expressions that involve lists can vary significantly depending on the length of the list objects involved, as well as the nature of any operators used to compose the expressions. This fact might have an influence on the choice of using arrays rather than lists in some cases if evaluation time is a factor to consider. The example expressions that follow involve a list object (identified as <code>s</code> ) of complex number expressions that has a length of 10,000 and two different user-defined functions:<pre>(%i55) P1(s) := rectform (product(s[i], i, 1, length (s)))$ (%i56) P2(s) := xreduce (lambda ([a, b], rectform (a * b)), s)$ (%i57) s : makelist (random (1.0) + %i*random (1.0), 10^4)$ (%i58) showtime : true$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes. (%i59) P1(s); Evaluation took 32.3080 seconds (32.3860 elapsed) using 17944.301 MB. (%o59) 0.0 (%i60) P2(s); Evaluation took 0.0620 seconds (0.0620 elapsed) using 8.343 MB. (%o60) 0.0 (%i61) showtime : false$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.</pre> ==Arrays == <blockquote>"Maxima's current array/matrix semantics are a mess, I must say, with at least four different kinds of object (hash arrays, explicit lists, explicit matrices, Lisp arrays) supporting subscripting with varying semantics." <ref>[http://comments.gmane.org/gmane.comp.mathematics.maxima.general/21829 Maxima: Syntax improvements by Stavros Macrakis ]</ref> – Stavros Macrakis "Maxima's concept of arrays, lists, and matrices is pretty confused, since various ideas have accreted in the many years of the project... Yes, this is a mess. Sorry about that. These are all interesting ideas, but there is no unifying framework."<ref>[http://stackoverflow.com/a/29926692 Maxima: what does Maxima call an “array”? - answer by Robert Dodier]</ref> – Robert Dodier</blockquote> The various terminology used in the context of arrays undoubtedly can be confusing. For the sake of simplicity and clarity the following categories of array objects are referred to in this book: Maxima has three array categories :<ref>[http://permalink.gmane.org/gmane.comp.mathematics.maxima.general/13588 the Maxima mailing list <nowiki>: [Maxima] array and matrix? - answer by Robert Dodier</nowiki>]</ref> * Declared arrays * Undeclared (hashed) arrays * Lisp arrays '''''Declared arrays''''' are explicitly created using the <code>array()</code> operator, and unlike lists, which have only one index and are one-dimensional, declared arrays can be multi-dimensional – having one to five indices. The indices for declared array dimensions need not be equal. Indices for each dimension may be between 0 and the respective declared dimension. Each declared array may be for expressions of a specified type, which can be ''fixnum'' for integers or ''flonum'' for floating-point numbers. '''''Undeclared (hashed) arrays''''' are created implicitly by assigning an expression to an indexed identifier that does not name an existing list object. An undeclared array (hashed array) can grow dynamically as there is no fixed dimension limit for each index as there is with declared arrays Another difference is that numbers, identifiers, expressions and strings may be used for indices. Also, there is no fixed limit on the number of dimensions. The only real limitation is practical – the available computer memory and the underlying Lisp environment of the Maxima session. Hashed arrays with only one dimension may be confused with a list object. It is essential to keep in mind that list objects must always be created before values are assigned or referenced. Assigning an expression to a one-dimensional indexed identifier, that does not reference an existing list, implicitly creates a hashed array. '''''Lisp arrays''''' are created using the <code>'''make_array ()'''</code> operator. The array type may be specified as ''any'', ''flonum'', ''fixnum'', or ''hashed''. Lisp array objects may be created as one-dimensional or multi-dimensional as specified by the number of dimension size values used with the <code>'''make_array ()'''</code> operator. For each dimension value specified, the associated index value can be a number between 0 to 1 less than the respective dimension value. The same or different values may be used for each specified dimension. the ''hashed'' type does not require any dimensions. Lisp arrays may be used in cases where memory usage and garbage collection are factors. Examples of use and elaboration upon the technical details for each of these categories of array object types follows. {| class="wikitable" |+Array Operators and Flags |array |arraysetapply |rearray |- |arrayapply |has_key |remarray |- |arrayinfo |fillarray |subvar |- |arraymake |listarray |subvarp |- |arrays |make_array |use_fast_arrays |- | | |translate_fast_arrays |} === Declared Arrays === Declared arrays must be created before being referenced and are of fixed dimensions.<syntaxhighlight lang="maxima"> (%i1) array(A1, fixnum, 34,2); (%o1) A1 (%i2) array(A2, flonum, 35,2); (%o2) A2 (%i3) array(A3, 14,3); (%o3) A3 (%i4) arrayinfo (A1); (%o4) [complete,2,[34,2]] (%i5) arrayinfo (A2); (%o5) [complete,2,[35,2]] (%i6) arrayinfo (A3); (%o6) [declared,2,[14,3]] </syntaxhighlight> The first expression <code>%i1</code> creates a declared array object named using the identifier <code>A1</code>. This array is two-dimensional – the first index may have values from 0 to 34 and the second index may have values from 0 to 2. This array therefore is 35 by 3 in extent. The array type is declared to be <code>fixnum</code>. As it is, <code>A1</code> is an not empty array – it has values to reference as will be exemplified below. Similarly the second expression <code>%i2</code> creates a declared array object named using the identifier <code>A2</code>. This array is also two-dimensional – the first index may have values from 0 to 35 and the second index may have values from 0 to 2. This array therefore is 36 by 3 in extent. The array type is declared to be <code>flonum</code>. As it is, <code>A2</code> is not an empty array – it also has values to reference as will be exemplified below. The third expression <code>%i3</code> creates a declared array object named using the identifier <code>A3</code>. This array is also two-dimensional – the first index may have values from 0 to 13 and the second index may have values from 0 to 3. This array therefore is 15 by 4 in extent. The array type is not declared. As it is, <code>A3</code> is an empty array – it has no values to reference as will be exemplified below. The <code>'''arrayinfo ()'''</code> operator can be used to return a list object that has values reflecting information about an array. Note that arrays declared without a type will have <code>declared</code> as a value of the list. Arrays declared with <code>fixnum</code> or <code>flonum</code> as the type will have <code>complete</code> as a value of the list. This technical detail is not well-documented. The returned information list also shows a value for the dimension of the array ( 2 in these examples ) and an inner list with values for the maximum index for each dimension. A look inside each of these declared arrays provides a clue as to why <code>complete</code> is returned instead of <code>declared</code> when the type is specified as <code>fixnum</code> or <code>flonum</code>:<syntaxhighlight lang="maxima">/* This array reference has a value of 0 */ (%i7) A1[0,0]; (%o7) 0 /* This array reference has a value of 0.0 */ (%i8) A2[0,0]; (%o8) 0.0 /* This array reference has a value of itself */ (%i9) A3[0,0]; (%o9) A3[0,0]</syntaxhighlight> In fact, ''all'' values of the array <code>A1</code> have been assigned 0, and ''all'' values of the array <code>A2</code> have beenassigned 0.0. However, ''all'' values of the array <code>A3</code> have been not been assigned any value.<syntaxhighlight lang="maxima">(%i10) listarray(A1); (%o10) [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0] (%i11) listarray(A2); (%o11) [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] (%i12) listarray(A3); (%o12) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####]</syntaxhighlight> Thus, arrays <code>A1</code> and <code>A2</code> are <code>complete</code> in this sense, and array <code>A3</code> is simply <code>declared</code>. It might seem reasonable, that Maxima would complain if a value was assigned to an array that is at odds with the declared type. Such is not the case however. Once an array is declared with a type, Maxima does not enforce any type checking of values assigned to the array. The effect of the type (if any) in the declaration is simply to fill the array with values of #####, 0 or 0.0. Subsequently, those values can be replaced by the assignment of different values that will not be checked for the type of value. One way to enforce type checking is by using predicate operators to check values at the point in time of assignment to arrays. For example, using one or more of: * numberp (expr) * floatnump (expr) * integerp (expr) * ratnump (expr) * stringp (obj) * listp (expr) * featurep (a, f) and possibly others.<syntaxhighlight lang="maxima"> /* A1 was declared as type fixnum */ (%i13) A1[5,2]:3.14159; (%o13) 3.14159 /* A2 was declared as type flonum */ (%i14) A2[3,0]:7129; (%o14) 7129 /* A1 which was declared as type fixnum assigned a string */ (%i15) A1[4,1]:"a string"; (%o15) "a string" /* A2 which was declared as type flonum assigned a math expression*/ (%i16) A2[6,1]:3*x^2 + 4*x +10; (%o16) 3*x^2+4*x+10 </syntaxhighlight> There are other ways to assign values to an array. One way is to read the values from a comma separated (CSV) file using the <code>'''read_array ()'''</code> operator from the ''numericalio'' package.<syntaxhighlight lang="maxima"> (%i17) load(numericalio); (%o17) "/app/plugins/maxima/share/maxima/5.50.0/share/numericalio/numericalio.mac" </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data_nh.csv</code> :<syntaxhighlight lang="text"> 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight> Note that the following expression assumes that the CSV file is located in the Maxima working directory.<syntaxhighlight lang="maxima"> (%i18) read_array("tree_data_nh.csv", A1, ","); (%o18) done (%i19) listarray(A1); (%o19) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142, 1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172, 2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108, 3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112, 4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484,49, 5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177] </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data.csv</code> which has a header row, but is otherwise the same as <code>tree_data_nh.csv</code>:<syntaxhighlight lang="text"> "Tree","age","circumference" 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight><syntaxhighlight lang="maxima">(%i20) read_array("tree_data.csv", A2, ","); (%o20) done (%i21) listarray(A2); (%o21) ["Tree","age","circumference",1,118,30,1,484,58,1,664,87,1,1004, 115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111, 2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51, 3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174, 5,1582,177]</syntaxhighlight>The previous values of 0 and 0,0 as well as the assigned values of <code>A1</code> and <code>A2</code> have been replaced with the values from the CSV files. The third array A3 can be used with values from the dataset.csv file below:<syntaxhighlight lang="text">"Last Name","Sales","Country","Quarter" "Smith",16753.00,"UK","Qtr 3" "Johnson",14808.00,"USA","Qtr 4" "Williams",10644.00,"UK","Qtr 2" "Jones",1390.00,"USA","Qtr 3" "Brown",4865.00,"USA","Qtr 4" "Williams",12438.00,"UK","Qtr 1" "Johnson",9339.00,"UK","Qtr 2" "Smith",18919.00,"USA","Qtr 3" "Jones",9213.00,"USA","Qtr 4" "Jones",7433.00,"UK","Qtr 1" "Brown",3255.00,"USA","Qtr 2" "Williams",14867.00,"USA","Qtr 3" "Williams",19302.00,"UK","Qtr 4" "Smith",9698.00,"USA","Qtr 1"</syntaxhighlight><syntaxhighlight lang="maxima">(%i22) read_array("dataset.csv", A3, ","); (%o22) done (%i23) listarray(A3); (%o23) ["Last Name","Sales","Country","Quarter", "Smith",16753.0,"UK","Qtr 3", "Johnson",14808.0,"USA","Qtr 4", "Williams",10644.0,"UK","Qtr 2", "Jones",1390.0,"USA","Qtr 3", "Brown",4865.0,"USA","Qtr 4", "Williams",12438.0,"UK","Qtr 1", "Johnson",9339.0,"UK","Qtr 2", "Smith",18919.0,"USA","Qtr 3", "Jones",9213.0,"USA","Qtr 4", "Jones",7433.0,"UK","Qtr 1", "Brown",3255.0,"USA","Qtr 2", "Williams",14867.0,"USA","Qtr 3", "Williams",19302.0,"UK","Qtr 4", "Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> Values of the array can be referenced by indices as required for some purpose:<syntaxhighlight lang="maxima"> (%i24) A3[0,0]; (%o24) "Last Name" (%i25) A3[4,2]; (%o25) "USA" </syntaxhighlight> A row list object can be created using the <code>'''makelist ()'''</code> operator:<syntaxhighlight lang="maxima"> (%i26) row1A3: makelist(A3[0, j], j, 0, 3)$ (%i27) row1A3; (%o27) ["Last Name","Sales","Country","Quarter"] (%i28) row1A3[1]; (%o28) "Last Name" (%i29) row15A3: makelist(A3[14, j], j, 0, 3)$ (%i30) row15A3; (%o30) ["Smith",9698.0,"USA","Qtr 1"] (%i31) row15A3[2]; (%o31) 9698.0 </syntaxhighlight> A list of the indices of the array can be created:<syntaxhighlight lang="maxima"> (%i32) indices_A3 : arrayinfo(A3)[3]; (indices_A3) [14,3] </syntaxhighlight> The number of indices of array <code>A3</code> can also be referenced using the <code>'''length (''')</code> operator:<syntaxhighlight lang="maxima"> (%i33) length(arrayinfo(A3)[3]); (%o33) 2 </syntaxhighlight>The number of values of the array <code>A3</code> can be returned using the '''<code>length ()</code>''' operator:<syntaxhighlight lang="maxima"> (%i34) length(listarray(A3)); (%o34) 60 </syntaxhighlight> The values of the array <code>A3</code> can be printed as output using the list of values with a loop programming expression:<syntaxhighlight lang="maxima"> (%i35) for i:1 thru length (listarray(A3)) do print('A3[i] ," = ", listarray(A3)[i])$ A3[1]" = ""Last Name" A3[2]" = ""Sales" A3[3]" = ""County" A3[4]" = ""Quarter" A3[5]" = ""Smith" A3[6]" = "16753.0 A3[7]" = ""UK" A3[8]" = ""Qtr 3" A3[9]" = ""Johnson" A3[10]" = "14808.0 A3[11]" = ""USA" A3[12]" = ""Qtr 4" A3[13]" = ""Williams" A3[14]" = "10644.0 A3[15]" = ""UK" A3[16]" = ""Qtr 2" A3[17]" = ""Jones" A3[18]" = "1390.0 A3[19]" = ""USA" A3[20]" = ""Qtr 3" A3[21]" = ""Brown" A3[22]" = "4865.0 A3[23]" = ""USA" A3[24]" = ""Qtr 4" A3[25]" = ""Williams" A3[26]" = "12438.0 A3[27]" = ""UK" A3[28]" = ""Qtr 1" A3[29]" = ""Johnson" A3[30]" = "9339.0 A3[31]" = ""UK" A3[32]" = ""Qtr 2" A3[33]" = ""Smith" A3[34]" = "18919.0 A3[35]" = ""USA" A3[36]" = ""Qtr 3" A3[37]" = ""Jones" A3[38]" = "9213.0 A3[39]" = ""USA" A3[40]" = ""Qtr 4" A3[41]" = ""Jones" A3[42]" = "7433.0 A3[43]" = ""UK" A3[44]" = ""Qtr 1" A3[45]" = ""Brown" A3[46]" = "3255.0 A3[47]" = ""USA" A3[48]" = ""Qtr 2" A3[49]" = ""Williams" A3[50]" = "14867.0 A3[51]" = ""USA" A3[52]" = ""Qtr 3" A3[53]" = ""Williams" A3[54]" = "19302.0 A3[55]" = ""UK" A3[56]" = ""Qtr 4" A3[57]" = ""Smith" A3[58]" = "9698.0 A3[59]" = ""USA" A3[60]" = ""Qtr 1" </syntaxhighlight> Maxima treats declared arrays as fixed-sized, and individual values are accessed via indices. There is no built-in "row" object — rows must be extracted manually using the <code>'''makelist ()'''</code> operator or by looping through values of an array.<syntaxhighlight lang="maxima"> (%i36) array(rowsA3,15); (%o36) rowsA3 (%i37) arrayinfo(rowsA3); (%o37) [declared,1,[15]] (%i38) for i:0 thru 14 do (rowsA3[i+1]:makelist(A3[i, j], j, 0, 3), print("Row ",i+1,": ",rowsA3[i+1]))$; "Row "1": "["Last Name","Sales","Country","Quarter"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"] </syntaxhighlight> Maxima does not have a built-in function like <code>delete</code> or <code>unset</code> for removing individual values from arrays using indices. Existing values of an array can be changed by assignment however:<syntaxhighlight lang="maxima">(%i52) rowsA3[1]:["Solomon",1045.0,"USA","Qtr 4"]$ (%i53) for i:1 thru 15 do (newRowsA3[i]:rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$; "Row "1": "["Solomon",1045.0,"USA","Qtr 4"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> The <code>'''arrayapply ()'''</code> operator can be used a follows to reference values of a declared array:<syntaxhighlight lang="maxima"> (%i39) arrayapply(rowsA3,[5]); (%o39) ["Jones",1390.0,"USA","Qtr 3"] (%i40) arrayapply(A3, [5,1]); (%o40) 4865.0 </syntaxhighlight>The operator <code>'''fillarray (A, B)'''</code> assigns values to array <code>A</code> from <code>B</code>, which can be a list or an array.The dimensions of the arrays <code>A</code> and <code>B</code> may not be the same. In that case, array <code>A</code> is filled in "row-major" order. There may not be enough values in <code>B</code> compared to <code>A</code>. In that case, the last value of <code>B</code> is used to for the remaining values of <code>A</code>. There may be too many values of <code>B</code> compared to array <code>A</code>. In that case, the remaining values of <code>B</code> once <code>A</code> is filled are not used. The return value of <code>'''fillarray ()'''</code> is not the filled array <code>A</code>, but it is the first argument.<syntaxhighlight lang="maxima">/* Create a declared array B of type fixnum */ (%i41) array (B, fixnum, 9); (%o41) B /* list the values of array B */ (%i42) listarray (B); (%o42) [0,0,0,0,0,0,0,0,0,0] /* fill array B with the values of the list */ (%i43) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9.0]); (%o43) B /* list the values of array B */ (%i44) listarray (B); (%o44) [0,1,2,3,4,5,6,7,8,9.0] /* fill array B with the value 1.0 */ (%i45) fillarray (B, [1.0]); (%o45) B /* list the values of array B */ (%i46) listarray (B); (%o46) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* fill array B with the first 9 values of the list */ (%i47) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12]); (%o47) B /* list the values of array B */ (%i48) listarray (B); (%o48) [0,1,2,3,4,5,6,7,8,9] /* Create a declared array D of no type */ (%i49) array (D, 9); (%o49) D /* list the values of array D */ (%i50) listarray (D); (%o50) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####] /* fill array D with the value 1.0 */ (%i51) fillarray (D, [1.0]); (%o51) D /* list the values of array D */ (%i52) listarray (D); (%o52) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* Create a declared array E of no type */ (%i53) array (E, 15); (%o53) E /* fill array E with the values from the newRowsA3 list */ (%i54) fillarray (E, listarray (newRowsA3)); (%o54) E /* list the values of array D */ (%i55) listarray (E); (%o55) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"], ["Smith",9698.0,"USA","Qtr 1"]] /* remove array E */ (%i56) remarray (E); (%o56) [E] /* D is no longer an array */ (%i57) arrayinfo (E); arrayinfo: E is not an array. -- an error. To debug this try: debugmode(true);</syntaxhighlight> If you need to keep the array but remove only one value, you must reconstruct it without that value. The operator <code>'''remarray ()'''</code> is the typical way to completely remove an array. The <code>'''rearray (A, dim<sub>1</sub>, dim<sub>2</sub> ,…, dim<sub>n</sub>)'''</code> operator is used to change the dimensions of an array. The changed array will be filled with the elements of the existing array in row-major order. If the existing array has one or more smaller dimensions, the additional dimension values of the changed array are assigned with a value that depends on the type of the array. If the existing array has one or more larger dimensions, the deficient dimension values of the changed array are lost. The type of the array cannot be changed using this operator. <syntaxhighlight lang="maxima"> /* list with the values of array B */ (%i58) listarray(B); (%o58) [0,1,2,3,4,5,6,7,8,9] /* list with information about array B */ (%i59) arrayinfo(B); (%o59) [complete,1,[9]] /* increase the dimension of array B */ (%i60) rearray (B, 12); (%o60) \#\{Lisp array \[13\]\} /* list with information about array B with increased dimension */ (%i61) arrayinfo(B); (%o61) [complete,1,[12]] /* list with the values of array B */ (%i62) listarray(B); (%o62) [0,1,2,3,4,5,6,7,8,9,0,0,0] /* decrease the dimension of array B */ (%i63) rearray (B, 6); (%o63) \#\{Lisp array \[7\]\} /* list with information about array B with decreased dimension */ (%i64) arrayinfo(B); (%o64) [complete,1,[6]] /* list with the values of array B */ (%i65) listarray(B); (%o65) [0,1,2,3,4,5,6] </syntaxhighlight> The <code>'''arraymake ()'''</code> operator returns a value that is an array reference without evaluation. This operator, in spite of the name, does not "make" an array. It returns this reference as a value whether or not an array exists as an object:<syntaxhighlight lang="maxima"> /* the arraymake operator returns the unevaluated reference to A */ (%i66) arraymake (A, [i,j]); (%o66) A[i,j] /* however array A is not an array object*/ (%i67) arrayinfo (A); arrayinfo: A is not an array. -- an error. To debug this try: debugmode(true); /* Maxima sees A[j,k] as a reference to an undefined memoizing function */ (%i68) op (arraymake (A, [i,j])); (%o68) A </syntaxhighlight> However, from a practical point of view, this operator is used with existing arrays:<syntaxhighlight lang="maxima"> (%i69) listarray (newRowsA3); (%o69) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"]] (%i70) arraymake (newRowsA3, [4]); (%o70) newRowsA3[4] (%i71) ''%; (%o71) ["Williams",10644.0,"UK","Qtr 2"] (%i72) arraymake (newRowsA3, [i]); (%o72) newRowsA3[i] (%i73) ''%, i = 6; (%o73) ["Brown",4865.0,"USA","Qtr 4"] </syntaxhighlight> The operator <code>arraymake (x, [i])</code> constructs the expression <code>x[i]</code>, but does not evaluate it. The operator <code>'''subvar'''</code> <code>'''(x, i)'''</code> evaluates the indexed expression <code>x[i]</code>, and evaluates its arguments. <syntaxhighlight lang="maxima"> (%i74) listarray(B); (%o174) [0,1,2,3,4,5,6] (%i75) x : B; (x) B (%i76) i : 4; (i) 4 (%i77) subvar (x, i); (%o77) 4 </syntaxhighlight> The operator <code>'''subvarp (expr)'''</code> returns a value of <code>true</code> if <code>expr</code> is a indexed identifier, and <code>false</code> otherwise. This operator evaluates the argument <code>expr</code>. <syntaxhighlight lang="maxima"> (%i78) z[p]; (%o78) z[p] (%i79) subvarp (z[p]); (%o79) true (%i80) x[i]; (%o80) 4 (%i81) subvar (x, i) (%o81) 4 (%i82) w : z[p]; (w) z[p] (%i83) subvarp (w); (%o83) true </syntaxhighlight> The expression <code>'''arrays'''</code> returns a list of allocated arrays: <syntaxhighlight lang="maxima">(%i84) arrays; (%o84) [A3,A2,A1,rowsA3,newRowsA3,B,D]</syntaxhighlight> The operator <code>'''arraysetapply (A, [i<sub>1</sub>,i<sub>2,</sub>…,i<sub>n</sub>], x)'''</code> assigns the value of expression <code>x</code> to <code>A</code><code>[i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub>]</code>, where <code>A</code> is an array and <code>i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub></code> are integers.<syntaxhighlight lang="maxima">(%i85) arraysetapply (newRowsA3, [8], ["George",20818.0,"UK","Qtr 4"]); (%o85) ["George",20818.0,"UK","Qtr 4"]</syntaxhighlight> === Undeclared Arrays === Maxima declared arrays and Maxima undeclared arrays will likely be the two types of data structures used by most users. Maxima undeclared arrays are also referred to as '''''hashed arrays'''''. For both of these two array types, memory allocation and structure occur "behind the curtain" of the Maxima user level, and "the man behind the curtain" is Lisp. Of these two types, hashed arrays are the most flexible from the user point of view, all other factors being equal: * The indices allowed for hashed arrays can be expressions, * The dimensions of a hashed array are dynamic and not fixed, and * Hashed arrays are relatively easier to create. In fact, hashed arrays can be somewhat too easy to create. In the examples of the previous section involving declared arrays, identifiers were used as names for arrays. here is the list of allocated arrays:<syntaxhighlight lang="maxima">(%i86) arrays; (%o86) [A3,A2,A1,rowsA3,newRowsA3,B,D,my_list,h]</syntaxhighlight>The array information for array <code>newRowsA3</code> is shown below:<syntaxhighlight lang="maxima"> (%i87) arrayinfo(newRowsA3); (%o87) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15]] </syntaxhighlight>So the array <code>newRowsA3</code> is not a declared array. it was created as part of a loop programming expression repeated below:<syntaxhighlight lang="maxima">(%i53) for i : 1 thru 15 do (newRowsA3[i] : rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$;</syntaxhighlight>When the first loop block was executed with i : 1, the assignment expression: <code>newRowsA3[i] : rowsA3[i]</code> created a hashed array named <code>newRowsA3</code> and assigned <code>newRowsA3[1]</code> the value of <code>rowsA3[1]</code> automatically without any declaration. After that the hashed array dynamically allocated memory for values of the loop identifier i from 2 through 15 with each successive pass in the loop expression. Since hashed arrays are undeclared, and their associated dimensions are not fixed, but rather increase dynamically, expressions can be added to hashed arrays without creating a error message. These added values can be can be any valid Maxima expression, and the value of the indices used are not limited to zero and nonzero integers: <syntaxhighlight lang="maxima"> (%i88) newRowsA3[16] : ["Maisel",12785.0,"USA","Qtr 2"]; (newRowsA3[16]) ["Maisel",12785.0,"USA","Qtr 2"] (%i89 arrayinfo(newRowsA3); (%o89) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16]] (%i90) newRowsA3[z] : 2*sin(y) ^2 + 3*sin(x)^3; (newRowsA3[z]) 2*sin(y)^2+3*sin(B)^3 (%i91) arrayinfo(newRowsA3); (%o91) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[z]] </syntaxhighlight>So one point to glean from this example is that all that is required to create a hashed array is an assignment expression to an indexed identifier, but it does require this assignment. If for some reason, a declared array is intended, but not declared using the <code>array</code> operator (as in the instance of <code>newRowsA3</code>), then a hashed array will be created at the first assignment of an expression to an indexed identifier. This issue can also occur in cases where reference to a list value is intended, but the list has not been created. Lists are one-dimensional objects by definition. A reference using an identifier with a single index intended to be a list with no list existing named by that identifier, can inadvertently create a hashed array.<syntaxhighlight lang="maxima"> (%i91) Alist[2] : 2*sin(y) ^2 + 3*sin(s)^3; (Alist[2]) 2*sin(y)^2+3*sin(s)^3 (%i92) listp(Alist); (%o92) false (%i93) arrayinfo(Alist); (%o93) [hashed,1,[2]] </syntaxhighlight>The identifier <code>Alist</code> is a name for a hashed array and not a list. However, hashed arrays, like declared arrays can, be multi-dimensional: <syntaxhighlight lang="maxima"> (%i94) a_hashed_array [j,k,l] : [12,s^(1/3), %i]; (%o94) [12,s^(1/3),%i] (%i95) arrayinfo(a_hashed_array); (%o95) [hashed,3,[j,k,l]] </syntaxhighlight>The <code>array</code> operator can be used to transform a hashed array into a declared array:<syntaxhighlight lang="maxima"> (%i96) another_hashed_array[ 0, 2, 3] : 55; (%o96) 55 (%i97) array (another_hashed_array, 2, 4, 5); (%o97) another_hashed_array (%i98) arrayinfo(another_hashed_array); (%o98) [declared,3,[2,4,5]] </syntaxhighlight>From the user point of view, hashed arrays and declared arrays typically can be used for the same purpose. If dynamic dimensions or index expression flexibility are factors, then hashed arrays are likely to be a better choice. Many of the operators that can use declared arrays as arguments, may also be used with hashed arrays. However, it should be noted at this point, that merely using a indexed identifier alone without an assignment, will not create a hashed array. Instead, Maxima interprets an expression so composed as an identifier for an undefined memoizing function, which is the topic of the next section. ==== Memoizing Functions ==== Assignment using an indexed identifier implicitly creates an undeclared (hashed) array. However, entering an expression that is an unassigned indexed identifier, from the point of view of Maxima, creates the identifier of a "memoizing" function. Memoizing functions are technically not an array topic, as these functions fall under the category of function definition. These functions have one foot in the function category and the other foot in the array category. Memoizing functions are defined in a manner similar to other user-defined functions, for example: <code>f(x, y, z) := x^2 + y^2 + z^2;</code> But instead of the arguments being enclosed in parentheses, they are enclosed using brackets: <code>f[x, y, z] := x^2 + y^2 + z^2;</code> However, memoizing functions may be referred to as ''array functions,'' and it is the case that these functions from the point of view of aggregate data structures are hashed arrays. So these are mentioned and exemplified here for that reason:<syntaxhighlight lang="maxima">/* reference an indexed identifier h without assignment */ (%i99) h[x]; (%o99) h[x] /* check identifier h as an array */ (%i100) arrayinfo (h); arrayinfo: h is not an array. -- an error. To debug this try: debugmode(true); /* check identifier h as a function */ (%i101) op(h[x]); (%o101) h /* define h[x] as a function */ (%i102) h[x] := 5*x^3 + sin(x); (h[x]) h[x]:=5*x^3+sin(x) /* check identifier h[x] as a function */ (%i103) op(h[x]); (%o103) "+" /* check identifier h as an array */ (%i104) arrayinfo (h); (%o104) [hashed,1,[x]] /* check the value of identifier h[x] */ (%i105) h[x]; (%o105) sin(x)+5*x^3 /* evaluate identifier h[x] with the argument 3*%pi */ (%i106) h[3*%pi]; (%o106) 135*%pi^3 /* list the values of identifier h as an array */ (%i107) listarray(h); (%o107) [135*%pi^3,sin(x)+5*x^3] /* check identifier h as an array */ (%i108) arrayinfo (h); (%o108) [hashed,1,[3*%pi],[x]]</syntaxhighlight>A defined memoizing function stores its value the ''first time'' it is referenced with arguments, and returns the stored value, without evaluation, when the same arguments are used with that function subsequently. The stored value is "frozen" after the initial evaluation. Thus, it behaves like a hashed array. The arguments of a memoizing function also serve as indices of the associated hashed array. === Lisp Arrays === Lisp arrays are created using the <code>make_array (type, dim<sub>1</sub>, dim<sub>2</sub>, …, dim<sub>n</sub>)</code> operator. Perhaps a better name for this operator would be <code>make_lisp_array ()</code>, which admittedly is a longer name. This operator creates and has a return value of a Lisp array. The array type may be <code>any</code>, <code>flonum</code>, <code>fixnum</code>, or <code>hashed</code> . The <code>functional</code> type referred to in the Maxima Manual appears to have been deprecated, and may result in an error message if used. There can be ''n'' indices, and where the associated indices can be a value from ''0'' to ''dim<sub>i</sub> -1'', and ''i'' can have a value of one of 1 to n inclusive. This operator can be used as an alternative to the <code>array ()</code> operator. The advantage of using <code>make_array()</code> is that the return value of <code>make_array()</code> ''does not have a name''. Once the Maxima identifier that is assigned to the array return value is no longer assigned, the array memory allocation is released, and the allocated memory can be garbage collected. What it is being referred to that Lisp arrays created using <code>make_array()</code> do not have names? <syntaxhighlight lang="maxima"> /* create a undeclared Maxima hashed array */ (%i109) arrayA1 [1] : 55; (%o109) 55 /* check the information about this undeclared Maxima hashed array */ (%i110) arrayinfo (arrayA1); (%o110) [hashed,1,[1]] /* check the value of this undeclared Maxima hashed array */ (%i111) arrayA1; (%o111) arrayA1 /* the name */ /* create a Lisp hashed array */ (%i112) arrayA2 : make_array (hashed); (arrayA2) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* check the information about this Lisp hashed array */ (%i113) arrayinfo (arrayA2); (%o113) [hash_table,1] /* check the value of this Lisp hashed array */ (%i114) arrayA2; (%o114) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* no name */ (%i115) listarray (arrayA2); (%o115) [] /* this hashed array is empty */ </syntaxhighlight>So Lisp arrays do not have a name as a value. So, Maxima identifiers assigned to a Lisp array have no name for the array as a value. These identifiers have the reference to the array itself as a value, Lisp hashed arrays created using <code>make_array()</code> with the hashed type specified, do not use dimensions. Lisp hashed arrays are often referred to as '''''hashed tables''''', and their indices are called '''''keys'''''. An example of a Lisp array with the type <code>any</code> follows: <syntaxhighlight lang="maxima"> /* make a Lisp 3 by 4 array of type any */ (%i116) arrayA3 : make_array (any, 3,4); (arrayA3) \#\{Lisp array \[3\\,4\]\} (%i117) arrayinfo (arrayA3); (%o117) [declared,2,[2,3]] (%i118) listarray(arrayA3); (%o118) [false,false,false,false,false,false,false,false,false,false,false,false] (%i119) arrayA3[1,1] : "a string" ; (%o119) "a string" (%i120) listarray(arrayA3); (%o120) [false,false,false,false,false,"a string", false,false,false,false,false,false] </syntaxhighlight>Contrary to statements made in some sources, type checking is is not accomplished automatically, and will not cause Maxima to return an error message, as the Lisp array with the type <code>fixnum</code> which follows is an exemplifies:<syntaxhighlight lang="maxima">(%i121) arrayA4 : make_array (fixnum, 3,4); (arrayA4) \#\{Lisp array \[3\\,4\]\} (%i122) arrayinfo (arrayA4); (%o122) [declared,2,[2,3]] (%i123) listarray (arrayA4); (%o123) [0,0,0,0,0,0,0,0,0,0,0,0] (%i124) arrayA4[0,2] : 3.14159; (%o124) 3.14159 (%i125) arrayA4[0,0] : "a string"; (%o125) "a string" /* value types not checked and no error message */ (%i126) listarray (arrayA4); (%o126) ["a string",0,3.14159,0,0,0,0,0,0,0,0,0]</syntaxhighlight>As was the case with declared arrays, there is no type checking and no error messages associated with assigned values of the array based on the declared type. The declared array type simply determines initial fill values, if any. Hashed arrays and Lisp hash tables have an operator in common: <code>has_key</code> <code>(A, L)</code> This expression has a a value of <code>true</code>, if the hashed array or Lisp hash table <code>A</code> has the key (index) or keys (indices) of the list object <code>L</code>. Otherwise the expression has a value of <code>false</code>. The array <code>A</code> must be a hashed (undeclared) array, a Lisp hash table value returned by the <code>make_array</code> operator, or created as an undeclared array with <code>use_fast_arrays</code> assigned the value <code>true</code>. If array A has only one key, that key must be the value of a list.<syntaxhighlight lang="maxima"> (%i127) arrayinfo (newRowsA3); (%o127) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10], [11],[12],[13],[14],[15],[16],[z]] (%i128) has_key (newRowsA3, [z]); (%o128) true (%i129) has_key (newRowsA3, [3]); (%o129) true (%i130) has_key(newRowsA3, [0]); (%o130) false (%i131) lisp_Array_1 [x]; (%o131) 3*x^2 (%i132) arrayinfo (lisp_Array_1); (%o132) [hash_table,1,x] (%i133) has_key (lisp_Array_1, [x]); (%o133) true (%i134) has_key (lisp_Array_1, [y]); (%o134) false </syntaxhighlight> === Arrays and Features === Maxima arrays can be assigned features in a manner similar to other identifiers:<syntaxhighlight lang="maxima"> (%i135) array (a6,fixnum, 5); (%o135) a6 (%i136) arrayinfo (a6); (%o136) [complete,1,[5]] (%i137) declare (a6, [real, noninteger]); (%o137) done (%i138) featurep (a6, real); (%o138) true (%i139) featurep (a6, noninteger); (%o139) true (%i140) a6[2] : 2; (a6[2]) 2 (%i141) listarray (a6); (%o141) [0,0,2,0,0,0] </syntaxhighlight>However, once again, declaring an array to have one or more features does not result in type checking of values assigned to an array. Perhaps the best way to ensure types of values assigned to arrays is type-checking of expressions using predicate operators prior to assignment to arrays. === Array Memory Storage Considerations === The following from the Maxima Manual<ref>{{Cite web |title=Maxima Manual Section 7.5.1 - Functions and Variables for Arrays |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Functions-and-Variables-for-Arrays}}</ref> is quoted here for the purpose of establishing the context of that which follows:<blockquote>''"Option variable: use_fast_arrays ¶'' ''Default value: false'' ''When use_fast_arrays is true, arrays declared by array are values instead of properties, and undeclared arrays (hashed arrays) are implemented as Lisp hashed arrays.'' ''When use_fast_arrays is false, arrays declared by array are properties, and undeclared arrays are implemented with Maxima’s own hashed array implementation.'' ''Note that the code use_fast_arrays switches to is not necessarily faster than the default one; Arrays created by make_array are not affected by use_fast_arrays."''</blockquote> This Maxima Manual entry requires some elaboration in order to have a sufficient understanding of the effect of the <code>'''use_fast_arrays'''</code> "flag" – referred to as an "Option Variable" in the above quotation. The first point to note is that the default value of this flag is <code>false</code>. So, if users take no action to assign this flag to the value <code>true</code>, then declared arrays created using the <code>array()</code> operator are treated as ''properties'' bound to a symbol, and behave in the manner previously described. Likewise undeclared arrays are a Maxima array implementation, and behave as legacy property hash tables, and these also behave as previously described. If action is taken to enter an expression that assigns the value <code>true</code> to this flag, then Maxima treat arrays as standard Lisp ''values'' rather than object properties:<syntaxhighlight lang="maxima"> (%i142) use_fast_arrays; (%o142) false (%i143) array (A1,fixnum, 10); (%o143) A1 (%i144) arrayinfo (A1); (%o144) [complete,1,[10]] (%i145) H1[1] : 1729; (H1[1]) 1729 (%i146) arrayinfo (H1); (%o146) [hashed,1,[1]] (%i147) use_fast_arrays : true; (use_fast_arrays) true (%i148) array (A2, fixnum, 10); (%o148) \#\{Lisp array \[11\]\} (%i149) A2; (%o149) \#\{Lisp array \[11\]\} (%i150) H2[1] : 1729; (H2[1]) 1729 (%i151) H2; (%o151) "#<HASH-TABLE :TEST EQUAL :COUNT 2 {1203AD15A3}>" (%i152) arrayinfo (H2); (%o152) [hash_table,1,1] </syntaxhighlight> The <code>use_fast_arrays</code> flag has no effect on arrays created using the <code>make_array ()</code> operator. Note the following: * Assigning <code>use_fast_arrays</code> <code>: true</code> does not speed up execution for all operations. It primarily optimizes memory footprint by minimizing cell allocations. The main benefit is optimization of memory footprints and structural representation inside Lisp. * If compiling Maxima expressions to native Lisp using the <code>translate</code> <code>()</code> operator, pair this flag with <code>translate_fast_arrays</code> <code>: true</code>. This flag instructs the translator to compile arrays as value-based. === Structures === Structures, although not an array data type is an aggregation data type.  By "aggregation" it is meant a data type that references other data types by reference to a name and some method of accessing individual values of instances of that aggregation by means of indices used to reference values individually. Thus, as has been previously described for example lists, hashed arrays, Lisp arrays, and declared arrays are all aggregation data types with syntactical means to refer to individual values of a named aggregation instance by way of indices, which are sometimes also referred to as subscripts or keys. As examples: * An existing '''list''' named <code>L1</code> has values that can be accessed as <code>L1[1]</code>, <code>L[2]</code>, <code>L[3]</code>, and so forth * An existing '''hashed array''' with two indices ("2D") named <code>ha</code> has values that can accessed as <code>ha[1,1</code>], <code>ha[1,2]</code>,..., <code>ha[2,1]</code>, <code>ha[2,2]</code>, and  so forth. * An existing '''declared array''' with three indices ("3D") named <code>da</code> has values that can be accessed as <code>da[1,1,1]</code>, <code>da[1,1,2]</code>,...,<code>da [2,1,1]</code>, ..., <code>da[3,1,1]</code>, and so forth. What makes the Maxima structure data type different from these array data types is the form of definition used and the means of accessing values of an instance of this type of aggregation. The Maxima structure data type seems to be the closest type of data that resembles an object in some other general-purpose programming languages. The structure type of data allows the creation of named entities with attributes, and named instances of those entities and the assignment of values to those attributes. Thus the Maxima structure data type is used to define custom, named composite data types that group related fields together under a single identifier. Structures enhance code organization and readability, especially when modeling real-world entities in symbolic computations. They are useful for managing complex data in programs involving algebraic manipulations, simulations, or data modeling. Structures are created using the <code>defstruct</code> operator, which defines a template with named attributes. Once defined, instances of the structure are created using the <code>new</code> operator, and attributes are accessed via the <code>@</code> operator. So in the interest of taking advantage of this information, consider a well-defined set of people. The people of this set may have many diverse attributes that might be of interest - name, age ,and city of residence as examples. A class of people of the set of interest with these attributes can be defined as follows: <syntaxhighlight lang="maxima">(%i153) defstruct (person (name, age, city)); (%o153) [person(name,age,city)] (%i54) structures; (%o154) [person(name, age, city)] (%i155) p : new (person ("Alice", 30, "New York")); (p) person(name="Alice",age=30,city="New York") (%i156) p@name; (%o156) "Alice" (%i157) p@city; (%o157) "New York" (%i158) kill(p@city); (%o158) done /* If the attribute a in x has not been assigned a value, or the value has been "killed," then x@a evaluates to itself */ (%i159) p@city; (%o159) p@city (%i160) p; (%o160) person(name="Alice",age=30,city) (%i161) p@city : "Rochester"; (%o161) "Rochester" (%i162) p; (%o162) person(name="Alice",age=30,city="Rochester") (%i163) defstruct (sales(LastName, Sales , Country , Quarter) ); (%o163) [sales(LastName, Sales, Country, Quarter)] (%i164) structures; (%o164) [person(name, age, city), sales(LastName, Sales, Country, Quarter)] (%i165) s : new (sales ("Smith",16753.00,"UK","Qtr 3")); (%o165) sales(LastName=Smith, Sales=16753.0, Country=UK, Quarter=Qtr 3) (%i166) s@Sales; (%o166) 16753.0 (%i167) s@Sales : 17375.0; (%o167) 17375.0 (%i168) s; (%o168) sales(LastName=Smith, Sales=17375.0, Country=UK, Quarter=Qtr 3)</syntaxhighlight>{{Bookcat}} 4q7c2qaqaebf08cisqd7o7z9wlhxkxx 4668966 4668964 2026-09-05T17:33:30Z Idavidmiller 3577687 /* Introduction */ 4668966 wikitext text/x-wiki == Maxima Aggregate Data Structures == === Introduction === This section is intended to present some of the essentials of what are called Maxima aggregate data structures. By this it is meant the data types that can be used to refer to the values of expressions using a means of indexing of a single identifier (name) that refers to an aggregate (collection) of expressions as values. Built-in aggregate data types include: * lists * declared arrays * hashed (undeclared) arrays * Lisp arrays * structures Each of these has a means of indexing an identifier that names an instance of these data types. Please note that it is the case that this means of indexing an identifier for an aggregate data type may be referred to as involving "subscripts" or "sub-scripted variables" or "keys" as used by various computer programming languages, as well as in the context of Maxima documentation and commentary. In this book terms such as "index" or "indices" or "indexed identifiers"  are used instead. Also all built-in Maxima functions (including packages) for these data types are referred to as ''"operators"'' and not ''"functions"'' as this latter term in general serves better to refer to Maxima function expressions defined by the user -- as in <code>f(x) :=</code>, <code>g[s] :=</code> and <code>define ()</code> as examples. This section is not intended to be exhaustive. It is intended to provide familiarity with aggregate data types. What is included has been gleaned from various sources, and only a few attributions are provided. Therefore, there is no claim of originality implied. === Lists === ==== Introduction to Lists ==== Lists are one of the basic buildings block for Maxima and Lisp. Maxima expressions are in general represented as Lisp lists. For example, consider the Maxima expression:<syntaxhighlight lang="maxima"> (%i1) e+3; (%o1) e+3 </syntaxhighlight>This expression has the form of a Lisp list:<syntaxhighlight lang="maxima"> (%i2) :lisp #$[e+3]$ ((MLIST SIMP) ((MPLUS SIMP) 3 $E)) </syntaxhighlight>An expression in the form of a Lisp list can also be be displayed as a Maxima expression:<syntaxhighlight lang="maxima"> (%i2) :lisp (displa '((MLIST SIMP) ((MPLUS SIMP) 3 $E))); [e+3] NIL </syntaxhighlight>Note that the value of this expression using <code>displa '()</code> is <code>NIL</code>, and <code>[e+3]</code> is simply displayed in Maxima list object form. It is not necessary for the typical uses of Maxima to utilize this insight into the role Lisp lists have as one of the building blocks for Maxima, but it may be useful to have a familiarity with that role. Lists are often used as arguments to many operators, and the values of expressions are often in the form of lists. ==== Some Operators for Lists ==== Lists are created explicitly and list elements referenced using <code>[</code> and <code>]</code> to mark the beginning and end, respectively, of an instance of a list object, or to reference the expressions of an existing list object.<syntaxhighlight lang="maxima"> (%i3) [2,3,4]; (%o3) [2,3,4] </syntaxhighlight>The expression <code>[2,3,4]</code> creates a Maxima list object. In this case the object itself is not accessible as it was not assigned an identifier unless referenced by the <code>%</code> , <code>%i</code> or <code>%o</code> label.<syntaxhighlight lang="maxima"> (%i4) %; (%o4) [2,3,4] (%i5) %o4[2]; /* second expression of list object referenced by index */ (%o5) 3 </syntaxhighlight>That [2,3,4] is a list object can be tested using the <code>listp()</code> operator:<syntaxhighlight lang="maxima"> (%i6) listp ([2,3,4]); (%o6) true </syntaxhighlight>A list object can be assigned an identifier:<syntaxhighlight lang="maxima">(%i7) s:[%pi,%e,%phi]; (s) [%pi,%e,%phi] (%i8) listp (s); (%o8) true</syntaxhighlight> The value of an element of a list can be accessed using the list identifier and brackets with a index value.<syntaxhighlight lang="maxima"> (%i9) s[1]; (%o9) %pi (%i10) s[2]; (%o10) %e (%i11) s[3]; (%o11) %phi </syntaxhighlight> Invalid index values returns an error:<syntaxhighlight lang="maxima"> (%i12) s[4]; inpart: invalid index 4 of list or matrix. -- an error. To debug this try: debugmode(true); </syntaxhighlight> Consider the following relatively long list of integer atoms created explicitly and identified as <code>List_1</code>:<syntaxhighlight lang="maxima">(%i13) List_1:[1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582,145,2, 118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118, 30,3,484,51,3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32,4, 484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484, 49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177]; (List_1) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203,2,1582,203 ,3,118,30,3,484,51,3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582, 214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177]</syntaxhighlight> The number of values of this list can be returned using the <code>length()</code> operator:<syntaxhighlight lang="maxima"> (%i14) length (List_1); (%o14) 105 </syntaxhighlight> Create another list identified as <code>List_2</code>:<syntaxhighlight lang="maxima"> (%i15) List_2 : [6,1455,200,6,1607,205]; (List_2) [6,1455,200,6,1607,205] (%i16) length (List_2); (%o16) 6 </syntaxhighlight> Create a third list identified as <code>List_3</code>:<syntaxhighlight lang="maxima"> (%i17) List_3 : append (List_1, List_2)$ (%i18) length (List_3); (%o19) 111 </syntaxhighlight> Note that the <code>'''append ()'''</code> operator does not affect either of the list arguments <code>List_1</code> or <code>List</code>_2. It merely appends <code>List_2</code> to <code>List_1</code> and returns a new list, in this case assigned the identifier <code>List_3</code>.<syntaxhighlight lang="maxima">(%i20) length (List_1); (%o20) 105 (%i21) length (List_2); (%o21) 6 (%i22) length (List_3); (%o22) 111 (%i23) List_3; (%o23) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607,205]</syntaxhighlight> Values (the last one in this example) can be deleted from a list:<syntaxhighlight lang="maxima">(%i24) last (List_3); (%o24) 205 (%i25) delete (last (List_3), List_3); (%o25) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607]</syntaxhighlight> The <code>delete (List_3)</code> expression creates a new list object using <code>List_3</code>. <code>List_3</code> itself is not affected by the <code>'''delete ()'''</code> operator. Only the resulting list is affected. This is often the case with list operators. An identifier could be used to save the above resulting list if necessary:<syntaxhighlight lang="maxima">/* List_3 is the same length */ (%i26) length(List_3); (%o26) 111 /* The last value of List_3 is the same */ (%i27) List_3[111]; (%o27) 205 (%i28) last(List_3); (%o28) 205</syntaxhighlight>There was only one instance of <code>205</code> in <code>List_3</code>, so only that value was deleted from the list of <code>%o25</code>. If there are more than one value then the <code>delete ()</code> operator will remove all of those values from the returned list expression:<syntaxhighlight lang="maxima"> (%i29) NewList_3 : delete(118, List_3)$ /* all five instances of 118 removed from List_3 as NewList_3 */ (%i30) length(NewList_3); (%o30) 106 </syntaxhighlight>There are operators to refer to instances of list expressions by ordinal number:<syntaxhighlight lang="maxima"> (%i30) FirstThreeList_3:[first(List_3), second(List_3), third(List_3)]; (FirstThreeList_3) [1,118,30] </syntaxhighlight>Expressions of list objects can e referenced to create a new list object from the first n expressions of a list, the last n expressions of a list, or the rest remaining after n expressions from the beginning or -n expressions from the end of a list:<syntaxhighlight lang="maxima">/* first three expressions of List_3 */ (%i31) firstn(List_3,3); (%o31) [1,118,30] /* same three expressions of List_3 using the rest operator with -108 */ (%i32) rest(List_3, -108); (%o32) [1,118,30] /* last three expressions of List_3 */ (%i33) lastn(List_3,3); (%o33) [6,1607,205] /* same three expressions of List_3 using the rest operator with 108 */ (%i34) rest(List_3, 108); (%o34) [6,1607,205]</syntaxhighlight>Some further examples of the <code>'''firstn ()'''</code>, <code>'''lastn ()'''</code> and <code>'''rest ()'''</code> list operators:<syntaxhighlight lang="maxima"> /* first 63 expressions of List_3 */ (%i35) firstn (List_3, 63); (%o35) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108,3, 1231,115,3,1372,139,3,1582,140] /* last 63 expressions of List_3 */ (%i36) lastn (List_3, 63); (%o36) [3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5, 1582,177,6,1455,200,6,1607,205] /* first expressions of List_3 after removing the last 63*/ (%i37) rest (List_3, -63); (%o37) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51] </syntaxhighlight>Maxima programming expressions can be used with list operators to reference list expressions in various ways. For example, the expression which follows accesses the expressions of a list as lists of three each:<syntaxhighlight lang="maxima"> (%i38) (L4 : List_4, for i:(-length (List_4)) + 3 thru 0 step 3 do (disp (rest (L4, i)), L4 : rest (L4, 3)), "")$ [1,118,30] [1,484,58] [1,664,87] [1,1004,115] [1,1231,120] [1,1372,142] [1,1582,145] [2,118,33] [2,484,69] [2,664,111] [2,1004,156] [2,1231,172] [2,1372,203] [2,1582,203] [3,118,30] [3,484,51] [3,664,75] </syntaxhighlight>List operators can be used as arguments other list operators:<syntaxhighlight lang="maxima"> /* create a new empty list */ (%i39) newList4 : []; (newList4) [] /* append the first six & last six expressions of List_4 to the new list */ (%i40) newList4 : append (newList4, firstn (List_4, 6), lastn (List_4, 6))$ /* the new list now has the 12 appended expressions from List_4 */ (%i41) newList4; (%o41) [1,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> Maxima programming expressions can be used to step through the expressions of lists using list operators to reference "slices" of different lengths:<syntaxhighlight lang="maxima">(%i42) L4 : List_4; (L4) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582 145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203, 2,1582,203,3,118,30,3,484,51,3,664,75] (%i43) length (L4); (%o43) 51 (%i44) (L4 : List_4, for i : 21 thru 3 step -3 do print (L4 : lastn (L4, i)," ", length (L4)), "")$ [2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 21 [2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 18 [2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 15 [2,1582,203,3,118,30,3,484,51,3,664,75] 12 [3,118,30,3,484,51,3,664,75] 9 [3,484,51,3,664,75] 6 [3,664,75] 3</syntaxhighlight> ==== Using the <code>copylist</code> Operator ==== When an existing list object is assigned to an identifier, a reference to the memory location of the list object is used. This reference to the memory location is transparent from the point of view of the user. However,if this is not accounted for unintended side effects may occur when assigning another identifier to an existing one that references a list object. For example, in the expression <code>L4 : List_4</code> it might be assumed that this results in the list object referenced by <code>List_4</code> to simply be copied to a new memory location and reference for <code>L4</code>. This is not the case. Both <code>L4</code> and <code>List_4</code> refer to the same list object in memory. Consequently changes to the same list object can be effected by referencing the object using either alias.<syntaxhighlight lang="maxima"> (%i45) newList4; (%o45) [1,118,30,1,484,58,3,484,51,3,664,75] /* The identifier newList4 refers to a location in memory. The colon (:) assignment operator simply creates an alias using that same memory reference*/ (%i46) newList5 : newList4; (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Two different identifiers for the same memory location and therefore the same object. Changes to expressions of the list object using either identifier changes the same object in memory */ (%i47) newList5[1] : 99; (newList5[1]) 99 (%i48) newList4[1]; (%o48) 99 (%i49) newList4; (%o49) [99,118,30,1,484,58,3,484,51,3,664,75] (%i50) newList5; (%o50) [99,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> This "side effect" is often unwanted. The way to avoid this is by using the <code>copylist ()</code> operator instead of the assignment operator:<syntaxhighlight lang="maxima"> (%i51) newList4 : [1,118,30,1,484,58,3,484,51,3,664,75] ; (newList4) [1,118,30,1,484,58,3,484,51,3,664,75] (%i52) newList5 : copylist (newList4); (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Same list object expressions, but a different memory reference */ (%i53) newList5[1] : 99; (newList5[1]) 99 (%i54) newList4[1]; (%o54) 1 </syntaxhighlight> Changes to the values of either list will not affect the other list. {| class="wikitable" |+List Object Operators |[ |fourth |rreduce |- |] |fullsetify |second |- |append |join |setify |- |assoc |last |seventh |- |cons |length |sixth |- |copylist |listarith |some |- |create_list |listp |sort |- |delete |lmax |sublist |- |eighth |lmin |sublist_indices |- |endcons |lreduce |tenth |- |fifth |makelist |third |- |first |member |tree_reduce |- |flatten |reverse |xreduce |} Refer to the Maximal Manual<ref>{{Cite web |title=Maxima Manual Section 7.4.2 Functions and Variables for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref> for more complete description of operators and variables for Maxima lists. ==== Performance Considerations for Lists ==== <blockquote>''"Lists provide efficient ways of appending and removing elements. They can be created without knowing their final dimensions. Lisp provides efficient means of copying and handling lists. Also nested lists do not need to be strictly rectangular. These advantages over declared arrays come with the drawback that the amount of time needed for accessing a random element within a list may be roughly proportional to the element’s distance from its beginning."''<ref>{{Cite web |title=Maxima Manual Section 7.4.3 Performance considerations for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref></blockquote>Maxima list objects have many operators for creating, accessing, and changing the expressions of lists. Evaluation times of expressions that involve lists can vary significantly depending on the length of the list objects involved, as well as the nature of any operators used to compose the expressions. This fact might have an influence on the choice of using arrays rather than lists in some cases if evaluation time is a factor to consider. The example expressions that follow involve a list object (identified as <code>s</code> ) of complex number expressions that has a length of 10,000 and two different user-defined functions:<pre>(%i55) P1(s) := rectform (product(s[i], i, 1, length (s)))$ (%i56) P2(s) := xreduce (lambda ([a, b], rectform (a * b)), s)$ (%i57) s : makelist (random (1.0) + %i*random (1.0), 10^4)$ (%i58) showtime : true$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes. (%i59) P1(s); Evaluation took 32.3080 seconds (32.3860 elapsed) using 17944.301 MB. (%o59) 0.0 (%i60) P2(s); Evaluation took 0.0620 seconds (0.0620 elapsed) using 8.343 MB. (%o60) 0.0 (%i61) showtime : false$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.</pre> ==Arrays == <blockquote>"Maxima's current array/matrix semantics are a mess, I must say, with at least four different kinds of object (hash arrays, explicit lists, explicit matrices, Lisp arrays) supporting subscripting with varying semantics." <ref>[http://comments.gmane.org/gmane.comp.mathematics.maxima.general/21829 Maxima: Syntax improvements by Stavros Macrakis ]</ref> – Stavros Macrakis "Maxima's concept of arrays, lists, and matrices is pretty confused, since various ideas have accreted in the many years of the project... Yes, this is a mess. Sorry about that. These are all interesting ideas, but there is no unifying framework."<ref>[http://stackoverflow.com/a/29926692 Maxima: what does Maxima call an “array”? - answer by Robert Dodier]</ref> – Robert Dodier</blockquote> The various terminology used in the context of arrays undoubtedly can be confusing. For the sake of simplicity and clarity the following categories of array objects are referred to in this book: Maxima has three array categories :<ref>[http://permalink.gmane.org/gmane.comp.mathematics.maxima.general/13588 the Maxima mailing list <nowiki>: [Maxima] array and matrix? - answer by Robert Dodier</nowiki>]</ref> * Declared arrays * Undeclared (hashed) arrays * Lisp arrays '''''Declared arrays''''' are explicitly created using the <code>array()</code> operator, and unlike lists, which have only one index and are one-dimensional, declared arrays can be multi-dimensional – having one to five indices. The indices for declared array dimensions need not be equal. Indices for each dimension may be between 0 and the respective declared dimension. Each declared array may be for expressions of a specified type, which can be ''fixnum'' for integers or ''flonum'' for floating-point numbers. '''''Undeclared (hashed) arrays''''' are created implicitly by assigning an expression to an indexed identifier that does not name an existing list object. An undeclared array (hashed array) can grow dynamically as there is no fixed dimension limit for each index as there is with declared arrays Another difference is that numbers, identifiers, expressions and strings may be used for indices. Also, there is no fixed limit on the number of dimensions. The only real limitation is practical – the available computer memory and the underlying Lisp environment of the Maxima session. Hashed arrays with only one dimension may be confused with a list object. It is essential to keep in mind that list objects must always be created before values are assigned or referenced. Assigning an expression to a one-dimensional indexed identifier, that does not reference an existing list, implicitly creates a hashed array. '''''Lisp arrays''''' are created using the <code>'''make_array ()'''</code> operator. The array type may be specified as ''any'', ''flonum'', ''fixnum'', or ''hashed''. Lisp array objects may be created as one-dimensional or multi-dimensional as specified by the number of dimension size values used with the <code>'''make_array ()'''</code> operator. For each dimension value specified, the associated index value can be a number between 0 to 1 less than the respective dimension value. The same or different values may be used for each specified dimension. the ''hashed'' type does not require any dimensions. Lisp arrays may be used in cases where memory usage and garbage collection are factors. Examples of use and elaboration upon the technical details for each of these categories of array object types follows. {| class="wikitable" |+Array Operators and Flags |array |arraysetapply |rearray |- |arrayapply |has_key |remarray |- |arrayinfo |fillarray |subvar |- |arraymake |listarray |subvarp |- |arrays |make_array |use_fast_arrays |- | | |translate_fast_arrays |} === Declared Arrays === Declared arrays must be created before being referenced and are of fixed dimensions.<syntaxhighlight lang="maxima"> (%i1) array(A1, fixnum, 34,2); (%o1) A1 (%i2) array(A2, flonum, 35,2); (%o2) A2 (%i3) array(A3, 14,3); (%o3) A3 (%i4) arrayinfo (A1); (%o4) [complete,2,[34,2]] (%i5) arrayinfo (A2); (%o5) [complete,2,[35,2]] (%i6) arrayinfo (A3); (%o6) [declared,2,[14,3]] </syntaxhighlight> The first expression <code>%i1</code> creates a declared array object named using the identifier <code>A1</code>. This array is two-dimensional – the first index may have values from 0 to 34 and the second index may have values from 0 to 2. This array therefore is 35 by 3 in extent. The array type is declared to be <code>fixnum</code>. As it is, <code>A1</code> is an not empty array – it has values to reference as will be exemplified below. Similarly the second expression <code>%i2</code> creates a declared array object named using the identifier <code>A2</code>. This array is also two-dimensional – the first index may have values from 0 to 35 and the second index may have values from 0 to 2. This array therefore is 36 by 3 in extent. The array type is declared to be <code>flonum</code>. As it is, <code>A2</code> is not an empty array – it also has values to reference as will be exemplified below. The third expression <code>%i3</code> creates a declared array object named using the identifier <code>A3</code>. This array is also two-dimensional – the first index may have values from 0 to 13 and the second index may have values from 0 to 3. This array therefore is 15 by 4 in extent. The array type is not declared. As it is, <code>A3</code> is an empty array – it has no values to reference as will be exemplified below. The <code>'''arrayinfo ()'''</code> operator can be used to return a list object that has values reflecting information about an array. Note that arrays declared without a type will have <code>declared</code> as a value of the list. Arrays declared with <code>fixnum</code> or <code>flonum</code> as the type will have <code>complete</code> as a value of the list. This technical detail is not well-documented. The returned information list also shows a value for the dimension of the array ( 2 in these examples ) and an inner list with values for the maximum index for each dimension. A look inside each of these declared arrays provides a clue as to why <code>complete</code> is returned instead of <code>declared</code> when the type is specified as <code>fixnum</code> or <code>flonum</code>:<syntaxhighlight lang="maxima">/* This array reference has a value of 0 */ (%i7) A1[0,0]; (%o7) 0 /* This array reference has a value of 0.0 */ (%i8) A2[0,0]; (%o8) 0.0 /* This array reference has a value of itself */ (%i9) A3[0,0]; (%o9) A3[0,0]</syntaxhighlight> In fact, ''all'' values of the array <code>A1</code> have been assigned 0, and ''all'' values of the array <code>A2</code> have beenassigned 0.0. However, ''all'' values of the array <code>A3</code> have been not been assigned any value.<syntaxhighlight lang="maxima">(%i10) listarray(A1); (%o10) [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0] (%i11) listarray(A2); (%o11) [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] (%i12) listarray(A3); (%o12) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####]</syntaxhighlight> Thus, arrays <code>A1</code> and <code>A2</code> are <code>complete</code> in this sense, and array <code>A3</code> is simply <code>declared</code>. It might seem reasonable, that Maxima would complain if a value was assigned to an array that is at odds with the declared type. Such is not the case however. Once an array is declared with a type, Maxima does not enforce any type checking of values assigned to the array. The effect of the type (if any) in the declaration is simply to fill the array with values of #####, 0 or 0.0. Subsequently, those values can be replaced by the assignment of different values that will not be checked for the type of value. One way to enforce type checking is by using predicate operators to check values at the point in time of assignment to arrays. For example, using one or more of: * numberp (expr) * floatnump (expr) * integerp (expr) * ratnump (expr) * stringp (obj) * listp (expr) * featurep (a, f) and possibly others.<syntaxhighlight lang="maxima"> /* A1 was declared as type fixnum */ (%i13) A1[5,2]:3.14159; (%o13) 3.14159 /* A2 was declared as type flonum */ (%i14) A2[3,0]:7129; (%o14) 7129 /* A1 which was declared as type fixnum assigned a string */ (%i15) A1[4,1]:"a string"; (%o15) "a string" /* A2 which was declared as type flonum assigned a math expression*/ (%i16) A2[6,1]:3*x^2 + 4*x +10; (%o16) 3*x^2+4*x+10 </syntaxhighlight> There are other ways to assign values to an array. One way is to read the values from a comma separated (CSV) file using the <code>'''read_array ()'''</code> operator from the ''numericalio'' package.<syntaxhighlight lang="maxima"> (%i17) load(numericalio); (%o17) "/app/plugins/maxima/share/maxima/5.50.0/share/numericalio/numericalio.mac" </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data_nh.csv</code> :<syntaxhighlight lang="text"> 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight> Note that the following expression assumes that the CSV file is located in the Maxima working directory.<syntaxhighlight lang="maxima"> (%i18) read_array("tree_data_nh.csv", A1, ","); (%o18) done (%i19) listarray(A1); (%o19) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142, 1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172, 2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108, 3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112, 4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484,49, 5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177] </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data.csv</code> which has a header row, but is otherwise the same as <code>tree_data_nh.csv</code>:<syntaxhighlight lang="text"> "Tree","age","circumference" 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight><syntaxhighlight lang="maxima">(%i20) read_array("tree_data.csv", A2, ","); (%o20) done (%i21) listarray(A2); (%o21) ["Tree","age","circumference",1,118,30,1,484,58,1,664,87,1,1004, 115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111, 2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51, 3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174, 5,1582,177]</syntaxhighlight>The previous values of 0 and 0,0 as well as the assigned values of <code>A1</code> and <code>A2</code> have been replaced with the values from the CSV files. The third array A3 can be used with values from the dataset.csv file below:<syntaxhighlight lang="text">"Last Name","Sales","Country","Quarter" "Smith",16753.00,"UK","Qtr 3" "Johnson",14808.00,"USA","Qtr 4" "Williams",10644.00,"UK","Qtr 2" "Jones",1390.00,"USA","Qtr 3" "Brown",4865.00,"USA","Qtr 4" "Williams",12438.00,"UK","Qtr 1" "Johnson",9339.00,"UK","Qtr 2" "Smith",18919.00,"USA","Qtr 3" "Jones",9213.00,"USA","Qtr 4" "Jones",7433.00,"UK","Qtr 1" "Brown",3255.00,"USA","Qtr 2" "Williams",14867.00,"USA","Qtr 3" "Williams",19302.00,"UK","Qtr 4" "Smith",9698.00,"USA","Qtr 1"</syntaxhighlight><syntaxhighlight lang="maxima">(%i22) read_array("dataset.csv", A3, ","); (%o22) done (%i23) listarray(A3); (%o23) ["Last Name","Sales","Country","Quarter", "Smith",16753.0,"UK","Qtr 3", "Johnson",14808.0,"USA","Qtr 4", "Williams",10644.0,"UK","Qtr 2", "Jones",1390.0,"USA","Qtr 3", "Brown",4865.0,"USA","Qtr 4", "Williams",12438.0,"UK","Qtr 1", "Johnson",9339.0,"UK","Qtr 2", "Smith",18919.0,"USA","Qtr 3", "Jones",9213.0,"USA","Qtr 4", "Jones",7433.0,"UK","Qtr 1", "Brown",3255.0,"USA","Qtr 2", "Williams",14867.0,"USA","Qtr 3", "Williams",19302.0,"UK","Qtr 4", "Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> Values of the array can be referenced by indices as required for some purpose:<syntaxhighlight lang="maxima"> (%i24) A3[0,0]; (%o24) "Last Name" (%i25) A3[4,2]; (%o25) "USA" </syntaxhighlight> A row list object can be created using the <code>'''makelist ()'''</code> operator:<syntaxhighlight lang="maxima"> (%i26) row1A3: makelist(A3[0, j], j, 0, 3)$ (%i27) row1A3; (%o27) ["Last Name","Sales","Country","Quarter"] (%i28) row1A3[1]; (%o28) "Last Name" (%i29) row15A3: makelist(A3[14, j], j, 0, 3)$ (%i30) row15A3; (%o30) ["Smith",9698.0,"USA","Qtr 1"] (%i31) row15A3[2]; (%o31) 9698.0 </syntaxhighlight> A list of the indices of the array can be created:<syntaxhighlight lang="maxima"> (%i32) indices_A3 : arrayinfo(A3)[3]; (indices_A3) [14,3] </syntaxhighlight> The number of indices of array <code>A3</code> can also be referenced using the <code>'''length (''')</code> operator:<syntaxhighlight lang="maxima"> (%i33) length(arrayinfo(A3)[3]); (%o33) 2 </syntaxhighlight>The number of values of the array <code>A3</code> can be returned using the '''<code>length ()</code>''' operator:<syntaxhighlight lang="maxima"> (%i34) length(listarray(A3)); (%o34) 60 </syntaxhighlight> The values of the array <code>A3</code> can be printed as output using the list of values with a loop programming expression:<syntaxhighlight lang="maxima"> (%i35) for i:1 thru length (listarray(A3)) do print('A3[i] ," = ", listarray(A3)[i])$ A3[1]" = ""Last Name" A3[2]" = ""Sales" A3[3]" = ""County" A3[4]" = ""Quarter" A3[5]" = ""Smith" A3[6]" = "16753.0 A3[7]" = ""UK" A3[8]" = ""Qtr 3" A3[9]" = ""Johnson" A3[10]" = "14808.0 A3[11]" = ""USA" A3[12]" = ""Qtr 4" A3[13]" = ""Williams" A3[14]" = "10644.0 A3[15]" = ""UK" A3[16]" = ""Qtr 2" A3[17]" = ""Jones" A3[18]" = "1390.0 A3[19]" = ""USA" A3[20]" = ""Qtr 3" A3[21]" = ""Brown" A3[22]" = "4865.0 A3[23]" = ""USA" A3[24]" = ""Qtr 4" A3[25]" = ""Williams" A3[26]" = "12438.0 A3[27]" = ""UK" A3[28]" = ""Qtr 1" A3[29]" = ""Johnson" A3[30]" = "9339.0 A3[31]" = ""UK" A3[32]" = ""Qtr 2" A3[33]" = ""Smith" A3[34]" = "18919.0 A3[35]" = ""USA" A3[36]" = ""Qtr 3" A3[37]" = ""Jones" A3[38]" = "9213.0 A3[39]" = ""USA" A3[40]" = ""Qtr 4" A3[41]" = ""Jones" A3[42]" = "7433.0 A3[43]" = ""UK" A3[44]" = ""Qtr 1" A3[45]" = ""Brown" A3[46]" = "3255.0 A3[47]" = ""USA" A3[48]" = ""Qtr 2" A3[49]" = ""Williams" A3[50]" = "14867.0 A3[51]" = ""USA" A3[52]" = ""Qtr 3" A3[53]" = ""Williams" A3[54]" = "19302.0 A3[55]" = ""UK" A3[56]" = ""Qtr 4" A3[57]" = ""Smith" A3[58]" = "9698.0 A3[59]" = ""USA" A3[60]" = ""Qtr 1" </syntaxhighlight> Maxima treats declared arrays as fixed-sized, and individual values are accessed via indices. There is no built-in "row" object — rows must be extracted manually using the <code>'''makelist ()'''</code> operator or by looping through values of an array.<syntaxhighlight lang="maxima"> (%i36) array(rowsA3,15); (%o36) rowsA3 (%i37) arrayinfo(rowsA3); (%o37) [declared,1,[15]] (%i38) for i:0 thru 14 do (rowsA3[i+1]:makelist(A3[i, j], j, 0, 3), print("Row ",i+1,": ",rowsA3[i+1]))$; "Row "1": "["Last Name","Sales","Country","Quarter"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"] </syntaxhighlight> Maxima does not have a built-in function like <code>delete</code> or <code>unset</code> for removing individual values from arrays using indices. Existing values of an array can be changed by assignment however:<syntaxhighlight lang="maxima">(%i52) rowsA3[1]:["Solomon",1045.0,"USA","Qtr 4"]$ (%i53) for i:1 thru 15 do (newRowsA3[i]:rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$; "Row "1": "["Solomon",1045.0,"USA","Qtr 4"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> The <code>'''arrayapply ()'''</code> operator can be used a follows to reference values of a declared array:<syntaxhighlight lang="maxima"> (%i39) arrayapply(rowsA3,[5]); (%o39) ["Jones",1390.0,"USA","Qtr 3"] (%i40) arrayapply(A3, [5,1]); (%o40) 4865.0 </syntaxhighlight>The operator <code>'''fillarray (A, B)'''</code> assigns values to array <code>A</code> from <code>B</code>, which can be a list or an array.The dimensions of the arrays <code>A</code> and <code>B</code> may not be the same. In that case, array <code>A</code> is filled in "row-major" order. There may not be enough values in <code>B</code> compared to <code>A</code>. In that case, the last value of <code>B</code> is used to for the remaining values of <code>A</code>. There may be too many values of <code>B</code> compared to array <code>A</code>. In that case, the remaining values of <code>B</code> once <code>A</code> is filled are not used. The return value of <code>'''fillarray ()'''</code> is not the filled array <code>A</code>, but it is the first argument.<syntaxhighlight lang="maxima">/* Create a declared array B of type fixnum */ (%i41) array (B, fixnum, 9); (%o41) B /* list the values of array B */ (%i42) listarray (B); (%o42) [0,0,0,0,0,0,0,0,0,0] /* fill array B with the values of the list */ (%i43) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9.0]); (%o43) B /* list the values of array B */ (%i44) listarray (B); (%o44) [0,1,2,3,4,5,6,7,8,9.0] /* fill array B with the value 1.0 */ (%i45) fillarray (B, [1.0]); (%o45) B /* list the values of array B */ (%i46) listarray (B); (%o46) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* fill array B with the first 9 values of the list */ (%i47) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12]); (%o47) B /* list the values of array B */ (%i48) listarray (B); (%o48) [0,1,2,3,4,5,6,7,8,9] /* Create a declared array D of no type */ (%i49) array (D, 9); (%o49) D /* list the values of array D */ (%i50) listarray (D); (%o50) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####] /* fill array D with the value 1.0 */ (%i51) fillarray (D, [1.0]); (%o51) D /* list the values of array D */ (%i52) listarray (D); (%o52) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* Create a declared array E of no type */ (%i53) array (E, 15); (%o53) E /* fill array E with the values from the newRowsA3 list */ (%i54) fillarray (E, listarray (newRowsA3)); (%o54) E /* list the values of array D */ (%i55) listarray (E); (%o55) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"], ["Smith",9698.0,"USA","Qtr 1"]] /* remove array E */ (%i56) remarray (E); (%o56) [E] /* D is no longer an array */ (%i57) arrayinfo (E); arrayinfo: E is not an array. -- an error. To debug this try: debugmode(true);</syntaxhighlight> If you need to keep the array but remove only one value, you must reconstruct it without that value. The operator <code>'''remarray ()'''</code> is the typical way to completely remove an array. The <code>'''rearray (A, dim<sub>1</sub>, dim<sub>2</sub> ,…, dim<sub>n</sub>)'''</code> operator is used to change the dimensions of an array. The changed array will be filled with the elements of the existing array in row-major order. If the existing array has one or more smaller dimensions, the additional dimension values of the changed array are assigned with a value that depends on the type of the array. If the existing array has one or more larger dimensions, the deficient dimension values of the changed array are lost. The type of the array cannot be changed using this operator. <syntaxhighlight lang="maxima"> /* list with the values of array B */ (%i58) listarray(B); (%o58) [0,1,2,3,4,5,6,7,8,9] /* list with information about array B */ (%i59) arrayinfo(B); (%o59) [complete,1,[9]] /* increase the dimension of array B */ (%i60) rearray (B, 12); (%o60) \#\{Lisp array \[13\]\} /* list with information about array B with increased dimension */ (%i61) arrayinfo(B); (%o61) [complete,1,[12]] /* list with the values of array B */ (%i62) listarray(B); (%o62) [0,1,2,3,4,5,6,7,8,9,0,0,0] /* decrease the dimension of array B */ (%i63) rearray (B, 6); (%o63) \#\{Lisp array \[7\]\} /* list with information about array B with decreased dimension */ (%i64) arrayinfo(B); (%o64) [complete,1,[6]] /* list with the values of array B */ (%i65) listarray(B); (%o65) [0,1,2,3,4,5,6] </syntaxhighlight> The <code>'''arraymake ()'''</code> operator returns a value that is an array reference without evaluation. This operator, in spite of the name, does not "make" an array. It returns this reference as a value whether or not an array exists as an object:<syntaxhighlight lang="maxima"> /* the arraymake operator returns the unevaluated reference to A */ (%i66) arraymake (A, [i,j]); (%o66) A[i,j] /* however array A is not an array object*/ (%i67) arrayinfo (A); arrayinfo: A is not an array. -- an error. To debug this try: debugmode(true); /* Maxima sees A[j,k] as a reference to an undefined memoizing function */ (%i68) op (arraymake (A, [i,j])); (%o68) A </syntaxhighlight> However, from a practical point of view, this operator is used with existing arrays:<syntaxhighlight lang="maxima"> (%i69) listarray (newRowsA3); (%o69) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"]] (%i70) arraymake (newRowsA3, [4]); (%o70) newRowsA3[4] (%i71) ''%; (%o71) ["Williams",10644.0,"UK","Qtr 2"] (%i72) arraymake (newRowsA3, [i]); (%o72) newRowsA3[i] (%i73) ''%, i = 6; (%o73) ["Brown",4865.0,"USA","Qtr 4"] </syntaxhighlight> The operator <code>arraymake (x, [i])</code> constructs the expression <code>x[i]</code>, but does not evaluate it. The operator <code>'''subvar'''</code> <code>'''(x, i)'''</code> evaluates the indexed expression <code>x[i]</code>, and evaluates its arguments. <syntaxhighlight lang="maxima"> (%i74) listarray(B); (%o174) [0,1,2,3,4,5,6] (%i75) x : B; (x) B (%i76) i : 4; (i) 4 (%i77) subvar (x, i); (%o77) 4 </syntaxhighlight> The operator <code>'''subvarp (expr)'''</code> returns a value of <code>true</code> if <code>expr</code> is a indexed identifier, and <code>false</code> otherwise. This operator evaluates the argument <code>expr</code>. <syntaxhighlight lang="maxima"> (%i78) z[p]; (%o78) z[p] (%i79) subvarp (z[p]); (%o79) true (%i80) x[i]; (%o80) 4 (%i81) subvar (x, i) (%o81) 4 (%i82) w : z[p]; (w) z[p] (%i83) subvarp (w); (%o83) true </syntaxhighlight> The expression <code>'''arrays'''</code> returns a list of allocated arrays: <syntaxhighlight lang="maxima">(%i84) arrays; (%o84) [A3,A2,A1,rowsA3,newRowsA3,B,D]</syntaxhighlight> The operator <code>'''arraysetapply (A, [i<sub>1</sub>,i<sub>2,</sub>…,i<sub>n</sub>], x)'''</code> assigns the value of expression <code>x</code> to <code>A</code><code>[i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub>]</code>, where <code>A</code> is an array and <code>i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub></code> are integers.<syntaxhighlight lang="maxima">(%i85) arraysetapply (newRowsA3, [8], ["George",20818.0,"UK","Qtr 4"]); (%o85) ["George",20818.0,"UK","Qtr 4"]</syntaxhighlight> === Undeclared Arrays === Maxima declared arrays and Maxima undeclared arrays will likely be the two types of data structures used by most users. Maxima undeclared arrays are also referred to as '''''hashed arrays'''''. For both of these two array types, memory allocation and structure occur "behind the curtain" of the Maxima user level, and "the man behind the curtain" is Lisp. Of these two types, hashed arrays are the most flexible from the user point of view, all other factors being equal: * The indices allowed for hashed arrays can be expressions, * The dimensions of a hashed array are dynamic and not fixed, and * Hashed arrays are relatively easier to create. In fact, hashed arrays can be somewhat too easy to create. In the examples of the previous section involving declared arrays, identifiers were used as names for arrays. here is the list of allocated arrays:<syntaxhighlight lang="maxima">(%i86) arrays; (%o86) [A3,A2,A1,rowsA3,newRowsA3,B,D,my_list,h]</syntaxhighlight>The array information for array <code>newRowsA3</code> is shown below:<syntaxhighlight lang="maxima"> (%i87) arrayinfo(newRowsA3); (%o87) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15]] </syntaxhighlight>So the array <code>newRowsA3</code> is not a declared array. it was created as part of a loop programming expression repeated below:<syntaxhighlight lang="maxima">(%i53) for i : 1 thru 15 do (newRowsA3[i] : rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$;</syntaxhighlight>When the first loop block was executed with i : 1, the assignment expression: <code>newRowsA3[i] : rowsA3[i]</code> created a hashed array named <code>newRowsA3</code> and assigned <code>newRowsA3[1]</code> the value of <code>rowsA3[1]</code> automatically without any declaration. After that the hashed array dynamically allocated memory for values of the loop identifier i from 2 through 15 with each successive pass in the loop expression. Since hashed arrays are undeclared, and their associated dimensions are not fixed, but rather increase dynamically, expressions can be added to hashed arrays without creating a error message. These added values can be can be any valid Maxima expression, and the value of the indices used are not limited to zero and nonzero integers: <syntaxhighlight lang="maxima"> (%i88) newRowsA3[16] : ["Maisel",12785.0,"USA","Qtr 2"]; (newRowsA3[16]) ["Maisel",12785.0,"USA","Qtr 2"] (%i89 arrayinfo(newRowsA3); (%o89) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16]] (%i90) newRowsA3[z] : 2*sin(y) ^2 + 3*sin(x)^3; (newRowsA3[z]) 2*sin(y)^2+3*sin(B)^3 (%i91) arrayinfo(newRowsA3); (%o91) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[z]] </syntaxhighlight>So one point to glean from this example is that all that is required to create a hashed array is an assignment expression to an indexed identifier, but it does require this assignment. If for some reason, a declared array is intended, but not declared using the <code>array</code> operator (as in the instance of <code>newRowsA3</code>), then a hashed array will be created at the first assignment of an expression to an indexed identifier. This issue can also occur in cases where reference to a list value is intended, but the list has not been created. Lists are one-dimensional objects by definition. A reference using an identifier with a single index intended to be a list with no list existing named by that identifier, can inadvertently create a hashed array.<syntaxhighlight lang="maxima"> (%i91) Alist[2] : 2*sin(y) ^2 + 3*sin(s)^3; (Alist[2]) 2*sin(y)^2+3*sin(s)^3 (%i92) listp(Alist); (%o92) false (%i93) arrayinfo(Alist); (%o93) [hashed,1,[2]] </syntaxhighlight>The identifier <code>Alist</code> is a name for a hashed array and not a list. However, hashed arrays, like declared arrays can, be multi-dimensional: <syntaxhighlight lang="maxima"> (%i94) a_hashed_array [j,k,l] : [12,s^(1/3), %i]; (%o94) [12,s^(1/3),%i] (%i95) arrayinfo(a_hashed_array); (%o95) [hashed,3,[j,k,l]] </syntaxhighlight>The <code>array</code> operator can be used to transform a hashed array into a declared array:<syntaxhighlight lang="maxima"> (%i96) another_hashed_array[ 0, 2, 3] : 55; (%o96) 55 (%i97) array (another_hashed_array, 2, 4, 5); (%o97) another_hashed_array (%i98) arrayinfo(another_hashed_array); (%o98) [declared,3,[2,4,5]] </syntaxhighlight>From the user point of view, hashed arrays and declared arrays typically can be used for the same purpose. If dynamic dimensions or index expression flexibility are factors, then hashed arrays are likely to be a better choice. Many of the operators that can use declared arrays as arguments, may also be used with hashed arrays. However, it should be noted at this point, that merely using a indexed identifier alone without an assignment, will not create a hashed array. Instead, Maxima interprets an expression so composed as an identifier for an undefined memoizing function, which is the topic of the next section. ==== Memoizing Functions ==== Assignment using an indexed identifier implicitly creates an undeclared (hashed) array. However, entering an expression that is an unassigned indexed identifier, from the point of view of Maxima, creates the identifier of a "memoizing" function. Memoizing functions are technically not an array topic, as these functions fall under the category of function definition. These functions have one foot in the function category and the other foot in the array category. Memoizing functions are defined in a manner similar to other user-defined functions, for example: <code>f(x, y, z) := x^2 + y^2 + z^2;</code> But instead of the arguments being enclosed in parentheses, they are enclosed using brackets: <code>f[x, y, z] := x^2 + y^2 + z^2;</code> However, memoizing functions may be referred to as ''array functions,'' and it is the case that these functions from the point of view of aggregate data structures are hashed arrays. So these are mentioned and exemplified here for that reason:<syntaxhighlight lang="maxima">/* reference an indexed identifier h without assignment */ (%i99) h[x]; (%o99) h[x] /* check identifier h as an array */ (%i100) arrayinfo (h); arrayinfo: h is not an array. -- an error. To debug this try: debugmode(true); /* check identifier h as a function */ (%i101) op(h[x]); (%o101) h /* define h[x] as a function */ (%i102) h[x] := 5*x^3 + sin(x); (h[x]) h[x]:=5*x^3+sin(x) /* check identifier h[x] as a function */ (%i103) op(h[x]); (%o103) "+" /* check identifier h as an array */ (%i104) arrayinfo (h); (%o104) [hashed,1,[x]] /* check the value of identifier h[x] */ (%i105) h[x]; (%o105) sin(x)+5*x^3 /* evaluate identifier h[x] with the argument 3*%pi */ (%i106) h[3*%pi]; (%o106) 135*%pi^3 /* list the values of identifier h as an array */ (%i107) listarray(h); (%o107) [135*%pi^3,sin(x)+5*x^3] /* check identifier h as an array */ (%i108) arrayinfo (h); (%o108) [hashed,1,[3*%pi],[x]]</syntaxhighlight>A defined memoizing function stores its value the ''first time'' it is referenced with arguments, and returns the stored value, without evaluation, when the same arguments are used with that function subsequently. The stored value is "frozen" after the initial evaluation. Thus, it behaves like a hashed array. The arguments of a memoizing function also serve as indices of the associated hashed array. === Lisp Arrays === Lisp arrays are created using the <code>make_array (type, dim<sub>1</sub>, dim<sub>2</sub>, …, dim<sub>n</sub>)</code> operator. Perhaps a better name for this operator would be <code>make_lisp_array ()</code>, which admittedly is a longer name. This operator creates and has a return value of a Lisp array. The array type may be <code>any</code>, <code>flonum</code>, <code>fixnum</code>, or <code>hashed</code> . The <code>functional</code> type referred to in the Maxima Manual appears to have been deprecated, and may result in an error message if used. There can be ''n'' indices, and where the associated indices can be a value from ''0'' to ''dim<sub>i</sub> -1'', and ''i'' can have a value of one of 1 to n inclusive. This operator can be used as an alternative to the <code>array ()</code> operator. The advantage of using <code>make_array()</code> is that the return value of <code>make_array()</code> ''does not have a name''. Once the Maxima identifier that is assigned to the array return value is no longer assigned, the array memory allocation is released, and the allocated memory can be garbage collected. What it is being referred to that Lisp arrays created using <code>make_array()</code> do not have names? <syntaxhighlight lang="maxima"> /* create a undeclared Maxima hashed array */ (%i109) arrayA1 [1] : 55; (%o109) 55 /* check the information about this undeclared Maxima hashed array */ (%i110) arrayinfo (arrayA1); (%o110) [hashed,1,[1]] /* check the value of this undeclared Maxima hashed array */ (%i111) arrayA1; (%o111) arrayA1 /* the name */ /* create a Lisp hashed array */ (%i112) arrayA2 : make_array (hashed); (arrayA2) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* check the information about this Lisp hashed array */ (%i113) arrayinfo (arrayA2); (%o113) [hash_table,1] /* check the value of this Lisp hashed array */ (%i114) arrayA2; (%o114) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* no name */ (%i115) listarray (arrayA2); (%o115) [] /* this hashed array is empty */ </syntaxhighlight>So Lisp arrays do not have a name as a value. So, Maxima identifiers assigned to a Lisp array have no name for the array as a value. These identifiers have the reference to the array itself as a value, Lisp hashed arrays created using <code>make_array()</code> with the hashed type specified, do not use dimensions. Lisp hashed arrays are often referred to as '''''hashed tables''''', and their indices are called '''''keys'''''. An example of a Lisp array with the type <code>any</code> follows: <syntaxhighlight lang="maxima"> /* make a Lisp 3 by 4 array of type any */ (%i116) arrayA3 : make_array (any, 3,4); (arrayA3) \#\{Lisp array \[3\\,4\]\} (%i117) arrayinfo (arrayA3); (%o117) [declared,2,[2,3]] (%i118) listarray(arrayA3); (%o118) [false,false,false,false,false,false,false,false,false,false,false,false] (%i119) arrayA3[1,1] : "a string" ; (%o119) "a string" (%i120) listarray(arrayA3); (%o120) [false,false,false,false,false,"a string", false,false,false,false,false,false] </syntaxhighlight>Contrary to statements made in some sources, type checking is is not accomplished automatically, and will not cause Maxima to return an error message, as the Lisp array with the type <code>fixnum</code> which follows is an exemplifies:<syntaxhighlight lang="maxima">(%i121) arrayA4 : make_array (fixnum, 3,4); (arrayA4) \#\{Lisp array \[3\\,4\]\} (%i122) arrayinfo (arrayA4); (%o122) [declared,2,[2,3]] (%i123) listarray (arrayA4); (%o123) [0,0,0,0,0,0,0,0,0,0,0,0] (%i124) arrayA4[0,2] : 3.14159; (%o124) 3.14159 (%i125) arrayA4[0,0] : "a string"; (%o125) "a string" /* value types not checked and no error message */ (%i126) listarray (arrayA4); (%o126) ["a string",0,3.14159,0,0,0,0,0,0,0,0,0]</syntaxhighlight>As was the case with declared arrays, there is no type checking and no error messages associated with assigned values of the array based on the declared type. The declared array type simply determines initial fill values, if any. Hashed arrays and Lisp hash tables have an operator in common: <code>has_key</code> <code>(A, L)</code> This expression has a a value of <code>true</code>, if the hashed array or Lisp hash table <code>A</code> has the key (index) or keys (indices) of the list object <code>L</code>. Otherwise the expression has a value of <code>false</code>. The array <code>A</code> must be a hashed (undeclared) array, a Lisp hash table value returned by the <code>make_array</code> operator, or created as an undeclared array with <code>use_fast_arrays</code> assigned the value <code>true</code>. If array A has only one key, that key must be the value of a list.<syntaxhighlight lang="maxima"> (%i127) arrayinfo (newRowsA3); (%o127) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10], [11],[12],[13],[14],[15],[16],[z]] (%i128) has_key (newRowsA3, [z]); (%o128) true (%i129) has_key (newRowsA3, [3]); (%o129) true (%i130) has_key(newRowsA3, [0]); (%o130) false (%i131) lisp_Array_1 [x]; (%o131) 3*x^2 (%i132) arrayinfo (lisp_Array_1); (%o132) [hash_table,1,x] (%i133) has_key (lisp_Array_1, [x]); (%o133) true (%i134) has_key (lisp_Array_1, [y]); (%o134) false </syntaxhighlight> === Arrays and Features === Maxima arrays can be assigned features in a manner similar to other identifiers:<syntaxhighlight lang="maxima"> (%i135) array (a6,fixnum, 5); (%o135) a6 (%i136) arrayinfo (a6); (%o136) [complete,1,[5]] (%i137) declare (a6, [real, noninteger]); (%o137) done (%i138) featurep (a6, real); (%o138) true (%i139) featurep (a6, noninteger); (%o139) true (%i140) a6[2] : 2; (a6[2]) 2 (%i141) listarray (a6); (%o141) [0,0,2,0,0,0] </syntaxhighlight>However, once again, declaring an array to have one or more features does not result in type checking of values assigned to an array. Perhaps the best way to ensure types of values assigned to arrays is type-checking of expressions using predicate operators prior to assignment to arrays. === Array Memory Storage Considerations === The following from the Maxima Manual<ref>{{Cite web |title=Maxima Manual Section 7.5.1 - Functions and Variables for Arrays |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Functions-and-Variables-for-Arrays}}</ref> is quoted here for the purpose of establishing the context of that which follows:<blockquote>''"Option variable: use_fast_arrays ¶'' ''Default value: false'' ''When use_fast_arrays is true, arrays declared by array are values instead of properties, and undeclared arrays (hashed arrays) are implemented as Lisp hashed arrays.'' ''When use_fast_arrays is false, arrays declared by array are properties, and undeclared arrays are implemented with Maxima’s own hashed array implementation.'' ''Note that the code use_fast_arrays switches to is not necessarily faster than the default one; Arrays created by make_array are not affected by use_fast_arrays."''</blockquote> This Maxima Manual entry requires some elaboration in order to have a sufficient understanding of the effect of the <code>'''use_fast_arrays'''</code> "flag" – referred to as an "Option Variable" in the above quotation. The first point to note is that the default value of this flag is <code>false</code>. So, if users take no action to assign this flag to the value <code>true</code>, then declared arrays created using the <code>array()</code> operator are treated as ''properties'' bound to a symbol, and behave in the manner previously described. Likewise undeclared arrays are a Maxima array implementation, and behave as legacy property hash tables, and these also behave as previously described. If action is taken to enter an expression that assigns the value <code>true</code> to this flag, then Maxima treat arrays as standard Lisp ''values'' rather than object properties:<syntaxhighlight lang="maxima"> (%i142) use_fast_arrays; (%o142) false (%i143) array (A1,fixnum, 10); (%o143) A1 (%i144) arrayinfo (A1); (%o144) [complete,1,[10]] (%i145) H1[1] : 1729; (H1[1]) 1729 (%i146) arrayinfo (H1); (%o146) [hashed,1,[1]] (%i147) use_fast_arrays : true; (use_fast_arrays) true (%i148) array (A2, fixnum, 10); (%o148) \#\{Lisp array \[11\]\} (%i149) A2; (%o149) \#\{Lisp array \[11\]\} (%i150) H2[1] : 1729; (H2[1]) 1729 (%i151) H2; (%o151) "#<HASH-TABLE :TEST EQUAL :COUNT 2 {1203AD15A3}>" (%i152) arrayinfo (H2); (%o152) [hash_table,1,1] </syntaxhighlight> The <code>use_fast_arrays</code> flag has no effect on arrays created using the <code>make_array ()</code> operator. Note the following: * Assigning <code>use_fast_arrays</code> <code>: true</code> does not speed up execution for all operations. It primarily optimizes memory footprint by minimizing cell allocations. The main benefit is optimization of memory footprints and structural representation inside Lisp. * If compiling Maxima expressions to native Lisp using the <code>translate</code> <code>()</code> operator, pair this flag with <code>translate_fast_arrays</code> <code>: true</code>. This flag instructs the translator to compile arrays as value-based. === Structures === Structures, although not an array data type is an aggregation data type.  By "aggregation" it is meant a data type that references other data types by reference to a name and some method of accessing individual values of instances of that aggregation by means of indices used to reference values individually. Thus, as has been previously described for example lists, hashed arrays, Lisp arrays, and declared arrays are all aggregation data types with syntactical means to refer to individual values of a named aggregation instance by way of indices, which are sometimes also referred to as subscripts or keys. As examples: * An existing '''list''' named <code>L1</code> has values that can be accessed as <code>L1[1]</code>, <code>L[2]</code>, <code>L[3]</code>, and so forth * An existing '''hashed array''' with two indices ("2D") named <code>ha</code> has values that can accessed as <code>ha[1,1</code>], <code>ha[1,2]</code>,..., <code>ha[2,1]</code>, <code>ha[2,2]</code>, and  so forth. * An existing '''declared array''' with three indices ("3D") named <code>da</code> has values that can be accessed as <code>da[1,1,1]</code>, <code>da[1,1,2]</code>,...,<code>da [2,1,1]</code>, ..., <code>da[3,1,1]</code>, and so forth. What makes the Maxima structure data type different from these array data types is the form of definition used and the means of accessing values of an instance of this type of aggregation. The Maxima structure data type seems to be the closest type of data that resembles an object in some other general-purpose programming languages. The structure type of data allows the creation of named entities with attributes, and named instances of those entities and the assignment of values to those attributes. Thus the Maxima structure data type is used to define custom, named composite data types that group related fields together under a single identifier. Structures enhance code organization and readability, especially when modeling real-world entities in symbolic computations. They are useful for managing complex data in programs involving algebraic manipulations, simulations, or data modeling. Structures are created using the <code>defstruct</code> operator, which defines a template with named attributes. Once defined, instances of the structure are created using the <code>new</code> operator, and attributes are accessed via the <code>@</code> operator. So in the interest of taking advantage of this information, consider a well-defined set of people. The people of this set may have many diverse attributes that might be of interest - name, age ,and city of residence as examples. A class of people of the set of interest with these attributes can be defined as follows: <syntaxhighlight lang="maxima">(%i153) defstruct (person (name, age, city)); (%o153) [person(name,age,city)] (%i54) structures; (%o154) [person(name, age, city)] (%i155) p : new (person ("Alice", 30, "New York")); (p) person(name="Alice",age=30,city="New York") (%i156) p@name; (%o156) "Alice" (%i157) p@city; (%o157) "New York" (%i158) kill(p@city); (%o158) done /* If the attribute a in x has not been assigned a value, or the value has been "killed," then x@a evaluates to itself */ (%i159) p@city; (%o159) p@city (%i160) p; (%o160) person(name="Alice",age=30,city) (%i161) p@city : "Rochester"; (%o161) "Rochester" (%i162) p; (%o162) person(name="Alice",age=30,city="Rochester") (%i163) defstruct (sales(LastName, Sales , Country , Quarter) ); (%o163) [sales(LastName, Sales, Country, Quarter)] (%i164) structures; (%o164) [person(name, age, city), sales(LastName, Sales, Country, Quarter)] (%i165) s : new (sales ("Smith",16753.00,"UK","Qtr 3")); (%o165) sales(LastName=Smith, Sales=16753.0, Country=UK, Quarter=Qtr 3) (%i166) s@Sales; (%o166) 16753.0 (%i167) s@Sales : 17375.0; (%o167) 17375.0 (%i168) s; (%o168) sales(LastName=Smith, Sales=17375.0, Country=UK, Quarter=Qtr 3)</syntaxhighlight>{{Bookcat}} m8lenlneqjznbdxktwfrp17erygjika 4669041 4668966 2026-09-06T03:02:00Z Idavidmiller 3577687 Work in progress. Saving Changes. 4669041 wikitext text/x-wiki == Maxima Aggregate Data Structures == === Introduction === This section is intended to present some of the essentials of what are called Maxima aggregate data structures. By this it is meant the data types that can be used to refer to the values of expressions using a means of indexing of a single identifier (name) that refers to an aggregate (collection) of expressions as values. Built-in aggregate data types include: * lists * declared arrays * hashed (undeclared) arrays * Lisp arrays * structures Each of these has a means of indexing an identifier that names an instance of these data types. Please note that it is the case that this means of indexing an identifier for an aggregate data type may be referred to as involving "subscripts" or "sub-scripted variables" or "keys" as used by various computer programming languages, as well as in the context of Maxima documentation and commentary. In this book terms such as "index" or "indices" or "indexed identifiers"  are used instead. Also all built-in Maxima functions (including packages) for these data types are referred to as ''"operators"'' and not ''"functions"'' as this latter term in general serves better to refer to Maxima function expressions defined by the user -- as in <code>f(x) :=</code>, <code>g[s] :=</code> and <code>define ()</code> as examples. This section is not intended to be exhaustive. It is intended to provide familiarity with aggregate data types. What is included has been gleaned from various sources, and only a few attributions are provided. Therefore, there is no claim of originality implied. === Lists === ==== Introduction to Lists ==== Lists are one of the basic buildings block for Maxima and Lisp. Maxima expressions are in general represented as Lisp lists. For example, consider the Maxima expression:<syntaxhighlight lang="maxima"> (%i1) e+3; (%o1) e+3 </syntaxhighlight>This expression has the form of a Lisp list:<syntaxhighlight lang="maxima"> (%i2) :lisp #$[e+3]$ ((MLIST SIMP) ((MPLUS SIMP) 3 $E)) </syntaxhighlight>An expression in the form of a Lisp list can also be be displayed as a Maxima expression:<syntaxhighlight lang="maxima"> (%i2) :lisp (displa '((MLIST SIMP) ((MPLUS SIMP) 3 $E))); [e+3] NIL </syntaxhighlight>Note that the value of this expression using <code>displa '()</code> is <code>NIL</code>, and <code>[e+3]</code> is simply displayed in Maxima list object form. It is not necessary for the typical uses of Maxima to utilize this insight into the role Lisp lists have as one of the building blocks for Maxima, but it may be useful to have a familiarity with that role. Lists are often used as arguments to many operators, and the values of expressions are often in the form of lists. ==== Some Operators for Lists ==== Lists are created explicitly and list elements referenced using <code>[</code> and <code>]</code> to mark the beginning and end, respectively, of an instance of a list object, or to reference the expressions of an existing list object.<syntaxhighlight lang="maxima"> (%i3) [2,3,4]; (%o3) [2,3,4] </syntaxhighlight>The expression <code>[2,3,4]</code> creates a Maxima list object. In this case the object itself is not accessible as it was not assigned an identifier unless referenced by the <code>%</code> , <code>%i</code> or <code>%o</code> label.<syntaxhighlight lang="maxima"> (%i4) %; (%o4) [2,3,4] (%i5) %o4[2]; /* second expression of list object referenced by index */ (%o5) 3 </syntaxhighlight>That [2,3,4] is a list object can be tested using the <code>listp()</code> operator:<syntaxhighlight lang="maxima"> (%i6) listp ([2,3,4]); (%o6) true </syntaxhighlight>A list object can be assigned an identifier:<syntaxhighlight lang="maxima">(%i7) s : [%pi,%e,%phi]; (s) [%pi,%e,%phi] (%i8) listp (s); (%o8) true</syntaxhighlight> The value of an element of a list can be accessed using the list identifier and brackets with a index value.<syntaxhighlight lang="maxima"> (%i9) s[1]; (%o9) %pi (%i10) s[2]; (%o10) %e (%i11) s[3]; (%o11) %phi </syntaxhighlight> Invalid index values returns an error:<syntaxhighlight lang="maxima"> (%i12) s[4]; inpart: invalid index 4 of list or matrix. -- an error. To debug this try: debugmode(true); </syntaxhighlight> Consider the following relatively long list of integer atoms created explicitly and identified as <code>List_1</code>:<syntaxhighlight lang="maxima">(%i13) List_1 : [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177]; (List_1) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177]</syntaxhighlight> The number of values of this list can be returned using the <code>length()</code> operator:<syntaxhighlight lang="maxima"> (%i14) length (List_1); (%o14) 105 </syntaxhighlight> Create another list identified as <code>List_2</code>:<syntaxhighlight lang="maxima"> (%i15) List_2 : [6,1455,200,6,1607,205]; (List_2) [6,1455,200,6,1607,205] (%i16) length (List_2); (%o16) 6 </syntaxhighlight> Create a third list identified as <code>List_3</code>:<syntaxhighlight lang="maxima"> (%i17) List_3 : append (List_1, List_2)$ (%i18) length (List_3); (%o19) 111 </syntaxhighlight> Note that the <code>'''append ()'''</code> operator does not affect either of the list arguments <code>List_1</code> or <code>List</code>_2. It merely appends <code>List_2</code> to <code>List_1</code> and returns a new list, in this case assigned the identifier <code>List_3</code>.<syntaxhighlight lang="maxima">(%i20) length (List_1); (%o20) 105 (%i21) length (List_2); (%o21) 6 (%i22) length (List_3); (%o22) 111 (%i23) List_3; (%o23) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607,205]</syntaxhighlight> Values (only the last one in this example) can be deleted from a list:<syntaxhighlight lang="maxima">(%i24) last (List_3); (%o24) 205 (%i25) delete (last (List_3), List_3); (%o25) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372, 142,1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2, 1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664, 75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4, 1582,214,5,118,30,5,484,49,5,664,81,5,1004,125,5,1231, 142,5,1372,174,5,1582,177,6,1455,200,6,1607]</syntaxhighlight> The <code>delete (List_3)</code> expression creates a new list object using <code>List_3</code>. <code>List_3</code> itself is not affected by the <code>'''delete ()'''</code> operator. Only the resulting list is affected. This is often the case with list operators. An identifier could be used to save the above resulting list if necessary:<syntaxhighlight lang="maxima">/* List_3 is the same length */ (%i26) length(List_3); (%o26) 111 /* The last value of List_3 is the same */ (%i27) List_3[111]; (%o27) 205 (%i28) last(List_3); (%o28) 205</syntaxhighlight>There was only one instance of <code>205</code> in <code>List_3</code>, so only that value was deleted from the list of <code>%o25</code>. If there are more than one value then the <code>delete ()</code> operator will remove all of those values from the returned list expression:<syntaxhighlight lang="maxima"> (%i29) NewList_3 : delete(118, List_3)$ /* all five instances of 118 removed from List_3 as NewList_3 */ (%i30) length(NewList_3); (%o30) 106 </syntaxhighlight>There are operators to refer to instances of list expressions by ordinal number. Here are few examples:<syntaxhighlight lang="maxima"> (%i30) FirstThreeList_3:[first(List_3), second(List_3), third(List_3)]; (FirstThreeList_3) [1,118,30] </syntaxhighlight>Expressions of list objects can be referenced to create a new list object from the first ''n'' expressions of a list, the last ''n'' expressions of a list, or the rest remaining after ''n'' expressions from the beginning or ''-n'' expressions from the end of a list:<syntaxhighlight lang="maxima">/* first three expressions of List_3 */ (%i31) firstn(List_3,3); (%o31) [1,118,30] /* same three expressions of List_3 using the rest operator with -108 */ (%i32) rest(List_3, -108); (%o32) [1,118,30] /* last three expressions of List_3 */ (%i33) lastn(List_3,3); (%o33) [6,1607,205] /* same three expressions of List_3 using the rest operator with 108 */ (%i34) rest(List_3, 108); (%o34) [6,1607,205]</syntaxhighlight>Some further examples of the <code>'''firstn ()'''</code>, <code>'''lastn ()'''</code> and <code>'''rest ()'''</code> list operators:<syntaxhighlight lang="maxima"> /* first 63 expressions of List_3 */ (%i35) firstn (List_3, 63); (%o35) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108,3, 1231,115,3,1372,139,3,1582,140] /* last 63 expressions of List_3 */ (%i36) lastn (List_3, 63); (%o36) [3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174,5, 1582,177,6,1455,200,6,1607,205] /* first expressions of List_3 after removing the last 63*/ (%i37) rest (List_3, -63); (%o37) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1, 1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2, 1372,203,2,1582,203,3,118,30,3,484,51] </syntaxhighlight>Maxima programming expressions can be used with list operators to reference list expressions in various ways. For example, the expression which follows accesses the expressions of a list as lists of three each:<syntaxhighlight lang="maxima"> (%i38) (L4 : List_4, for i:(-length (List_4)) + 3 thru 0 step 3 do (disp (rest (L4, i)), L4 : rest (L4, 3)), "")$ [1,118,30] [1,484,58] [1,664,87] [1,1004,115] [1,1231,120] [1,1372,142] [1,1582,145] [2,118,33] [2,484,69] [2,664,111] [2,1004,156] [2,1231,172] [2,1372,203] [2,1582,203] [3,118,30] [3,484,51] [3,664,75] </syntaxhighlight>List operators can be used as arguments of other list operators:<syntaxhighlight lang="maxima"> /* create a new empty list */ (%i39) newList4 : []; (newList4) [] /* append the first six & last six expressions of List_4 to the new list */ (%i40) newList4 : append (newList4, firstn (List_4, 6), lastn (List_4, 6))$ /* the new list now has the 12 appended expressions from List_4 */ (%i41) newList4; (%o41) [1,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> Maxima programming expressions can be used to step through the expressions of lists using list operators to reference "slices" of different lengths:<syntaxhighlight lang="maxima">(%i42) L4 : List_4; (L4) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142,1,1582 145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172,2,1372,203, 2,1582,203,3,118,30,3,484,51,3,664,75] (%i43) length (L4); (%o43) 51 (%i44) (L4 : List_4, for i : 21 thru 3 step -3 do print (L4 : lastn (L4, i)," ", length (L4)), "")$ [2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 21 [2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 18 [2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75] 15 [2,1582,203,3,118,30,3,484,51,3,664,75] 12 [3,118,30,3,484,51,3,664,75] 9 [3,484,51,3,664,75] 6 [3,664,75] 3</syntaxhighlight> ==== Using the <code>copylist</code> Operator ==== When an existing list object is assigned to an identifier, a reference to the memory location of the list object is used. This reference to the memory location is transparent from the point of view of the user. However, if this is not accounted for, unintended side effects may occur when assigning another identifier to an existing one that references a list object. For example, in the expression <code>L4 : List_4</code> it might be assumed that this results in the list object referenced by <code>List_4</code> to simply be copied to a new memory location and reference for <code>L4</code>. This is not the case. Both <code>L4</code> and <code>List_4</code> refer to the same list object in memory. Consequently, changes to the same list object can be effected by referencing the object using either alias.<syntaxhighlight lang="maxima"> (%i45) newList4; (%o45) [1,118,30,1,484,58,3,484,51,3,664,75] /* The identifier newList4 refers to a location in memory. The colon (:) assignment operator simply creates an alias using that same memory reference*/ (%i46) newList5 : newList4; (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Two different identifiers for the same memory location and therefore the same object. Changes to expressions of the list object using either identifier changes the same object in memory */ (%i47) newList5[1] : 99; (newList5[1]) 99 (%i48) newList4[1]; (%o48) 99 (%i49) newList4; (%o49) [99,118,30,1,484,58,3,484,51,3,664,75] (%i50) newList5; (%o50) [99,118,30,1,484,58,3,484,51,3,664,75] </syntaxhighlight> This "side effect" is often unwanted. The way to avoid this is by using the <code>copylist ()</code> operator instead of the assignment operator:<syntaxhighlight lang="maxima"> (%i51) newList4 : [1,118,30,1,484,58,3,484,51,3,664,75] ; (newList4) [1,118,30,1,484,58,3,484,51,3,664,75] (%i52) newList5 : copylist (newList4); (newList5) [1,118,30,1,484,58,3,484,51,3,664,75] /* Same list object expressions, but a different memory reference */ (%i53) newList5[1] : 99; (newList5[1]) 99 (%i54) newList4[1]; (%o54) 1 </syntaxhighlight> Changes to the values of either list will not affect the other list. {| class="wikitable" |+List Object Operators |[ |fourth |rreduce |- |] |fullsetify |second |- |append |join |setify |- |assoc |last |seventh |- |cons |length |sixth |- |copylist |listarith |some |- |create_list |listp |sort |- |delete |lmax |sublist |- |eighth |lmin |sublist_indices |- |endcons |lreduce |tenth |- |fifth |makelist |third |- |first |member |tree_reduce |- |flatten |reverse |xreduce |} Refer to the Maximal Manual<ref>{{Cite web |title=Maxima Manual Section 7.4.2 Functions and Variables for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref> for more complete description of operators and variables for Maxima lists. ==== Performance Considerations for Lists ==== <blockquote>''"Lists provide efficient ways of appending and removing elements. They can be created without knowing their final dimensions. Lisp provides efficient means of copying and handling lists. Also nested lists do not need to be strictly rectangular. These advantages over declared arrays come with the drawback that the amount of time needed for accessing a random element within a list may be roughly proportional to the element’s distance from its beginning."''<ref>{{Cite web |title=Maxima Manual Section 7.4.3 Performance considerations for Lists |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Lists}}</ref></blockquote>Maxima list objects have many operators for creating, accessing, and changing the expressions of lists. Evaluation times of expressions that involve lists can vary significantly depending on the length of the list objects involved, as well as the nature of any operators used to compose the expressions. This fact might have an influence on the choice of using arrays rather than lists in some cases if evaluation time is a factor to consider. The example expressions that follow involve a list object (identified as <code>s</code> ) of complex number expressions that has a length of 10,000 and two different user-defined functions:<pre>(%i55) P1(s) := rectform (product(s[i], i, 1, length (s)))$ (%i56) P2(s) := xreduce (lambda ([a, b], rectform (a * b)), s)$ (%i57) s : makelist (random (1.0) + %i*random (1.0), 10^4)$ (%i58) showtime : true$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes. (%i59) P1(s); Evaluation took 32.3080 seconds (32.3860 elapsed) using 17944.301 MB. (%o59) 0.0 (%i60) P2(s); Evaluation took 0.0620 seconds (0.0620 elapsed) using 8.343 MB. (%o60) 0.0 (%i61) showtime : false$ Evaluation took 0.0000 seconds (0.0000 elapsed) using 0 bytes.</pre> ==Arrays == <blockquote>"Maxima's current array/matrix semantics are a mess, I must say, with at least four different kinds of object (hash arrays, explicit lists, explicit matrices, Lisp arrays) supporting subscripting with varying semantics." <ref>[http://comments.gmane.org/gmane.comp.mathematics.maxima.general/21829 Maxima: Syntax improvements by Stavros Macrakis ]</ref> – Stavros Macrakis "Maxima's concept of arrays, lists, and matrices is pretty confused, since various ideas have accreted in the many years of the project... Yes, this is a mess. Sorry about that. These are all interesting ideas, but there is no unifying framework."<ref>[http://stackoverflow.com/a/29926692 Maxima: what does Maxima call an “array”? - answer by Robert Dodier]</ref> – Robert Dodier</blockquote> The various terminology used in the context of arrays undoubtedly can be confusing. For the sake of simplicity and clarity the following categories of array objects are referred to in this book: Maxima has three array categories :<ref>[http://permalink.gmane.org/gmane.comp.mathematics.maxima.general/13588 the Maxima mailing list <nowiki>: [Maxima] array and matrix? - answer by Robert Dodier</nowiki>]</ref> * Declared arrays * Undeclared (hashed) arrays * Lisp arrays '''''Declared arrays''''' are explicitly created using the <code>array()</code> operator, and unlike lists, which have only one index and are one-dimensional, declared arrays can be multi-dimensional – having one to five indices. The indices for declared array dimensions need not be equal. Indices for each dimension may be between 0 and the respective declared dimension. Each declared array may be be declared with a specified type, which can be ''<code>fixnum</code>'' for integers or ''<code>flonum</code>'' for floating-point numbers. '''''Undeclared (hashed) arrays''''' are created implicitly by assigning an expression to an indexed identifier that does not name an existing list object. An undeclared array (hashed array) can grow dynamically as there is no fixed dimension limit for each index as there is with declared arrays Another difference is that numbers, identifiers, expressions and strings may be used for indices. Also, there is no fixed limit on the number of dimensions. The only real limitation is practical – the available computer memory and the underlying Lisp environment of the Maxima session. Hashed arrays with only one dimension may be confused with a list object. It is essential to keep in mind that list objects must always be created before values are assigned or referenced. Assigning an expression to a one-dimensional indexed identifier, that does not reference an existing list, implicitly creates a hashed array. '''''Lisp arrays''''' are created using the <code>'''make_array ()'''</code> operator. The array type may be specified as ''any'', ''<code>flonum</code>'', ''<code>fixnum</code>'', or ''<code>hashed</code>''. Lisp array objects may be created as one-dimensional or multi-dimensional as specified by the number of dimension size values used with the <code>'''make_array ()'''</code> operator. For each dimension value specified, the associated index value can be a number between 0 to 1 less than the respective dimension value. The same or different values may be used for each specified dimension. The ''<code>hashed</code>'' type does not require any dimensions. Lisp arrays may be used in cases where memory usage and garbage collection are factors. Examples of use and elaboration upon the technical details for each of these categories of array object types follows. {| class="wikitable" |+Array Operators and Flags |array |arraysetapply |rearray |- |arrayapply |has_key |remarray |- |arrayinfo |fillarray |subvar |- |arraymake |listarray |subvarp |- |arrays |make_array |use_fast_arrays |- | | |translate_fast_arrays |} === Declared Arrays === Declared arrays must be created before being referenced and are of fixed dimensions.<syntaxhighlight lang="maxima"> (%i1) array (A1, fixnum, 34,2); (%o1) A1 (%i2) array (A2, flonum, 35,2); (%o2) A2 (%i3) array (A3, 14,3); (%o3) A3 (%i4) arrayinfo (A1); (%o4) [complete,2,[34,2]] (%i5) arrayinfo (A2); (%o5) [complete,2,[35,2]] (%i6) arrayinfo (A3); (%o6) [declared,2,[14,3]] </syntaxhighlight> The first expression <code>%i1</code> creates a declared array object named using the identifier <code>A1</code>. This array is two-dimensional – the first index may have values from 0 to 34 and the second index may have values from 0 to 2. This array therefore is 35 by 3 in extent. The array type is declared to be <code>fixnum</code>. As it is, <code>A1</code> is an not empty array – it has values to reference as will be exemplified below. Similarly the second expression <code>%i2</code> creates a declared array object named using the identifier <code>A2</code>. This array is also two-dimensional – the first index may have values from 0 to 35 and the second index may have values from 0 to 2. This array therefore is 36 by 3 in extent. The array type is declared to be <code>flonum</code>. As it is, <code>A2</code> is not an empty array – it also has values to reference as will be exemplified below. The third expression <code>%i3</code> creates a declared array object named using the identifier <code>A3</code>. This array is also two-dimensional – the first index may have values from 0 to 13 and the second index may have values from 0 to 3. This array therefore is 15 by 4 in extent. The array type is not declared. As it is, <code>A3</code> is an empty array – it has no values to reference as will be exemplified below. The <code>'''arrayinfo ()'''</code> operator can be used to return a list object that has values reflecting information about an array. Note that arrays declared without a type will have <code>declared</code> as a value of the list. Arrays declared with <code>fixnum</code> or <code>flonum</code> as the type will have <code>complete</code> as a value of the list. This technical detail is not well-documented. The returned information list also shows a value for the dimension of the array ( 2 in these examples ) and an inner list with values for the maximum index for each dimension. A look inside each of these declared arrays provides a clue as to why <code>complete</code> is returned instead of <code>declared</code> when the type is specified as <code>fixnum</code> or <code>flonum</code>:<syntaxhighlight lang="maxima">/* This array reference has a value of 0 */ (%i7) A1[0,0]; (%o7) 0 /* This array reference has a value of 0.0 */ (%i8) A2[0,0]; (%o8) 0.0 /* This array reference has a value of itself */ (%i9) A3[0,0]; (%o9) A3[0,0]</syntaxhighlight> In fact, ''all'' values of the array <code>A1</code> have been assigned 0, and ''all'' values of the array <code>A2</code> have beenassigned 0.0. However, ''all'' values of the array <code>A3</code> have been not been assigned any value.<syntaxhighlight lang="maxima">(%i10) listarray (A1); (%o10) [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0] (%i11) listarray (A2); (%o11) [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] (%i12) listarray (A3); (%o12) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####,#####,#####,#####,#####,#####,#####, #####,#####,#####,#####,#####]</syntaxhighlight> Thus, arrays <code>A1</code> and <code>A2</code> are <code>complete</code> in this sense, and array <code>A3</code> is simply <code>declared</code>. It might seem reasonable, that Maxima would complain if a value was assigned to an array that is at odds with the declared type. Such is not the case however. Once an array is declared with a type, Maxima does not enforce any type checking of values assigned to the array. The effect of the type (if any) in the declaration is simply to fill the array with values of #####, 0 or 0.0. Subsequently, those values can be replaced by the assignment of different values that will not be checked for the type of value. One way to enforce type checking is by using predicate operators to check values at the point in time of assignment to arrays. For example, using one or more of: * numberp (expr) * floatnump (expr) * integerp (expr) * ratnump (expr) * stringp (obj) * listp (expr) * featurep (a, f) and possibly others.<syntaxhighlight lang="maxima"> /* A1 was declared as type fixnum */ (%i13) A1[5,2]:3.14159; (%o13) 3.14159 /* A2 was declared as type flonum */ (%i14) A2[3,0]:7129; (%o14) 7129 /* A1 which was declared as type fixnum assigned a string */ (%i15) A1[4,1]:"a string"; (%o15) "a string" /* A2 which was declared as type flonum assigned a math expression*/ (%i16) A2[6,1]:3*x^2 + 4*x +10; (%o16) 3*x^2+4*x+10 </syntaxhighlight> There are other ways to assign values to an array. One way is to read the values from a comma separated (CSV) file using the <code>'''read_array ()'''</code> operator from the ''numericalio'' package.<syntaxhighlight lang="maxima"> (%i17) load (numericalio); (%o17) "/app/plugins/maxima/share/maxima/5.50.0/share/numericalio/numericalio.mac" </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data_nh.csv</code> :<syntaxhighlight lang="text"> 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight> Note that the following expression assumes that the CSV file is located in the Maxima working directory.<syntaxhighlight lang="maxima"> (%i18) read_array("tree_data_nh.csv", A1, ","); (%o18) done (%i19) listarray(A1); (%o19) [1,118,30,1,484,58,1,664,87,1,1004,115,1,1231,120,1,1372,142, 1,1582,145,2,118,33,2,484,69,2,664,111,2,1004,156,2,1231,172, 2,1372,203,2,1582,203,3,118,30,3,484,51,3,664,75,3,1004,108, 3,1231,115,3,1372,139,3,1582,140,4,118,32,4,484,62,4,664,112, 4,1004,167,4,1231,179,4,1372,209,4,1582,214,5,118,30,5,484,49, 5,664,81,5,1004,125,5,1231,142,5,1372,174,5,1582,177] </syntaxhighlight> Below are of the values of the CSV data file <code>tree_data.csv</code> which has a header row, but is otherwise the same as <code>tree_data_nh.csv</code>:<syntaxhighlight lang="text"> "Tree","age","circumference" 1,118,30 1,484,58 1,664,87 1,1004,115 1,1231,120 1,1372,142 1,1582,145 2,118,33 2,484,69 2,664,111 2,1004,156 2,1231,172 2,1372,203 2,1582,203 3,118,30 3,484,51 3,664,75 3,1004,108 3,1231,115 3,1372,139 3,1582,140 4,118,32 4,484,62 4,664,112 4,1004,167 4,1231,179 4,1372,209 4,1582,214 5,118,30 5,484,49 5,664,81 5,1004,125 5,1231,142 5,1372,174 5,1582,177 </syntaxhighlight><syntaxhighlight lang="maxima">(%i20) read_array ("tree_data.csv", A2, ","); (%o20) done (%i21) listarray (A2); (%o21) ["Tree","age","circumference",1,118,30,1,484,58,1,664,87,1,1004, 115,1,1231,120,1,1372,142,1,1582,145,2,118,33,2,484,69,2,664,111, 2,1004,156,2,1231,172,2,1372,203,2,1582,203,3,118,30,3,484,51, 3,664,75,3,1004,108,3,1231,115,3,1372,139,3,1582,140,4,118,32, 4,484,62,4,664,112,4,1004,167,4,1231,179,4,1372,209,4,1582,214, 5,118,30,5,484,49,5,664,81,5,1004,125,5,1231,142,5,1372,174, 5,1582,177]</syntaxhighlight>The previous values of 0 and 0,0 as well as the assigned values of <code>A1</code> and <code>A2</code> have been replaced with the values from the CSV files. The third array <code>A3</code> can be used with values from the <code>dataset.csv</code> file below:<syntaxhighlight lang="text">"Last Name","Sales","Country","Quarter" "Smith",16753.00,"UK","Qtr 3" "Johnson",14808.00,"USA","Qtr 4" "Williams",10644.00,"UK","Qtr 2" "Jones",1390.00,"USA","Qtr 3" "Brown",4865.00,"USA","Qtr 4" "Williams",12438.00,"UK","Qtr 1" "Johnson",9339.00,"UK","Qtr 2" "Smith",18919.00,"USA","Qtr 3" "Jones",9213.00,"USA","Qtr 4" "Jones",7433.00,"UK","Qtr 1" "Brown",3255.00,"USA","Qtr 2" "Williams",14867.00,"USA","Qtr 3" "Williams",19302.00,"UK","Qtr 4" "Smith",9698.00,"USA","Qtr 1"</syntaxhighlight><syntaxhighlight lang="maxima">(%i22) read_array ("dataset.csv", A3, ","); (%o22) done (%i23) listarray (A3); (%o23) ["Last Name","Sales","Country","Quarter", "Smith",16753.0,"UK","Qtr 3", "Johnson",14808.0,"USA","Qtr 4", "Williams",10644.0,"UK","Qtr 2", "Jones",1390.0,"USA","Qtr 3", "Brown",4865.0,"USA","Qtr 4", "Williams",12438.0,"UK","Qtr 1", "Johnson",9339.0,"UK","Qtr 2", "Smith",18919.0,"USA","Qtr 3", "Jones",9213.0,"USA","Qtr 4", "Jones",7433.0,"UK","Qtr 1", "Brown",3255.0,"USA","Qtr 2", "Williams",14867.0,"USA","Qtr 3", "Williams",19302.0,"UK","Qtr 4", "Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> Values of the array can be referenced by indices as required for some purpose:<syntaxhighlight lang="maxima"> (%i24) A3[0,0]; (%o24) "Last Name" (%i25) A3[4,2]; (%o25) "USA" </syntaxhighlight> A row list object can be created using the <code>'''makelist ()'''</code> operator:<syntaxhighlight lang="maxima"> (%i26) row1A3: makelist (A3[0, j], j, 0, 3)$ (%i27) row1A3; (%o27) ["Last Name","Sales","Country","Quarter"] (%i28) row1A3[1]; (%o28) "Last Name" (%i29) row15A3: makelist (A3[14, j], j, 0, 3)$ (%i30) row15A3; (%o30) ["Smith",9698.0,"USA","Qtr 1"] (%i31) row15A3[2]; (%o31) 9698.0 </syntaxhighlight> A list of the indices of the array can be created:<syntaxhighlight lang="maxima"> (%i32) indices_A3 : arrayinfo (A3)[3]; (indices_A3) [14,3] </syntaxhighlight> The number of indices of array <code>A3</code> can also be referenced using the <code>'''length (''')</code> operator:<syntaxhighlight lang="maxima"> (%i33) length (arrayinfo(A3)[3]); (%o33) 2 </syntaxhighlight>The number of values of the array <code>A3</code> can be returned using the '''<code>length ()</code>''' operator:<syntaxhighlight lang="maxima"> (%i34) length (listarray (A3)); (%o34) 60 </syntaxhighlight> The values of the array <code>A3</code> can be printed as output using the list of values with a loop programming expression:<syntaxhighlight lang="maxima"> (%i35) for i : 1 thru length (listarray (A3)) do print ('A3[i] ," = ", listarray (A3)[i])$ A3[1]" = ""Last Name" A3[2]" = ""Sales" A3[3]" = ""County" A3[4]" = ""Quarter" A3[5]" = ""Smith" A3[6]" = "16753.0 A3[7]" = ""UK" A3[8]" = ""Qtr 3" A3[9]" = ""Johnson" A3[10]" = "14808.0 A3[11]" = ""USA" A3[12]" = ""Qtr 4" A3[13]" = ""Williams" A3[14]" = "10644.0 A3[15]" = ""UK" A3[16]" = ""Qtr 2" A3[17]" = ""Jones" A3[18]" = "1390.0 A3[19]" = ""USA" A3[20]" = ""Qtr 3" A3[21]" = ""Brown" A3[22]" = "4865.0 A3[23]" = ""USA" A3[24]" = ""Qtr 4" A3[25]" = ""Williams" A3[26]" = "12438.0 A3[27]" = ""UK" A3[28]" = ""Qtr 1" A3[29]" = ""Johnson" A3[30]" = "9339.0 A3[31]" = ""UK" A3[32]" = ""Qtr 2" A3[33]" = ""Smith" A3[34]" = "18919.0 A3[35]" = ""USA" A3[36]" = ""Qtr 3" A3[37]" = ""Jones" A3[38]" = "9213.0 A3[39]" = ""USA" A3[40]" = ""Qtr 4" A3[41]" = ""Jones" A3[42]" = "7433.0 A3[43]" = ""UK" A3[44]" = ""Qtr 1" A3[45]" = ""Brown" A3[46]" = "3255.0 A3[47]" = ""USA" A3[48]" = ""Qtr 2" A3[49]" = ""Williams" A3[50]" = "14867.0 A3[51]" = ""USA" A3[52]" = ""Qtr 3" A3[53]" = ""Williams" A3[54]" = "19302.0 A3[55]" = ""UK" A3[56]" = ""Qtr 4" A3[57]" = ""Smith" A3[58]" = "9698.0 A3[59]" = ""USA" A3[60]" = ""Qtr 1" </syntaxhighlight> Maxima treats declared arrays as fixed-sized, and individual values are accessed via indices. There is no built-in "row" object — rows must be extracted manually using the <code>'''makelist ()'''</code> operator or by looping through values of an array.<syntaxhighlight lang="maxima"> (%i36) array (rowsA3,15); (%o36) rowsA3 (%i37) arrayinfo (rowsA3); (%o37) [declared,1,[15]] (%i38) for i : 0 thru 14 do (rowsA3[i+1] : makelist (A3[i, j], j, 0, 3), print ("Row ",i+1,": ",rowsA3[i+1]))$; "Row "1": "["Last Name","Sales","Country","Quarter"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"] </syntaxhighlight> Maxima does not have a built-in function like <code>delete</code> or <code>unset</code> for removing individual values from arrays using indices. Existing values of an array can be changed by assignment however:<syntaxhighlight lang="maxima">(%i52) rowsA3[1] : ["Solomon",1045.0,"USA","Qtr 4"]$ (%i53) for i : 1 thru 15 do (newRowsA3[i] : rowsA3[i], print ("Row ",i,": ",newRowsA3[i]))$; "Row "1": "["Solomon",1045.0,"USA","Qtr 4"] "Row "2": "["Smith",16753.0,"UK","Qtr 3"] "Row "3": "["Johnson",14808.0,"USA","Qtr 4"] "Row "4": "["Williams",10644.0,"UK","Qtr 2"] "Row "5": "["Jones",1390.0,"USA","Qtr 3"] "Row "6": "["Brown",4865.0,"USA","Qtr 4"] "Row "7": "["Williams",12438.0,"UK","Qtr 1"] "Row "8": "["Johnson",9339.0,"UK","Qtr 2"] "Row "9": "["Smith",18919.0,"USA","Qtr 3"] "Row "10": "["Jones",9213.0,"USA","Qtr 4"] "Row "11": "["Jones",7433.0,"UK","Qtr 1"] "Row "12": "["Brown",3255.0,"USA","Qtr 2"] "Row "13": "["Williams",14867.0,"USA","Qtr 3"] "Row "14": "["Williams",19302.0,"UK","Qtr 4"] "Row "15": "["Smith",9698.0,"USA","Qtr 1"]</syntaxhighlight> The <code>'''arrayapply ()'''</code> operator can be used a follows to reference values of a declared array:<syntaxhighlight lang="maxima"> (%i39) arrayapply (rowsA3,[5]); (%o39) ["Jones",1390.0,"USA","Qtr 3"] (%i40) arrayapply (A3, [5,1]); (%o40) 4865.0 </syntaxhighlight>The operator <code>'''fillarray (A, B)'''</code> assigns values to array <code>A</code> from <code>B</code>, which can be a list or an array. The dimensions of the arrays <code>A</code> and <code>B</code> may not be the same. In that case, array <code>A</code> is filled in "row-major" order. There may not be enough values in <code>B</code> compared to <code>A</code>. In that case, the last value of <code>B</code> is used to for the remaining values of <code>A</code>. There may be too many values of <code>B</code> compared to array <code>A</code>. In that case, the remaining values of <code>B</code> once <code>A</code> is filled are not used. The return value of <code>'''fillarray ()'''</code> is not the filled array <code>A</code>, but it is the first argument.<syntaxhighlight lang="maxima">/* Create a declared array B of type fixnum */ (%i41) array (B, fixnum, 9); (%o41) B /* list the values of array B */ (%i42) listarray (B); (%o42) [0,0,0,0,0,0,0,0,0,0] /* fill array B with the values of the list */ (%i43) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9.0]); (%o43) B /* list the values of array B */ (%i44) listarray (B); (%o44) [0,1,2,3,4,5,6,7,8,9.0] /* fill array B with the value 1.0 */ (%i45) fillarray (B, [1.0]); (%o45) B /* list the values of array B */ (%i46) listarray (B); (%o46) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* fill array B with the first 9 values of the list */ (%i47) fillarray (B, [0,1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,12]); (%o47) B /* list the values of array B */ (%i48) listarray (B); (%o48) [0,1,2,3,4,5,6,7,8,9] /* Create a declared array D of no type */ (%i49) array (D, 9); (%o49) D /* list the values of array D */ (%i50) listarray (D); (%o50) [#####,#####,#####,#####,#####,#####,#####,#####,#####,#####] /* fill array D with the value 1.0 */ (%i51) fillarray (D, [1.0]); (%o51) D /* list the values of array D */ (%i52) listarray (D); (%o52) [1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0] /* Create a declared array E of no type */ (%i53) array (E, 15); (%o53) E /* fill array E with the values from the newRowsA3 list */ (%i54) fillarray (E, listarray (newRowsA3)); (%o54) E /* list the values of array D */ (%i55) listarray (E); (%o55) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"], ["Smith",9698.0,"USA","Qtr 1"]] /* remove array E */ (%i56) remarray (E); (%o56) [E] /* E is no longer an array */ (%i57) arrayinfo (E); arrayinfo: E is not an array. -- an error. To debug this try: debugmode(true);</syntaxhighlight> If you need to keep the array but remove only one value, you must reconstruct it without that value. The operator <code>'''remarray ()'''</code> is the typical way to completely remove an array. The <code>'''rearray (A, dim<sub>1</sub>, dim<sub>2</sub> ,…, dim<sub>n</sub>)'''</code> operator is used to change the dimensions of an array. The changed array will be filled with the elements of the existing array in row-major order. If the existing array has one or more smaller dimensions, the additional dimension values of the changed array are assigned with a value that depends on the type of the array. If the existing array has one or more larger dimensions, the deficient dimension values of the changed array are lost. The type of the array cannot be changed using this operator. <syntaxhighlight lang="maxima"> /* list with the values of array B */ (%i58) listarray (B); (%o58) [0,1,2,3,4,5,6,7,8,9] /* list with information about array B */ (%i59) arrayinfo (B); (%o59) [complete,1,[9]] /* increase the dimension of array B */ (%i60) rearray (B, 12); (%o60) \#\{Lisp array \[13\]\} /* list with information about array B with increased dimension */ (%i61) arrayinfo (B); (%o61) [complete,1,[12]] /* list with the values of array B */ (%i62) listarray (B); (%o62) [0,1,2,3,4,5,6,7,8,9,0,0,0] /* decrease the dimension of array B */ (%i63) rearray (B, 6); (%o63) \#\{Lisp array \[7\]\} /* list with information about array B with decreased dimension */ (%i64) arrayinfo (B); (%o64) [complete,1,[6]] /* list with the values of array B */ (%i65) listarray (B); (%o65) [0,1,2,3,4,5,6] </syntaxhighlight> The <code>'''arraymake ()'''</code> operator returns a value that is an array reference without evaluation. This operator, in spite of the name, does not "make" an array. It returns this reference as a value whether or not an array exists as an object:<syntaxhighlight lang="maxima"> /* the arraymake operator returns the unevaluated reference to A */ (%i66) arraymake (A, [i,j]); (%o66) A[i,j] /* however array A is not an array object*/ (%i67) arrayinfo (A); arrayinfo: A is not an array. -- an error. To debug this try: debugmode(true); /* Maxima sees A[j,k] as a reference to an undefined memoizing function */ (%i68) op (arraymake (A, [i,j])); (%o68) A </syntaxhighlight> However, from a practical point of view, this operator is used with existing arrays:<syntaxhighlight lang="maxima"> (%i69) listarray (newRowsA3); (%o69) [["Solomon",1045.0,"USA","Qtr 4"], ["Smith",16753.0,"UK","Qtr 3"], ["Johnson",14808.0,"USA","Qtr 4"], ["Williams",10644.0,"UK","Qtr 2"], ["Jones",1390.0,"USA","Qtr 3"], ["Brown",4865.0,"USA","Qtr 4"], ["Williams",12438.0,"UK","Qtr 1"], ["Johnson",9339.0,"UK","Qtr 2"], ["Smith",18919.0,"USA","Qtr 3"], ["Jones",9213.0,"USA","Qtr 4"], ["Jones",7433.0,"UK","Qtr 1"], ["Brown",3255.0,"USA","Qtr 2"], ["Williams",14867.0,"USA","Qtr 3"], ["Williams",19302.0,"UK","Qtr 4"], ["Smith",9698.0,"USA","Qtr 1"]] (%i70) arraymake (newRowsA3, [4]); (%o70) newRowsA3[4] (%i71) ''%; (%o71) ["Williams",10644.0,"UK","Qtr 2"] (%i72) arraymake (newRowsA3, [i]); (%o72) newRowsA3[i] (%i73) ''%, i = 6; (%o73) ["Brown",4865.0,"USA","Qtr 4"] </syntaxhighlight> The operator <code>arraymake (x, [i])</code> constructs the expression <code>x[i]</code>, but does not evaluate it. The operator <code>'''subvar'''</code> <code>'''(x, i)'''</code> evaluates the indexed expression <code>x[i]</code>, and evaluates its arguments. <syntaxhighlight lang="maxima"> (%i74) listarray (B); (%o174) [0,1,2,3,4,5,6] (%i75) x : B; (x) B (%i76) i : 4; (i) 4 (%i77) subvar (x, i); (%o77) 4 </syntaxhighlight> The operator <code>'''subvarp (expr)'''</code> returns a value of <code>true</code> if <code>expr</code> is a indexed identifier, and <code>false</code> otherwise. This operator evaluates the argument <code>expr</code>. <syntaxhighlight lang="maxima"> (%i78) z[p]; (%o78) z[p] (%i79) subvarp (z[p]); (%o79) true (%i80) x[i]; (%o80) 4 (%i81) subvar (x, i) (%o81) 4 (%i82) w : z[p]; (w) z[p] (%i83) subvarp (w); (%o83) true </syntaxhighlight> The expression <code>'''arrays'''</code> returns a list of allocated arrays: <syntaxhighlight lang="maxima">(%i84) arrays; (%o84) [A3,A2,A1,rowsA3,newRowsA3,B,D]</syntaxhighlight> The operator <code>'''arraysetapply (A, [i<sub>1</sub>,i<sub>2,</sub>…,i<sub>n</sub>], x)'''</code> assigns the value of expression <code>x</code> to <code>A</code><code>[i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub>]</code>, where <code>A</code> is an array and <code>i<sub>1</sub>,i<sub>2</sub>,…,i<sub>n</sub></code> are integers.<syntaxhighlight lang="maxima">(%i85) arraysetapply (newRowsA3, [8], ["George",20818.0,"UK","Qtr 4"]); (%o85) ["George",20818.0,"UK","Qtr 4"]</syntaxhighlight> === Undeclared Arrays === Maxima declared arrays and Maxima undeclared arrays will likely be the two types of data structures used by most users. Maxima undeclared arrays are also referred to as '''''hashed arrays'''''. For both of these two array types, memory allocation and structure occur "behind the curtain" of the Maxima user level, and "the man behind the curtain" is Lisp. Of these two types, hashed arrays are the most flexible from the user point of view, all other factors being equal: * The indices allowed for hashed arrays can be expressions, * The dimensions of a hashed array are dynamic and not fixed, and * Hashed arrays are relatively easier to create. In fact, hashed arrays can be somewhat too easy to create. In the examples of the previous section involving declared arrays, identifiers were used as names for arrays. here is the list of allocated arrays:<syntaxhighlight lang="maxima">(%i86) arrays; (%o86) [A3,A2,A1,rowsA3,newRowsA3,B,D,my_list,h]</syntaxhighlight>The array information for array <code>newRowsA3</code> is shown below:<syntaxhighlight lang="maxima"> (%i87) arrayinfo(newRowsA3); (%o87) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15]] </syntaxhighlight>So the array <code>newRowsA3</code> is not a declared array. it was created as part of a loop programming expression repeated below:<syntaxhighlight lang="maxima">(%i53) for i : 1 thru 15 do (newRowsA3[i] : rowsA3[i], print("Row ",i,": ",newRowsA3[i]))$;</syntaxhighlight>When the first loop block was executed with i : 1, the assignment expression: <code>newRowsA3[i] : rowsA3[i]</code> created a hashed array named <code>newRowsA3</code> and assigned <code>newRowsA3[1]</code> the value of <code>rowsA3[1]</code> automatically without any declaration. After that the hashed array dynamically allocated memory for values of the loop identifier i from 2 through 15 with each successive pass in the loop expression. Since hashed arrays are undeclared, and their associated dimensions are not fixed, but rather increase dynamically, expressions can be added to hashed arrays without creating a error message. These added values can be can be any valid Maxima expression, and the value of the indices used are not limited to zero and nonzero integers: <syntaxhighlight lang="maxima"> (%i88) newRowsA3[16] : ["Maisel",12785.0,"USA","Qtr 2"]; (newRowsA3[16]) ["Maisel",12785.0,"USA","Qtr 2"] (%i89 arrayinfo(newRowsA3); (%o89) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16]] (%i90) newRowsA3[z] : 2*sin(y) ^2 + 3*sin(x)^3; (newRowsA3[z]) 2*sin(y)^2+3*sin(B)^3 (%i91) arrayinfo(newRowsA3); (%o91) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[z]] </syntaxhighlight>So one point to glean from this example is that all that is required to create a hashed array is an assignment expression to an indexed identifier, but it does require this assignment. If for some reason, a declared array is intended, but not declared using the <code>array</code> operator (as in the instance of <code>newRowsA3</code>), then a hashed array will be created at the first assignment of an expression to an indexed identifier. This issue can also occur in cases where reference to a list value is intended, but the list has not been created. Lists are one-dimensional objects by definition. A reference using an identifier with a single index intended to be a list with no list existing named by that identifier, can inadvertently create a hashed array.<syntaxhighlight lang="maxima"> (%i91) Alist[2] : 2*sin(y) ^2 + 3*sin(s)^3; (Alist[2]) 2*sin(y)^2+3*sin(s)^3 (%i92) listp(Alist); (%o92) false (%i93) arrayinfo(Alist); (%o93) [hashed,1,[2]] </syntaxhighlight>The identifier <code>Alist</code> is a name for a hashed array and not a list. However, hashed arrays, like declared arrays can, be multi-dimensional: <syntaxhighlight lang="maxima"> (%i94) a_hashed_array [j,k,l] : [12,s^(1/3), %i]; (%o94) [12,s^(1/3),%i] (%i95) arrayinfo(a_hashed_array); (%o95) [hashed,3,[j,k,l]] </syntaxhighlight>The <code>array</code> operator can be used to transform a hashed array into a declared array:<syntaxhighlight lang="maxima"> (%i96) another_hashed_array[ 0, 2, 3] : 55; (%o96) 55 (%i97) array (another_hashed_array, 2, 4, 5); (%o97) another_hashed_array (%i98) arrayinfo(another_hashed_array); (%o98) [declared,3,[2,4,5]] </syntaxhighlight>From the user point of view, hashed arrays and declared arrays typically can be used for the same purpose. If dynamic dimensions or index expression flexibility are factors, then hashed arrays are likely to be a better choice. Many of the operators that can use declared arrays as arguments, may also be used with hashed arrays. However, it should be noted at this point, that merely using a indexed identifier alone without an assignment, will not create a hashed array. Instead, Maxima interprets an expression so composed as an identifier for an undefined memoizing function, which is the topic of the next section. ==== Memoizing Functions ==== Assignment using an indexed identifier implicitly creates an undeclared (hashed) array. However, entering an expression that is an unassigned indexed identifier, from the point of view of Maxima, creates the identifier of a "memoizing" function. Memoizing functions are technically not an array topic, as these functions fall under the category of function definition. These functions have one foot in the function category and the other foot in the array category. Memoizing functions are defined in a manner similar to other user-defined functions, for example: <code>f(x, y, z) := x^2 + y^2 + z^2;</code> But instead of the arguments being enclosed in parentheses, they are enclosed using brackets: <code>f[x, y, z] := x^2 + y^2 + z^2;</code> However, memoizing functions may be referred to as ''array functions,'' and it is the case that these functions from the point of view of aggregate data structures are hashed arrays. So these are mentioned and exemplified here for that reason:<syntaxhighlight lang="maxima">/* reference an indexed identifier h without assignment */ (%i99) h[x]; (%o99) h[x] /* check identifier h as an array */ (%i100) arrayinfo (h); arrayinfo: h is not an array. -- an error. To debug this try: debugmode(true); /* check identifier h as a function */ (%i101) op(h[x]); (%o101) h /* define h[x] as a function */ (%i102) h[x] := 5*x^3 + sin(x); (h[x]) h[x]:=5*x^3+sin(x) /* check identifier h[x] as a function */ (%i103) op(h[x]); (%o103) "+" /* check identifier h as an array */ (%i104) arrayinfo (h); (%o104) [hashed,1,[x]] /* check the value of identifier h[x] */ (%i105) h[x]; (%o105) sin(x)+5*x^3 /* evaluate identifier h[x] with the argument 3*%pi */ (%i106) h[3*%pi]; (%o106) 135*%pi^3 /* list the values of identifier h as an array */ (%i107) listarray(h); (%o107) [135*%pi^3,sin(x)+5*x^3] /* check identifier h as an array */ (%i108) arrayinfo (h); (%o108) [hashed,1,[3*%pi],[x]]</syntaxhighlight>A defined memoizing function stores its value the ''first time'' it is referenced with arguments, and returns the stored value, without evaluation, when the same arguments are used with that function subsequently. The stored value is "frozen" after the initial evaluation. Thus, it behaves like a hashed array. The arguments of a memoizing function also serve as indices of the associated hashed array. === Lisp Arrays === Lisp arrays are created using the <code>make_array (type, dim<sub>1</sub>, dim<sub>2</sub>, …, dim<sub>n</sub>)</code> operator. Perhaps a better name for this operator would be <code>make_lisp_array ()</code>, which admittedly is a longer name. This operator creates and has a return value of a Lisp array. The array type may be <code>any</code>, <code>flonum</code>, <code>fixnum</code>, or <code>hashed</code> . The <code>functional</code> type referred to in the Maxima Manual appears to have been deprecated, and may result in an error message if used. There can be ''n'' indices, and where the associated indices can be a value from ''0'' to ''dim<sub>i</sub> -1'', and ''i'' can have a value of one of 1 to n inclusive. This operator can be used as an alternative to the <code>array ()</code> operator. The advantage of using <code>make_array()</code> is that the return value of <code>make_array()</code> ''does not have a name''. Once the Maxima identifier that is assigned to the array return value is no longer assigned, the array memory allocation is released, and the allocated memory can be garbage collected. What it is being referred to that Lisp arrays created using <code>make_array()</code> do not have names? <syntaxhighlight lang="maxima"> /* create a undeclared Maxima hashed array */ (%i109) arrayA1 [1] : 55; (%o109) 55 /* check the information about this undeclared Maxima hashed array */ (%i110) arrayinfo (arrayA1); (%o110) [hashed,1,[1]] /* check the value of this undeclared Maxima hashed array */ (%i111) arrayA1; (%o111) arrayA1 /* the name */ /* create a Lisp hashed array */ (%i112) arrayA2 : make_array (hashed); (arrayA2) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* check the information about this Lisp hashed array */ (%i113) arrayinfo (arrayA2); (%o113) [hash_table,1] /* check the value of this Lisp hashed array */ (%i114) arrayA2; (%o114) "#<HASH-TABLE :TEST EQUAL :COUNT 1 {1202987DC3}>" /* no name */ (%i115) listarray (arrayA2); (%o115) [] /* this hashed array is empty */ </syntaxhighlight>So Lisp arrays do not have a name as a value. So, Maxima identifiers assigned to a Lisp array have no name for the array as a value. These identifiers have the reference to the array itself as a value, Lisp hashed arrays created using <code>make_array()</code> with the hashed type specified, do not use dimensions. Lisp hashed arrays are often referred to as '''''hashed tables''''', and their indices are called '''''keys'''''. An example of a Lisp array with the type <code>any</code> follows: <syntaxhighlight lang="maxima"> /* make a Lisp 3 by 4 array of type any */ (%i116) arrayA3 : make_array (any, 3,4); (arrayA3) \#\{Lisp array \[3\\,4\]\} (%i117) arrayinfo (arrayA3); (%o117) [declared,2,[2,3]] (%i118) listarray(arrayA3); (%o118) [false,false,false,false,false,false,false,false,false,false,false,false] (%i119) arrayA3[1,1] : "a string" ; (%o119) "a string" (%i120) listarray(arrayA3); (%o120) [false,false,false,false,false,"a string", false,false,false,false,false,false] </syntaxhighlight>Contrary to statements made in some sources, type checking is is not accomplished automatically, and will not cause Maxima to return an error message, as the Lisp array with the type <code>fixnum</code> which follows is an exemplifies:<syntaxhighlight lang="maxima">(%i121) arrayA4 : make_array (fixnum, 3,4); (arrayA4) \#\{Lisp array \[3\\,4\]\} (%i122) arrayinfo (arrayA4); (%o122) [declared,2,[2,3]] (%i123) listarray (arrayA4); (%o123) [0,0,0,0,0,0,0,0,0,0,0,0] (%i124) arrayA4[0,2] : 3.14159; (%o124) 3.14159 (%i125) arrayA4[0,0] : "a string"; (%o125) "a string" /* value types not checked and no error message */ (%i126) listarray (arrayA4); (%o126) ["a string",0,3.14159,0,0,0,0,0,0,0,0,0]</syntaxhighlight>As was the case with declared arrays, there is no type checking and no error messages associated with assigned values of the array based on the declared type. The declared array type simply determines initial fill values, if any. Hashed arrays and Lisp hash tables have an operator in common: <code>has_key</code> <code>(A, L)</code> This expression has a a value of <code>true</code>, if the hashed array or Lisp hash table <code>A</code> has the key (index) or keys (indices) of the list object <code>L</code>. Otherwise the expression has a value of <code>false</code>. The array <code>A</code> must be a hashed (undeclared) array, a Lisp hash table value returned by the <code>make_array</code> operator, or created as an undeclared array with <code>use_fast_arrays</code> assigned the value <code>true</code>. If array A has only one key, that key must be the value of a list.<syntaxhighlight lang="maxima"> (%i127) arrayinfo (newRowsA3); (%o127) [hashed,1,[1],[2],[3],[4],[5],[6],[7],[8],[9],[10], [11],[12],[13],[14],[15],[16],[z]] (%i128) has_key (newRowsA3, [z]); (%o128) true (%i129) has_key (newRowsA3, [3]); (%o129) true (%i130) has_key(newRowsA3, [0]); (%o130) false (%i131) lisp_Array_1 [x]; (%o131) 3*x^2 (%i132) arrayinfo (lisp_Array_1); (%o132) [hash_table,1,x] (%i133) has_key (lisp_Array_1, [x]); (%o133) true (%i134) has_key (lisp_Array_1, [y]); (%o134) false </syntaxhighlight> === Arrays and Features === Maxima arrays can be assigned features in a manner similar to other identifiers:<syntaxhighlight lang="maxima"> (%i135) array (a6,fixnum, 5); (%o135) a6 (%i136) arrayinfo (a6); (%o136) [complete,1,[5]] (%i137) declare (a6, [real, noninteger]); (%o137) done (%i138) featurep (a6, real); (%o138) true (%i139) featurep (a6, noninteger); (%o139) true (%i140) a6[2] : 2; (a6[2]) 2 (%i141) listarray (a6); (%o141) [0,0,2,0,0,0] </syntaxhighlight>However, once again, declaring an array to have one or more features does not result in type checking of values assigned to an array. Perhaps the best way to ensure types of values assigned to arrays is type-checking of expressions using predicate operators prior to assignment to arrays. === Array Memory Storage Considerations === The following from the Maxima Manual<ref>{{Cite web |title=Maxima Manual Section 7.5.1 - Functions and Variables for Arrays |url=https://maxima.sourceforge.io/docs/manual/Data-Types-and-Structures.html#Functions-and-Variables-for-Arrays}}</ref> is quoted here for the purpose of establishing the context of that which follows:<blockquote>''"Option variable: use_fast_arrays ¶'' ''Default value: false'' ''When use_fast_arrays is true, arrays declared by array are values instead of properties, and undeclared arrays (hashed arrays) are implemented as Lisp hashed arrays.'' ''When use_fast_arrays is false, arrays declared by array are properties, and undeclared arrays are implemented with Maxima’s own hashed array implementation.'' ''Note that the code use_fast_arrays switches to is not necessarily faster than the default one; Arrays created by make_array are not affected by use_fast_arrays."''</blockquote> This Maxima Manual entry requires some elaboration in order to have a sufficient understanding of the effect of the <code>'''use_fast_arrays'''</code> "flag" – referred to as an "Option Variable" in the above quotation. The first point to note is that the default value of this flag is <code>false</code>. So, if users take no action to assign this flag to the value <code>true</code>, then declared arrays created using the <code>array()</code> operator are treated as ''properties'' bound to a symbol, and behave in the manner previously described. Likewise undeclared arrays are a Maxima array implementation, and behave as legacy property hash tables, and these also behave as previously described. If action is taken to enter an expression that assigns the value <code>true</code> to this flag, then Maxima treat arrays as standard Lisp ''values'' rather than object properties:<syntaxhighlight lang="maxima"> (%i142) use_fast_arrays; (%o142) false (%i143) array (A1,fixnum, 10); (%o143) A1 (%i144) arrayinfo (A1); (%o144) [complete,1,[10]] (%i145) H1[1] : 1729; (H1[1]) 1729 (%i146) arrayinfo (H1); (%o146) [hashed,1,[1]] (%i147) use_fast_arrays : true; (use_fast_arrays) true (%i148) array (A2, fixnum, 10); (%o148) \#\{Lisp array \[11\]\} (%i149) A2; (%o149) \#\{Lisp array \[11\]\} (%i150) H2[1] : 1729; (H2[1]) 1729 (%i151) H2; (%o151) "#<HASH-TABLE :TEST EQUAL :COUNT 2 {1203AD15A3}>" (%i152) arrayinfo (H2); (%o152) [hash_table,1,1] </syntaxhighlight> The <code>use_fast_arrays</code> flag has no effect on arrays created using the <code>make_array ()</code> operator. Note the following: * Assigning <code>use_fast_arrays</code> <code>: true</code> does not speed up execution for all operations. It primarily optimizes memory footprint by minimizing cell allocations. The main benefit is optimization of memory footprints and structural representation inside Lisp. * If compiling Maxima expressions to native Lisp using the <code>translate</code> <code>()</code> operator, pair this flag with <code>translate_fast_arrays</code> <code>: true</code>. This flag instructs the translator to compile arrays as value-based. === Structures === Structures, although not an array data type is an aggregation data type.  By "aggregation" it is meant a data type that references other data types by reference to a name and some method of accessing individual values of instances of that aggregation by means of indices used to reference values individually. Thus, as has been previously described for example lists, hashed arrays, Lisp arrays, and declared arrays are all aggregation data types with syntactical means to refer to individual values of a named aggregation instance by way of indices, which are sometimes also referred to as subscripts or keys. As examples: * An existing '''list''' named <code>L1</code> has values that can be accessed as <code>L1[1]</code>, <code>L[2]</code>, <code>L[3]</code>, and so forth * An existing '''hashed array''' with two indices ("2D") named <code>ha</code> has values that can accessed as <code>ha[1,1</code>], <code>ha[1,2]</code>,..., <code>ha[2,1]</code>, <code>ha[2,2]</code>, and  so forth. * An existing '''declared array''' with three indices ("3D") named <code>da</code> has values that can be accessed as <code>da[1,1,1]</code>, <code>da[1,1,2]</code>,...,<code>da [2,1,1]</code>, ..., <code>da[3,1,1]</code>, and so forth. What makes the Maxima structure data type different from these array data types is the form of definition used and the means of accessing values of an instance of this type of aggregation. The Maxima structure data type seems to be the closest type of data that resembles an object in some other general-purpose programming languages. The structure type of data allows the creation of named entities with attributes, and named instances of those entities and the assignment of values to those attributes. Thus the Maxima structure data type is used to define custom, named composite data types that group related fields together under a single identifier. Structures enhance code organization and readability, especially when modeling real-world entities in symbolic computations. They are useful for managing complex data in programs involving algebraic manipulations, simulations, or data modeling. Structures are created using the <code>defstruct</code> operator, which defines a template with named attributes. Once defined, instances of the structure are created using the <code>new</code> operator, and attributes are accessed via the <code>@</code> operator. So in the interest of taking advantage of this information, consider a well-defined set of people. The people of this set may have many diverse attributes that might be of interest - name, age ,and city of residence as examples. A class of people of the set of interest with these attributes can be defined as follows: <syntaxhighlight lang="maxima">(%i153) defstruct (person (name, age, city)); (%o153) [person(name,age,city)] (%i54) structures; (%o154) [person(name, age, city)] (%i155) p : new (person ("Alice", 30, "New York")); (p) person(name="Alice",age=30,city="New York") (%i156) p@name; (%o156) "Alice" (%i157) p@city; (%o157) "New York" (%i158) kill(p@city); (%o158) done /* If the attribute a in x has not been assigned a value, or the value has been "killed," then x@a evaluates to itself */ (%i159) p@city; (%o159) p@city (%i160) p; (%o160) person(name="Alice",age=30,city) (%i161) p@city : "Rochester"; (%o161) "Rochester" (%i162) p; (%o162) person(name="Alice",age=30,city="Rochester") (%i163) defstruct (sales(LastName, Sales , Country , Quarter) ); (%o163) [sales(LastName, Sales, Country, Quarter)] (%i164) structures; (%o164) [person(name, age, city), sales(LastName, Sales, Country, Quarter)] (%i165) s : new (sales ("Smith",16753.00,"UK","Qtr 3")); (%o165) sales(LastName=Smith, Sales=16753.0, Country=UK, Quarter=Qtr 3) (%i166) s@Sales; (%o166) 16753.0 (%i167) s@Sales : 17375.0; (%o167) 17375.0 (%i168) s; (%o168) sales(LastName=Smith, Sales=17375.0, Country=UK, Quarter=Qtr 3)</syntaxhighlight>{{Bookcat}} 4s7gwbtjumlc6ybqweoczqsasfl5tv2 User:EVolvo/sandbox 2 444945 4668933 4049007 2026-09-05T12:44:31Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668933 wikitext text/x-wiki ==VIN table== {| class="wikitable" style="text-align:center" |- ! VIN Digit | style="width:5%" | 1 | style="width:5%" | 2 | style="width:5%" | 3 | style="width:5%" | 4 | style="width:5%" | 5 | style="width:5%" | 6 | style="width:5%" | 7 | style="width:5%" | 8 | style="width:5%;background:#aaaaaa;{{Text default color}};" | 9 | style="width:5%" | 10 | style="width:5%" | 11 | style="width:5%" | 12 | style="width:5%" | 13 | style="width:5%" | 14 | style="width:5%" | 15 | style="width:5%" | 16 | style="width:5%" | 17 |- ! Section | colspan="3" style="background:#aaffaa;{{Text default color}};" | [[Vehicle_Identification_Numbers_(VIN_codes)/World_Manufacturer_Identifier_(WMI)|WMI]] | colspan="6" style="background:#aaaaff;{{Text default color}};" | [[Vehicle_Identification_Numbers_(VIN_codes)/Vehicle_Descriptor_Section|VDS]] | colspan="8" style="background:#ffaaaa;{{Text default color}};" | [[Vehicle_Identification_Numbers_(VIN_codes)/Vehicle_Identifier_Section|VIS]] |} ns8om234qchp47k3f5dy69swvbwyeti User talk:Wilson Mohammed 3 448809 4669050 4098050 2026-09-06T06:35:08Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669050 wikitext text/x-wiki <div style="padding:5px; border:1px solid #A9A9A9; background-color:#FFEFD5;{{text default color}}; min-height:40px;">[[File:Stop x nuvola.svg|40px|left|link=]] '''[[Wikibooks:Blocking policy|You cannot edit]] indefinitely due to disruptive editing'''. You may appeal this action with a reasonable argument by adding the text <!-- Copy the text as it appears on your page, not as it appears in this edit area. Do not include the "tlx" argument. -->{{tlx|unblock|Your reason here}} below. </div><!-- Template:blocked --> --[[User:Xania|Xania]] [[Image:Flag_of_Estonia.svg|15px]] [[Image:Flag_of_Ukraine.svg|15px]] [[User talk:Xania|<sup>talk</sup>]] 00:59, 2 September 2022 (UTC) 2ezk8eniwrnmuujlxv002gl3bm4t47t User talk:Jakobarvidsson 3 449241 4669056 4111922 2026-09-06T06:39:01Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669056 wikitext text/x-wiki <div style="padding:5px; border:1px solid #A9A9A9; background-color:#FFEFD5;{{text default color}}; min-height:40px;">[[File:Stop x nuvola.svg|40px|left|link=]] '''[[Wikibooks:Blocking policy|You cannot edit]] indefinitely due to disruptive editing'''. You may appeal this action with a reasonable argument by adding the text <!-- Copy the text as it appears on your page, not as it appears in this edit area. Do not include the "tlx" argument. -->{{tlx|unblock|Your reason here}} below. </div><!-- Template:blocked --> --[[User:Xania|Xania]] [[Image:Flag_of_Estonia.svg|15px]] [[Image:Flag_of_Ukraine.svg|15px]] [[User talk:Xania|<sup>talk</sup>]] 09:34, 20 September 2022 (UTC) 1kza3z9dsb61eppkwic6ncu9feh7t0k User talk:Frog Bat Good 3 455870 4669058 4288337 2026-09-06T06:39:49Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4669058 wikitext text/x-wiki <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Frog Bat Good!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}};"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;{{text default color}}; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7;{{text default color}}; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> <div style="clear:both;"> </div> [[User:Kittycataclysm|Kittycataclysm]] ([[User talk:Kittycataclysm|discuss]] • [[Special:Contributions/Kittycataclysm|contribs]]) 21:33, 11 May 2023 (UTC) dlegclyq2fgj3jq9m1yt73si3au90mb User:Belteshazzar 2 461127 4668922 4322344 2026-09-05T12:18:23Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668922 wikitext text/x-wiki __NOINDEX__ <table style="border: 1px solid #aaa; margin: 4px 10%; border-collapse: collapse; background: #f9f9f9;{{Text default color}};" class="plainlinks" role="presentation"><tr><td style="border:none; padding:2px 0 2px 0.9em;">[[File:Wikimedia Foundation logo - vertical.svg|45px|alt=Wikimedia Foundation Logo]]</td><td style="border:none; padding: 0.25em 0.9em; text-align:center;">'''Consistent with the Terms of Use, {{#ifexpr:floor({{NAMESPACENUMBER}}/2)=1|{{BASEPAGENAME}}|this user}} has been banned by the Wikimedia Foundation from editing Wikimedia sites.''' <br /> Please address any questions to ca[[File:At sign.svg|x15px|middle|link=|alt=@]]wikimedia.org.</td></tr></table> {{#ifeq:{{NAMESPACENUMBER}}|3|[[Category:Opted-out of message delivery]]}}[[Category:Wikimedians banned by the WMF]] 8fqapi6ys9zxk997e078kn5pw8nekmp Manshu/Chapter 1 0 464538 4668967 4620962 2026-09-05T17:33:32Z WereSpielChequers 248949 typo 4668967 wikitext text/x-wiki {{Nav}} {{incomplete translation}} {{translation header | language = zh | original = | title = [[../]] | author = Fan Chuo | override_editor = Palace Museum Library | translator = Walter Stanish | section = | previous = | next = | notes = }} [[zh:蛮书/卷01]] ==Translator's note== [[File:Hong-Hin Village (Circa very early 1900s).png|thumb|Turn of the 20th century false color postcard showing ''Hong-Hin'', the then Sino-Tonkin border, on the route traversed within this fragment of the text.]][[File:Sampans on the Red River (circa 1900).png|thumb|Turn of the 20th century postcard showing sampans on the Red River.]][[File:Paysage Annamite Montagne et Riviere Postcard (Circa 1900).jpg|thumb|Turn of the 20th century postcard showing the landscape of parts of the Red River, presumably those closer to modern-day Hanoi, possibly around '''Fēngzhōu'''/'''Phong Châu''' (峯州 or 峰州; modern '''Việt Trì''') and '''Dēngzhōu''' (登州).]] In general for many portions I am confident of a reasonable translation. However, there are also more than a few areas where I am certain there are errors: to what degree, however, I am less sure. In general you should be able to interpret the confidence of translation by the depth of notes and/or mapping around the passage(s) in question. The final portion is particularly murky. The sections are of my own construction. ===Differences with previous Gordon H. Luce Translation=== I am currently (December 2015) reviewing this portion of the translation against [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=18;node=seap044%3A4;page=root;size=100 Gordon H. Luce's Previous English Translation]. This should allow the detection of errors and/or points of disagreement for further investigation and comment. The following list excludes systemic and stylistic differences and focuses on objective issues. *'''Correct title''' ::Luce titles the chapter ''Road-stages within the Frontiers of Yunnan'', whereas we use ''Distances within Yunnan and at its Borders''.<ref>The original Chinese uses the two characters 界内 (''jiè nèi'') — meaning literally ''(border) (internal)''. Luce has interpreted this literally as a compound noun phrase (NP), whereas we have interpreted it as a list. Our rationale is straightforward: many distances are described under foreign administrations (eg. well within Annam and Sichuan), thus a list-based interpretation makes more sense.</ref> *'''Specific errors''' **In the note regarding the demarcation of borders, Luce's translation appears to mistranslate the reign year as 43, whereas we calculate 44—45. The recalculated year is placed by us within the body of the translation, whereas Luce omits it entirely. **After identifying the correct pronunciation of ''Xiefai'' based on the transliterator's note, Luce's translation continues to identify the place name using a modern Mandarin pronunciation (''Jumie''). **Luce's translation improperly assumes intermediate place names and place name suffixes while describing the route from Annam to Guyong, specifically creating the nonexistant place ''Hsia-pu'' and the nonexistant suffix ''-pu'' to Guyong. This is because Luce failed to understand that there was a section of rapids in this part of the river forcing dismount from boats, and the ''-pu'' he could not comprehend was emphasizing walking to compensate rather than travel by boat. **Luce drops the "via ''Denglu''" place name entirely as the route proceeds from ''Guyong''. **Luce wrongfully asserts ''Jiangchuan'' as 'District headquarters', with no evidence whatsoever. **Luce wrongfully reads the last character of the place name ''Bái​shì​'' (白士) — ie. 士 ''shì​'' — as the visually similar and relatively common yet distinct character 土 (''tǔ''). He also erroneously provides this mistaken version in handwritten Chinese. **Luce reads the ancient Sichuan prefecture toponym 巂 as ''sui'' instead of ''xī'', which according to my dictionary should be the correct reading. **Luce misreads the description of inspectors on the Sichuan portion of the Chengdu to Yunnan route as "official civil and military".<ref>From 將軍專知 which can be conceived as (challenge) (particular or focus) (knowledge) .. the 軍 character losing its military sense entirely.</ref> **Luce runs together the interpretation of subsequent statements regarding areas "beyond" (meaning under non-Chinese control — ie. west of) ''Yaozhou'' (modern ''Yaoan'', north-west of ''Chuxiong'') and the roads to the modern Guizhou and Guangxi regions. **While describing the upper Yangtse in the route toward modern Dali from modern Sichuan, Luce implies that his ''Lu-shui'' is another reference to the ''Lu-chiang'' (瀘江) river rather than a place name, which seems more likely. **In Luce's translation, a rope-bridge is ascribed to the ''Ch'ing-ch'u-p'u''—''T'sang-p'ang'' portion of the route. However, in the digital version of our Palace Museum Library edition source text, a firmly placed full stop attributes this bridge instead to the ''Jiā​pí​guǎn​'' (伽毗館)—''Qīngqúpù'' (清渠鋪) portion. Without additional sources, we err in favour of our edition but note this point of contention for future readers. **Luce translates a phrase referring to a route stage in steep mountains as "dangerous and steep" where there is apparently no evidence for the "danger" concept in the text. **Discussing ''Lòngdòng'' city (弄棟城), Luce ascribes an historical affiliation with both ''Yáozhōu'' (姚州) and ''Xīchuān'' (西川), whereas we consider this an unlikely reading and assert the former as current at the time of writing, and the latter as a previous political affiliation. **Luce ascribes a third character to the historical military commander-in-chief of ''Yaozhou'', ''Zhāng​ Qián​'' (張乾), calling him ''Chang Ch'ien-t'o''. We side with our source edition's interpretation and consider this character separately. ==Distances within Yunnan and at its Borders (云南界内途程; ''yúnnán jiè nèi túchéng'')== ===Jiāozhǐ (交阯城) to Yángxiefai (陽苴咩城)=== [[File:Tonghai Landscape from Temple (2009).jpg|thumb|right|339px|Photo toward the Tonghai plain (and the 'ocean'-like lakes) from a temple on a mountain, taken 2009 by Christopher, Tania and Isabelle Luna.]] <!-- [[File:Map for Manshu Chapter 1.svg|thumb|center|599px|Modern satellite map of the region showing some of the locations discussed within the first portion of this chapter. Note that many of the route's features are labelled in grey, this means the positions are approximate. Only places shown in white are identified with relative confidence.]] --> {| class="wikitable" style="text-align:center; width:80%;" |- ! scope="col" | Original <small>pp. [https://archive.org/stream/06061161.cn#page/n7/mode/1up 7]—[https://archive.org/stream/06061161.cn#page/n11/mode/1up 11]</small> ! scope="col" | Translation ! scope="col" | Luce (1961) — <small>pp. [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=18;node=seap044%3A4;page=root;size=100 4],[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=19;node=seap044%3A4;page=root;size=100 5]+[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=27;node=seap044%3A4;page=root;size=100 13],[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=28;node=seap044%3A4;page=root;size=100 14]</small> |- |安寧城,後漢元鼎二年伏波將軍馬援立銅柱定疆界之所。 |At '''[http://en.wikipedia.org/wiki/Anning,_Yunnan Ān​níng​]''' city (安寧城), in 44—45,<ref>See subsequent former transliterator's note.</ref> the '''[[:w:Ma Yuan (Han dynasty)|General Mǎ​yuán​]]''' (馬援), titled ''Breaker of the Waves''<ref>Apparently this title has no relationship to the events described in [[Translation:Manshu/Chapter 3#Part Four: The Kingdom of L.C3.A0ngqi.C3.B3ng .28.E6.B5.AA.E7.A9.B9.29 and The Breaking of the Wave .28.E5.8A.8D.E6.B5.AA.29|Chapter 3, Part 4]] as General Mayuan is not involved there. Therefore we are forced to ascertain an assumption that breaking of waves was some form of then-popular metaphor for the subduing of wild tribes, whose periodic military resistance is apparently likened to like waves lapping at the great shore of Chinese civilization.</ref>, completed the demarcation of the borders with bronze-alloy<ref>Originally I had translated this character, which can mean either copper, brass, or bronze as copper — however after referencing Gordon H. Luce's translation and thinking about weathering effects on metals exposed to the outdoors, I concluded that he was probably more correct in translating this as bronze.</ref> pillars.<ref>銅柱</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">An-ning city was the place where, in the 2nd year of the Yuan-ting period of the Later Han Dynasty, the Fu-po-chiang-chun (General Subduer of the Waves) Ma Yuan set up bronze pillars to fix the frontier.</p> |- |<span style="color:#aaa">(案:馬援定交阯,為後漢光武帝建武十九年事。元鼎乃西漢武帝紀年,後漢並無此號,蓋樊綽失於考據之誤)</span> |<span style="color:#aaa">(Former transliterators' note: The demarcation of the borders by '''General Mǎ​yuán​''' on behalf of the Later (ie. Eastern) Han Dynasty '''Emperor Guāng​wǔ​dì​''' (光武帝)<ref>Born ''Liú​ Xiù​'' (劉秀), reigned 25—57.</ref> occurred in the 19th year of that emperor's initial ''Jiànwǔ'' (建武) reign<ref>The Later (ie. Eastern) Han Dynasty '''Emperor Guangwudi''' (光武帝)'s initial ''Jiànwǔ'' (建武) reign lasted from 25—56. His second and final ''Jiànwǔzhōngyuán'' (建武中元) reign lasted from 56—57.</ref> [ie. 44—45].<ref>Gordon H. Luce's prior translation appear to erroneously state the year here as 43. This appears to be incorrect as if the reign began in the solar year 25, the solar year 26 could have been either lunar year 1 or lunar year 2 of the reign, likewise solar year 46 could have been lunar year number 20 or lunar year number 21 of the reign, and either of the solar years 44 or 45 could have been lunar year number 19 of the reign.</ref> The year name ''Yuándǐng'' (元鼎) refers only to a reign of the Former (ie. Western) Han Dynasty '''Emperor Hàn​ Wǔ​dì​''' (汉武帝) (ie. 116—111BC). There is no such year under the Later (ie. Eastern) Han Dynasty. This appears to be an error in literary reference of the original author.)</span><ref>ie. Possibly the author confused Later (ie. Eastern) Han Dynasty '''Emperor Guāng​wǔ​dì​''' (光武帝) with Former (ie. Western) Han Dynasty '''Emperor Hàn​ Wǔ​dì​''' (汉武帝). However, such an error would be more plausible in later copying, so pointing the finger at the original author from 18th century fragmentary, derived sources seems a little over the top to me!</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">(Comment: We hold that Ma Yuan's fixing of Chiao-chih was an event which occurred in the 19th year of the Chien-wu period of Kuang-wu-ti of the Later Han. (43 A.D.); whereas Yuan-ting was a year-name in the annals of Wu-ti of the Western Han. There is no such year-name in the Later Han Dynasty. It must be a mistake due to Fan Ch'o's negligence in checking his evidence.)</p> |- |去交阯城池四十八日程。 |It takes forty eight days to reach '''Ān​níng​''' (安寧)<ref>Originally I had translated this as 'to the city of Jiāozhǐ' however after reading Luce's translation and comparing it with the direction of described travel, it is in fact clear from context that the reader is supposed to interpret this sentence as 'to reach Anning, from the city of Jiāozhǐ'.</ref> from the city and lakes<ref>Luce's translation states "moated city" here. While Hanoi's environs were extremely wet — in fact essentially swamp-like — this is not present in the text, which literally says ''(city) (pond or lake)''. Hanoi's water bodies have reduced significantly over time as drainage has occurred — these developments are reviewed cartographically in Jim Goodman's ''A Dragon Still Ascending: 1000 Years of Hanoi'', Thé̂ Giới Publishers (2010), ISBN: 9786047700967 (paperback; 260 pp., ill., maps).</ref> of '''[http://en.wikipedia.org/wiki/Jiaozhi Jiāozhǐ]''' (交阯城).<ref>ie. An earlier version of [http://en.wikipedia.org/wiki/Hanoi Hanoi], the dominant delta-region settlement for the [http://en.wikipedia.org/wiki/Red_River Red River] in what is now northern [http://en.wikipedia.org/wiki/Vietnam Vietnam]. The route would almost certainly have involved descending to the Red River, probably down one of the valleys in the general vicinity of '''[http://en.wikipedia.org/wiki/Jianshui Jianshui]''' or '''[http://en.wikipedia.org/wiki/Gejiu Gejiu]''', probably after moving south from the lakes of central Yunnan via '''[http://en.wikipedia.org/wiki/Tonghai Tonghai]''', then following the Red River either by foot and mule or perhaps even descending by boat. Early use of boats is well testified in the bronze drum culture of the region, of which historic Jiāozhǐ appears (at least by cursory quantitative analysis and geographic distribution) to have been the pan Southeast Asian center. The bronze drum industry quite likely used tin from the famous vein of '''Gejiu''', which is located en-route between the lake-plateaux of central Yunnan and Jiāozhǐ.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">(An-ning) is 48 day-stages distant from the moated city of Chiao-chih.</p> |- |漢時城壁尚存,碑銘並在。 |Both the wall of the Han period city, and inscribed stelae are still there.<ref>Fan Chuo is writing in the 9th century, thus the walls and inscriptions were allegedly about 800 years old.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">The city-walls and fortifications of the Han period are still extant, and there are also stone inscriptions.</p> |- |苴咩<span style="color:#aaa">(上音斜,下符差切)</span>城,從安南府城至蠻王見坐苴咩城水陸五十二日程,只計日,無裏數。 |It takes 58 days<ref>From '''Jiāozhǐ''' to the modern '''Dali''' region (Nanzhao's seat) via '''Kunming'''. A shared passage northward from the Red River valley to '''Kunming''', then under only ten days between the two, which is quite fast. The shared route from the Red River would was well established by early times: Dian bronzes are clearly attributable to the Jiāozhǐ-region Dongson culture, and the tin vein of '''Gejiu''' is likely to have been exploitated for export downriver to the southeast. To possibly further underscore the importance of this 'southern orientation', the relatively southerly location of the Dian king's tomb (ie. at 石寨山; ''shizhaishan'') — favourable for taxation and defence of this passage — lies at the mountains southeast of Dianchi, as opposed to anywhere near modern '''Kunming''' (then Shanchan/Tuodong) city in the north of the basin... a location which would appear to offer superior access to extensive flat and well-watered potential agricultural tracts receiving greater volumes of sunshine, routes westward toward Nanzhao's seat at '''Xiefai''' ('''Dali'''), and a more comfortable / flatter topography.</ref> of travel by boat and land<ref>Here is direct evidence of the use of watercraft to transit up the Red River during this period. The phrase used is 水陸 or ''shuǐlù'', roughly translating to 'by water and land'.</ref> from '''Annam'''<ref>Apparently referring, though, specifically to Jiāozhǐ or the modern '''Hanoi''' region.</ref> to the barbarian king's city of '''Xiefai''' (苴咩城; lit. '(Place with) Hemp (and the) Bleating (of sheep or goats)';<ref>Though a literal interpretation is not necessarily possible, particularly if in fact this is a transliteration from a non-Chinese language in to Chinese. In more recent times the area is known for both wild hemp and the rearing of goats, however.</ref> ie. '''[http://en.wikipedia.org/wiki/Dali_City Dali]''') <span style="color:#aaa">(Note: The first character 苴 is pronounced ''xie'' (斜),<ref>ie. /ʒɛər/ in my attempt at rendering correctly the IPA pronunciation.</ref> the second 咩 is pronounced as ''f'' (from 符's ''fu'') + ''a'' or ''ai'' (from 差's ''cha'' or ''chai''​) — ie. ''fa​'' or ''fai​''<ref>ie. either /fa/ or /faɪ/ in my attempt at rendering correctly the IPA pronunciation.</ref>)</span><ref>Note that there is no assigned age for this pronunciation suggestion and that Mandarin has very little to do with a lot of the ancient pronunciation in southern China, so this note — whilst present and translated — should not be taken as gospel, in fact quite the opposite: it needs modern analytical attention from a historically-focused linguists in a range of potentially relevant language families. For what it's worth, here are [http://starling.rinet.ru/cgi-bin/response.cgi?root=config&morpho=0&basename=\data\sintib\stibet&first=1&off=&text_proto=&method_proto=substring&ic_proto=on&text_meaning=&method_meaning=substring&ic_meaning=on&text_chin=&method_chin=substring&ic_chin=on&text_tib=&method_tib=substring&ic_tib=on&text_burm=&method_burm=substring&ic_burm=on&text_kach=&method_kach=substring&ic_kach=on&text_lush=&method_lush=substring&ic_lush=on&text_lepcha=&method_lepcha=substring&ic_lepcha=on&text_kir=&method_kir=substring&ic_kir=on&text_comments=&method_comments=substring&ic_comments=on&text_any=%E8%8B%B4&method_any=substring&sort=proto&ic_any=on alleged Proto-Sino-Tibetan, Sino-Tibetan and Sino-Caucasian etymologies of 苴 (alleged ''xie'')] and [http://ctext.org/dictionary.pl?if=en&char=%E5%92%A9 the ctext.org entry for 咩 (alleged ''fa'' or ''fai'')].</ref> - ie. [http://en.wikipedia.org/wiki/Nanzhao Nanzhao]. On such a journey, one may count but the days, not the miles.<ref>The phrase 只計日,無裏數 comes across to me as if Fan Chuo is dismissing the intermediary wilderness as vast and uncivilized.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">From the prefectural capital of Annam, to reach Chu-mieh city (The first syllable is pronounced hsieh. The second is ''fu''+ ''ch'a'' (or ''ch'ai''; i.e. ''fa'' or ''fai'').), the seat of the ''Man'' king, by water and land route, is 52 day-stages. We can only reckon the days, without giving the number of ''li''. (i.e. the mileage).</p> |- |從安南上水至峰州兩日,至登州兩日,至忠誠州三日,至多利州兩日,至奇富州兩日,至甘棠州兩日,至下步三日,至黎武賁柵四日,至賈<span style="color:#f00">男</span>步五日。 |From '''Annam''' one travels upriver to '''Fēngzhōu'''/'''Phong Châu''' (峯州 or 峰州; modern ''Việt Trì'')<ref>''Phong Châu'' (峯州 or 峰州; a ruined city near Bạch Hạc (白鹤? See [http://jnxb.jnu.edu.cn/skb/CN/article/downloadArticleFile.do?attachType=PDF&id=743 source].) District, Việt Trì, Phú Thọ Province, Vietnam) was originally the capital city of Văn Lang (文郎; the then northern-Vietnamese state centered on the Red River). Supposedly founded in 2879 BCE, it existed until 258 BCE when it was invaded by the Âu Việt tribe (known to the Chinese as the ''Kingdom of Eastern Ou'' (東甌), and associated with Tai/Zhuang peoples). The Âu Việt king, Thục Phán, proclaimed himself King An Dương Vương and reigned from a more easterly location, just east of modern Hanoi at [https://en.wikipedia.org/wiki/C%E1%BB%95_Loa_Citadel Cổ Loa]. Thus, by the time our author mentions the location in passing as two days upriver from Annam, the elevated status of ''Phong Châu'' (峯州 or 峰州) was all ancient history and evidently the name had merely persisted for the general area. Today, the name refers to the nearby but separate Phong Châu district, Phú Thọ province. Geographically, this is the southern (encompassed) side of a major bend in the Red River after being joined by a major tributary, the [https://en.wikipedia.org/wiki/Black_River_%28Asia%29 Black River] (''sông Đà''). As such, it is a location that would have been ideal for tridirectional trade, is probably highly fertile, would have provided an easy point of taxation, and was thus a natural early political center. Note that ''Việt Trì'' and the original ruins are apparently on the northern side of the river, whereas modern ''Phong Châu'' is on the southern side. While studies have almost certainly been done, I have not consulted any, so do be aware that it is not wholly unlikely that the river's course may have moved before drawing any conclusions from this disparity.</ref> for two days, onward to '''Dēngzhōu​''' (登州)<ref>Though distances would suggest approximately the modern location of [https://en.wikipedia.org/wiki/Ph%C3%BA_Th%E1%BB%8D_Province Phú Thọ] and probably no further than [https://en.wikipedia.org/wiki/Y%C3%AAn_B%C3%A1i Yên Bái], at the time of writing, using available online sources, no firm identification appeared to be possible. (Partly this is because the area around Penglai, to the west of Yantai in northern China's Shandong province is far better known by the same characters and widely referenced in Chinese history and literature.) However, given that the next identification of Hekou (modern China/Vietnam border) is made with some confidence, perhaps this was indeed slightly beyond Yên Bái, for example in the region around Mau Dong / Mau A. Note there is apparently [http://epress.nus.edu.sg/msl/entry/444?hl=%22Deng+Subprefecture%22 a passing reference] to a local Dengzhou in the (much later) ''Míngshǐlù'' (明史录; usually in English ''Records of the Ming Dynasty''; lit. ''Historical Records of the Ming Dynasty'').</ref> for two days, onward to '''Zhōngchéngzhōu''' (忠誠州)<ref>Possibly modern day [https://en.wikipedia.org/wiki/Hekou_Yao_Autonomous_County Hekou], ie. the modern China/Vietnam border.</ref> after three days, onward to '''Duō​lì​zhōu​''' (多利州)<ref>Unidentified.</ref> after two days, onward to '''Qífùzhōu''' (奇富州)<ref>Unidentified.</ref> after two days, onward to '''Gāntángzhōu''' (甘棠州)<ref>Apparently [http://jnxb.jnu.edu.cn/skb/CN/article/downloadArticleFile.do?attachType=PDF&id=743 previously identified] as about 2/3 of the way to the modern border, beyond the town of Yên Bái but not close to the town of Lào Cai. French maps seem to confirm the identification of the site as '''Bảo Hà''', Bảo Yên District, the very first place one comes to after entering Lào Cai Province. In addition, the maps show rapids on the Red River following this point which would explain the walking. Certain French colonial era postcards from the early 20th century appear to spuriously identify 甘棠 with Lào Cai — labels read ''Laokay'' but visible Chinese characters in the photograph read 甘棠 — but this makes sense if they were referring to the province since '''Bảo Hà''' lies within.</ref> after two days, continuing for a further three days by walking, onward to '''Líwǔbìzhà''' (黎武賁柵; [https://en.wikipedia.org/wiki/Hekou_Yao_Autonomous_County Hekou]?)<ref>Literally 'Black military bright fence', suggesting a wall, frontier or bastion. Unidentified, but possibly modern [https://en.wikipedia.org/wiki/Hekou_Yao_Autonomous_County Hekou], lit. 'River Mouth', at the confluence of the Red River and one of its tributaries, the ''Nam-Thi'' (Name in local Tai language families; ''Nam'' means river). French photographs from the early 20th century show that the presentation of the confluence is rather sudden and oblique, not unlike a wall, and as a confluence would make a perfect location for collecting tolls, surveying transit and participating in trade. Note also that the pronunciation is a guess: the third character could allegedly be any of ''bì bēn féi fén fèn'' ... but no clues are apparent as to when or why. Luce's translation opts for one of the ''fen'' options and calls it ''Li-wu-fen stockade''.</ref> after four days, and finally onward to '''Gǔyǒng''' (賈勇; lit. 'Brave Merchant')<ref>The source writes '''Gǔ​nán''' (賈男) — this would mean 'merchant man' and is unidentified anywhere. However, it looks ''a lot'' like the place 賈勇 (lit. 'Brave Merchant') below, and is thus potentially a miswritten character for the same place. In Luce's translation, it is given the latter's written form and pronunciation (though erroneously granted a ''-pu'' suffix due to Luce's misunderstanding of this area of the text). Therefore, the error is probably in our version of the source text (ie. an error likely originating in the digitization of the original, which would not exist in the paper or photographic derivative form of the same movable type produced version Luce used), so I count this error as very probable and ignore the spurious name. Note also that the subsequent comment states that a watercourse has been followed to this point, but Guyong in particular may be up a tributary. This lesser water-body would account for the switch to walking.</ref> by walking for five days. |<p style="color:#aaa;font-size:80%;line-height:110%">From Annam, going upstream, to reach Feng-chou is 2 days. To reach Teng-chou is 2 days. To reach Chung-ch'eng-chou is 3 days. To reach To-li-chou is 2 days. To reach Ch'i-fu-chou is 2 days. To reach Kan-t'ang-chou is 2 days. To reach Hsia-pu is 3 days. To reach Li-wu-fen stockade is 4 days. To reach Ku-yung-pu is 5 days.</p> |- |已上二十五日程,並是水路。 |The above takes twenty five days, and follows the watercourse.<ref>This appears to imply that the rest of the route continues from here, overland. Luce's translation erroneously implies the above was all by water route, whereas in fact that was both impossible and not-so-explicitly described in its aversion by the text.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">The above 25 day-stages are all by water-route.</p> |- |大中初,悉屬安南管系,其刺史並委首領勾當。 |In 846 (at the beginning of the Dazhong period<ref>Tang Xuān Zōng (唐宣宗)'s reign, 846–859.</ref>), the area became a dependency of Annam,<ref>Thus a possession of the central Chinese imperial government.</ref> and began to be governed,<ref>This may be seen to imply that, rather than wresting the area from some foreign power, it was brought in to governance from a previously ungoverned, non-state situation.</ref> but the Annam provincial governor had illicit dealings with the local chiefs.<ref>Luce asserts "... might also depute the native chiefs to take a hand in management", though such a focus on delegation does not seem to be evidenced in the text, which merely states 委首領勾當 — literally ''(trust or appoint, send, commission) (chieftains) (illicit dealings)''.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">At the beginning of the ''Ta-chung'' period (847-859)(these parts) were all dependent on and attached to the administration of Annam. But the ''Tz'u-shih'' (of Annam) might also depute the native chiefs to take a hand in the management.</p> |- |大中八年,經略使苛暴,川洞離心,疆內首領旋被蠻賊誘引,數處陷在賊中。 |In the eighth year of the Dazhong era (ie. 853), the [https://zh.wikipedia.org/wiki/%E7%B6%93%E7%95%A5%E5%AE%89%E6%92%AB%E4%BD%BF Emperor's Official]<ref>Luce put me on the right path here: I had failed to recognize 經略使 as an official position and completely munged this paragraph's translation!</ref> was cruel, such that the [population of the] river-valleys and caves<ref>Implying the total geography of the area.</ref> within the frontier became unsettled and a few of them fell to the deceitful enticements of the treacherous barbarians. |<p style="color:#aaa;font-size:80%;line-height:110%">In the 8th year of ''Ta-chung'' (854 A.D.) the ''Ching-lueh-shih'' (Imperial General) was cruel and oppressive. The native areas (lit. valleys and ravines) were divided in heart. The native chiefs within the frontiers (of China) were subsequently seduced by the ''Man'' rebels; and this caused a number of places to fall in to rebel hands.</p> |- |從賈勇步登陸至矣符管一日。 |Walking from '''Gǔyǒng''' (賈勇) via '''Dēnglù''' (登陸)<ref>This place name is wholly omitted by Luce.</ref> to '''Yǐfúguǎn''' (矣符管; lit. 'Yifu Station') takes a day. |<p style="color:#aaa;font-size:80%;line-height:110%">From Ku-yung-pu, going up by land, to reach I-fu-kuan is 1 day.</p> |- |從矣符管至曲烏館一日,至思下館一日,至沙<span style="color:#f00">雙</span>館一日,至南場館一日,至曲江館一日,至通海城一日,至江川縣一日,至進寧館一日,至鄯闡<span style="color:#f00">柘</span>東城一日<span style="color:#aaa">(案:「柘東,」《舊唐書》及《通鑒》俱作「拓東胡」,三省雲,言開拓東境也,《新唐書》作「柘」,從木,與此同)</span>。 |From '''Yǐfúguǎn''' to '''Qūwūguǎn''' (曲烏館; lit. 'Hunched Crow House'<ref>Inexplicably this is suddenly translated as "Chu-wu Inn" by Luce, whereas previous 館 are suffixed ''-kuan''. Subsequent places follow the new pattern.</ref>) takes one day, '''Sīxiàguǎn''' (思下館) another, '''Shāzhīguǎn''' (沙[隹+又]館<ref>It seems here that the source text here has another incorrect character. Luce's translation [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=27;node=seap044%3A4;page=root;size=100 specifies a character in note number 26, page 13] that is apparently not recognized in Unicode, that of 隹 ("a bird") at the top, and 又 ("a right hand") at the bottom. Fortunately, [http://www.zhongwen.com/ zhongwen.com] has an entry for this under ''zhī'', which appears to accord with Luce's Wade Giles romanization and clarify the mystery.</ref>; lit. 'Station at the sandy place for bird or small animal catching') another, '''Nánchǎngguǎn''' (南場館)<ref>Guessing by distance, possibly a town in the northern Jianshui plateau, or Jianshui itself? Apparently Jianshui was called 惠历 (Huili) by Nanzhao, who established it in the year 810 under the command of Tonghai. To them, then, it would have been a southerly place ... perhaps the origin of the 南 in 南場館 — which can be literally interpreted as something vaguely like 'central-office of a southern place'. I am unable to find any secondary sources attesting to a Nanchangguan or Nanchang in the area, though there is a Nanchang southwest of Dali that is certainly not the place referenced.</ref> another, '''Qūjiāngguǎn''' (曲江館; lit. 'Meandering River';<ref>Luce's literal translation, and a good one. Why he decides to provide one for this place name and not others is lost to the mists of time!</ref> ie. modern Qujiang<ref>Under Jianshui's administration — 建水县曲江镇 — and located just across the mountains from Tonghai on the next plain south. Note that the old road may have been first walking west, then turning north up the more westerly canyon via ''Lishan'' village; the new (≈2010) freeway from Tonghai to Jianshui takes a far more easterly path, ie. straight north out of Qujiang.</ref>) another, '''Tōnghǎichéng''' (通海城; lit. 'City of the Connection to the Oceans',<ref>So called not for its connection to the Red River and onward to the South China Sea (南海), but rather for its function as a natural gateway for those journeying from lands to the south, including the Red River and important towns like Jianshui and Gejiu toward the great lakes of Yunnan's central plateaux.</ref> ie. modern [https://en.wikipedia.org/wiki/Tonghai Tonghai]) another, '''Jiāngchuānxiàn''' (江川縣; lit. 'River-plain';<ref>Luce inexplicably presents this in supposed literal translation as 'District headquarters' — with apparently no basis whatsoever!</ref> ie. [https://en.wikipedia.org/wiki/Jiangchuan_County Jiangchuan]) another, '''Jìnníngguǎn''' (進寧館; ie. modern [https://en.wikipedia.org/wiki/Jinning_County Jinning County]) another, '''Shànchǎn / Tuòdōng Chéng''' (鄯闡拓東城; lit. 'The city of Shanchan / Tuodong',<ref>The source had mistranscribed 柘 in place of 拓 — otherwise, the portion "...柘東城" would refer to the city to the east of the 「柘」 (thorny tree, possibly a mulberry bush), which sounds rather spurious.</ref> ie. modern [https://en.wikipedia.org/wiki/Kunming Kunming]) another. <span style="color:#aaa">(Former transliterator's note: The first character of 「柘東」 occurs as 「拓」 with the 「扌」 (hand) radical at left both within the ''History of the Early Tang Dynasty'' (舊唐書) and the later Song Dynasty text ''Comprehensive Mirror in Aid of Governance'' (通鑒; [https://zh.wikisource.org/wiki/%E8%AE%80%E9%80%9A%E9%91%92%E8%AB%96 full text on Chinese wikisource])<ref>By the famous historian '''Sīmǎ Guāng''' (司馬光)]. '''Hú Sānxǐng''' (胡三省), a respected commentator on the ''Comprehensive Mirror in Aid of Governance'' (通鑒) who lived at the end of the Song and the beginning of the Yuan Dynasty.</ref> which further states that this means "[place of] eastward development".). The ''History of the Later Tang Dynasty'', by contrast, records the character 「柘」 with the 「木」 (tree) radical at left [which is likely to be in error] as here.<ref>This implies that this portion of the text may have been lifted from the ''History of the Later Tang Dynasty'' (新唐書) by the compilers of this edition of the text, which is known to have been reconstructed from disparate portions. Someone with more interest than me can definitely go do more research on probable origins of the various portions of the text.</ref>)</span> |<p style="color:#aaa;font-size:80%;line-height:110%">From I-fu-kuan, to reach Ch'u-wu Inn is 1 day. To reach Ssu-hsia Inn is 1 day. To reach Nan-ch'ang Inn is 1 day. To reach Ch'u-chiang (Meandering river) Inn is 1 day. To reach Chin-ning Inn is 1 day. To reach Shan-shan Che-tung city is 1 day. (Comment: We hold that Che-tung, both in the ''Old T'ang history'' and in the ''T'ung chien'', is written ''Chih-tung''. Hu San-sheng says it means to open and take the eastern frontier. The ''New T'ang history'' writes che with the tree radical, as here.)</p> |- |從<span style="color:#f00">柘</span>東節度城至寧寔館一日,安寧館本是漢寧郡城也。 |From the '''Tuòdōng City''' (拓東) military commandery to '''Níngshíguǎn''' (寧寔館)<ref>Uncertain but perhaps this was this supposed to be Anning? It would make a lot more sense.</ref> takes a day. '''Ānníngguǎn''' (安寧館) was known as '''Níngjùn City''' (寧郡城; lit. 'Peaceful Capital City') during the Han Dynasty.<ref>Originally I had translated this differently and probably incorrectly, taking 郡 to be a region and 漢寧 to be a descriptive adjectival phrase, — ie. "capital of the (pacified [and] Han Chinese [occupied]) (region) [in contrast to other areas]". However, after reviewing Luce's work, I think his interpretation is far more straightforward and likely to be correct.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">From the ''Chieh-tu'' city of Che-tung, to reach Ning-shih Inn is 1 day. An-ning Inn originally was the Ning-chun city of the Han dynasty.</p> |- |從安寧城至龍和館一日,至沙雌館一日,至曲館一日,至沙卻館一日,至求贈館一日,至雲南驛一日,至波大驛一日,至白嚴驛一日,至龍尾城一日。 |From '''Ānníngchéng''' (安寧城; lit. 'Peaceful City') to '''Lónghéguǎn''' (龍和館; lit. 'Station of Harmonious Dragons') is a day, '''Shācíguǎn''' (沙雌館) another, '''Qūguǎn''' (曲館) another, '''Shāquèguǎn''' (沙卻館) another, '''Qiúzèngguǎn''' (求贈館) another, '''Yúnnányì''' (雲南驛<ref>Luce translates this as "Yunnan post-station", a trend here established for subsequent ''-yi'' placenames. I do not agree with reading so much in to the suffix here.</ref>) another, '''Bōdàyì''' (波大驛) another, '''Báiyányì''' (白嚴驛) another, '''Lóngwěichéng''' (龍尾城; lit. 'Dragon's tail city', ie. modern [https://en.wikipedia.org/wiki/Xiaguan Xiaguan] near [https://en.wikipedia.org/wiki/Dali_City Dali]) another. |<p style="color:#aaa;font-size:80%;line-height:110%">From An-ning city, to reach Lung-ho Inn is 1 day. To reach Sha-tz'u Inn is 1 day. To reach Ch'u Inn is 1 day. To reach Sha-ch'i Inn is 1 day. To reach Ch'iu-tseng Inn is 1 day. To reach Yunnan post-station is 1 day. To reach Po-ta post-station is 1 day. To reach Po-yen post-station is 1 day. To reach Lung-wei (Dragon's Tail) city is 1 day.</p> |- |李謐伐蠻於龍尾城,誤陷軍二十萬眾,今為萬人冢。 |''Lǐ Mì'' (李謐)<ref>Though, at this point in the text, it seems strange to suddenly switch to descriptions of unidentified characters. After some reference to other sources, this appears to be the Tang general who invaded from the north in 754 but was defeated.</ref> attacked<ref>伐; from other sources we learn this occurred in the year 754.</ref> the barbarians<ref>蠻; referring to the Nanzhao kingdom's people.</ref> at '''Lóngwěi''' (龍尾城), wasting<ref>This seems the most apt translation for 誤陷軍 (''wùxiànjūn'') which could be interpreted a few ways. It should be possible to more confidently translate the verb given additional texts of the era for context, or a more experienced translator.</ref> a great army<ref>The text is actually states 二十萬 (20 x 10,000 = 200,000), though as much classical Chinese is loose with numbers, translating to give a large impression without the stupendous figure may be more accurate. Apparently others have re-estimated the figure at 100,000, though basically all we can reasonably conclude is "a great number" or "a large army".</ref> of underlings,<ref>The text uses the character 眾 (see [https://en.wiktionary.org/wiki/%E7%9C%BE English Wiktionary]), which based upon the glyph's upper portion (an eye) and the lower portion (three people) is presumably an antiquated form of noun, here used to indicate militarily commanded soldiers.</ref> who are now<ref>今為</ref> but 10,000 graves.<ref>萬人冢</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">Li Mi attacked the ''Man'' at the city of ''Lung-wei''. By blundering he lost altogether 200,000 men of his army. It is now called "The Grave of a Myriad Men".</p> |- |至陽<span style="color:#aaa">(「陽」,《新唐書》作「羊」)</span>苴咩城一日<span style="color:#aaa">(蠻王從大和城移在苴咩城。案「蠻王至咩城」十一字,原本誤入正文,今改正)</span> |It takes one day to '''Yángxiefai''' (陽苴咩城) city. <span style="color:#aaa">(Former transliterator's note: The ''[http://en.wikipedia.org/wiki/New_Book_of_Tang History of the Later Tang]'' (新唐書) uses the character 羊 in place of 陽.<ref>As an aside, it may be meaningful to note that the lead compiler of that official dynastic history, Ouyang Xiu (歐陽脩), has a surname that according to his own, respected historical research was [https://en.wikipedia.org/wiki/Ouyang#History associated with far southern China] including regions adjacent to Yunnan such as northern Vietnam (aka. Jiāozhǐ/Annam) and Guangxi. Conjecture: being a historian with family roots in the region, this change ''may'' have been deliberate, for example to reflect or record simplification in popular or short-hand use of the period.</ref>)</span> <span style="color:#aaa">(Former transliterator's note: Note that 11 characters 「蠻王從大和城移在苴咩城」 indicating that the Barbarian King had moved from '''Dà​hé''' (大和) to '''Xiefai''' (苴咩) were mistakenly inserted in to the main text and were not present in the original — these have accordingly been removed [to this comment<ref>Though in typical clarity no further statement on source, time or evidence is made! To make matters worse, our digital source text does not even make it clear which compiler wrote the note originally or in modified form.</ref>].)</span> |<p style="color:#aaa;font-size:80%;line-height:110%">To reach Yang Chu-mieh city is 1 day. (Comment: We hold that ''yang'' is written ''yang'' in the ''New T'ang history''.) The ''Man'' king has moved his residence from Ta-ho city to Chu-mieh city. (Comment: We hold that the 11 characters, from '''Man'' king' to 'Mieh city' in the original edition were wrongly inserted in to the main body of the text. Now we have altered and corrected it.)</p> |} ===Chéngdū (成都府) to Yángxiefai (陽苴咩城)=== <!-- [[File:Map_for_Manshu_Chapter_1_-_Part_2.svg|thumb|center|509px|Modern satellite map of the region showing some of the locations discussed within the second portion of this chapter. Note that the majority of the route's features are labelled in grey, this means the positions are approximate (in the middle portion, extremely). Only places shown in white are identified with relative confidence.]] --> Note that the borderland region between modern Yunnan proper and the Sichuan basin through which this section's route passes is historically inhabited by the Yi. The Yi were both powerful and independent until after the Yuan Dynasty when their princess made a deal with the invading Mongols. They wore impressive armour, examples of which can be seen online [http://scudm.scu.edu.cn/bwgen/modules/EDUCATION/NewsView.jsp?id=821 here at Sichuan University Museum] and [https://www.peabody.harvard.edu/node/2096 here at Harvard], or in person at the Anthropology Museum of Yunnan University on Beimenjie in Kunming. ====Chéngdū (成都府) to the Yúnnán (雲南) boundary==== {| class="wikitable" style="text-align:center; width:80%;" |- ! scope="col" | Original <small>pp. [https://archive.org/stream/06061161.cn#page/n11/mode/1up 11]—[https://archive.org/stream/06061161.cn#page/n13/mode/1up 13]</small> ! scope="col" | Translation ! scope="col" | Luce (1961) — <small>pp. [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=19;node=seap044%3A4;page=root;size=100 5],[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=20;node=seap044%3A4;page=root;size=100 6],[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=21;node=seap044%3A4;page=root;size=100 7]+[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=28;node=seap044%3A4;page=root;size=100 14]</small> |- |自西川成都府至雲南蠻王府、州、縣、館、驛、江、嶺開塞,並裏數計二千七百二十裏。 |From '''Chéngdū''' (成都府) city in the '''Xīchuān''' (西川)<ref>Apparently a historical administrative region denoting borderlands from what is now modern western Sichuan.</ref> region to the capital of the barbarian<ref>Meaning Nanzhao.</ref> prince of '''Yúnnán''' (雲南) one crosses cities,<ref>府</ref> prefectures,<ref>州</ref> counties,<ref>縣</ref> towns,<ref>館</ref> stations,<ref>驛</ref>, rivers,<ref>江</ref> and mountain ranges<ref>嶺</ref> over a total distance of 2720 ''li''. |<p style="color:#aaa;font-size:80%;line-height:110%">From Ch'eng-tu prefecture of Hsi-ch'uan, to reach the prefectural headquarters of the ''Man'' king of Yunnan, (including) the ''chou'' (divisions), ''hsien'' (districts), inns, post-stations, rivers, mountain-ranges, and frontier-passes, the total mileage amounts to 2,720 ''li''.</p> |- |從府城至雙流縣二江驛四十裏,至蜀州新津縣三江驛四十裏,至延貢驛四十裏,至臨邛驛四十裏,至順城驛五十裏,至雅州百丈驛四十裏,至名山縣順陽驛四十裏,至嚴道縣延化驛四十裏,從延化驛六十裏至管長賁關,從奉義驛至雅州界榮經縣南道驛七十五裏,至漢昌六十裏<span style="color:#aaa">(案:此句上有脫文)</span>,屬雅州,城名葛店。 |From '''Chengdu''' to '''Shuāng​liú​xiàn''' (雙流縣; lit. Double Flow [River] county-town)<ref>A modern place exists with the same name outside of Chengdu in Sichuan province (四川省成都市双流县; circa 30.447N,104.03E).</ref>) there are two river crossings over a distance of 40 ''li''. To '''Xīn​jīn​xiàn''' (新津縣; lit. [County of the] New [water or ferry] Crossing<ref>Again, outside of Chengdu in Sichuan province (四川省成都市新津县).</ref>) of '''Shǔ​zhōu​''' (蜀州<ref>[https://zh.wikipedia.org/wiki/%E8%9C%80%E5%B7%9E_(%E5%94%90%E6%9C%9D) Apparently] administered at the time from modern Chongzhou (崇州市), currently north-west of Xīn​jīn.</ref>) there are three river crossings over a distance of 40 ''li''.<ref>Presumably referring in part to the 岷江 (Mínjiāng) and the 大渡河 (Dàdù Hé) — one of the former's tributaries —, and possibly the 雅砻江 (Yǎlóngjiāng). The identity of the fourth river remains unclear, though no doubt good studies of the former flows of rivers in this region have been made, particularly given the proximity to China's [https://en.wikipedia.org/wiki/Dujiangyan_irrigation_system famous early irrigation project at 都江堰] (Dūjiāngyàn), so there is hope for a positive identification.</ref> To '''Yán​gòng​''' (延貢<ref>Vaguely possible literal meaning 'delayed tribute', very questionably referring to poor punctuality in taxation? In any event, seems to equate with the modern village 四川省成都市邛崃市冉义镇延贡村 at 30.4286N,103.649E.</ref>) station it is a further 40 ''li'', to '''Lín​qióng​''' (臨邛<ref>The place name means literally 'the overlooking mound' or 'hillock with a view'. [http://baike.baidu.com/link?url=RGI__MEyATZn3Ql0q7z0rdWk7Px4kXWKLvHZyu4s10tZNcozvc8y_GjYbDOJRzXs8dIyAVuTvZI8Ie3IUW_cGq Identified historically at Baidu Baike], though the final definition is a few hundred years before our period.</ref>) station a further 40 ''li'', to '''Shùn​chéng​''' (順城) a further 50 ''li'', to '''Bǎi​zhàng​''' (百丈<ref>Conjecture: 丈 here possibly refers to the Chinese measure, being 3.3 meters, if so the literal translation of the place would be '330 meter station', which could refer to the approximate length of the settlement along the road.</ref>) station of '''Yǎ​zhōu​''' (雅州) a further 40 ''li'', '''Shùn​yáng​''' (順陽<ref>Literal geographical meaning could be 'along the sunny side [of the mountain]'.</ref>) station of '''Míng​shān​xiàn''' (名山縣<ref>Literally 'bright mountain county'.</ref>) a further 40 ''li'', '''Yán​huà​''' (延化<ref>Conjecture: Possibly referring to the length of seasonal change, for example as indicated by an abnormal length of foliage on deciduous trees in the local microclimate.</ref>) station of '''Yándào​xiàn​''' (嚴道縣<ref>Yandao county, possibly literal meaning 'tight or well-sealed road', which could suggest a prominent mountain pass, military garrison and/or customs levy.</ref>) a further 40 ''li''. From '''Yán​huà​''' station to '''Guǎn​chángbì​guān​''' (管長賁關<ref>This toponym is possibly of unlikely length and could alternatively be interpreted as 'Biguan' of 'Guanchang [area]', ie. 'bright pass of everwatch [area]'. However, the style of surrounding text suggests that it is indeed a four-character toponym, thus a literal meaning would be 'Everwatch Bright Pass'.</ref>) it is 60 ''li''. From '''Fèngyì​​''' (奉義<ref>As yet not introduced, possibly synonymous with the pass just mentioned.</ref>) station to '''Nándào​​''' (南道<ref>Literally 'Southerly Road'.</ref>) station of '''Róng​jīng​''' (榮經<ref>Modern Róng​jīng​ County in Ya'an (四川省雅安市荣经县).</ref>) county on the '''Yǎ​zhōu''' (雅州<ref>Apparently the then-name of the capital of the broader district with the same name, on the site of modern Ya'an (四川省雅安市). [http://zh.wikipedia.org/wiki/%E9%9B%85%E5%B7%9E#.E5.94.90.E4.BB.A3.5B1.5D A history is available] at Chinese Wikipedia.</ref>) border<ref>界</ref> it is a further 75 ''li'', it is a further 60 ''li'' to '''Hàn​chāng​''' (漢昌<ref>Can't find any clear references online, except north-west of Chengdu which seems incorrect though may indicate that a new route from Chengdu is under discussion... we shall see with subsequent placenames.</ref>), <span style="color:#aaa">(Former transliterator's note: There appear to be some characters missing here)</span> which is subordinate to '''Yǎ​zhōu'''<ref>ie. Modern Ya'an (四川省雅安市).</ref> and whose city is called '''Gě​diàn​''' (葛店<ref>Literally 'hemp cloth selling place'. I can't find any clear references to this place online, except in far-flung places that are clearly incorrect identifications, or in copies of this same text. Therefore, its location remains a mystery, but it must be nearby Róng​jīng County (四川省雅安市荣经县)​ to the south or southwest of modern Ya'an (四川省雅安市).</ref>). |<p style="color:#aaa;font-size:80%;line-height:110%">From the prefectural city (ie. Ch'eng-tu), to reach Erh-chiang post-station of Shuang-liu-hsien (district), is 40 ''li''. To reach San-chiang-i (Three Rivers post-station) of Hsin-ching-hsien (New Ford district) of Shu chou is 40 ''li''. To reach Yen-kung post-station is 40 ''li''. To reach Lin-chiung post-station is 40 ''li''. To reach Shun-ch'eng post-station is 50 ''li''. To reach Pai-chang (One Thousand Feet) post-station of Ya-chou, is 40 ''li''. To reach Shun-yang post-station of Ming-shan district is 40 ''li''. To reach Yen-hua post-station of Yen-tao district is 40 ''li''. From Yen-hua post-station (one goes) 60 ''li'' and reaches Kuan-ch'ang-fen-kuan (frontier gate). From Feng-i post-station, to reach Nan-tao post-station of Jung-ching district on the boundard<ref>Error in original.</ref> of Ya-chou, is 75 ''li''. To reach Han-ch'ang is 60 ''li''. (... dependent on Ya-chou) (Comment: We hold that at the beginning of this sentence there is an omission.) (The name of the town is Ko-tien.)</p> |- |至皮店三十裏,至黎州潘倉驛五十裏,至黎武城六十裏,至白士驛三十五裏<span style="color:#aaa">(過漢源縣十裏)</span>,至通望縣本筤驛四十裏<span style="color:#aaa">(去大渡十裏)</span>,至望星驛四十五裏,至清溪關五十裏,至大定城六十裏,至達士驛五十裏<span style="color:#aaa">(黎、巂二州分界)</span>,至新安城三十裏,至菁口驛六十裏,至榮水驛八十裏,至初裏驛三十五裏,至臺登城平樂驛四十裏<span style="color:#aaa">(古縣,今廢)</span>,至蘇祁驛四十裏<span style="color:#aaa">(古縣)</span>,至巂州三阜城四十裏<span style="color:#aaa">(州城在三阜山上)</span>,至沙也城八十裏<span style="color:#aaa">(故巂州,大和年移在臺登)</span>,至儉浪驛八十裏,至俄淮嶺七十裏,下此嶺入雲南界。 |To '''Pí​diàn​''' (皮店<ref>Literally '[animal] skin [or fur] selling place'.</ref>) it is a further 30 ''li'', to '''Pāncāng​​''' (潘倉<ref>Literally 'Pan storehouse' or 'Pan's cabin'.</ref>) station of '''Lízhōu​''' (黎州) a further 50 ''li'', to '''Lí​wǔ''' (黎武<ref>Literally 'black militia'.</ref>) city a further 60 ''li'', to '''Bái​shì​''' (白士<ref>Literally something like 'hundred scholars' or 'scholarly'.</ref>) station a further 35 ''li'' <span style="color:#aaa">(10 ''li'' across '''Hàn​yuán​''' (漢源) county)</span>, and 40 ''li'' to '''Běn​láng​''' (本筤) station of '''Wàngxiàn​''' (望縣) county <span style="color:#aaa">(10 ''li'' to '''Dàdù​''' (大渡)</span>. Continuing to '''Wàng​xīng​''' (望星<ref>Literally 'star gazing'. Conjecture: This could be atop a particularly high point or in a microclimate without evening cloud. Alternatively, the name may refer to a local cultural habit of astromancy.</ref>) station is a further 45 ''li'', '''Qīng​xīguān​​''' (清溪關<ref>Literally 'clear stream pass'.</ref>) a further 50 ''li'', '''Dà​dìng​''' city (大定城<ref>Literally this could possibly be something like 'city of great permanence'.</ref>) a further 60 ''li'', to '''Dá​shì​''' (達士<ref>Literally something like 'passing the scholarly exam', which seems fairly elevated as a reference for such a presumably remote location and therefore suspect. Other explanations are a mere transliteration, possibly in jest, of some form of endemic language such as Yi or Naxi.</ref>) station a further 50 ''li'' <span style="color:#aaa">(on the border of '''Lí​''' (黎) and '''Xī'''<ref>The character 巂 has multiple pronunciations, however with the dictionary I am using this pronunciation is listed specifically as a Sichuan-related toponym, so seems the most likely candidate. Luce uses a more common reading of the character, ''sui'', which is possibly wrong.</ref> (巂) prefectures), to '''Xīn​'ān​''' city (新安城<ref>Literally 'new peaceful city'.</ref>) a further 30 ''li'', to '''Jīng​kǒu​''' (菁口) station a further 60 ''li'', to '''Róngshuǐ​''' (榮水<ref>Literally 'thriving water', suggesting a fast-moving stream.</ref>) station a further 80 ''li'', to '''Chū​lǐ''' (初裏) station another 35 ''li'', to '''Píng​lè​''' (平樂) station in '''Tái​dēng​''' city (臺登城) another 40 ''li'' <span style="color:#aaa">(an ancient county, since abandoned)</span>, to '''Sū​qí​''' (蘇祁<ref>This toponym sounds suspiciously transliteration-like to me.</ref>) station a further 40 ''li'' <span style="color:#aaa">(an ancient county)</span>, to '''Sān​fù​''' city (三阜城) of '''Xī​zhōu​''' (巂州) prefecture another 40 ''li'' <span style="color:#aaa">(the prefectural capital city's walls lie atop Sān​fù​shān​ (三阜山; lit. 'Three Mounds Mountain'<ref>Unidentified. There is apparently a similarly named mountain (characters uncertain) known for its mineral ores in the Shandong region — [http://www.researchgate.net/publication/278114099_Stable_isotope_geochemistry_and_Re-Os_ages_of_the_Yinan_gold_deposit_Shandong_Province_northeastern_China source].</ref>)</span>, to '''Shā​yě​''' city (沙也城) another 80 ''li'' <span style="color:#aaa">(then and formerly part of '''Xī​zhōu​''' (巂州) — it was moved to administration beneath '''Tái​dēng​''' (臺登) in the first year of Taihe<ref>Referring either to [http://zh.wikipedia.org/wiki/%E5%A4%A7%E5%92%8C_%28%E5%8D%97%E5%90%B4%29 929-930] or [http://zh.wikipedia.org/wiki/%E5%A4%A7%E5%92%8C_%28%E5%94%90%E6%9C%9D%29 827-828], probably the former.</ref> (ca. 930?))</span>, to '''Jiǎnlàng​''' (儉浪) station a further 80 ''li'', to the '''É​huái​''' mountain range (俄淮嶺) a further 70 ''li'', thence down the mountain range to enter the border of '''Yún​nán​''' (雲南; lit.<ref>By received wisdom.</ref> '(The region lying) south (of the) [https://en.wikipedia.org/wiki/Yunling_Mountains ''Yunling Mountains'']'<ref>雲嶺</ref>).</span> |<p style="color:#aaa;font-size:80%;line-height:110%">To reach P'i-tien is 30 ''li''. To reach P'an-ts'ang post-station of Li-chou is 50 ''li''. To reach Li-wu city is 60 ''li''. To reach Pai-t'u post-station is 35 ''li''. (10 ''li'' beyond (the headquarters of) Han-yuan district.) To reach Pen-lang post-station of T'ung-wang district is 40 ''li''. (10 ''li'' from Ta-tu (Big Ferry).) To reach Wang-hsing post-station is 45 ''li''. To reach Ch'ing-ch'i-kuan (frontier gate) is 50 ''li''. To reach Ta-ting city (or fort?) is 60 ''li''. To reach Ta-shih post-station is 50 ''li''. (Here is the boundary between Li-chou and Sui-chou.) To reach Hsin-an city is 30 ''li''. To reach Ch'ing-k'ou post-station is 60 ''li''. To reach Jung Shui post-station is 80 ''li''. To reach Ch'u-li post-station is 35 ''li''. To reach P'ing-lo post-station of T'ai-teng city is 40 ''li''. (It is an old ''hsien'' (district), now abolished.) To reach Su-ch'i post-station is 40 ''li''. (An old ''hsien'' (district).) To reach San-fou city of Sui-chou is 40 ''li''. (The city of the ''chou'' (division) is on the San-fou (Three Mounds) mountain.) To reach Sha-yeh city is 80 ''li''. (The former T'ai-ho-nien (?) of Sui-chou was removed to T'ai-teng. (Query emend: "It was formerly (part of) Sui-chou. During the T'ai-ho period (827-835 A.D.), it was moved to T'ai-teng"?)) To reach Chien-lang post-station is 80 ''li''. To reach O-huai mountain-range is 70 ''li''. Descending from the range, one enters the frontiers of Yunnan.</p> |- |已上三十二驛,計一千八百八十裏<span style="color:#aaa">(案:上文惟三十驛,計一千四百九十五裏,與此數不符)</span>。 |These 32 stations total 1880 ''li'' <span style="color:#aaa">(Former transliterator's note: The text only states 30 stations, totalling 1495 ''li'', thus the total is inconsistent.<ref>This note from the electronic source text in Chinese, by an unknown author, does not discuss any attempt to locate the various places and/or probable distances, which would probably be fruitful given that their notes suggest multiple places are already known. It may be worth mapping this region and attempting to infer the missing distances.</ref>)</span> |<p style="color:#aaa;font-size:80%;line-height:110%">(Above, are 32 post-stations, (the distance) totalling 1880 ''li''.) (Comment: We hold that the above text only mentions 30 post-stations, totalling 1495 ''li''. It does not tally with this number.)</p> |- |並屬西川管,差官人將軍專知驛務。 |All are governed by the '''Xīchuān''' (西川) region, which sends out special inspectors to monitor the transport relay stations' affairs. |<p style="color:#aaa;font-size:80%;line-height:110%">All are dependent on the Hsi-ch'uan administration, which sends out official civil and military, who are specially acquainted with the affairs of the post-stations.</p> |} ====The Yúnnán (雲南) boundary to Yángxiefai (陽苴咩城)==== {| class="wikitable" style="text-align:center; width:80%;" |- ! scope="col" | Original <small>pp. [https://archive.org/stream/06061161.cn#page/n13/mode/1up 13]—[https://archive.org/stream/06061161.cn#page/n14/mode/1up 14]</small> ! scope="col" | Translation ! scope="col" | Luce (1961) — <small>pp. [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=21;node=seap044%3A4;page=root;size=100 7],[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=22;node=seap044%3A4;page=root;size=100 8]+[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=28;node=seap044%3A4;page=root;size=100 14]</small> |- |雲南蠻界:從巂州俄淮嶺七十裏至菁口驛,三十裏至芘驛,六十裏至會川鎮,差蠻三人充鎮。 |The Yunnan barbarian boundary:<ref>Referring to Nanzhao.</ref> From the '''É​huái​''' mountain range (俄淮嶺) of '''Xī​zhōu​''' (巂州; ie. modern Xichang / 西昌<ref>Apparently modern Xichang, in Sichuan (四川省西昌市) ... today most notably the approximate site of a major Chinese spaceport.</ref>) prefecture it is 70 ''li'' to '''Jīng​kǒu​''' (菁口<ref>Literally perhaps 'luxuriant pass' or 'gateway to luxuriance'. There appear to be no less than four modern locations with this name in the approximate area. All candidates are under the modern jurisdiction of Luzhou (泸州市; ''Lúzhōu shì''): two more westerly and thus perhaps more likely candidates are in its Xuyong county (泸州市叙永县; ''Xùyǒngxiàn''), and two are in its Gulin county (古蔺县; ''Gǔlìnxiàn''). Of the westerly Xuyong candidates, the northerly is at 27.9174625N,105.520287E and appears to describe a hill in modern times with a secondary road from the south, the 011县到 or number 11 county-level road, arriving to its west and perhaps delivering travelers to an area of relative flat. The southerly is at 27.80265N,105.5403784E and appears to describe a position at the northern and elevated end of a mountain pass running north/south. Of the easterly Gulin candidates, neither appear to describe logical sites on a northward progression toward the Sichuan basin. [http://www.mala.cn/thread-1116357-1-1.html Apparently] identified by others as equivalent to modern ''Diānshāguān'' / 甸沙关, lying about half-way between Panzhihua and Liangshan, just east of the modern freeway and railway line.</ref>; ie. modern ''Diānshāguān'' / 甸沙关) station, 30 ''li'' to '''Pí''' station (芘驛<ref>[http://www.mala.cn/thread-1116357-1-1.html Apparently] identified as modern ''Bāsōng'' / 巴松 at 27.029898N, 102.260703E.</ref>; ie. modern ''Bāsōng'' / 巴松), 60 ''li'' to '''Huì​chuān​''' village (會川鎮<ref>[http://www.lsrb.cn/html/2008-08/07/content_14368.htm Apparently] [http://www.mala.cn/thread-1116357-1-1.html identified] as modern ''Huìlǐ'' / 会理 at 26.663578N, 102.247416E — from which a very clear topography defines an ancient passage north.</ref>; ie. modern ''Huìlǐ'' / 会理) where three barbarians are commissioned to keep the peace.<ref>This last part was revised after comparing Luce's translation which seemed a more likely interpretation.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">Frontiers of the Man of Yunnan. From the O-huai mountain-range of Sui-chou, after 70 ''li'' one reaches Ching-k'ou post-station. After 30 ''li'' one reaches Pi (''or'' P'i) post-station. After 60 ''li'' one reaches Hui-ch'uan-chen (garrison-town), where they send three ''Man'' men to act as guards.</p> |- |五十五裏至目集驛,七十裏至會川,有蠻充刺史,稱會川都督。 |For 55 ''li'' to '''Mù​jí​''' (目集<ref>[http://www.mala.cn/thread-1116357-1-1.html Apparently identified] as modern ''Fèngshānyíng'' (凤山营) at 26.496801N, 102.134590E. However, this is far more southerly than previously discussed locations and represents a contextual shift within the text if correctly identified. Place name possibly suggests collecting, not very usefully for our purposes implying adjacency to forest (probably mountains, being less likely to be uncultivated land) rather than a flat agricultural area.</ref>; ie. modern ''Fèngshānyíng'' / 凤山营) station, and 70 ''li'' to '''Huì​chuān​''' (會川), the governor is a barbarian,<ref>Revised vs. Luce's interpretation.</ref> who is styled<ref>稱</ref> the ''Commander-in-chief''<ref>都督</ref> ''of Huì​chuān''<ref>會川都督</ref>​. |<p style="color:#aaa;font-size:80%;line-height:110%">After 55 ''li'' one reaches Mu-chi Inn. After 70 ''li'' one reaches Hui-ch'uan, where is a ''Man'' acting as ''Tz'u-shih'', who calls himself the ''Tu-tu'' of Hui-ch'uan.</p> |- |從目集驛至河子鎮七十裏。 |From '''Mù​jí​''' station to '''Hé​zi​''' town (河子鎮<ref>Apparently identified as modern ''Jiāngyì'' / 姜驿 at 26.068453N, 101.910703E.</ref>; ie. modern ''Jiāngyì'' / 姜驿) is 70 ''li''. |<p style="color:#aaa;font-size:80%;line-height:110%">From Mu-chi post-station, to reach Ho-tzu-chen (garrison-town) is 70 ''li''.</p> |- |瀘江,乘皮船渡瀘水,從河子鎮至末柵館五十裏,至伽毗館七十裏,至清渠鋪八十裏,渡繩橋<span style="color:#aaa">(《雲南行記》雲「渠桑驛」)</span>。 |On the '''Lú​jiāng​''' river (瀘江<ref>Identification here was non-trivial. [http://zh.wikipedia.org/wiki/%E6%B3%B8%E6%B1%9F Chinese Wikipedia] suggests that the term has been used in the context of the region to refer to at least two separate rivers, one of which flows from Shiping to Kaiyuan (thus being in completely the wrong area for this discussion), and one of which is a name for a tributary to the Red River within modern Vietnam (again, completely the wrong area). One may then assume that the Lujiang or Lu River under reference is in fact a river known by alternate modern names in the previously geographically established context, ie. that roughly of southern Sichuan's Liangshan Yi Autonomous Region (凉山彝族自治州), or thereabouts. To aid in identification, we could assert that a skin boat of the simple inflated type that is most likely referenced would have been most appropriate for relatively broad river in a relatively mountainous or remote location, given that a settled agricultural zone with higher population, specialist workers and frequent need to cross the water would likely provide rapidly for comfortable crossing by bridge or more permanent/sophisticated watercraft. The answer to the riddle appears to be, [http://baike.baidu.com/subview/186709/15968415.htm according to Baidu Baike], that the major river in the area, the upper Yangtze, locally known as the Jinshajiang (金沙江) since the Song Dynasty (960-1279), was in ancient times from the Three Kingdoms period (220–280) known by this name (amongst others). The period of usage reflected here in the ''Manshu'' accords with this information.</ref>; ie. the modern ''Jīn​shā​jiāng​'' (金沙江) or upper Yangtze), skin boats<ref>Skin boats refers at the most basic and certainly regionally historically attested level to inflated skins or organs of various animals used as buoyancy devices to float across rivers. At the more complex level skin boats may include relatively sophisticated boats made of a bamboo, wood, bone or other type of frame holding without a usually sewn collection of multiple skins including sewing, caulking and heat treatment technologies. In this region, the former is almost certainly the type of boat referenced, as attested by early photographs and probably other types of sources. More sophisticated boats in the region appear to have been limited to Yunnan's major lakes, the Red River (technology via Vietnam) and the edge of the Sichuan basin, these were of wood rather than skin and probably represented a completely different and independent evolutionary lineage of watercraft.</ref> are used to cross to '''Lú​shuǐ​''' (瀘水<ref>In modern times, the name apparently refers to the town of Liuku, capital of Nujiang prefecture in far western Yunnan (bordering Burma's Kachin State). However, such an identification is neither in keeping with the established geographic context or in keeping with the later known traditions of that area to cross rivers by rope bridge (owing to the extreme depth of that gorge and often low temperatures). Given the identification of the river, we can narrow the identification of this town to approximately riverside sites. Since Panzhihua was apparently only founded in the 1960s as a steel-making town, we can rule that out.</ref>). From '''Hé​zi​''' to '''Mòzhà​​guǎn​''' (末柵館) pass is 50 ''li'', onward to '''Jiā​pí​guǎn​''' (伽毗館) pass is 70 ''li'', onward to '''Qīngqúpù''' (清渠鋪) is 80 ''li'', crossing a rope bridge.<ref name="ropebridge">In Luce's translation, the rope-bridge is ascribed to the ''Ch'ing-ch'u-p'u''—''T'sang-p'ang'' portion of the route. However, in the digital version of our Palace Museum Library edition source text, a firmly placed full stop attributes this bridge instead to the ''Jiā​pí​guǎn​'' (伽毗館)—''Qīngqúpù'' (清渠鋪) portion. Without additional sources, we err in favour of our edition but note this point of contention for future readers.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">(As for the) Lu-chiang,<ref>Luce appears to concur with the interpretation as a river rather than a settlement or region.</ref> one rides a leather boat to cross the Lu-shui.<ref>Here Luce departs from our interpretation by implying that his ''Lu-shui'' is another reference to the ''Lu-chiang'' (瀘江) river rather than a place name.</ref> From Ho-tzu garrison-town, to reach Mo-cha (Mo stockade) Inn is 50 ''li''. To reach Ch'ieh-p'i Inn is 70 ''li''. To reach Ch'ing-ch'u-p'u (bed) is 80 ''li''. Crossing the rope-bridge...(The ''Yun-nan hsing chi'' (Diary of a journey to Yunnan) mentions Ch'u-sang post-station.)<ref name="ropebridge"/></p> |- |至藏傍館七十四裏,至陽裒館六十裏,過大嶺,險峻極。 |Onward to '''Cángbàngguǎn''' (藏傍館<ref>Literally 'the pass [near/relying on/of] the storehouse'.</ref>) is a further 74 ''li'', onward to '''Yángpóuguǎn''' (陽裒館<ref>Probably literally 'sunny collection pass', where ''yang'' is taken in its male 'which-side-of-the-mountain' type sense, possibly referring to either the collection of taxes from travelers or the collection of some wild animal, plant or mineral resource by foraging travelers. An alternative and far less likely translation would be a place to collect men (with an emphasis on male), perhaps with reference to the slave-taking traditions of the ''Yi'' people of the region or to a local mercenary tradition.</ref>) is a further 60 ''li'' across the great mountain range which is extremely steep and hard-going.<ref name="steepness">The phrase is 過大嶺,險峻極 which was originally presumably without punctuation and could be interpreted a few ways from the basic components as follows: 過 (to cross) 大嶺 (the or a great mountain range) 險峻 (arduous/steep) 極 (extremely/top). Some may interpret this as crossing "by the steep summit" (though this is likely too specific), others as "with great difficulty" or "it is very steep". I choose a combination of the latter to cover all bases, but acknowledge some ambiguity here.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">... to reach T'sang-p'ang Inn is 74 ''li''. To reach Yang-pao Inn is 60 li. One crosses a big mountain-ridge, which is very dangerous and steep.<ref name="steepness"/></p> |- |從陽裒至弄棟城七十裏,本是姚州,舊屬西川。 |From '''Yángpóu''' (陽裒) to '''Lòngdòng''' city (弄棟城<ref>Probably literally 'alley of buildings city'. Alternatively, this could be '''Nòngdòng''' and have a meaning like 'messy ridgepoles city'.</ref>) is 70 ''li'', now of '''Yáozhōu''' province (姚州<ref>Literally 'good-looking region'.</ref>), though formerly belonging to '''Xīchuān''' (西川<ref>Literally something like 'the western source of rivers'.</ref>).<ref name="longdong">We read 本是 as "currently" and 舊屬 as "formerly of". Luce instead reads both as historic reference, which seems an odd sentence structure to take given the rest of the text.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">From Yang-pao, to reach Lung-tung city is 70 ''li''. It was originally Yao-chou,<ref name="longdong"/> and formerly depended on Hsi-ch'uan.<ref name="longdong"/></p> |- |天寶九載,為姚州都督張乾<span style="color:#aaa">(案:「乾」《唐書》作「虔」)</span>陀附蠻所陷。 |In the ninth year of the ''Tianbao'' (天寶) reign (ie. ~750<ref>Emperor ''Tang Xuán Zōng'' (玄宗)'s ''Tiānbǎo'' (天寶) reign lasted from 742–756. ''Emperor Xuanzong'' (唐玄宗) (8 September 685—3 May 762), also commonly known as ''Emperor Ming of Tang'' (唐明皇), personal name ''Li Longji'' (李隆基), known as ''Wu Longji'' (武隆基) from 690—705, was the seventh emperor of the Tang dynasty in China, reigning from 712—756. His reign of 43 years was the longest during the Tang Dynasty. In the early half of his reign he was a diligent and astute ruler. Ably assisted by capable chancellors like Yao Chong, Song Jing and Zhang Yue, he was credited with bringing Tang China to a pinnacle of culture and power. He was blamed, however, for over-trusting Li Linfu, Yang Guozhong and An Lushan during his late reign, with Tang's golden age ending in the Anshi Rebellion. This marked the beginning of the Tang dynasty's decline.</ref>), the military commander-in-chief of '''Yáozhōu''' (姚州) ''Zhāng​ Qián​'' (張乾) <span style="color:#aaa">(Former transliterator's note: In the ''Tangshu'', 乾 is written as 虔.)</span> was defeated here by the barbarians.<ref name="zhangqian">We interpret 陀附蠻所陷 as 陀 (fell or lost-out) 附 (to) 蠻 (barbarian) 所 ('s) 陷 ([via] defeat in battle). Luce however tacks the first character on to the general's name, probably in error.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">In the 9th year of the T'ien-pao period (750 A.D.), it was lost when the ''Tu-tu'' of Yao-chou, ''Chang Ch'ien-t'o''<ref name="zhangqian"/> fell under the ''Man''. (Comment: We hold that for ''Ch'ien'' the ''T'ang history'' writes ''Ch'ien'')</p> |- |從弄棟城至外彌蕩八十裏,從外彌蕩至求贈館<span style="color:#aaa">(案:此句下有脫文)</span>。 |From '''Lòngdòng''' city (弄棟城) to '''Wàimídàng''' (外彌蕩<ref>This place name could mean 'outer' or 'external' 彌蕩, however this feels like an overly modern interpretation. From dictionary sources, it appears this place name may be something not dissimilar to 'outsiders completely removed', potentially referring to the reinstatement of local governance, but this is not really useful as a clue even if true. This is also the first place, heading from Nanzhao toward Sichuan, that differs from the Vietnam to Nanzhao route description, thus we may assume that it lies northward a little of the primary east-west route — ie. represents a path between '''Qiúzèng''' station (求贈館) and the upper Yangtse. Based upon this latter evidence, and the known association of the previous sites with '''Yáozhōu''' (姚州), it could make sense to place this between modern '''Yáozhōu''' (姚州) — again marked as a walled city on my 1950s maps — and the tentative identification of '''Qiúzèng''' station (求贈館) as '''Pǔ​péng​jiē​''' (普淜街). Approximately precisely half-way between those is '''Mí​xī​zhèn​''' (瀰溪鎮), which seems the most likely candidate, if indeed it existed at all in those days.</ref>; ie. modern ''Mí​xī​zhèn​'' (瀰溪鎮)?) is 80 ''li'', after which one arrives at '''Qiúzèng''' station (求贈館<ref>Apparently literally not unlike 'the place at which presents are sought', ie. taxes or levies are extracted, either legally or by graft. This is also the last place that is shared between the two routes (to Vietnam and to Sichuan) described within the text, thus we may assume that it is in an eastward direction from the Dali area but not significantly north or south. The place known in the 20th century as '''Pǔ​péng​jiē​''' (普淜街; lit. 'Roaring [like waves] street' — possibly implying busyness) seems to be a strong candidate, lying at the natural topographic intersection of the east-south-easterly route toward Kunming and the north-easterly route to the upper Yangtse or Jinshajiang.</ref>; ie. modern ''Pǔ​péng​jiē​'' (普淜街)?). <span style="color:#aaa">(Former transliterator's note: There are characters missing after this position.)</span> |<p style="color:#aaa;font-size:80%;line-height:110%">(From Lung-tung city, to reach Wai-mi-tang is 80 ''li''.) (From Wai-mi-tang, to reach Ch'iu-tseng Inn ... (Comment: We hold that below this clause there are some characters missing))</p> |- |至雲南城七十裏,至波大驛四十裏,至渠藍趙館四十裏,至龍尾城三十裏。 |To the city of '''Yunnan''' (雲南城; ie. modern Yunnanyi) it is 70 ''li'', thence 40 ''li'' to '''Bōdàyì''' (波大驛<ref>Literally 'great storm (postal or relay) station'. Based upon stage distances and topography, I must be a town identified on maps from the 1950s as 'Hsiang-yun' and noted as being a walled town (hence, probably quite old and lending further credence to the identification) — modern Xiangyun County (祥云县) — which lies on the western edge of the swampy (by 1950s map's definition!) depression immediately northwest of that containing Yunnanyi, the southeast of which contains a small lake known as Qinghai (presumably 青海).</ref>), thence 40 ''li'' to '''Qúlánzhào''' station (渠藍趙館<ref>This place is not mentioned in the ''Jiāozhǐ (交阯城) to Yángxiefai (陽苴咩城)'' section, above, instead being replaced by the location '''Báiyányì''' (白嚴驛). It is not possible to compare distances however, because that former section does not quote them. However, it is reasonable to assume that the de-facto unit of measure with regards to places worth mentioning en-route was a caravan-capable day-stage, and that this is reflected inexplicitly within the current section. If these reasonable assumptions are true, then given both the topography and the distances involved, these two place names are fairly likely to be synonyms, ie. '''Qúlánzhào''' station (渠藍趙館) is likely the same as '''Báiyányì''' (白嚴驛). As for a modern identification, the 1950s map I have shows the town of 'Feng-i (Chao-chou)' — modern '''Fengyi''' (凤仪镇) — noted as a walled and therefore a relatively established or ancient town, in the north-south valley proceeding southward from the south-eastern corner of Erhai Lake, ie. the valley which currently houses the Dali Expressway. This is very likely to be the correct identification for at least one of these places, and possibly both. Alternatively, if this identification is incorrect, then the name probably refers to the southern end of that river-valley where it emerges in to another swampy valley with 1950s place names in its north including '''Guǒ​yuán​''' (果园; ie. 'Fruit Orchard') and '''Hóng​yán​''' (红岩; ie. 'Red Cliff'). Unfortunately, that area is now apparently under an expressway and appears to have no identifiable town center.</ref>), thence 30 ''li'' to '''Lóngwěi''' city (龍尾城; lit. 'Dragon's tail city', ie. modern Xiaguan). |<p style="color:#aaa;font-size:80%;line-height:110%">To reach Yunnan city is 70 ''li''. To reach Po-ta post-station is 40 ''li''. To reach Ch'u-lan-chao Inn is 40 ''li''. To reach Lung-wei (Dragon's Tail) city is 30 ''li''.</p> |- |從龍尾城至陽苴咩城五十裏,以上一十九驛,計一千五十四裏<span style="color:#aaa">(案:十九驛,共計一千六十九裏,與此數亦不符)</span>。 |From '''Lóngwěi''' city (龍尾城) to '''Yángxiefai''' city (陽苴咩城; ie. modern Dali) is 50 ''li'', bringing the total for the previous 19 stages to 1054 ''li''. <span style="color:#aaa">(Former transliterator's note: In fact the 19 stages add to 1069 ''li'', an inconsistent total)</span> |<p style="color:#aaa;font-size:80%;line-height:110%">(From Lung-wei city, to reach Yang Chu-mieh city is 50 ''li''.) (The above 19 post-stations total (a mileage of) 1054 ''li''.) (Comment: We hold that there are 19 post-stations, totalling 1069 ''li''. This, too, does not tally with the number given.)</p> |} ====Beyond ''Yáozhōu'' (姚州)==== {| class="wikitable" style="text-align:center; width:80%;" |- ! scope="col" | Original <small>p. [https://archive.org/stream/06061161.cn#page/n14/mode/1up 14]</small> ! scope="col" | Translation ! scope="col" | Luce (1961) — <small>pp. [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=22;node=seap044%3A4;page=root;size=100 8]+[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=28;node=seap044%3A4;page=root;size=100 14]</small> |- |南蠻因姚州之後,屬蠻管系。 |The Southern Barbarians (南蠻; ie. Nanzhao's peoples) beyond '''Yáozhōu''' (姚州; lit. 'the beautiful region'; ie. the modern Yao'an County<ref>[http://baike.baidu.com/subview/3482306/16192459.htm Baidu Baike] and the Chinese academic source [http://www.kaogu.net.cn/cn/xccz/20151116/52040.html Kaogu] concur here, apparently on an area directly to the east of the modern town (see [http://www.kaogu.net.cn/uploads/cn/201511/20151116yn9.jpg Kaogu map]).</ref> area northwest of Chuxiong, roughly equidistant between the Dali/Erhai Lake and Kunming/Dianchi Lake plateaux), are subordinate to the barbarians (ie. subordinate to Nanzhao). |<p style="color:#aaa;font-size:80%;line-height:110%">Because the Southern ''Man'', after Yao-chou, became dependent on and attached to the ''Man'' administration...<ref name="2routes">Here Luce runs together the interpretation of a statement regarding the lands west ("beyond") Yaozhou/Yao'an, and two subsequent statements referring to roads to the east/northeast. This appears to be in error.</ref></p> |} ===Roads from Yōngzhōu (邕州) and Qiánzhōu (黔州)=== {| class="wikitable" style="text-align:center; width:80%;" |- ! scope="col" | Original <small>p. [https://archive.org/stream/06061161.cn#page/n14/mode/1up 14]</small> ! scope="col" | Translation ! scope="col" | Luce (1961) — <small>pp. [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=22;node=seap044%3A4;page=root;size=100 8]+[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=28;node=seap044%3A4;page=root;size=100 14]</small> |- |從邕州路至蠻苴咩城,從黔州路至蠻苴咩城,兩地途程,臣未諳。 |The roads from both '''Yōngzhōu''' (邕州; ie. the modern Guangxi region<ref>Meaning Nanning or the general direction of Guangxi province.</ref>) and '''Qiánzhōu''' (黔州; ie. the modern Guizhou region<ref>Meaning Guizhou province.</ref>) to '''Yángxiefai''' city (陽苴咩城; ie. modern Dali) are both unclear. |<p style="color:#aaa;font-size:80%;line-height:110%">... your humble servant could not be expert or familiar with the stages of the two land-routes:<ref name="2routes"/> (i) the Yung-chou road to Chü-mieh city of the Man, and (ii) the Ch'ien-chou road to Chü-mieh city of the Man.</p> |- |委伏乞下堂帖令分析。 |Perhaps an order should be issued to investigate these.<ref>I'm a little vague about the first part 委伏乞下堂 — but overall meaning seems on the mark — 委伏 (some kind of deferential personal pronoun phrase) 乞 (beg) 下堂 (issue downward 'from the palace') ...</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">I humbly beg Your Majesty to send down an official notification ordering a detailed survey.</p> |} ===Politics=== Note that this entire portion is taken to have been a latter explanatory diversion, and not part of the main body of text. {| class="wikitable" style="text-align:center; width:80%;" |+ Chapter 1: ''Distances within Yunnan and at its Borders'' (云南界内途程; ''yúnnán jiè nèi túchéng'') — Politics |- ! scope="col" | Original <small>p. [https://archive.org/stream/06061161.cn#page/n15/mode/1up 15]</small> ! scope="col" | Translation ! scope="col" | Luce (1961) — <small>pp. [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=22;node=seap044%3A4;page=root;size=100 8],[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=23;node=seap044%3A4;page=root;size=100 9]+[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=28;node=seap044%3A4;page=root;size=100 14]</small> |- |緣南蠻奸猾,攻劫在心,田桑之余,便<span style="color:#f00">習</span><ref name="changwrong"/>鬥敵。 |Due to the Southern Barbarians' (南蠻; ie. Nanzhao) treacherous nature, with attack and plunder ever-present in their minds, whenever mulberries<ref>This is an interesting choice of crop to describe harvest season with, and could be a visual flourish implying evil or a thirst for blood; as the color of the fruit is similar to blood. Wikipedia states: "Mulberry fruit color derives from ''anthocyanins'' which are under basic research for mechanisms of various diseases. Anthocyanins are responsible for the attractive colors of fresh plant foods, including orange, red, purple, black, and blue. These colors are water-soluble and easily extractable".</ref> in the fields are plentiful they will seize the opportunity to drill<ref name="changwrong">The digital source text wrongly replaces the 習 (as written in the digital Palace Museum Library edition [https://archive.org/stream/06061161.cn#page/n15/mode/1up over here, at the bottom of the second column from the right]) with 昌 (''chang1'') ("flatter" or "flourishing").</ref> against their enemies. |<p style="color:#aaa;font-size:80%;line-height:110%">Because the Southern ''Man'' are cunning and treacherous, and (the idea of) attacking and plundering is ever present in their minds, whenever they have some leisure from (cultivating their) fields and mulberry trees, they practise fighting the enemy.</p> |- |若不四面征戰,兇惡難悛。 |If not engaged from all sides, the ferocious evil<ref>Meaning Nanzhao.</ref> will be difficult to resolve.<ref>Obviously all sides (literally 四面 or 'four directions') is essentially impossible when one of them is the Himalayas and the other is tropical, malaria-ridden jungle. It may therefore either be assumed that the writer, Fan Chuo, was not particularly familiar with north-western, western, south-western and southern Yunnanese geography... or alternatively, that this is a figurative statement.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">If, then, we do not invade and attack them from all four sides, they are violent and bad persons, and difficult to reform.</p> |- |所以錄其城鎮川原,麈黷宸扆。 |Thus: record their cities, towns, rivers and their sources; that stags will defile their palace screens.<ref>Apparently a contemporary metaphor suggesting the end of empire. The structure of the metaphor perhaps suggests that — to the civilization-obsessed Chinese, who viewed literature as its cornerstone — being overrun by wild animals is fate worse than being overrun by a rival kingdom.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">That is why I record their cities and garrison-towns, their river-valleys and plains--mere dust defiling the audience-screen of the Imperial apartments.</p> |- |或冀破其蟻聚之眾,永清羌虜之夷。 |Thus we may destroy the ant<ref>Strange as it seems, Fan Chuo here appears to liken the Nanzhao kingdom (and any allied tribes) to ants.</ref> masses (ie. Nanzhao's people), clean<ref>ie. Pacify.</ref> forever the region<ref>The character 羌 represents the Qiang region (ie. the greater eastern Himalayan foothills, particularly from northern Yunnan through Sichuan to Gansu). However, it is also used to represent [https://en.wikipedia.org/wiki/Muntjac muntjac], and thus may be some kind of reference to the former sentence ("...that stags will defile their palace screens"), perhaps an instance of olden-day literary jest!</ref> and capture the barbarians.<ref>ie. Nanzhao people.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">Perhaps one might hope to wipe out their host of ant-swarms, and purge for ever (these) ''Ch'iang'' barbarian rebels.</p> |- |臣披瀝懇忱,無任隕越之至<span style="color:#aaa">(案:此條乃附載陳說之詞,如後世著書之案語,原本誤連正文,遂令文義格礙,今低一格以別之,後仿此)</span>。 |Sincerely, your humble servant, in the hopes of avoiding slaughter.<ref>Vague, particularly the last portion. A more experienced and confident translator may be able to add detail here.</ref> <span style="color:#aaa">(Former transliterator's note: This section is an addition containing commentary, similar to 'notes' in later written formats. Our original mistakenly conjoined it, causing issues of comprehension. Thus in the present edition we drop the text by one line, and will hereupon continue with this typographic convention.)</span> |<p style="color:#aaa;font-size:80%;line-height:110%">Your humble servant speaks without reserve and implores Your Majesty with all sincerity that he may not be held responsible even though he lapse into the most extreme error. (Comment: We hold that this paragraph is by way of a supplement, containing an explanatory statement, like the formal statements of books composed in latter generations. In the original copy it was wrongly included in the main body of the text, and consequently interfered with the sense of the text. Now we have lowered it one line in order to distinguish it. In future we shall follow this method.)</p> |} ===The Stone Gate (石門) and the Kunming-Xichuan Route (昆川至雲南)=== [[File:Eastern Yunnan - Route from Kunming to Zhaotong (Scan of Lithograph of Photograph by Gervais-Courtellemont. Printed by Bong and Company, Paris, 1913).jpg|thumb|center|800px|1913 lithographic print by Bong and Company, Paris, of a photograph by Gervais-Courtellemont, titled in French but equating to 'Eastern Yunnan: Route from Kunming to Zhaotong'.]] (note: here we shall have a new map! currently under development...) {| class="wikitable" style="text-align:center; width:80%;" |- ! scope="col" | Original <small>pp. [https://archive.org/stream/06061161.cn#page/n15/mode/1up 15]—[https://archive.org/stream/06061161.cn#page/n21/mode/1up 21]</small> ! scope="col" | Translation ! scope="col" | Luce (1961) — <small>pp. [http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=23;node=seap044%3A4;page=root;size=100 9]-[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=25;node=seap044%3A4;page=root;size=100 11]+[http://seapdatapapers.library.cornell.edu/cgi/t/text/pageviewer-idx?c=seap;cc=seap;rgn=full%20text;idno=seap044;didno=seap044;view=image;seq=28;node=seap044%3A4;page=root;size=100 14]</small> |- |從石門外出魯望、昆川至雲南,謂之北路。 |Outside (ie. south<ref>Based upon the assumption that the author writes from a contemporary Chinese imperial perspective, which seems supported by later text in this section.</ref>) of the '''Shímén''' (石門; lit. (the) stone gate<ref>Referring to an historic pass located near '''Dòushā Village''' (豆沙真) in modern '''Yán​jīn County''' (盐津县) of '''Zhāo​tōng​''' (昭通) along the '''Héngjiāng River''' (横江), the last major tributary to the upper Yangtze before '''Yíbīn''' (宜宾) and the Sichuan basin proper. In ancient times, this Yunnan-Guizhou plateau/Sichuan basin transition area was the domain of the Bo people, whose neolithic but similarly cliff-inspired culture incorporated hanging cliff tombs, a tradition still preserved to this day in only one location by an offshoot emigrant community who moved to Bainitang in Wenshan prefecture, southeastern Yunnan. Sadly that community is now endangered by open cut mining. See for example [http://www.travelyunnan.org/yunnantour/zhaotong/nujiang/2856.html this Chinese source] for further information on the pass itself, which is discussed further subsequently in this section of the text. For maps, see [http://ids.lib.harvard.edu/ids/view/2419066?buttons=y Harvard's historical US military topographic map of the area] (zoom in to the southwest of Yen-ching at the bottom), [https://www.openstreetmap.org/#map=15/28.0362/104.1209&layers=C OpenStreetMap] or [https://www.google.com/maps/@28.0329213,104.1271244,3109m/data=!3m1!1e3 Google Maps].</ref>) is '''Lǔwàng''' (魯望; ie. Qujing?) and the '''Kunming'''-'''Xichuan'''<ref>Inferred from context, 昆 and 川 respectively being used to refer to Kunming and Sichuan in modern times, but Xichuan being the apparently closest contemporary toponym discussed in the text.</ref> '''Route''' to '''Yunnan''' (probably '''Yún​nányì​​'''; 云南驿<ref>Possibly referring to the town of '''Yunnanyi''' (云南驿), acknowledged as an historically critical transport juncture including acting as the terminus for roads to Sichuan, Dali and Kunming, and geographically something of an eastern gateway to the Erhai Plateau (modern Dali and Xiaguan) that was the seat of Nanzhao's power. For example, [http://en.ynta.gov.cn/Item/578.aspx this modern government source] states "Yunnan Yi used to be a must-take position since it can connect Dali, Chengdu, Kunming, South and West Yunnan".</ref>), also known as the '''Northern Road''' (北路). |<p style="color:#aaa;font-size:80%;line-height:110%">From beyond Shih-men (Stone Gate), to go out via Lu-wang and K'un-ch'uan and reach Yunnan, is called the North Road.</p> |- |黎州、清溪關出邛部,過會通,至雲南,謂之南路。 |Leaving the '''Qīngxīguān''' (清溪關; lit. 'Clear Stream Pass') of '''Lízhōu''' (黎州; lit. 'Black Region'), one reaches '''Qióngbù''' (邛部), '''Huitong''' (會通), then '''Yúnnányì''' (云南驿). This route is known as the '''Southern Road''' (南路). |<p style="color:#aaa;font-size:80%;line-height:110%">From the Ch'ing-ch'i-kuan (frontier-gate) of Li-chou to go out via Chiang-pu, pass through Hui-t'ung and reach Yunnan, is called the South Road.</p> |- |從戎州南十日程至石門,上有隋初刊記處,雲:「開皇五年十月二十五日,兼法曹黃榮領始、益二州石匠,鑿石四孔,各深一丈,造偏梁橋閣,通越析州、津州。」蓋史萬歲南征出於此也。 |From '''Róngzhōu''' (戎州; lit. "The Military City"; ie. modern Yibin, Sichuan<ref>今四川宜宾市</ref>) southward it is 10 days' travel to '''Shímén''' (石門; lit. the Stone Gate). An inscription above from the early Sui dynasty reads: "On the 5th year, 10th month, 25th day of the of the Kaihuang emperor (ie. ~587CE),<ref>Emperor Wen of Sui (隋文帝; 21 July 541 – 13 August 604), personal name Yang Jian (楊堅), Xianbei name Puliuru Jian (普六茹堅), nickname Naluoyan (那羅延), the founder and first emperor of China's Sui Dynasty (581–618 AD).</ref> The official titled '''Jiānfǎ''' (兼法; perhaps Grand Juror?), '''Cáohuángróng''' (曹黃榮), led the stonemasons of the two provinces of '''Shǐ​zhōu​''' (始州) and '''Yì​zhōu''' (益州) to bore four very deep holes of one ''zhàng'' (around 3 to 3.7 meters) each in depth,<ref>Apparently the foundations of the bridge. It may be interesting or relevant to note that the area of southern Sichuan not very distant to the north was actually the world's earliest site of the development of deep drilling technology, for the purpose of commercial salt wells. A great museum exists to this effect in modern '''Zìgòng''' (自貢), a city which in 1939 became the merged successor of the earlier — ie. relatively textually contemporary — cities of '''Zìliújǐng''' (自流井; lit. 'artesian well') and '''Gòngjǐng''' (貢井; lit. 'tribute well'). It might be arguably be possible to therefore infer that Fan Chuo was not familiar with deep drilling capacity common in the region.</ref> and constructed a slanting bridge with a pavilion to reach '''Yuèxīzhōu''' (越析州; lit. 'Province of the Divided Peoples'<ref>Implying perhaps extreme topography and ethnic diversity.</ref>) and '''Jīnzhōu''' (津州; lit. 'Province of the River-Crossing')." '''Shǐ Wànsuì''' (史萬歲) passed through here.<ref>'''Shǐ Wànsuì''' (史萬歲; b. 549, d. 600-11-20) was a famous and skilled Sui Dynasty military strategist, inheritor of the position of ''Duke of the Pacified Regions'' from his father '''Shǐ Jìng''' (史靜), and fathered a son '''Shǐ Huáiyì''' (史懷義). See [https://zh.wikipedia.org/zh-tw/%E5%8F%B2%E8%90%AC%E6%AD%B2 Traditional Chinese Wikipedia].</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">To the south of Jung-chou, after 10 day-stages one reaches Shih-men (Stone Gate). Above it there is an inscription of the beginning of the Sui dynasty (fl. 589-618A.D.), which says: "The 25th day of the 10th month of the 5th year of K'ai-huang (Nov. 22nd., 585 A.D.). Huang Jung, prefect in charge of Shih-chou and I-chou, with the combined office of Fa-ts'ao (? Member of the Board of Law)." Stone-masons bored four holes in the stone, each 10 ft. in depth, and constructed the leaning bridge with covered way connecting Yueh-hsi-chou and Ching-chou. It is the place from which Shih Wan-sui started on his expedition to the south.</p> |- |越析州今西河河東一日程,越析州諮長故地也。 |'''Yuèxīzhōu''' (越析州) is one day's easterly travel beyond present-day<ref>Meaning Tang dynasty, versus Sui dynasty &mdash; the period just quoted.</ref> '''Xī​hé​ River''' (西河; lit. 'Western River'), the former lands of the '''Zī​zhǎng​''' (諮長; lit. 'Chief of Consultation', perhaps 'Chief of Affairs'). |<p style="color:#aaa;font-size:80%;line-height:110%">(As for) Yueh-hsi-chou, after crossing (?) the Hsi-ho (West River), (it is) 1 day-stage east of the Ho. Yueh-hsi-chou is the former land of the Tzu-chang (Senior Counsellor?). </p> |- |津州未詳其處。 |The location of '''Jīnzhōu''' (津州) is unknown.<ref>Though from its "River-crossing Province" name we can infer that it was an important river crossing point of the area, which probably significantly narrows potential locations.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">As for Ching-chou I have no knowledge of its topography.</p> |- |天寶中,鮮於仲通南溪下兵,亦是此路,後遂閉絕。 |During the Tiānbǎo era (ie. 742–756<ref>The last of three era names during the reign of '''[https://en.wikipedia.org/wiki/Emperor_Xuanzong_of_Tang Emperor Tang Xuanzong]''' (玄宗, Xuánzōng)</ref>; ie. circa 750), the army of '''Xiān​yū​zhòng​''' (鮮於仲) came down through '''Nán​xī​''' (南溪<ref>Now a county in Yibin, Sichuan.</ref>) and used this road, but they were utterly destroyed.<ref>Possibly blocked rather than destroyed, but I feel "utterly destroyed" is the probable sense from 閉絕 &mdash; (stopped or obstructed)(entirely).</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">During the T'ien-pao period (742-755 A.D.) Hsien-yu Chung-t'ung, from Nan-ch'i, sent down troops; this was the route. Afterwards it got blocked and (communications) interrupted for nearly 50 years.</p> |- |僅五十年來,貞元十年,南詔立功歸化,朝廷發使冊命。 |Only 50 years ago in the 10th year of Zhengyuan era<ref>The Zhēngyuán (貞元) 785-805 era of Dezong. From Wikipedia: "Emperor Dezong of Tang (唐德宗) (May 27, 742 – February 25, 805), personal name Li Kuo (李适), was an emperor of the Chinese Tang Dynasty and the oldest son of his father Emperor Daizong. His reign of 26 years was the third longest in the Tang dynasty (surpassed only by Emperor Xuanzong and Emperor Gaozong). Emperor Dezong started out as a diligent and frugal emperor and he tried to reform the governmental finances by introducing new tax laws. His attempts to destroy the powerful regional warlords and the subsequent mismanagement of those campaigns, however, resulted in a number of rebellions that nearly destroyed him and the Tang Dynasty. After those events, he dealt cautiously with the regional governors, causing warlordism to become unchecked, and his trust of eunuchs caused the eunuchs' power to rise greatly. He was also known for his paranoia about officials' wielding too much power, and late in his reign, he did not grant much authority to his chancellors."</ref> (ie. 795CE), Nanzhao submitted its sovereignty to China and their court dispatched envoys to announce the proclamation. |<p style="color:#aaa;font-size:80%;line-height:110%">In the 10th year of Cheng-yuan (794 A.D.) Nan-chao acted meritoriously and returned to its allegiance (to China). The Court sent out envoys and orders of appointment.</p> |- |而邛部舊路方有兆吐蕃請鈔隔關。 |Owing to the prosperity of the old '''Qióngbù''' (邛部) road, the '''Tǔbō''' (吐蕃; ie. post-Tibetan Empire Kham Tibetans) demanded money at the passes. |<p style="color:#aaa;font-size:80%;line-height:110%">And the old road of Chiung-pu for the moment was thriving. But the Tibetans appropriated the cash and blocked the frontier-gates.</p> |- |其年七月,西川節度韋臯乃遣巡官監察禦史馬益閉石門路,量行館。 |On the 7th month of that year, '''Wéigāonǎi''' (韋臯乃) of the '''Xichuan''' government's Jiedu (節度) department dispatched the official '''Shǐmǎyì''' (史馬益) to supervise, defend and close the '''Shímén''' (石門; lit. (the) stone gate) '''Road''' and its '''Liàngxíng''' garrison (量行館; lit. measure traffic garrison<ref>Quite possibly indicating a point of road toll style taxation.</ref>). |<p style="color:#aaa;font-size:80%;line-height:110%">So in the 7th month of that year (Aug. 1 to 29, 794), Wei Kao, the Chieh-tu of Hsi-ch'uan, sent the Hsun-kuan (Inspecting Officer), the Chien-ch'a-yu-shih (Examining Censor) Ma I, to close the Liang-hsing-kuan (Inn) of the Shih-men (Stone Gate) road.</p> |- |石門東崖石壁,直上萬仞,下臨朱提江流,又下入地中數百尺,惟聞水聲,人不可到。 |<span style="color:#f0f">[luce translation review up to here]</span>The rock cliffs to the east of the '''Shímén''' (石門; lit. (the) stone gate) are of extreme height,<ref>Actual term used is 10,000 (萬; wàn) ''rèn''-fathoms (仞; ancient unit of measure equal to approximately 8 modern feet, or 2.4 meters). Given the figures, this is clearly a figurative use rather than a literal one.</ref> beneath which the '''Zhuti River''' (朱提江; ie. early upper Yangtze or Jinsha river<ref>Apparently the name given to the upper Yangtze (ie. Jinsha) river in the vicinity of modern Shuifu prefecture, Zhaotong city, Yunnan. This is only a few kilometers from modern Yibin (宜宾市) in Sichuan province, ie. would have represented the initial stages of a southbound journey from the Han China controlled Sichuan basin (previously stolen from the ancient and endemic Shu kingdom) toward Yunnan. A good flowery description of the area in early Han perception is available in the ''Classic of Mountains and Seas'' (山海經), ca. 4th century BCE.</ref>) flows only to enter the earth again through a hundred caverns. Listening to the sound of the water here, one is swept beyond the world of men. |<p style="color:#aaa;font-size:80%;line-height:110%">The east cliff of Shih-men is a sheer precipice rising ten thousand fathoms. Below, it borders the Chu-t'i-chiang. The stream moreover flows underground for several hundred feet. You can only hear the sound of the water, but no man can reach it.</p> |- |西崖亦是石壁,傍崖亦有閣路,橫闊一步,斜亙三十余裏,半壁架空欹危虛險,其安梁石孔,即隋朝所鑿也。 |The rock cliffs to the west are also vertical. The road along their precipice sports pavilions and is but one pace wide, and over 30 ''li'' in length. Half the cliff stands bare forming a dangerous narrow pass, through which a safe passage was bored during the Sui dynasty. |<p style="color:#aaa;font-size:80%;line-height:110%">The west cliff is also a stone precipice. Along the side of the cliff there is a covered road, 1 pace broad. It goes up and down and round for over 30 li. Halfway along the cliff there is a gap in the frame of the road, with a dangerous topple and an awful void. The stone holes on which the bridge rests, were bored under the Sui dynasty.</p> |- |閣外至夔嶺七日程,直經朱提江,下上躋攀,傴身側足,又有黃蠅、飛蛭、毒蛇、短狐、沙虱之類。 |Beyond the pavilion it is 7 days' journey to the '''Kuílǐng Range''' (夔嶺; lit. monstrous mountain range), passing the '''Zhuti River''' (朱提江; ie. upper Yangtse or Jinsha river) through steep topography, a back-breaking journey featuring yellow flies, flying leeches, venomous snakes, foxes, and all manner of parasites. |<p style="color:#aaa;font-size:80%;line-height:110%">Beyond the covered road, one reaches K'uei-ling (range) in 7 day stages. One goes straight across the Chu-t'i-chang at the bottom, and then starts clambering up with a hunched body and feet awry. There are also yellow flies, flying leeches, poisonous snakes, short foxes (?), sand-lice, etc. etc.</p> |- |石門外第三程至牛頭山,山有諸葛古城,館臨水,名馬安渡。 |On the third day one reaches '''Niútóu Shān''' (牛頭山; lit. Ox-head Mountain), which features the ancient '''Zhūgé''' city (諸葛古城<ref>Presumably a reference to a settlement or military garrison dating back to the time of Zhuge Liang (諸葛亮), whose two-character family name 諸葛 was shared by his relatives. From Wikipedia: "Zhuge Liang (181–234), courtesy name Kongming (孔明), was a chancellor of the state of Shu Han during the Three Kingdoms period. He is recognised as the greatest and most accomplished strategist of his era, and has been compared to another great ancient Chinese strategist, Sun Tzu."</ref>). There is a building near the water at a place known as '''Mǎāndù''' (馬安渡; lit. Peaceful Horse Crossing). |<p style="color:#aaa;font-size:80%;line-height:110%">At the third stage beyond Shih-men one reaches Niu-t'ou-shan (Cow's Head Mountain). On the mountain there is the old city (or fort) of Chu-ko (Liang) with the inn (kuan) on the brink of the stream. It is called Ma-an (Horse-saddle) Ferry.</p> |- |上源從阿等路部落,繞蒙夔山,又東折與朱提江合。 |The road follows the head of '''Kuílǐng Range''' (夔嶺; lit. monstrous mountain range) as it descends, wrapping about the mountain, bending eastward again to follow the '''Zhuti River''' (朱提江; ie. upper Yangtse or Jinsha river). |<p style="color:#aaa;font-size:80%;line-height:110%">The source comes down from the (habitat of the) tribes of Ah and other roads. It winds around the Meng-k'uei mountains, and breaking eastwards joins the Chu-t'i-chiang.</p> |- |第五程至生蠻阿部落,第七程至蒙夔嶺,嶺當大漏天,直上二十裏,積陰凝閉,晝夜不分。 |On the fifth day one reaches '''Shēngmán'ē''' (生蠻阿; lit. (perhaps) Barbarian Birth Mountain), and on the seventh day '''Méngkuílǐng''' (蒙夔嶺; lit. Ignorant Monster Mountain) whose ridge is like a great sky-funnel rising 20 ''li'', accumulating ''yin''<ref>ie. Ancient Chinese concept from the ''Book of Changes'' (易經; diviniation text dating from at least 1000BCE). In general use it means a female energy — darness, water, etc.</ref> and freezing it in place such that the night and day are no longer distinct. |<p style="color:#aaa;font-size:80%;line-height:110%">At the fifth stage one reaches the wild Man, the Ah tribes. At the seventh stage one reaches the Meng-k'uei mountain-range. The range is completely open to the sky, standing straight up for 20 li. Its accumulated shade congeals solid, so there is no difference between day and night.</p> |- |從此嶺頭南下八九裏,青松白草,川路漸平。 |From the head of this mountain range, one descends through peaceful pine forests and white grasses, and the '''Chuan Road''' (川路; lit. the road of the upper rivers; fig. the road to/from Xichuan or Sichuan) gradually becomes flat. |<p style="color:#aaa;font-size:80%;line-height:110%">From the top of this range one descends south 8 or 9 li through green pines and white grasses, while the valley-road gradually levels out.</p> |- |第九程至魯望,即蠻、漢兩界,舊曲靖之地也。 |On the ninth day one reaches '''Lǔwàng''' (魯望) — former '''Qujing''' (曲靖) — which is the border separating two worlds: the Chinese, and the barbarian. |<p style="color:#aaa;font-size:80%;line-height:110%">At the ninth stage one reaches Lu-wang, which is the common border between the Man and the Chinese, the land of the old Ch'u (and) Ching.</p> |- |曲州、靖州廢城及邱墓碑闕皆在。 |The abandoned cities of the '''Qūzhōu''' (曲州) and '''Jìngzhōu''' (靖州) regions are but mounds with lettered gravestones. |<p style="color:#aaa;font-size:80%;line-height:110%">The abandoned cities of Ch'u-chou and Ching-chou, and the burial mounds and tombs with their stone tablets and gates(?), are all still extant.</p> |- |依山有阿竿路部落,過魯望第七程至竹子嶺,嶺東有暴蠻部落,嶺西有盧鹿蠻部落。 |In the mountains is the '''Ēgān Road''' (阿竿路; lit. Mountain Bamboo Road) along which, seven days beyond '''Lǔwàng''' (魯望; ie. roughly Qujing), lies the '''Zhúzilǐng Range''' (竹子嶺; lit. Bamboo Range). East of this range are savage barbarians, and west of this range are the '''Lúlù Barbarians''' (盧鹿蠻; ie. Yi people<ref>Operating on the assumption that until recent times Yi were referred to as Luoluo or Lolo in many sources, and we're in the right area here.</ref>). |<p style="color:#aaa;font-size:80%;line-height:110%">Resting on the mountains there are the A-kan road tribes. After passing Lu-wang, at the 7th stage, one reaches Chu-tzu-ling (Bamboo mountain-range). To the east there are the tribes of savage Man. To the west of the range there are the tribes of Lu-lu Man.</p> |- |第六程至生蠻磨彌殿部落,此等部落皆東爨烏蠻也。 |On the sixth day one reaches '''Mómídiàn''' (磨彌殿) of the wild barbarians, which along with other areas belongs to the '''Dark Eastern Civilizing Barbarians''' (東爨烏蠻; ''dōng cuàn wū mán''). |<p style="color:#aaa;font-size:80%;line-height:110%">At the 6th stage one reaches the wild Man, the Mo-mi-tien tribes. These various tribes are all Eastern Ts'uan, Wu Man (Black Barbarians).</p> |- |男則發髻,女則散發,見人無禮節拜跪,三譯四譯,乃與華通。 |Their men wear their hair in a topknot, whereas their women leave it loose. It is understood that they have no custom of respect such as to kneel or bow, and when speaking with us make sounds like ''sānyìsìyì''. |<p style="color:#aaa;font-size:80%;line-height:110%">The men have dressed hair, the women have their hair loose. When they meet people, they have no rules of etiquette. They (just) bow and kneel. They need three or four interpreters in order to communicate with the Chinese.</p> |- |大部落則有鬼主,百家二百牛馬<span style="color:#aaa">(案:此句未詳)</span>,無布帛,男女悉披牛羊皮。 |The greater area has but one overlord, controlling one hundred houses and two hundred oxes and horses. <span style="color:#aaa">(Former transliterator's note: Sheep are not mentioned here.)</span> They have no textiles, and man and woman alike wear the skin of sheep and oxen. |<p style="color:#aaa;font-size:80%;line-height:110%">A big tribe will have a "Devil-Lord", (administering) 100 families with 200 cattle or horses. (Comment: We hold that this sentence is not definite.) They have no cotton cloth nor silk. Men and women all wear the skins of cattle or sheep.</p> |- |第九程至制長館,於是始有門閣廨宇迎候供養之禮,皆漢地。 |On the ninth day one reaches '''Zhìzhǎngguǎn''' station (制長館) — a place of gates, pavilions, offices, welcome, resupply and proper manners — all people here are Han Chinese. |<p style="color:#aaa;font-size:80%;line-height:110%">At the ninth stage one reaches Chih-ch'ang-kuan (Inn). Here for the first time we find gates and pavilions, government buildings and houses. The etiquette of waiting and welcoming, of making presents and entertaining, are all (like) those of China.</p> |- |凡從魯望行十二程方始到柘東。 |In total it is 12 days' journey from '''Lǔwàng''' (魯望; ie. Qujing?) to '''Tuodong''' (柘東<ref>Note that in other places the character 柘 is replaced with 拓 — ie. 拓东 — however the meaning here seems clear.</ref>; ie. Kunming). |<p style="color:#aaa;font-size:80%;line-height:110%">From Lu-wang, going altogether 12 stages, one then first reaches Che-tung.</p> |- |黎州南一百三十裏有清溪峽,乾元二年置關。 |130 ''li'' south of the '''Lizhou''' region (黎州; lit. black region) lies '''Qīngxīxiá''' gorge (清溪峽; ie. clear stream gorge), which was closed in the second year of the Qianyuan era (ie. ~759).<ref>The 乾元 (Qiányuán) era lasted from 758–760, and was one of the era names for the reign of Emeperor Suzong. From Wikipedia: "Emperor Suzong of Tang (唐肅宗; February 21, 711 – May 16, 762; r. 756 – 762), personal name Li Heng (李亨), né Li Sisheng (李嗣升), known as Li Jun (李浚) from 725 to 736, known as Li Yu (李璵) from 736 to 738, known briefly as Li Shao (李紹) in 738, was an emperor of the Tang Dynasty and the son of Emperor Xuanzong. Suzong ascended the throne after his father fled to Sichuan during the An Shi Rebellion in 756; Li Heng himself had fled in the opposite direction, to Lingwu, where he was declared emperor by the army. Much of Emperor Suzong's reign was spent in quelling the aforementioned rebellion, which was ultimately put down in 763 during the reign of his son Emperor Daizong."</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">130 li south of Li-chou there is Ch'ing-ch'i gorge. Here, in the 2nd year of Ch'ien-yuan (759 A.D.) there was set up a frontier-gate (kuan).</p> |- |關外三十裏即巂州界也。 |30 ''li'' beyond the pass is the border of '''Guīzhōu''' (巂州; ie. not modern Guizhou province, but rather the modern Xichang-Meigu region of southern Sichuan<ref>According to [https://zh.wikipedia.org/wiki/%E5%B7%82%E5%B7%9E Chinese Wikipedia].</ref>). |<p style="color:#aaa;font-size:80%;line-height:110%">30 li beyond the frontier-gate, is the border of Sui-chou.</p> |- |行三百五十裏至邛部川,故邛部縣之地也。 |A further 350 ''li'' brings you to '''Qióngbùchuān''' (邛部川; lit. Qiongbu upper-river region), formerly known as '''Qióngbùxiàn''' (邛部縣; lit. Qiongbu county). |<p style="color:#aaa;font-size:80%;line-height:110%">Going 350 li, one reaches Chiung-pu-ch'uan (valley and stream). It is the land of the old Chiung-pu hsien.</p> |- |下南一百三十裏至臺登,西南八十裏至普安城,劍南西川節度使重兵大將鎮焉。 |Southward 130 ''li'' lies '''Táidēng''' (臺登), and [a further?] southwest 80 ''li'' lies '''Pǔ'ānchéng''' (普安城), a large and important military garrison under the '''Jiànnán''' / '''Xīchuān''' (劍南西川) commandery (節度; jiédù). |<p style="color:#aaa;font-size:80%;line-height:110%">Descending south 130 li, one reaches T'ai-teng. 80 li to the south-west, one reaches P'u-an city. The Chieh-tu-shih of Hsi-ch'uan of Chien-nan kept a garrison here with double reinforcements and a big general.</p> |- |臺登直北去保塞城八十裏,吐蕃謂之北谷,天寶以前巂州柳強鎮也。 |Directly north from '''Táidēng''' (臺登) at a distance of 80 ''li'' lies '''Bǎosāi''' city (保塞城). The '''Tǔbō''' (吐蕃; ie. post-Tibetan Empire Kham Tibet) hold its '''Northern Gorge''' (北谷). It was formerly known as '''Liǔqiáng''' town (柳強鎮) of '''Guīzhōu''' (巂州). |<p style="color:#aaa;font-size:80%;line-height:110%">T'ai-teng, due north, is 80 li distant from Pao-sai city. The Tibetans called it Pei-ku, (Northern Ravine). Before the T'ien-pao period (742-755 A.D.) it was Liu-ch'iang-chen (garrison-town) of Sui-chou.</p> |- |自入吐蕃,更增修崄,因城下有路向曩恭地。 |Since repelling the '''Tǔbō''' (吐蕃; ie. post-Tibetan Empire Kham Tibet), much work has been done atop the local peaks, as beneath the city lies the road to '''Nǎnggōng''' (曩恭). |<p style="color:#aaa;font-size:80%;line-height:110%">Since its accession to the Tibetans, they have repaired and added to it and improved its strategic value. So below the city there is a road leading towards the land of Nang-kung.</p> |- |谷東南一百三十裏至羅山城,天寶以後,吐蕃新築,非國家舊城。 |Southeast of the valley some 130 ''li'' one arrives at '''Luóshān''' city (羅山城), which after imperial rule has protected against the '''Tǔbō''' (吐蕃; ie. post-Tibetan Empire Kham Tibet), but was formerly an ancient city with no national affinity. |<p style="color:#aaa;font-size:80%;line-height:110%">Going south-east 130 li, one reaches Lo-shan city. After the T'ien-pao period, the Tibetans rebuilt the old city of Fei-kuo-chia (or Fei State).</p> |- |貞元十年十月,西川節度兵馬與雲南軍並力破保塞,大定,獻俘闕下。 |In the 10th month of the 10th year of the Zhengyuan era<ref>The Zhēngyuán (貞元) 785-805 era of Dezong. From Wikipedia: "Emperor Dezong of Tang (唐德宗) (May 27, 742 – February 25, 805), personal name Li Kuo (李适), was an emperor of the Chinese Tang Dynasty and the oldest son of his father Emperor Daizong. His reign of 26 years was the third longest in the Tang dynasty (surpassed only by Emperor Xuanzong and Emperor Gaozong). Emperor Dezong started out as a diligent and frugal emperor and he tried to reform the governmental finances by introducing new tax laws. His attempts to destroy the powerful regional warlords and the subsequent mismanagement of those campaigns, however, resulted in a number of rebellions that nearly destroyed him and the Tang Dynasty. After those events, he dealt cautiously with the regional governors, causing warlordism to become unchecked, and his trust of eunuchs caused the eunuchs' power to rise greatly. He was also known for his paranoia about officials' wielding too much power, and late in his reign, he did not grant much authority to his chancellors."</ref> (ie. ~795CE), the '''Xīchuān''' (西川) commandery gave troops to the Yunnan military for defense, and a great battle occurred beneath the '''Xiànfúquè''' (獻俘闕; lit. prisoner-taking tower). |<p style="color:#aaa;font-size:80%;line-height:110%">In the 10th month of the 10th year of Cheng-yuan (Oct. 29th-Nov. 26th, 794 A.D.), the infantry and cavalry of the Chieh-tu of Hsi-ch'uan, joined forces with the army of Yunnan, and destroyed Pao-sai, greatly pacified (the country), and presented prisoners of war at the Gate of the Court.</p> |- |十一年正月,西川又拔羅山,置兵固守。 |Three months later, '''Xīchuān''' (西川) again raided the mountains, permanently establishing troops for defense. |<p style="color:#aaa;font-size:80%;line-height:110%">In the 1st month of the 11th year (Jan. 26th-Feb. 23rd,795 A.D.) Hsi-ch'uan went on to capture Lo-shan, and stationed troops there to keep strong guard.</p> |- |邛南驛路由此遂通。 |The '''Qióngnányì Road''' (邛南驛路; lit. 'the relay road south from Qióngbù') was thus finally made open. |<p style="color:#aaa;font-size:80%;line-height:110%">The postal-service road south of Chiung henceforward could communicate with T'ai-teng city.</p> |- |臺登城直西有西望川,行一百五十裏入曲羅。 |Directly west of '''Táidēng''' (臺登) lies '''Xīwàngchuān''' (西望川; lit. the upper-river region of Xiwang), from which journeying 150 ''li'' one enters '''Qūluó''' (曲羅). |<p style="color:#aaa;font-size:80%;line-height:110%">Due west there is Hsi-wang-ch'uan (Looking West Stream). Going 150 li, it enters Ch'u-lo (or the meandering Lu-shui?).</p> |- |瀘水從北來,至曲羅縈迥三曲。 |[However,] if coming from '''Lúshuǐ''' (瀘水; lit. rushing waters) one approaches from the north,<ref>I believe that is the correct reading, at least!</ref> arriving at '''Qūluó''' (曲羅) along three crooked roads.<ref>This last past is uncertain/vague.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">The Lu-shui comes from the north, and reaches Chu-lo (the Meanders?) and winds round and round in three curves.</p> |- |每中間皆有磨些部落,以其負阻深險,承上莫能攻討同川。 |Everywhere in between is deep and dangerous passes, that even the most talented general cannot tame.<ref>Vague.</ref> |<p style="color:#aaa;font-size:80%;line-height:110%">In the middle of each there are Mo-so tribes. On account being stopped by deep abysses and dangerous heights, no Cheng-shang has yet been able to attack or punish them. (Comment: We hold that Cheng-shang is the name of a Man official. See what follows)</p> |- |邊水左右,總謂之西蠻。 |On either side of the water, the '''Western Barbarians''' (西蠻) are said to lie. |<p style="color:#aaa;font-size:80%;line-height:110%"></p> |- |邛部東南三百五十裏至勿鄧部落,入鬼主夢沖,地方闊千裏。 |350 ''li'' southeast of '''Qióngbù''' (邛部) is '''Wùdèng''' (勿鄧), a place 1000 ''li'' wide under the rule of the barbarian lord '''Mèngchōng''' (夢沖). |<p style="color:#aaa;font-size:80%;line-height:110%"></p> |- |邛部一姓白蠻,五姓烏蠻。 |For each house in '''Qióngbù''' (邛部) there are 100 barbarians; and for each five houses, one black barbarian. |<p style="color:#aaa;font-size:80%;line-height:110%"></p> |- |初止五姓,在邛部、臺登中間,皆烏蠻也。 |Other than five households, in between '''Táidēng''' (臺登) and '''Qióngbù''' (邛部) all are black barbarians. |<p style="color:#aaa;font-size:80%;line-height:110%"></p> |- |婦人以黑繪為衣,其長曳地,又束、欽兩姓在北谷,皆白蠻,三姓皆屬。 |Married women use black pigment of smeared dirt as clothing, albeit carefully applied. Except two households of the '''Northern Gorge''' (北谷), all are barbarians, including the other three households. |<p style="color:#aaa;font-size:80%;line-height:110%"></p> |- |夢沖內受恩賞於國,外私於吐蕃。 |In areas controlled by '''Mèngchōng''' (夢沖), the country is peaceful, and beyond lies '''Tǔbō''' (吐蕃; ie. post-Tibetan Empire Kham Tibet). |<p style="color:#aaa;font-size:80%;line-height:110%"></p> |- |貞元七年,節度使韋臯使巂州刺史蘇隗殺夢沖,因別立大鬼主。 |In the seventh year of the Zhengyuan era (ie. ~792CE), the government sent (weigao?) to kill mengchong, in order to prevent him from becoming barbarian king. |<p style="color:#aaa;font-size:80%;line-height:110%"></p> |- |勿鄧南七十裏有兩姓部落。<span style="color:#aaa">(案:此下當有闕文)</span> |70 ''li'' south of '''Wùdèng''' (勿鄧) is the domain of the two households. |} ==References and notes== {{reflist}} 9rqhubuy7z5ipb527pie1mun7cli7gx Wikibooks:Sandbox 4 464822 4668915 4668884 2026-09-05T12:00:49Z JackBot 396820 Bot: Automatically cleaned 4668915 wikitext text/x-wiki {{Sandbox heading}} <!-- Hello! Feel free to try your formatting and editing skills below this line. As this page is for editing experiments, this page will automatically be cleaned every 12 hours. --> efa5udpbb942msq2oco4mlj2yz47q14 User:Mazimil/sandbox 2 465564 4668990 4377009 2026-09-05T19:03:06Z ShakespeareFan00 46022 Attempting to solve lints - Please ignore the notification this edit generated. 4668990 wikitext text/x-wiki <div style="width:100%; clear:both; float:left; text-align:center; padding-bottom: 1em; "> <!----><div style="font-size:162%; padding:0.1em;">[[Wikibooks:Welcome|Welcome]] to [[Wikibooks:What is Wikibooks|Wikibooks]],</div> <!----><div style="font-size:95%; padding-top:0.2em;">the open-content textbooks collection that [[Help:Contributing|anyone can edit]].</div> <!----><div id="pagecount" style="font-size:85%;">[[Wikibooks Stacks/Departments|{{NUMBEROFBOOKS}} books]] with [[Special:Allpages|{{NUMBEROFARTICLES}} pages]].<!-- above div --></div> </div> <div style="flex: 1 0 50%; width:100%; min-width:10em; float: right; box-sizing: border-box; font-size:95%; display: flex; flex-wrap: wrap;"> <div style="width:100%; text-align:center">'''Browse Bookshelves'''</div> <!----><div style="float:left; width:25%; flex: 1 0 25%; min-width: 12em;"> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Computing|Computing]]</div> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Engineering|Engineering]]</div> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Humanities|Humanities]]</div> <!----></div> <!----><div style="float:left; width:25%; flex: 1 0 25%; min-width: 12em;"> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Languages|Languages]]</div> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Mathematics|Mathematics]]</div> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Miscellaneous|Miscellaneous]]</div> <!----></div> <!----><div style="float:left; width:25%; flex: 1 0 25%; min-width: 12em;"> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Recreational activities|Recreational activities]]</div> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Science|Science]]</div> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Social sciences|Social sciences]]</div> <!----></div> <!----><div style="float:left; width:25%; flex: 1 0 25%; min-width: 12em;"> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Standard curricula|Standard curricula]]</div> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">[[Department:Wikijunior|Wikijunior]]</div> <div style="background-color:#F3F3F3;{{Text default color}}; text-align:center; margin: 4pt 2pt;">'''[[Wikibooks Stacks/Departments|All subjects]]'''</div> <!----></div> </div> <div id="mf-main" style="width:100%; margin:0px; padding:0px 5px 5px 5px; "><!-- Opening div --> <div id="mf-help" style="clear:both; text-align:center; font-size:95%; margin:0em 1em 0em 1em;"> [[Wikibooks:Featured books|Featured books]] • [[Wikijunior|Wikijunior]] • [[Cookbook:Table of Contents|Cookbook]] • [[Wikibooks:Card Catalog Office|Browse books]] • [[Help:Contents|Help]] • [[Wikibooks:Reading room|Forum]] • [[Using Wikibooks]] </div> <div style="clear:both; width:100%; margin: 25px 0 0 0; display: flex; flex-wrap: wrap; box-sizing: border-box; " id="mp-content"> <div style="width:100%; text-align:center">'''Today's Featured Content'''</div> <!----><div style="box-sizing: border-box; float:left; flex: 1 0 33%; width:33%; border: 0.2em solid #FAFAFA; padding: 1em; background-color:#F3F3F3;{{Text default color}}; min-width: 20em; overflow:hidden; ">{{:Main Page/Featured}}</div> <!----><div style="box-sizing: border-box; float:left; flex: 1 0 33%; width:33%; border: 0.2em solid #FAFAFA; padding: 1em; background-color:#F3F3F3;{{Text default color}}; min-width: 20em; overflow:hidden; ">{{:Main Page/Wikijunior}}</div> <!----><div style="box-sizing: border-box; float:left; flex: 1 0 33%; width:33%; border: 0.2em solid #FAFAFA; padding: 1em; background-color:#F3F3F3;{{Text default color}}; min-width: 20em; overflow:hidden; ">{{:Main Page/Recipe}}</div><!-- 1. Promoted shelf --> <!----><div style="box-sizing: border-box; float:left; flex: 1 0 33%; width:33%; border: 0.2em solid #FAFAFA; padding: 1em; background-color:#F3F3F3;{{Text default color}}; min-width: 20em; overflow:hidden; ">{{Promoted shelf|title=Shelf:Games|cover=Chess_board_blank.svg|desc=[[Shelf:Games]] contains books on games, and includes the subsection shelves [[Shelf:Athletic games|athletic games]], [[Shelf:Board games|board games]], [[Shelf:Card games|card games]], [[Shelf:Electronic games|electronic games]], and [[Shelf:Game design|game design]].}}</div><!-- 2. Promoted shelf --> <!----><div style="box-sizing: border-box; float:left; flex: 1 0 33%; width:33%; border: 0.2em solid #FAFAFA; padding: 1em; background-color:#F3F3F3;{{Text default color}}; min-width: 20em; overflow:hidden; ">{{Promoted shelf|title=Shelf:Computer programming|cover=Openscad SVG.svg|desc=[[Shelf:Computer programming]] contains books on programming, such as [[LaTeX]], [[OpenSCAD User Manual]], [[Python Programming]], and [[Java Programming]].}}</div><!-- 3. Promoted shelf --> <!----><div style="box-sizing: border-box; float:left; flex: 1 0 33%; width:33%; border: 0.2em solid #FAFAFA; padding: 1em; background-color:#F3F3F3;{{Text default color}}; min-width: 20em; overflow:hidden; ">{{Promoted shelf|title=Shelf:Languages of Asia|cover=Taj Mahal in March 2004.jpg|desc=[[Shelf:Languages of Asia]] contains books on Asian languages, such as [[Marathi]], [[Bengali]], [[Kannada]], [[Hindi]], and [[Sanskrit]].}}</div> </div> {{:Main Page/Sisters}} </div><!-- Closing div --> [[Category:Main page| ]] 1gjrfv734f5c417o3l1mf2xl7pwehao User:JJPMaster (bot)/markAdmins-Data.json 2 471107 4668986 4668674 2026-09-05T18:49:14Z JJPMaster (bot) 3488561 Bot: Updating markAdmins data 4668986 json application/json { ".snoopy.": [ "global-rollbacker", "editor" ], "1234qwer1234qwer4": [ "editor", "steward" ], "157yagz5r48a5f1a1f": [ "editor" ], "1997kB": [ "global-rollbacker", "global-renamer", "editor" ], "1F616EMO": [ "global-renamer" ], "1exec1": [ "transwiki", "editor" ], "1sfoerster": [ "editor" ], "20041027 tatsu": [ "global-rollbacker" ], "2005-Fan": [ "transwiki", "editor", "uploader" ], "331dot": [ "global-renamer" ], "33rogers": [ "editor" ], "3MMPEYTON": [ "editor" ], "4PlayerChess": [ "autoreview" ], "4pillars": [ "editor" ], "511KeV": [ "global-rollbacker" ], "94rain": [ "global-rollbacker", "editor" ], "A R King": [ "editor" ], "A Sulaiman Z": [ "editor" ], "A.K.Karthikeyan": [ "editor" ], "A09": [ "steward" ], "AFBorchert": [ "vrt-permissions" ], "AIProf": [ "editor" ], "ALittleSlow": [ "autoreview" ], "AManWithNoPlan": [ "editor" ], "ATannedBurger": [ "global-renamer" ], "AVRS": [ "editor" ], "Aafi": [ "vrt-permissions" ], "Abenwagner": [ "editor" ], "Abigor": [ "editor" ], "Abitt002": [ "editor" ], "Abyssal": [ "editor" ], "Acagastya": [ "autoreview" ], "Acalamari": [ "global-renamer" ], "Acarologiste": [ "editor" ], "AcidBat": [ "editor" ], "Acrow005": [ "editor" ], "Actualist": [ "editor" ], "Adalvis": [ "editor" ], "Adart001": [ "editor" ], "Adavyd": [ "global-renamer" ], "Addihockey10": [ "editor" ], "Addihockey10 (automated)": [ "editor" ], "Adrignola": [ "editor" ], "AdventureWriter": [ "editor" ], "Aelxen": [ "global-renamer" ], "Aferg006": [ "editor" ], "Afett001": [ "editor" ], "Affe2011": [ "global-rollbacker" ], "Agnerf": [ "editor", "uploader" ], "Agpires": [ "editor" ], "Agricola": [ "editor" ], "Agusbou2015": [ "editor" ], "Ah3kal": [ "editor" ], "Ahecht": [ "global-renamer", "vrt-permissions" ], "Ahonc": [ "global-renamer", "vrt-permissions" ], "AiClassEland": [ "editor" ], "Ainz Ooal Gown": [ "editor" ], "Airpmb": [ "editor" ], "Ajraddatz": [ "editor", "steward" ], "Aka": [ "vrt-permissions" ], "Alanah.97": [ "autoreview" ], "Albertoleoncio": [ "steward", "vrt-permissions" ], "Albmont": [ "editor" ], "Alchimista": [ "vrt-permissions" ], "Aldnonymous": [ "editor" ], "Aledownload": [ "editor" ], "Alexlatham96": [ "editor" ], "Alextejthompson": [ "editor" ], "Alison": [ "global-rollbacker" ], "AllenZh": [ "editor" ], "Alphama": [ "global-renamer" ], "AlvaroMolina": [ "editor" ], "AmandaNP": [ "steward" ], "Ambrevar": [ "editor" ], "Amcgail": [ "editor" ], "Ameisenigel": [ "global-rollbacker", "global-sysop", "ombuds", "editor", "vrt-permissions" ], "AmieKim": [ "editor" ], "Amire80": [ "global-sysop" ], "Anachronist": [ "editor", "vrt-permissions" ], "Ancient9983": [ "editor" ], "Andrei Stroe": [ "vrt-permissions" ], "Andrew janke": [ "editor" ], "Andriy.v": [ "vrt-permissions" ], "Andyross": [ "editor" ], "Anil Shaligram": [ "editor" ], "Animajosser": [ "editor" ], "Anne Correia": [ "editor" ], "Anonim Şahıs": [ "editor" ], "Anonymity": [ "editor" ], "AnotherEditor144": [ "autoreview" ], "Antanana": [ "vrt-permissions" ], "Antandrus": [ "editor" ], "Anthere": [ "editor" ], "AntiCompositeNumber": [ "steward", "vrt-permissions" ], "Antonizoon": [ "editor" ], "Antonw": [ "editor" ], "Apfelmus": [ "editor" ], "Aphoneyclimber": [ "editor" ], "Aplucas0703": [ "vrt-permissions" ], "Apocheir": [ "editor" ], "Aqurs1": [ "global-rollbacker", "global-renamer", "global-sysop" ], "AramilFeraxa": [ "steward" ], "Arch dude": [ "editor" ], "Archolman": [ "editor" ], "Arcticocean": [ "ombuds" ], "ArdentPerf": [ "editor", "uploader" ], "Arian": [ "global-renamer" ], "Arlen22": [ "transwiki", "editor" ], "Armchair": [ "editor" ], "Arno-nl": [ "editor" ], "Arrow303": [ "vrt-permissions" ], "Arthurvogel": [ "editor" ], "Artoria2e5": [ "editor" ], "Arturoiochoam": [ "editor" ], "Arunreginald": [ "editor" ], "AshLin": [ "editor" ], "Atcovi": [ "sysop", "global-rollbacker" ], "Athrash": [ "editor" ], "Atiedebee": [ "editor" ], "Atlas.Spheres": [ "editor" ], "Atsme": [ "vrt-permissions" ], "Auremel": [ "editor" ], "Austncorp": [ "editor" ], "AuthorsAndContributorsBot": [ "autoreview" ], "Avicennasis": [ "editor" ], "Avraham": [ "global-renamer", "editor" ], "Awesome Princess": [ "editor" ], "Axpde": [ "editor" ], "Az1568": [ "global-rollbacker" ], "Az2008": [ "editor" ], "Azotochtli": [ "editor" ], "B.Korlah": [ "editor" ], "BD2412": [ "editor" ], "BORGATO Pierandrea": [ "editor" ], "BRPever": [ "global-rollbacker", "global-sysop" ], "BRUTE": [ "editor" ], "Backfromquadrangle": [ "editor" ], "Baiji": [ "global-rollbacker" ], "Bakasakali": [ "editor" ], "Balaji.md au": [ "editor" ], "BarkingFish": [ "editor" ], "Barras": [ "steward" ], "Base": [ "steward", "vrt-permissions" ], "Bastique": [ "editor" ], "Bautsch": [ "editor" ], "BeardMD": [ "editor" ], "Beetstra": [ "global-rollbacker" ], "BenTels": [ "editor" ], "Bencemac": [ "global-rollbacker", "global-renamer", "vrt-permissions" ], "Benjamin J. Burger": [ "editor" ], "Benjamin.doe": [ "editor" ], "Benrattray": [ "editor" ], "Benson Muite": [ "editor" ], "Bentbracke": [ "editor" ], "Bequw": [ "editor" ], "Bert Niehaus": [ "autoreview" ], "BethNaught": [ "editor" ], "Beuc": [ "editor" ], "Bhardwaj Anil": [ "autoreview" ], "BiT": [ "editor" ], "Bigdelboy": [ "transwiki" ], "Bignose~enwikibooks": [ "editor" ], "Billinghurst": [ "editor" ], "Billymac00": [ "editor" ], "Biplab Anand": [ "global-rollbacker", "global-sysop" ], "Birdofadozentides": [ "editor" ], "BitterAsianMan": [ "editor" ], "Bluefoxicy": [ "editor" ], "Bluerasberry": [ "vrt-permissions" ], "BobChan2": [ "editor" ], "Bobby Cohn": [ "global-renamer" ], "Bodhisattwa": [ "vrt-permissions" ], "BoldLuis": [ "editor" ], "Borhan": [ "global-rollbacker", "vrt-permissions" ], "Boris1951zz": [ "editor" ], "Bpenn005": [ "editor" ], "Brewster239": [ "global-rollbacker" ], "Bridget": [ "global-rollbacker", "editor" ], "Brienna.Hall77": [ "editor" ], "Brim": [ "editor" ], "Brittanys": [ "editor" ], "Bronwynh": [ "editor" ], "Bsadowski1": [ "editor", "steward" ], "Buddpaul": [ "editor" ], "Bullercruz1": [ "editor" ], "Buncic": [ "editor" ], "Bunnypranav": [ "global-renamer" ], "BurakD53": [ "editor" ], "Burkep": [ "editor" ], "ByGrace": [ "editor" ], "Bykim2012": [ "editor" ], "C1203sc": [ "editor" ], "CJakes1": [ "editor" ], "CKWG - Ada Magica": [ "editor" ], "Cabayi": [ "global-renamer" ], "CaitlinCarbury": [ "autoreview" ], "CalciumTetraoxide": [ "editor" ], "CalendulaAsteraceae": [ "editor" ], "Caliburn": [ "editor" ], "CallumPoole": [ "editor" ], "Calvin.Andrus": [ "editor" ], "Cameron11598": [ "editor" ], "Camouflaged Mirage": [ "editor" ], "Captain-tucker": [ "vrt-permissions" ], "Carlo.milanesi": [ "editor" ], "Caro de Segeda": [ "editor" ], "CarsracBot": [ "editor" ], "Catermark": [ "editor" ], "Cecila123": [ "autoreview" ], "Cedar101": [ "editor" ], "Champion": [ "editor" ], "Chaojidage": [ "editor" ], "Chaojoker": [ "editor" ], "Chaotic Enby": [ "autoreview", "global-renamer" ], "Chapka": [ "editor" ], "Charidri": [ "editor" ], "Charleneabeana": [ "autoreview" ], "Charles Jeffrey Danoff": [ "editor" ], "CharlesHoffman": [ "editor" ], "Chazz": [ "editor" ], "Chelseafan528": [ "editor" ], "Cheryl2012": [ "editor" ], "Chescargot": [ "vrt-permissions" ], "Chi Sigma": [ "editor" ], "Chinmayee Mishra": [ "ombuds" ], "Chongkian": [ "editor" ], "Chowbok": [ "editor" ], "ChrisHodgesUK": [ "editor" ], "ChrisWallace": [ "editor" ], "Chriswaterguy": [ "editor" ], "Chuckhoffmann": [ "editor" ], "Church of emacs": [ "global-rollbacker" ], "Cic": [ "editor" ], "Ciell": [ "vrt-permissions" ], "Cilantrohead": [ "editor" ], "Cintilo": [ "editor" ], "Circuit dreamer": [ "editor" ], "Circuit-fantasist": [ "editor" ], "Civvì": [ "global-rollbacker", "global-renamer" ], "Ckwalker": [ "editor" ], "Clairerusselll": [ "autoreview" ], "Cloidl": [ "autoreview" ], "Cmsmcq": [ "editor" ], "Cnrowley": [ "editor" ], "CocoaZen": [ "editor" ], "CoconutOctopus": [ "global-renamer" ], "Codename Noreste": [ "sysop", "global-rollbacker", "interface-admin" ], "Codename Noroeste": [ "editor" ], "Codinghead": [ "editor" ], "CommonsDelinker": [ "autoreview" ], "Comp.arch": [ "editor" ], "Conan": [ "editor" ], "Cormullion": [ "editor" ], "Count Count": [ "steward" ], "Coupe": [ "editor" ], "Courcelles": [ "global-rollbacker", "editor" ], "CptViraj": [ "global-rollbacker", "global-renamer", "global-sysop" ], "Craignewland": [ "editor" ], "Craxd1": [ "editor" ], "CrazyEddy": [ "editor" ], "Cremastra": [ "editor" ], "Cremastra (JWB)": [ "autoreview" ], "Cromium": [ "editor" ], "Cromwellt": [ "editor" ], "Crystal East": [ "editor" ], "Cttcraig": [ "editor" ], "Cultures17": [ "editor" ], "Cultures33": [ "editor" ], "Cultures4": [ "editor" ], "Cultures92": [ "editor" ], "CunninghamJohn": [ "autoreview" ], "Curtaintoad": [ "editor" ], "Cyberpower678": [ "global-rollbacker" ], "Céréales Killer": [ "global-renamer" ], "D1n05aur5 4ever": [ "editor" ], "DARIO SEVERI": [ "autoreview", "global-rollbacker", "global-sysop" ], "DC Slagel": [ "editor" ], "DCB": [ "vrt-permissions" ], "DD 8630": [ "editor" ], "DERDAKI ILIAS": [ "global-renamer" ], "DGerman": [ "editor" ], "DVD206": [ "editor" ], "DZadventiste": [ "editor" ], "DaB.": [ "vrt-permissions" ], "DaGizza": [ "editor" ], "Dagana4": [ "autoreview" ], "Dallas1278": [ "editor" ], "Dan Koehl": [ "editor" ], "Dan Polansky": [ "editor" ], "Dan-aka-jack": [ "editor" ], "DanCherek": [ "autoreview" ], "Danarwaller": [ "editor" ], "DanielWhernchend": [ "editor" ], "Danielravennest": [ "editor" ], "Danilka5469": [ "editor" ], "Daniuu": [ "steward", "vrt-permissions" ], "DannyS712": [ "editor" ], "Darklama": [ "editor" ], "Darklilac": [ "editor" ], "Darrelljon": [ "editor" ], "DarwIn": [ "vrt-permissions" ], "Dave Braunschweig": [ "editor" ], "David L Davis": [ "editor" ], "DavidCary": [ "editor" ], "DavidLevinson": [ "editor" ], "Davidbena": [ "editor" ], "Dayshade": [ "editor" ], "Dchmelik": [ "editor" ], "Dcljr": [ "editor" ], "Dcondon": [ "editor" ], "Deepfriedokra": [ "global-renamer" ], "DejaVu": [ "global-rollbacker" ], "DennisDaniels": [ "editor" ], "Dennisblu": [ "uploader" ], "Denniss": [ "editor" ], "Der-Wir-Ing": [ "global-rollbacker" ], "DerHexer": [ "editor", "steward", "vrt-permissions" ], "Derek Andrews": [ "editor" ], "Designermadsen": [ "editor" ], "Deu": [ "global-rollbacker" ], "Dexxor": [ "editor" ], "Dezedien": [ "vrt-permissions" ], "Diandramartin": [ "autoreview" ], "Didym": [ "vrt-permissions" ], "Dino Bronto Rex": [ "editor" ], "Dirk Hünniger": [ "editor" ], "Divinations": [ "global-rollbacker" ], "Djb": [ "editor" ], "Djbrown": [ "editor" ], "Dlrohrer2003": [ "editor" ], "Dmccreary": [ "editor" ], "Doc Taxon": [ "vrt-permissions" ], "Doctorxgc": [ "editor" ], "Dom walden": [ "editor" ], "Domdomegg": [ "editor" ], "DominikTurner": [ "autoreview" ], "DonaldKronos": [ "editor" ], "DoubleGrazing": [ "global-renamer" ], "Doubleotoo": [ "editor" ], "Downdate": [ "editor" ], "Dr-Taher": [ "global-renamer" ], "Dr.Unclear": [ "editor" ], "Dreftymac": [ "editor" ], "Drpundir": [ "editor" ], "Drummingman": [ "global-rollbacker", "global-renamer", "vrt-permissions" ], "DuLithgow": [ "editor" ], "Dungodung": [ "vrt-permissions" ], "Duplode": [ "editor" ], "DustDFG": [ "editor" ], "Dyolf77": [ "vrt-permissions" ], "EDCU320RHT": [ "editor" ], "EDUC320 Sylvialiang": [ "editor" ], "EE JRW": [ "editor" ], "EMAD KAYYAM": [ "editor" ], "EPIC": [ "steward" ], "EarlGrey2005": [ "autoreview" ], "Ebe123": [ "editor" ], "Ecarew": [ "editor" ], "Edgar181": [ "editor" ], "Edit filter": [ "sysop" ], "EdoDodo": [ "editor" ], "Edornbush": [ "editor" ], "Edriiic": [ "editor" ], "Efex": [ "editor" ], "Efex3": [ "editor" ], "Effeietsanders": [ "editor", "vrt-permissions" ], "EggRoll97": [ "editor" ], "Egil": [ "editor" ], "Eihel": [ "global-rollbacker", "editor" ], "Ejs-80": [ "global-renamer" ], "Ekaroleski": [ "editor" ], "Elaurier": [ "editor" ], "Elcobbola": [ "vrt-permissions" ], "Electro": [ "editor" ], "ElfSnail123": [ "editor" ], "Eli bubo4ka": [ "editor" ], "Eliarani": [ "editor" ], "Elli": [ "global-renamer", "vrt-permissions" ], "Ellywa": [ "vrt-permissions" ], "Elmacenderesi": [ "vrt-permissions" ], "Elton": [ "editor", "steward" ], "Emha": [ "vrt-permissions" ], "EmilymDaniel": [ "autoreview" ], "Empire3131": [ "editor" ], "Encik Tekateki": [ "editor" ], "Enzomartinelli": [ "editor" ], "Eric Evers": [ "editor" ], "Erigena": [ "editor" ], "Erik Baas": [ "editor" ], "ErinNik": [ "editor" ], "Erinamukuta": [ "editor" ], "ErrantX": [ "editor" ], "EruannoVG": [ "editor" ], "Espen180": [ "editor" ], "Eta Carinae": [ "global-renamer" ], "Ethacke1": [ "editor" ], "Eumolpo": [ "editor" ], "Euphydryas": [ "global-renamer" ], "Eurodyne": [ "editor" ], "EvDawg93": [ "editor" ], "EvanCarroll": [ "editor" ], "Ewen": [ "editor" ], "Exusiai": [ "global-renamer" ], "Ezarate": [ "global-rollbacker", "vrt-permissions" ], "Fabartus": [ "editor", "uploader" ], "Faendalimas": [ "ombuds" ], "Fasten": [ "editor" ], "Faster than Thunder": [ "editor" ], "Fathoms Below": [ "global-renamer" ], "Fcorthay": [ "editor" ], "Fdena": [ "editor" ], "Federhalter": [ "editor" ], "Fehufanga": [ "global-rollbacker", "global-sysop" ], "Fekarp": [ "editor" ], "Fephisto": [ "editor" ], "Ferien": [ "global-rollbacker" ], "Fernando2812l": [ "editor" ], "Fernly": [ "editor" ], "Ffion B Thompson": [ "autoreview" ], "Fimatic": [ "editor" ], "FischX": [ "editor" ], "Fishpi": [ "editor" ], "Flattail": [ "editor" ], "FlightTime": [ "global-renamer" ], "Flolit": [ "editor" ], "Fluffernutter": [ "vrt-permissions" ], "FlyingAce": [ "global-rollbacker" ], "Fountain Pen": [ "editor" ], "Fr33kman": [ "editor" ], "FrancisFromGaspesie": [ "editor" ], "Frantsch": [ "autoreview" ], "Fredericknortje": [ "editor" ], "Fritzlein~enwikibooks": [ "editor" ], "Frozen Wind": [ "transwiki", "editor" ], "Ftaljaard": [ "editor" ], "Ftiercel": [ "editor" ], "Furrykef": [ "editor" ], "GKFX": [ "editor" ], "Galahad": [ "global-rollbacker" ], "Gampe": [ "vrt-permissions" ], "Ganímedes": [ "vrt-permissions" ], "Gary Dorman Wiggins": [ "editor", "uploader" ], "Garygaryj": [ "editor" ], "Gat lombard": [ "editor" ], "Gc211": [ "editor" ], "Geagea": [ "vrt-permissions" ], "Geekgirl": [ "editor" ], "GemmaCampbell": [ "autoreview" ], "Geoff Plourde": [ "editor" ], "Geofferybard": [ "transwiki", "editor" ], "GerbenRienk": [ "editor" ], "Gerges": [ "global-rollbacker", "global-renamer" ], "Germany Poul Ah": [ "editor" ], "Gertbuschmann": [ "editor" ], "Ggee0621": [ "editor" ], "Gifnk dlm 2020": [ "editor", "uploader" ], "Girdi": [ "editor" ], "Glaisher": [ "editor" ], "Glane23": [ "vrt-permissions" ], "Gleb713": [ "autoreview" ], "Glich": [ "editor" ], "Gllyons": [ "editor" ], "Gmasterman": [ "editor" ], "GoblinInventor": [ "editor" ], "Godsy": [ "autoreview" ], "Good afternoon": [ "editor" ], "GoreyCat": [ "editor" ], "GorgeUbuasha": [ "editor" ], "GorillaWarfare": [ "vrt-permissions" ], "Gott wisst": [ "editor" ], "Goulart": [ "editor" ], "Gpkp": [ "editor" ], "Gracebaysinger": [ "editor" ], "Graeme E. Smith": [ "editor" ], "Greatswrd": [ "editor" ], "GreenC": [ "editor" ], "Greenbreen": [ "editor" ], "Greenman": [ "editor" ], "GregXenon01": [ "editor" ], "Gretski247": [ "editor" ], "GreyCat": [ "editor" ], "Grin": [ "vrt-permissions" ], "Growl41": [ "editor" ], "Guaka": [ "editor" ], "Guanaco": [ "editor" ], "GuillermoHazebrouck": [ "editor" ], "Guus": [ "editor" ], "Guy vandegrift": [ "editor" ], "Guywan": [ "editor" ], "Gzuufy": [ "editor" ], "HJ Mitchell": [ "autoreview" ], "HLand": [ "editor" ], "HYanWong": [ "editor" ], "Ha98574": [ "editor" ], "Hagindaz": [ "editor" ], "HakanIST": [ "editor", "steward" ], "Hamish": [ "global-rollbacker", "global-renamer", "vrt-permissions" ], "Hanay": [ "vrt-permissions" ], "Hannes Röst": [ "editor" ], "Hans Adler": [ "editor" ], "Haoreima": [ "editor" ], "Happy-melon": [ "editor" ], "Harry Wood": [ "editor" ], "Harrybrowne1986": [ "editor" ], "Harv4": [ "editor" ], "Hasley": [ "editor" ], "Hazard-SJ": [ "global-rollbacker" ], "He7d3r": [ "editor" ], "HenkvD": [ "editor" ], "Herbythyme": [ "editor" ], "Hercule": [ "editor" ], "Herman darman": [ "editor" ], "HerrHartmuth": [ "editor" ], "Hethrir": [ "editor" ], "HgDeviasse": [ "editor" ], "Hippias": [ "editor" ], "Hliow": [ "autoreview" ], "Holder": [ "global-rollbacker", "global-sysop" ], "Holdoffhunger": [ "editor" ], "Hoo man": [ "editor", "steward" ], "HouseBlaster": [ "global-renamer" ], "Howard Beale": [ "editor" ], "Hpon": [ "editor" ], "Hrkalona": [ "autoreview" ], "Hskeet": [ "editor", "uploader" ], "Htm": [ "vrt-permissions" ], "Hugetim": [ "editor" ], "Humaira Ali": [ "editor" ], "Huntertur": [ "editor" ], "Hydriz": [ "global-rollbacker" ], "IB Muazzam": [ "editor" ], "Ibidthewriter": [ "editor" ], "Ibrahim.ID": [ "global-renamer", "vrt-permissions" ], "Icetruck": [ "editor" ], "Icodense": [ "global-rollbacker", "global-sysop" ], "Idavidmiller": [ "editor" ], "Ideasman42": [ "editor" ], "Igna": [ "editor" ], "Ijon": [ "vrt-permissions" ], "Illusional": [ "editor" ], "Iluvatar": [ "global-rollbacker", "vrt-permissions" ], "Indiana": [ "editor" ], "Inductiveload": [ "editor" ], "Inertia6084": [ "autoreview" ], "Inferno986return": [ "editor" ], "Infinite0694": [ "global-rollbacker", "global-sysop" ], "Ingolemo": [ "editor" ], "Insignificantwrangler": [ "editor" ], "Internoob": [ "transwiki", "editor" ], "InverseHypercube": [ "editor" ], "Isenhand": [ "editor" ], "Ish ishwar": [ "editor" ], "Iste Praetor": [ "editor" ], "ItsNyoty": [ "vrt-permissions" ], "Itsmeyash31": [ "autoreview" ], "Itswikisam": [ "editor" ], "Itti": [ "global-renamer", "vrt-permissions" ], "Ixfd64": [ "editor" ], "J ansari": [ "global-rollbacker" ], "J.palacios.jean": [ "editor" ], "J36miles": [ "editor" ], "JBW": [ "global-renamer" ], "JCrue": [ "editor" ], "JJ12880": [ "editor" ], "JJMC89": [ "vrt-permissions" ], "JJPMaster": [ "sysop", "global-rollbacker", "global-renamer", "interface-admin", "vrt-permissions" ], "JJPMaster (test 1)": [ "autoreview" ], "JJohnson": [ "editor" ], "JJohnson1701": [ "editor" ], "JPPINTO": [ "editor" ], "Jack Frost": [ "vrt-permissions" ], "JackBot": [ "editor" ], "JackPotte": [ "sysop", "interface-admin" ], "Jackhand1": [ "autoreview" ], "Jacob J. Walker": [ "editor" ], "Jafeluv": [ "global-rollbacker", "editor" ], "Jake Park": [ "global-renamer" ], "Jakec": [ "editor" ], "JamesCrook": [ "editor" ], "JamesNZ": [ "editor" ], "Jamesofur": [ "global-rollbacker" ], "Jamesssss": [ "editor" ], "Jamzze": [ "editor" ], "Jan Myšák": [ "global-rollbacker" ], "Jan.duggan": [ "autoreview" ], "Janbery": [ "global-rollbacker", "vrt-permissions" ], "Janpha": [ "editor" ], "Janschejbal": [ "editor" ], "Jason.Cozens": [ "editor" ], "Jaspalkaler": [ "editor" ], "Jasper Deng": [ "global-rollbacker" ], "JavaHurricane": [ "global-rollbacker", "editor" ], "Javier Carro": [ "editor" ], "JavierCantero": [ "editor" ], "Jay Bolero": [ "editor" ], "Jazzmanian": [ "editor" ], "Jcb": [ "editor", "vrt-permissions" ], "Jcwf": [ "editor" ], "Jeff G.": [ "global-rollbacker", "editor" ], "Jeff1138": [ "editor" ], "Jellysandwich0": [ "editor" ], "JenVan": [ "editor" ], "JenniferPalacios": [ "editor" ], "Jenniferjkidd": [ "editor" ], "Jens Østergaard Petersen": [ "editor" ], "JeremyMcCracken": [ "editor" ], "Jeroenr": [ "editor" ], "Jerome Charles Potts": [ "editor" ], "Jerry vlntn": [ "editor" ], "Jesdisciple": [ "editor" ], "Jessephu": [ "editor" ], "Jfmantis": [ "editor" ], "Jianhui67": [ "global-rollbacker", "editor" ], "Jianhui67 public": [ "editor" ], "Jim Ashby": [ "autoreview" ], "JimKillock": [ "editor" ], "Jimbotyson": [ "editor" ], "Jimmy Xu": [ "vrt-permissions" ], "Jkauf007": [ "editor" ], "Jmdeschamps": [ "uploader" ], "Jnanaranjan sahu": [ "ombuds" ], "Jnewh001": [ "editor" ], "Jobin RV": [ "editor" ], "Joewiz": [ "editor" ], "Johannes Bo": [ "editor" ], "Johannnes89": [ "steward" ], "John Cross": [ "editor" ], "JohnMarcelo": [ "editor" ], "Johnkn63": [ "editor" ], "Johnwhelan": [ "editor" ], "Jokes Free4Me": [ "editor" ], "Jomegat": [ "editor" ], "Jon Harald Søby": [ "vrt-permissions" ], "Jon Kolbert": [ "steward", "vrt-permissions" ], "Jonathan Webley": [ "editor" ], "Jordan Brown": [ "editor" ], "JorisvS": [ "editor" ], "Josve05a": [ "vrt-permissions" ], "Jrincayc": [ "editor" ], "Jsnaree": [ "editor" ], "Jtneill": [ "editor" ], "JuethoBot": [ "autoreview" ], "Jugandi": [ "editor" ], "Jules*": [ "global-renamer" ], "Juliancolton": [ "global-rollbacker", "editor" ], "Jumark27": [ "editor" ], "JustTheFacts33": [ "editor" ], "Justlettersandnumbers": [ "global-renamer", "vrt-permissions" ], "K6ka": [ "global-rollbacker", "global-renamer" ], "Kadı": [ "global-renamer", "vrt-permissions" ], "Kai Burghardt": [ "editor" ], "Kaltenmeyer": [ "editor" ], "Kambai Akau": [ "editor" ], "Kanjy": [ "global-rollbacker", "editor" ], "Kapooht": [ "editor" ], "Karl Wick": [ "editor" ], "Karosent": [ "editor" ], "Kashkhan": [ "editor" ], "Kathryn Mary Nicholson": [ "autoreview" ], "Katiemgeorge": [ "editor" ], "Katyauchter": [ "editor" ], "Kaushlendratripathi": [ "editor" ], "Kaw8yh": [ "editor" ], "Kayau": [ "transwiki", "editor" ], "Kellen": [ "editor" ], "Kelti": [ "editor" ], "Kiefer.Wolfowitz": [ "editor" ], "Killarnee": [ "editor" ], "King of Hearts": [ "vrt-permissions" ], "Kingaustin07": [ "editor" ], "Kingofnuthin": [ "editor" ], "Kirito": [ "global-rollbacker", "editor" ], "Kittycataclysm": [ "sysop" ], "Kj cheetham": [ "global-renamer" ], "Kkmurray": [ "editor" ], "Kl-robertson": [ "editor" ], "Klaas van Buiten": [ "editor" ], "Knittedbees": [ "transwiki", "editor" ], "Knoppson": [ "autoreview" ], "Koantum": [ "editor" ], "Koavf": [ "sysop", "global-rollbacker" ], "Kodos": [ "editor" ], "KonstantinaG07": [ "editor", "steward" ], "Kowey": [ "editor" ], "KrakatoaKatie": [ "vrt-permissions" ], "Krd": [ "vrt-permissions" ], "Krdbot": [ "vrt-permissions" ], "Kri": [ "editor" ], "Krinkle": [ "global-rollbacker" ], "Kropotkine 113": [ "vrt-permissions" ], "Kruusamägi": [ "vrt-permissions" ], "Ktucker": [ "editor" ], "Kwamikagami": [ "editor" ], "Kwhitefoot": [ "editor" ], "Kylu": [ "editor" ], "Kızıl": [ "global-renamer" ], "L10nM4st3r": [ "editor" ], "LABoyd2": [ "editor" ], "LR0725": [ "global-rollbacker", "global-sysop" ], "Ladislav": [ "editor" ], "Ladsgroup": [ "global-renamer" ], "Ladybug62": [ "editor" ], "Lagoset": [ "editor" ], "Larsnooden": [ "editor" ], "Laurianedani": [ "editor" ], "Lcraw005": [ "editor" ], "Ldo": [ "editor" ], "Leaderboard": [ "sysop", "global-renamer", "interface-admin" ], "Learnerktm": [ "editor" ], "Lechatjaune": [ "vrt-permissions" ], "Leighblackall": [ "editor" ], "Lemonaka": [ "global-rollbacker" ], "Lengel46": [ "editor" ], "Lentokonefani": [ "global-renamer" ], "LeoChiukl": [ "editor" ], "Leonard64": [ "uploader" ], "Leonidlednev": [ "autoreview", "global-rollbacker" ], "Leovanderven": [ "editor" ], "Lesless": [ "vrt-permissions" ], "Leyo": [ "global-rollbacker" ], "Lgriot": [ "editor" ], "Liam987": [ "editor" ], "Liao": [ "editor" ], "Libperry": [ "editor" ], "Limiza": [ "editor" ], "Lionel Cristiano": [ "editor" ], "Litlok": [ "global-renamer" ], "Little Sunshine": [ "global-renamer" ], "Llakew": [ "editor" ], "LlamaAl": [ "editor" ], "Lobsteroh": [ "editor" ], "LodestarChariot2": [ "editor" ], "Lofty abyss": [ "global-rollbacker", "editor", "vrt-permissions" ], "Logictheo": [ "editor" ], "Lomita": [ "vrt-permissions" ], "Londonjackbooks": [ "editor" ], "Lovepeacejoy404": [ "editor" ], "Lp0 on fire": [ "autoreview", "global-rollbacker" ], "Lubaochuan": [ "editor" ], "Luckas Blade": [ "editor" ], "Lucystewpid": [ "autoreview" ], "Ludovic Brenta": [ "editor" ], "Ludovicocaldara": [ "editor", "uploader" ], "Lukas²³": [ "editor" ], "LukeCEL": [ "editor" ], "Lvova": [ "vrt-permissions" ], "Lwill031": [ "editor" ], "M7": [ "steward" ], "MARKELLOS": [ "vrt-permissions" ], "MBq": [ "global-renamer" ], "MF-Warburg": [ "global-rollbacker", "global-sysop", "editor" ], "MGA73": [ "vrt-permissions" ], "MIacono": [ "editor" ], "MNeuschaefer": [ "editor" ], "MS Sakib": [ "global-renamer", "vrt-permissions" ], "Mabdul": [ "transwiki", "editor", "uploader" ], "Madisonhen": [ "autoreview" ], "Magda.dagda": [ "editor" ], "Magnus Manske": [ "editor" ], "Mahagaja": [ "editor" ], "MaikoM93": [ "editor" ], "Maire": [ "global-renamer" ], "Malarz pl": [ "global-renamer" ], "Manchiu": [ "global-renamer" ], "MandoRachovitsa": [ "autoreview" ], "Mandy Hopkins": [ "editor" ], "ManuelGR": [ "editor" ], "MarcGarver": [ "sysop", "checkuser", "steward" ], "Marco Klunder": [ "editor" ], "MarcoAurelio": [ "editor" ], "Marcus Cyron": [ "vrt-permissions" ], "Mardus": [ "editor" ], "MarkJFernandes": [ "editor" ], "MarkTraceur": [ "editor" ], "Markcwm": [ "editor" ], "Markhobley": [ "editor" ], "MarsRover": [ "editor" ], "Marshman~enwikibooks": [ "editor" ], "Martin Kraus": [ "editor" ], "Martin Sauter": [ "editor" ], "Martin Urbanec": [ "editor", "steward", "vrt-permissions" ], "MartinPoulter": [ "editor" ], "Martinwguy2": [ "editor" ], "MarygoldRules": [ "editor" ], "Master tongue": [ "editor" ], "Masti": [ "steward", "vrt-permissions" ], "Math buff": [ "editor" ], "MathXplore": [ "global-rollbacker", "editor" ], "Mathildem16": [ "autoreview" ], "Mathmensch": [ "editor" ], "Mathmensch-Smalledits": [ "editor" ], "Mathmogeek": [ "editor" ], "Maths314": [ "editor" ], "Matiia": [ "editor" ], "Matrix": [ "autoreview", "vrt-permissions" ], "Matsievsky": [ "editor" ], "Mattb112885": [ "editor" ], "Mattbarton.exe": [ "editor" ], "Matttest": [ "autoreview" ], "Max": [ "global-renamer", "global-sysop" ], "Max Milas": [ "editor" ], "Maxim": [ "editor" ], "Maximillion Pegasus": [ "global-rollbacker", "editor" ], "Maxint2": [ "editor" ], "Mazbel": [ "global-rollbacker" ], "Mbch331": [ "vrt-permissions" ], "Mbrickn": [ "transwiki", "editor" ], "Mcdonnkm": [ "editor" ], "Mcld": [ "editor" ], "Mdkoch84": [ "editor" ], "Mdmckenzie": [ "editor" ], "MdsShakil": [ "steward", "vrt-permissions" ], "Mdupont": [ "editor" ], "Me Lendroz": [ "editor" ], "Meanmicio": [ "editor" ], "Mecanismo": [ "editor" ], "MediaKyle": [ "editor" ], "Meditation": [ "editor" ], "Meev0": [ "editor" ], "Mehman": [ "ombuds", "vrt-permissions" ], "Melos": [ "steward", "vrt-permissions" ], "MemicznyJanusz": [ "global-renamer" ], "Mendelivia~enwikibooks": [ "editor" ], "Meniktah": [ "editor" ], "Mercy": [ "global-rollbacker", "editor" ], "MerlLinkBot": [ "editor" ], "Mfield": [ "global-renamer" ], "Mh7kJ": [ "editor" ], "Michael Romanov": [ "editor" ], "MichaelFrey": [ "editor" ], "Michaelbluett": [ "editor", "uploader" ], "Mido": [ "vrt-permissions" ], "MihalOrela": [ "editor" ], "MiiCii": [ "editor" ], "Mike Hayes": [ "editor" ], "Mike.lifeguard": [ "editor" ], "Mild Bill Hiccup": [ "editor" ], "Mill3315": [ "editor" ], "Millbart": [ "vrt-permissions" ], "Mimarx": [ "editor" ], "Min1996": [ "autoreview" ], "Minorax": [ "global-rollbacker", "global-sysop", "editor" ], "Mirinano": [ "global-rollbacker" ], "Mithridates": [ "editor" ], "Mjbt": [ "editor" ], "Mjchael": [ "editor" ], "Mjkaye": [ "editor" ], "Mkline": [ "autoreview" ], "Mlipl001": [ "editor" ], "Moby-Dick4000": [ "editor" ], "Mohean": [ "editor" ], "Money-lover-12345": [ "editor" ], "Moonriddengirl": [ "autoreview", "vrt-permissions" ], "Mortense": [ "editor" ], "Mpfau": [ "editor" ], "Mr. Stradivarius": [ "editor" ], "MrAlanKoh": [ "editor" ], "MrJaroslavik": [ "global-rollbacker", "ombuds" ], "Mrajcok": [ "editor" ], "Mrjulesd": [ "editor" ], "Mrwojo": [ "editor" ], "Mschrag": [ "editor" ], "Msmithma": [ "editor" ], "MtPenguinMonster": [ "editor" ], "Mtarch11": [ "global-rollbacker", "global-sysop", "editor" ], "Musical Inquisit": [ "editor" ], "Mussklprozz": [ "vrt-permissions" ], "Mvolz": [ "editor" ], "Mwtoews": [ "editor" ], "Mxn": [ "editor" ], "Myklaw": [ "editor" ], "Mykola7": [ "steward" ], "Mys 721tx": [ "global-renamer", "vrt-permissions" ], "NDG": [ "global-rollbacker", "global-sysop", "editor" ], "Nadzik": [ "global-rollbacker", "global-renamer" ], "NahidSultan": [ "vrt-permissions" ], "Nangkhan Magar": [ "editor" ], "Natuur12": [ "vrt-permissions" ], "Nbarth": [ "editor" ], "Nbro": [ "editor" ], "Nehaoua": [ "ombuds" ], "Neils51": [ "editor" ], "Nemoralis": [ "vrt-permissions" ], "Neojacob": [ "editor" ], "Neriah": [ "global-rollbacker", "global-renamer" ], "Nesbit": [ "editor" ], "Newlisp": [ "editor" ], "Nfgdayton": [ "editor" ], "NguoiDungKhongDinhDanh": [ "global-rollbacker", "editor" ], "NhacNy2412": [ "global-renamer" ], "Nick.anderegg": [ "editor" ], "NickPenguin": [ "editor" ], "NicoScribe": [ "editor" ], "Nicole Sharp": [ "editor" ], "Nieuwsgierige Gebruiker": [ "editor" ], "Nigos": [ "autoreview" ], "Nihonjoe": [ "global-renamer" ], "Nikai": [ "editor" ], "Ninjastrikers": [ "vrt-permissions" ], "NipplesMeCool": [ "editor" ], "Njardarlogar": [ "editor" ], "Nobody60": [ "editor" ], "Nolispanmo": [ "vrt-permissions" ], "Nomstuff": [ "autoreview" ], "Nonenmac": [ "editor" ], "Norton": [ "editor" ], "Npettiaux": [ "editor" ], "Nsaa": [ "vrt-permissions" ], "Nthep": [ "vrt-permissions" ], "NuclearWarfare": [ "global-rollbacker", "editor" ], "OMSMike": [ "editor" ], "Officer781": [ "editor" ], "Oleander": [ "editor" ], "Oliviacatherall": [ "autoreview" ], "Omphalographer": [ "editor" ], "OnBeyondZebrax": [ "editor" ], "Onsen": [ "editor" ], "Ontzak": [ "global-renamer" ], "Orderud": [ "editor" ], "OrenBochman": [ "editor" ], "Oshwah": [ "global-renamer" ], "Ottawahitech": [ "editor" ], "Owain.davies": [ "editor" ], "PAC": [ "editor" ], "PAC2": [ "editor" ], "PK 97": [ "editor" ], "PNW Raven": [ "editor" ], "Pac8612": [ "editor" ], "Paloi Sciurala": [ "global-rollbacker" ], "Panic2k4": [ "transwiki", "editor" ], "Pascal Pignard": [ "editor" ], "Pastbury": [ "editor" ], "Pathfinders": [ "editor" ], "Pathoschild": [ "editor" ], "Patrik": [ "editor" ], "PauSix": [ "editor" ], "Paul James": [ "editor" ], "Pavroo": [ "editor" ], "PbakerODU": [ "editor" ], "Pbrower2a": [ "editor" ], "Pearts": [ "editor" ], "Peeragogia": [ "editor" ], "Peri Coleman": [ "editor" ], "Perl~enwikibooks": [ "editor" ], "Peter1180": [ "editor" ], "PeterEasthope": [ "editor" ], "Peyton09": [ "editor" ], "Phan M. Nhat": [ "autoreview" ], "PhilKnight": [ "global-renamer" ], "Phoebe": [ "editor" ], "Phosgram": [ "editor" ], "Pi zero": [ "editor" ], "PieWriter": [ "editor" ], "Piotrus": [ "editor" ], "Pithikos": [ "editor" ], "Pittsburgh Poet": [ "editor" ], "Pjpearce": [ "editor" ], "Pkkao": [ "editor" ], "Planotse": [ "editor" ], "Platonides": [ "vrt-permissions" ], "Pluke": [ "editor" ], "PlyrStar93": [ "global-rollbacker", "editor" ], "Pminh141": [ "global-renamer" ], "Pmlineditor": [ "editor" ], "Pmw57": [ "editor" ], "Poetcsw": [ "editor" ], "PoizonMyst": [ "editor" ], "Pola 2607": [ "autoreview" ], "Polimerek": [ "vrt-permissions" ], "Polluks": [ "editor" ], "Pookiyama": [ "editor" ], "Popski": [ "editor" ], "Povigna": [ "editor" ], "Ppolar bear": [ "global-rollbacker", "global-renamer" ], "Pppery": [ "autoreview" ], "Prahlad balaji": [ "editor" ], "Pratyeka": [ "editor" ], "Praxidicae": [ "global-rollbacker", "global-sysop", "editor" ], "Primefac": [ "vrt-permissions" ], "Prince Kassad~enwikibooks": [ "editor" ], "Pronesto": [ "editor" ], "Prototyperspective": [ "autoreview" ], "Psoup": [ "editor" ], "Psr1909": [ "editor" ], "PullUpYourSocks": [ "editor" ], "PurpleBuffalo": [ "global-renamer" ], "PurplePieman": [ "editor" ], "Purplebackpack89": [ "editor" ], "Putukas01": [ "editor" ], "Qenalcu": [ "autoreview" ], "Quebecguy": [ "global-rollbacker" ], "QueerEcofeminist": [ "global-rollbacker", "global-renamer", "editor" ], "Quinlan83": [ "global-rollbacker", "editor" ], "Quintucket": [ "editor" ], "Qwerty number1": [ "editor" ], "Qwertyus": [ "editor" ], "Qədir": [ "global-rollbacker", "global-renamer", "vrt-permissions" ], "R. Henrik Nilsson": [ "editor" ], "RAdimer-WMF": [ "global-rollbacker" ], "RDBury": [ "editor" ], "RJHall": [ "editor" ], "Ra'ike": [ "vrt-permissions" ], "Rachboots": [ "editor" ], "Rachel": [ "editor" ], "Rachmat04": [ "global-renamer", "vrt-permissions" ], "RadiX": [ "editor", "steward", "vrt-permissions" ], "Raffaela Kunz": [ "editor" ], "Rahulkepapa": [ "editor" ], "Ramac": [ "editor" ], "Rambam rashi": [ "editor" ], "Randykitty": [ "autoreview", "global-rollbacker" ], "RatónMístico176": [ "editor" ], "Ravichandar84": [ "editor" ], "Rawheatley": [ "editor" ], "Ray Trygstad": [ "editor" ], "RayeChellMahela": [ "editor" ], "Raymond": [ "vrt-permissions" ], "Razr Nation": [ "editor" ], "Rchaswms01": [ "editor" ], "Rcragun": [ "editor", "uploader" ], "Readyokaygo": [ "editor" ], "Recent Runes": [ "editor" ], "Redlentil": [ "editor" ], "Refcanimm": [ "editor" ], "Regasterios": [ "vrt-permissions" ], "Reinhard Kraasch": [ "vrt-permissions" ], "RenaissanceMan2144": [ "autoreview" ], "Renamed user 242094acfb1a5b2f08e9e78f2e021a40": [ "editor" ], "Renamed user 5f91ca71739b07cfce8397eed758fe13": [ "editor", "uploader" ], "Renamed user f26394dcb19bd7bdad78f0d752896653": [ "editor" ], "Renvoy": [ "global-rollbacker", "global-sysop" ], "Reseletti": [ "editor" ], "Retropunk": [ "editor" ], "Reuben1508": [ "autoreview" ], "Revi C.": [ "global-rollbacker", "global-renamer", "ombuds", "editor", "vrt-permissions" ], "Reyk": [ "editor" ], "Rfc1394": [ "editor" ], "Rgdboer": [ "editor" ], "Rgreenone": [ "editor" ], "Rhole2001": [ "autoreview" ], "Rich Farmbrough": [ "editor" ], "Rickstambaugh": [ "editor" ], "Riggwelter": [ "vrt-permissions" ], "Risk": [ "editor" ], "Risteall": [ "editor" ], "Ritjesman": [ "editor" ], "RoMancer": [ "editor" ], "Robbiemorrison": [ "editor" ], "Robert Huber~enwikibooks": [ "editor" ], "Roberto Mura": [ "editor" ], "Robertsky": [ "global-renamer", "vrt-permissions" ], "RobinH": [ "editor" ], "Rodasmith": [ "editor" ], "Rodrigo": [ "editor" ], "Rodrigo.Argenton": [ "vrt-permissions" ], "Rogerborrell": [ "editor" ], "Rogerdpack": [ "editor" ], "RogueScholar": [ "editor" ], "Romainbehar": [ "editor" ], "RomaineBot": [ "vrt-permissions" ], "RonaldB": [ "vrt-permissions" ], "Rosser1954": [ "editor" ], "Rotlink": [ "editor" ], "RoySmith": [ "ombuds" ], "Rozzychan": [ "editor" ], "Rplano": [ "editor" ], "Rreagan007": [ "autoreview" ], "Rrgreen": [ "editor" ], "Rschen7754": [ "global-rollbacker", "editor" ], "RshieldsVA": [ "editor" ], "Rsjaffe": [ "global-renamer" ], "Rtaisis": [ "editor" ], "Ruakh": [ "editor" ], "Rudolpho~enwikibooks": [ "editor" ], "Runfellow": [ "editor" ], "Runner4lyfe": [ "editor" ], "RunningBlind": [ "editor" ], "Ruthven": [ "vrt-permissions" ], "Ruud Koot": [ "transwiki", "editor" ], "Rzuwig": [ "autoreview", "global-rollbacker" ], "S.Marchenko": [ "global-renamer" ], "S8321414": [ "global-renamer" ], "SB Johnny": [ "editor" ], "SCP-2000": [ "global-rollbacker", "global-renamer", "vrt-permissions" ], "SHB2000": [ "sysop", "steward" ], "SPM": [ "editor" ], "Sae1962": [ "editor" ], "Safuan12616": [ "editor" ], "SahniM": [ "editor" ], "Sakretsu": [ "steward" ], "Sakura emad": [ "global-rollbacker" ], "Salil Kumar Mukherjee": [ "editor" ], "Samat": [ "vrt-permissions" ], "Sammy2012": [ "editor" ], "Samuel.dellit": [ "editor" ], "Samuele2002": [ "global-rollbacker", "editor" ], "Samwilson": [ "editor" ], "SanBonne": [ "global-rollbacker", "global-renamer", "vrt-permissions" ], "Sandbergja": [ "editor" ], "Sannita": [ "vrt-permissions" ], "Sante Caserio~enwikibooks": [ "editor" ], "SarahFatimaK": [ "editor" ], "Sargoth": [ "vrt-permissions" ], "Saroj": [ "global-rollbacker" ], "Sascha Lill 95": [ "editor" ], "Satdeep Gill": [ "vrt-permissions" ], "Savh": [ "global-rollbacker", "editor" ], "Sbb1413": [ "editor" ], "Scention": [ "editor" ], "Schniggendiller": [ "steward" ], "SchreiberBike": [ "editor" ], "Scott.beckman": [ "editor" ], "Sebastian Wallroth": [ "vrt-permissions" ], "Seewolf": [ "global-rollbacker", "vrt-permissions" ], "Sekidoki": [ "vrt-permissions" ], "Selden": [ "editor" ], "Sennecaster": [ "vrt-permissions" ], "Serinap": [ "editor" ], "Seth Miller": [ "editor" ], "SevenSpheres": [ "editor" ], "Sfan00 IMG": [ "editor" ], "Sfoerster": [ "editor" ], "Sgarrigan": [ "editor" ], "Sgowal": [ "editor" ], "Shaitand": [ "editor" ], "ShakespeareFan00": [ "editor" ], "SharingNotes": [ "editor" ], "Shawntanchinyang": [ "editor" ], "Shdwninja8": [ "editor" ], "ShelleyAdams": [ "autoreview" ], "ShifaYT": [ "global-rollbacker" ], "Shii": [ "editor" ], "Shira the Mogul": [ "editor" ], "Shlomif": [ "editor" ], "ShuBraque": [ "editor" ], "Sidelight12": [ "editor" ], "Sidorkin": [ "editor" ], "Sidpatil": [ "editor" ], "Siebengang": [ "editor" ], "Sigma 7": [ "editor" ], "Simon Peter Hughes": [ "editor" ], "Sinus46": [ "editor" ], "Sir Beluga": [ "editor" ], "Sir Lestaty de Lioncourt": [ "vrt-permissions" ], "SixWingedSeraph": [ "editor" ], "Sj": [ "editor" ], "Sjc~enwikibooks": [ "editor" ], "Sjlegg": [ "editor" ], "Sjone101": [ "editor" ], "Sjö": [ "global-rollbacker" ], "Skymath": [ "editor" ], "Slava Ukraini Heroyam Slava 123": [ "editor", "uploader" ], "Slava Ukrajini Heroyam Slava": [ "editor" ], "Sluffs": [ "editor" ], "Smjg": [ "editor" ], "SnappyDragonPennyroyal": [ "editor" ], "SocialKnowledge": [ "editor" ], "SoftwareEngineerMoose": [ "autoreview" ], "Sonia": [ "editor" ], "Sophie Cheng": [ "editor" ], "Sotiale": [ "steward" ], "Soul windsurfer": [ "editor" ], "SouthParkFan65": [ "editor" ], "SoylentGreen": [ "editor" ], "Spamduck": [ "editor" ], "Spaynton": [ "editor" ], "Spender2001": [ "editor" ], "Speregrination": [ "editor" ], "Spiderworm": [ "editor" ], "Spoon!": [ "editor" ], "Squasher": [ "global-renamer" ], "Srhat": [ "editor" ], "Stang": [ "global-rollbacker", "editor", "vrt-permissions" ], "Stanglavine": [ "editor" ], "Steinsplitter": [ "global-renamer", "vrt-permissions" ], "StephT0704": [ "autoreview" ], "Stepheng3": [ "editor" ], "Stepro": [ "vrt-permissions" ], "Steve M": [ "editor" ], "Stilfehler": [ "editor" ], "Stockywood": [ "editor" ], "Storeye": [ "editor" ], "Strainu": [ "vrt-permissions" ], "Strange quark": [ "editor" ], "Stryn": [ "global-rollbacker", "editor" ], "Stïnger": [ "global-rollbacker", "editor" ], "Suchenwi": [ "editor" ], "Sumone10154": [ "editor" ], "SunCreator": [ "editor" ], "Sunny Cryolite": [ "global-rollbacker" ], "Sunshineconnelly": [ "editor" ], "SuperTyphoonNoru": [ "editor" ], "Superbass": [ "vrt-permissions" ], "Superpes15": [ "global-rollbacker", "global-renamer", "global-sysop", "vrt-permissions" ], "Supertoff": [ "vrt-permissions" ], "Superzerocool": [ "vrt-permissions" ], "SupremeUmanu": [ "editor" ], "Suruena": [ "editor" ], "Sutambe": [ "editor" ], "Sutton Publishing": [ "editor" ], "Sué González Hauck": [ "editor" ], "Svartava": [ "global-rollbacker", "global-renamer", "global-sysop", "editor" ], "SweetCanadianMullet": [ "editor" ], "Swift": [ "editor" ], "SyG": [ "editor" ], "Sylvesterchukwu04": [ "editor" ], "Sylvialim": [ "editor" ], "Sylviaread": [ "editor" ], "Synoman Barris": [ "global-rollbacker", "transwiki", "editor" ], "Syum90": [ "global-rollbacker", "editor" ], "Syunsyunminmin": [ "global-rollbacker", "global-renamer", "global-sysop", "editor" ], "T.seppelt": [ "editor" ], "TDang": [ "editor" ], "TTWIDEE": [ "editor" ], "Tahmid": [ "editor" ], "Taketa": [ "global-renamer" ], "Takipoint123": [ "vrt-permissions" ], "TakuyaMurata": [ "editor" ], "Tamzin": [ "global-renamer" ], "Tanbiruzzaman": [ "global-rollbacker", "global-renamer", "global-sysop", "editor", "vrt-permissions" ], "Tannertsf": [ "editor" ], "Taoheedah": [ "editor" ], "Tapsevarg": [ "editor" ], "TaronjaSatsuma": [ "vrt-permissions" ], "Taxman": [ "editor" ], "Tchoř": [ "global-renamer" ], "Tdkehoe": [ "editor" ], "Tdvorak": [ "editor" ], "Techman224": [ "editor" ], "Tegel": [ "editor", "steward" ], "Teles": [ "ombuds", "steward", "vrt-permissions" ], "Tem5psu": [ "editor" ], "Tempodivalse": [ "editor" ], "TenWhile6": [ "global-rollbacker", "global-renamer", "global-sysop", "editor" ], "Tenshi Hinanawi": [ "autoreview", "global-rollbacker" ], "Terence Kearey": [ "editor" ], "Ternarius": [ "global-renamer" ], "Ternera": [ "global-rollbacker", "global-renamer", "global-sysop", "editor" ], "Tesleemah": [ "editor" ], "Tevfik AKTUĞLU": [ "editor" ], "Tgregtregretgtr": [ "editor" ], "ThatBPengineer": [ "autoreview" ], "Thatonewikiguy": [ "editor" ], "The Squirrel Conspiracy": [ "vrt-permissions" ], "The labs": [ "editor" ], "TheGoodEndedHappily": [ "vrt-permissions" ], "ThePCKid": [ "editor" ], "TheSandDoctor": [ "global-renamer", "vrt-permissions" ], "Theknightwho": [ "editor" ], "Thenub314": [ "editor" ], "Theo Hughes": [ "editor" ], "Theornamentalist": [ "editor" ], "Thereen": [ "editor" ], "Thewinster": [ "editor" ], "Thierry Dugnolle": [ "editor" ], "Thinkglobalnow": [ "editor" ], "Thirunavukkarasye-Raveendran": [ "editor" ], "Thomas Simpson": [ "editor" ], "Thomas.haslwanter": [ "editor" ], "Thomas.lochmatter": [ "editor" ], "Tibetologist": [ "editor" ], "Tigerzeng": [ "global-rollbacker" ], "Tiled": [ "editor" ], "TimBorgNetzWerk": [ "editor" ], "Timothy Gu": [ "editor" ], "Timpo": [ "editor" ], "Tiptoety": [ "editor" ], "Tjyang": [ "editor" ], "Tlustulimu": [ "editor" ], "Tmvogel": [ "editor" ], "Tom Morris": [ "editor" ], "Tomato86": [ "editor" ], "TommyG": [ "vrt-permissions" ], "Tomt87": [ "editor" ], "Tomybrz": [ "editor" ], "Tonyvall": [ "autoreview" ], "Tp42": [ "editor" ], "Tracklayingninja": [ "editor" ], "Tradimus": [ "editor" ], "Tropicalkitty": [ "global-rollbacker", "editor" ], "TrulyShruti": [ "editor" ], "Ts12rAc": [ "global-rollbacker" ], "Tsarina CatarinaToo": [ "autoreview" ], "TunnelESON": [ "sysop" ], "Turbojet": [ "vrt-permissions" ], "Turkmen": [ "editor" ], "TwoThirty": [ "editor" ], "Tyoyafud": [ "editor" ], "Túrelio": [ "autoreview" ], "U$3rname008": [ "editor" ], "USSR-Slav": [ "global-rollbacker" ], "Uf.hun2201": [ "editor" ], "Uncitoyen": [ "global-rollbacker", "global-renamer" ], "Uncle G": [ "editor" ], "Unixxx": [ "editor" ], "User01938": [ "editor" ], "Username222": [ "editor" ], "Utcursch": [ "vrt-permissions" ], "Uziel302": [ "editor" ], "Uzume": [ "editor" ], "V0lkanic": [ "global-renamer" ], "VIGNERON": [ "steward" ], "Valery Starikov": [ "editor" ], "Van der Hoorn": [ "editor" ], "Varnent": [ "vrt-permissions" ], "Vdolar": [ "autoreview" ], "VectorVoyager": [ "editor" ], "Venzz": [ "vrt-permissions" ], "Verfassungsfreund": [ "editor" ], "Veritas Sapientiae": [ "global-rollbacker", "global-renamer", "vrt-permissions" ], "Vermont": [ "editor", "steward", "vrt-permissions" ], "Victor Stefan Stoica": [ "autoreview" ], "Victor Trevor": [ "autoreview" ], "Victoria.sandeman": [ "autoreview" ], "Vincent Vega": [ "global-renamer" ], "Vito Genovese": [ "editor" ], "Vituzzu": [ "editor" ], "Vladimir Solovjev": [ "global-renamer", "vrt-permissions" ], "Vogone": [ "global-rollbacker", "editor" ], "Vossman": [ "editor" ], "Vrinda": [ "editor" ], "VulcanWikiEdit": [ "editor" ], "Vwanweb": [ "editor" ], "WOSlinker": [ "autoreview" ], "Waihorace": [ "global-rollbacker" ], "Waldyrious": [ "editor" ], "WalshDay": [ "editor" ], "Wargo": [ "editor" ], "Wbjimmyd": [ "editor" ], "Wcoole": [ "editor" ], "WeelkyWikiReader": [ "editor" ], "Wekeepwhatwekill": [ "autoreview" ], "WereSpielChequers": [ "editor" ], "What no2000": [ "editor" ], "WhatamIdoing": [ "editor" ], "WhitePhosphorus": [ "global-rollbacker", "global-sysop" ], "Whiteknight": [ "editor" ], "Whoop whoop pull up": [ "editor" ], "Whym": [ "editor", "vrt-permissions" ], "Wiki13": [ "editor" ], "WikiBayer": [ "global-rollbacker", "global-sysop", "editor" ], "WikiFer": [ "vrt-permissions" ], "Wikimi-dhiann": [ "editor" ], "Wikiotics": [ "editor" ], "Wikiwau": [ "autoreview", "editor" ], "WillNess": [ "editor" ], "Willscrlt": [ "editor" ], "Wim b": [ "global-rollbacker", "global-sysop", "editor" ], "Wisden": [ "editor" ], "Withinfocus": [ "editor" ], "Wj32": [ "editor" ], "Wkee4ager": [ "editor" ], "Wobbit": [ "editor" ], "Wojciech Pędzich": [ "vrt-permissions" ], "Wooze": [ "global-rollbacker" ], "Wundermacht": [ "editor" ], "Wutsje": [ "global-rollbacker", "editor" ], "Ww2censor": [ "vrt-permissions" ], "Wüstenspringmaus": [ "global-rollbacker", "global-renamer" ], "XXBlackburnXx": [ "editor", "steward" ], "Xandradi": [ "editor" ], "Xania": [ "sysop", "checkuser" ], "Xaosflux": [ "editor", "steward" ], "XenonX3": [ "vrt-permissions" ], "Xerol": [ "editor" ], "Xeverything11": [ "editor", "uploader" ], "Xhungab": [ "editor" ], "Xinkai Wu": [ "editor" ], "Xixtas": [ "editor" ], "Xqt": [ "global-rollbacker" ], "Xxagile": [ "editor" ], "Xypron": [ "editor" ], "Xz64": [ "editor" ], "Y-S.Ko": [ "editor" ], "YMS": [ "editor" ], "Yahya": [ "steward", "vrt-permissions" ], "Yamla": [ "global-renamer" ], "Yann": [ "editor" ], "Yerpo": [ "global-renamer", "vrt-permissions" ], "Yikrazuul": [ "editor" ], "Ymblanter": [ "global-rollbacker" ], "Yndesai": [ "editor" ], "Youssefsan": [ "editor" ], "Ysangkok": [ "editor" ], "Yvelik": [ "uploader" ], "Yzmo": [ "editor" ], "ZI Jony": [ "editor" ], "Zabe": [ "global-rollbacker" ], "Zafer": [ "ombuds" ], "Zedshort": [ "editor" ], "ZeroOne": [ "editor" ], "Zetud": [ "global-rollbacker", "vrt-permissions" ], "Ziv": [ "editor" ], "Zoeannl": [ "editor" ], "Zollerriia": [ "editor" ], "Zoohouse": [ "editor" ], "Zoot": [ "editor" ], "Zsohl": [ "autoreview", "editor" ], "Zvsmith": [ "editor" ], "Zweighaft": [ "editor" ], "ZxxZxxZ": [ "editor" ], "~riley": [ "global-rollbacker", "editor" ], "Érico": [ "global-renamer" ], "İmmortalance": [ "global-renamer" ], "Виктор Пинчук": [ "editor" ], "Воображение": [ "editor" ], "Всевидящий": [ "global-rollbacker" ], "Д.Ильин": [ "editor" ], "Л.П. Джепко": [ "editor" ], "יהודה שמחה ולדמן": [ "editor" ], "מקף": [ "global-rollbacker", "global-renamer" ], "د. فارس الجويلي": [ "global-renamer" ], "روتانا": [ "global-renamer" ], "علاء": [ "steward", "vrt-permissions" ], "فيصل": [ "global-renamer", "vrt-permissions" ], "सीमा1": [ "editor" ], "タチコマ robot": [ "editor" ], "ネイ": [ "global-renamer" ], "一隻北極熊": [ "editor" ], "人间百态": [ "global-rollbacker" ], "臺灣象象": [ "autoreview" ], "范": [ "vrt-permissions" ], "青子守歌": [ "vrt-permissions" ], "魔琴": [ "global-rollbacker" ], "ꠢꠣꠍꠘ ꠞꠣꠎꠣ": [ "editor" ], "기나ㅏㄴ": [ "global-rollbacker", "global-renamer" ] } eplf7a8mnfwvjpp7hcq87fanlokv7bz User talk:Lemonaka 3 471898 4669030 4467512 2026-09-05T23:26:40Z Jonhson3029 3625272 /* Hello! */ new section 4669030 wikitext text/x-wiki {{Talk header}} == Welcome == <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Lemonaka!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> <div style="clear:both;"> </div> <sup>&#8212; [[User:L10nM4st3r|<span style="color:#c71300">L10nM4st3r</span>]]</sup> / <sub>[[User talk:L10nM4st3r|<span style="color:#ce3f00">'''ROAR''' at me!</span>]]</sub> 15:38, 15 January 2025 (UTC) == Hello! == Hello! [[User:Jonhson3029|Jonhson3029]] ([[User talk:Jonhson3029|discuss]] • [[Special:Contributions/Jonhson3029|contribs]]) 23:26, 5 September 2026 (UTC) lju6tj0u8kq9yx4j59gwmf1f2m9a3tq 4669032 4669030 2026-09-05T23:53:09Z Codename Noreste 3441010 [[WB:REVERT|Reverted]] edit by [[Special:Contributions/Jonhson3029|Jonhson3029]] ([[User talk:Jonhson3029|talk]]) to last version by L10nM4st3r 4467512 wikitext text/x-wiki {{Talk header}} == Welcome == <div style="text-align:center; font-size:110%; font-weight:bold;">[[Wikibooks:Welcome|Welcome]] to Wikibooks, Lemonaka!</div> <!-- FIRST COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7;"> <div style="border-bottom:1px solid #15304f; background-color:#89b5e7; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Crystal Clear app kedit.png|20px|link=|alt=]] '''First steps tutorial'''</div> <div style="padding:0.4em 1em 0.3em 1em;"> '''Wikibooks is for [[WB:AGF|collaborative]] development of free&nbsp;[[WB:WIW|textbooks]].''' You do not need technical skills to [[Using Wikibooks|contribute]]. You can [[WB:BOLD|easily change most books]]. Please [[WB:CHAT|introduce yourself]], and let us know what [[WB:PROJECTS|interests you]]. If you already contribute at other Wikimedia projects, our [[Wikibooks:Wikibooks for Wikimedians|Wikimedia Orientation]] should quickly get you started. </div> </div> <div class="collapsible" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Icon apps query.svg|20px|link=|alt=]] '''Getting help'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Read the [[Using Wikibooks]] book for a friendly introduction to the project, or our [[Help:Contents|help pages]] for more information. * You can get friendly help from the community in the [[WB:HELP|user assistance room]] or our [[irc:wikibooks|IRC channel]]. * Upload freely licensed files to [[commons:Wikimedia Commons|Wikimedia Commons]]. You may [[WB:RFP|request permission]] to upload [[w:fair use|fair use]] files locally. Please include author and source {{tl|information}} and a {{nowrap|{{tl|non-free use rationale}}}} for [[WB:FU|non-free]] files. </div> </div> </div> <!-- SECOND COLUMN --> <div style="width:49.5%; float:left; margin:0em; padding:0em;"> <div class="collapsible" style="margin:0.2em; border:1px solid #14304f; background-color:#f4eed7; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Nuvola filesystems trashcan full.png|20px|link=|alt=]] '''Made a mistake?'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * You can [[WB:REVERT|restore]] a previously saved version. * Pages should follow the [[WB:NP|<code>'''Book Title/Chapter Title'''</code>]] naming convention. * Need to rename a page? Use the ''move'' tab (is available once your account is 4 days old - until then, ask for [[WB:HELP|help]]). * To request a page be deleted, add {{tlx|delete|''your reason''}} to the top of the page. * Was a page you made deleted? Please read the [[WB:DP|deletion policy]], and check the [[Special:Log/delete|deletion log]] to find out why. Also check the [[WB:RFD|RFD]] archives if applicable. You can request undeletion at [[WB:RFU]], or ask the administrator who deleted the page. </div> </div> <div class="collapsible selected" style="margin:0.2em; border:1px solid #15304f; background-color:#f4eed7; text-align:left;"> <div class="title" style="border-bottom:1px solid #15304f; background-color:#89b5e7; padding:0.2em 0.5em; font-size:110%; font-weight:bold;">[[File:Transmission icon.png|20px|link=|alt=]] '''Goodies, tips and tricks'''</div> <div class="NavContent" style="padding:0.4em 1em 0.3em 1em;"> * Please fill in [[WB:ES|the edit summary]] and [[WB:PREVIEW|preview]] your edits before saving. * Sign your name on [[WB:TALK|discussion pages]] by typing &#126;&#126;&#126;&#126; * User scripts can make many tasks easier. Look at the ''Gadgets'' tab of [[Special:Preferences|''my preferences'']]; check off the boxes for the scripts you want, and hit ''save''! </div> </div> </div> <div style="clear:both; padding-right:1em; text-align:right; font-size:smaller">(Would you like to provide [[Template talk:Bigwelcome|feedback]] on this message?)</div> <div style="clear:both;"> </div> <sup>&#8212; [[User:L10nM4st3r|<span style="color:#c71300">L10nM4st3r</span>]]</sup> / <sub>[[User talk:L10nM4st3r|<span style="color:#ce3f00">'''ROAR''' at me!</span>]]</sub> 15:38, 15 January 2025 (UTC) 2waronj0mft3910wkng5l24r3e0wim8 General Literary Chinese from Scratch 0 481710 4669033 4660283 2026-09-06T00:07:57Z Shira the Mogul 3560559 /* Unit 1: Basic Skills */ I have thoroughly neglected the culinary side of this, but found a recipe that works perfectly. 4669033 wikitext text/x-wiki __notoc__ Welcome to the Wikibook for Literary Chinese (Known as 漢文 "Han Language" in East Asia or 文言 "Literary Language" in China), aimed at individuals hoping to gain a general knowledge of it before progressing into genres they wish to be acquainted with. This is not the [[Classical Chinese]] textbook, which is aimed at Chinese Zhou-Qin era texts. This text aims to shed light on post-Zhou-Qin texts across East Asia, which mimic those texts. However, as Zhou-Qin era texts served as the main body from which individuals learned, they are employed here as and when they are considered necessary or otherwise useful. It does so through a "buffet" approach, showering you, the reader, with an ocean of texts of myriad genre. ==Table of Contents== === Front matter === * [[/Introduction/]] * [[/Appendices/]] === Useful resources === These are quick grab-bags that can be useful for vocabulary-building. * [[/Antonym List/]] <!--- 文/武,大/小,厚/薄,橫/縱...---> * [[/Collocation Groups/]] <!--- e.g. 四象,三靈…… ---> * [[/Pronoun Table/]] * [https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/嚴譯及部定詞等 Yan Fu's Qing-era translations for modern terms] <!--- Wikiversity has this (https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/嚴譯及部定詞等) and the below, I will effectively be translating a lot of it! ---> * [https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/上古語考輯 Communicative Terms] <!--- this will be translated eventually, but right now it's bad to just leave this here. ---> === Useful primers === Across history, many primers have been made for teaching Literary Chinese to children. These are a few that are recommended for use alongside this work, ideally in flashcards. * [https://www.fdgwz.org.cn/Web/Show/11308 倉頡篇] - Cangjie's Chapters, the earliest one. It is extant, but incomplete. It contains several rare characters, and so if used, I would personally recommend doing so later, or out of interest. * 三字經 - The Three Character Classic, an excellent piece for Confucian education. Pair with 弟子规 for best results. ** 三字經(太平天國版)- For Christians, there is a version made by Hong Xiuquan from the Taiping Rebellion. Despite the context, it is a legitimately useful primer and can be used to self-teach for the Delegate's Edition of the Christian Bible. * 千字文 - The Thousand Character Classic, a remarkable piece of constrained writing that only uses each character once. Amazing for building vocabulary whilst seeing historical allusions and the like. * 五字鑑 - The Five-Character Mirror, essentially the 24 Histories of China compressed into a primer. Uses 5-character couplets, the longest in this list. * 龍文鞭影 - The Shadow of Longwen's Whip, a historical allusion trainer. Best paired with a context piece. ===Unit 0: The Han script=== This unit is intended for those with no familiarity of the Han script. It will prepare you for the units ahead, teaching largely pictographic characters. By the end of this unit, students will: * Recognise around 50 characters. * Understand how characters are composed and how this gives them meaning. * Have a basic idea of how to handwrite and/or type characters using the Cangjie Input Method. * Know some bare basics of Literary Chinese grammar (e.g. Basic word order, where adjectives go, lack of "is", 有...) Lessons: # [[/An Introduction to the Han Script/]] # [[/People, Big and Small/]] # [[/How do we write Chinese?/]] # [[/What are Chinese characters, anyway?/]] # [[/The Sun, the Moon, and the Five Elements/]] # [[/Getting Familiar with Body Parts/]] # [[/Using Numbers and Using Weapons/]] <!--- 竹戈十大中一弓廿卜---> # [[/Tilling the Fields with 有/]] <!--- 山田 ---> # [[/How Characters are Made/|How Characters are Made with Kiyohara no Sanemoto]] # [[/Cangjie Created Characters/]] <!--- Get people to use Cangjie ---> # [[/The Kangxi Radical System/]] <!--- Introduce some monoradical texts to train recognition. ---> ===Unit 1: Basic Skills=== This unit is intended for those with minimal familiarity with the Han script and no familiarity with Literary Chinese. There is a focus on simple structures, skills for dissecting common textual structures, and short-form poetry in this unit. Before starting this unit, students should: * Recognise around ~30 characters. * Can use Cangjie input. * Have given Unit 0 a cursory glance. <br> By the end of this unit, students will: * Recognise around ~100 characters. * Comprehend numbers, the Heavenly Stems, and the Earthly Branches, and be able to use them to quantify time and date. * Intuit the basic topic -> comment idea behind Literary Chinese. "This, it is..." * Understand basic function words such as 也, 而, 有, and 謂. Lessons: # [[/The All-Purpose 也/]] # [[/An Introduction to Chinese Numbers/]] <!--- It is hard to find authentic materials for this ---> # [[/One, Two, Left, and Right with Gongsun Long/]] <!--- 曰:「二有一乎?」 曰:「二無一。」 曰:「二有右乎?」 曰:「二無右。」 曰:「二有左乎?」 曰:「二無左。」 曰:「右可謂二乎?」 曰:「不可。」 曰:「左可謂二乎?」 曰:「不可。」 曰:「左與右可謂二乎?」 曰:「可。」 ---> # [[/The Heavenly Stems/]] <!--- Introduce ordinals, which will be used to demonstrate sentence patterns later. ---> # [[/Tell the Time with Earthly Branches/]] <!--- Introduce verbs and timekeeping ---> # [[/Lunar Dates with the Spring and Autumn Annals/]] <!--- Vocabulary: 歲,年,朔,月,日,來,前,初,正,春秋夏冬,曆,上,下. Consider including traditional names for months in a list. ---> # [[/Skimming for Major Events in Historical Annals/]] <!--- Don't simply use Confucius's Chunqiu: We can use texts inspired by it. E.g. 三國史記 - 十五年京城旱。秋七月,蝗。very few new characters, lots one can use. Instantly able to use. https://zh.wikisource.org/wiki/%E4%B8%89%E5%9C%8B%E5%8F%B2%E8%A8%98/%E5%8D%B701 Skimming annals is very possible and a very useful skill. Don't skip out on it. Teach students to skim read!!! ---> # [[/Dinner with the Daimyo/]] <!-- 侍宴·大友皇子 皇明光日月,帝徳載天地。 三才併秦昌,万国表臣義。 --> # [[/In Discourse with Jibong/]] <!-- 芝峰類說 倭國謂田爲畠。謂水田爲田。火田爲畑。猶我國以水田爲畓也。故官名有畠山殿。地名有畑島云。 --> # [[/How do we Write Height and Weight?/]] <!--- Hilarious oversight ---> # [[/Eating like a Zhou Aristocrat/]] # [[/Shinto FAQ with Honda Chikaatsu/]] <!--- https://wikisource.org/wiki/%E7%9C%9E%E9%81%93%E5%95%8F%E5%B0%8D 眞道問對 本田親徳 really good way of operationalising 乎 and much of the early grammar. 問 天帝無始無終乎。 對 天帝無始無終也。 旣以無始無終之力 與無始無終之體 造無始無終之萬物。 其功亦無始無終也。 問 天地大原在道乎。 對 天地大原實在道。 鬼神依道而立。 人民依道而活。 萬物依道而息。 This is great! ---> <!--- Some cool stuff I saw someone studying from https://zh.wikisource.org/wiki/%E8%87%B3%E5%B0%8F%E4%B8%98%E8%A5%BF%E5%B0%8F%E7%9F%B3%E6%BD%AD%E8%A8%98# https://zh.wikisource.org/wiki/%E6%A0%B8%E8%88%9F%E8%A8%98 Could be used for period focus ---> ===Unit 2: An Overview of Sinitic Poetry=== This unit will teach you how Sinitic Poetry operates; - that is, the way individuals in the Sinosphere compose poetry in Literary Chinese. Despite this language's fall out of favour in the past century, this tradition is still remarkably alive and well, and their short length makes them more accessible than elaborate prose. In this unit, you will begin from the ''Classic of Poetry'' before travelling through poems from the Tang dynasty, Singapore, Japan, Vietnam, the Ryukyu Kingdom, and Korea. When introducing poetry, I will furthermore use the language from the nation it is from to show how it is recited by its people. After discussing the Classic of Poetry, we will also be a small detour into a discussion on Ping-Ze 平仄, the Tang dynasty system of alternating tones, so to produce rhyme on tonal and phonological levels. This had a major impact on Literary Chinese poetry as a whole! By the end of this Unit, students will: * Recognise around 120 more characters. * Be able to explain how Sinitic Poetry rhymes and the themes it contains. * Be able to use function words such as 在, 無, 不, 聿, and 于/於 in poetic contexts. * Recognise the switch between 吾/我 in the subject-object positions and demonstrate it in usage. * (Chinese speakers) Be able to differentiate 于 and 於, and understand the "interest(ed) in" meaning of 好 in most circumstances. <!--- Summary of the above part about 于 and 於 for other editors: 于 and 於 were distinct words for an extremely long time and were still such to Literary Chinese writers. Their "merging" through Simplified-Traditional Chinese distinctions is a very modern thing. I will summarise their usages here, using Pulleyblank's Outline of Classical Chinese Grammar (2000); * 于 - This can mean "to go" or "to/at". 黃鳥于飛 "The yellow birds go flying". Must be post-verbal. It can also appear in 至于. * 於 - This is an all-purpose locative preposition - from "on/at/in" to "from" or even "than" (甲於乙). The implication of motion is not there at all. Must be pre-verbal. It can also appear in 之於 or be an archaic noun for a crow 於 (烏). ---> Lessons: # [[/Across the Rivers with Emperor Puliuru Guang/]] <!--- Illustrate ping-ze ---> # [[/To Study the Odes/]] # [[/A Detour into Orthodox Ping-Ze/]] <!--- 平 and 仄 are useful characters themselves. Show 仄 in the binomes 反仄,歉仄,逼仄 as it's often difficult to immediately use ---> # [[/The Restraint of Du Fu/]] # [[/The Longing of Li Bai/]] # [[/The Environment with Bukha Timur/]] # [[/Pillow Talk with Guan Yunshi/]] <!--- 紅繡鞋·貫雲石 挨著靠著雲窗同坐,偎著抱著月枕雙歌,聽著數著愁著怕著早四更過。四更過情未足,情未足夜如梭。天哪,更閏一更兒妨甚么! Uyghur author! ---> # [[/Buddhist Philosophy with Ngô Chân Lưu and Taisei Shōan/]] <!-- 元火·吳真流 木中元有火,元火復還生。 若為木無火,鉆燧何有萌。--> <!-- 杜鵑·大成聖安 夢覚孤床静 杜鵑帯雨飛 一声来近枕 何者不沾衣 --> # [[/Odes with Mō Taiei and Zheng Chengxun/]] <!-- 詠松·毛泰永 植體宜千仞,垂陰動百尋。 李膺真烈烈,和嶠自森森。 桃李何堪較,雪霜安得侵。 萬年身不老,種子又成林。 AKA Inoha Seiki 伊野波 盛紀 --> <!-- 詠班蘭·鄭成勛 南國多芳草,班蘭最有名。 深根將綠茁,長葉亦叢生。 取味迎賓合,入厨任水烹。 可憐經一用,擲棄不留情。 鄭成勛《樵隱詩集》 https://nus.edu.sg/nuslibraries/dsprojects/sg-jiutishi/poem/827 --> # [[/A Golden Cup and the Fall of a Dynasty with Yan Fu/]] # [[/On a Journey with Sadula/]] <!--- No lesson entry: 朝中措·襄陽古道灞陵橋 襄陽古道灞陵橋,詩興與秋高。 千古風流人物,一時多少雄豪。 霜清玉塞,雲飛隴首,風落江皋。 夢到鳳凰台上,山圍故國周遭。 北郊晚步 陂水荷凋晚,茅檐燕去涼。 遠林明落景,平麓淡秋光。 群牧歸村巷,孤禽立野航。 自諳閑散樂,園圃意尤長。 Jurchen poet and grandson of Emperor Shizong of Jin. He's a Zen Buddhist, so we'll go back to him later. ---> ===Unit 3: Confucianism and the World=== This is a Confucian-themed unit with a smattering of other items. You will see the odd geography of the past, early linguistic philosophy, and terrifying breakaway states! By the end of this unit, students should be able to: * Recognise around 200+ characters. * Read basic annals and histories with some dictionary assistance, and comprehend 3-character structures reliably. * Have encountered basic grammatical points such as 之、乎、者、也、而、則、乃、所、以、於、于、與、且、蓋、and 夫. ** 於 and 于 should be distinguishable. * Survive a text of at least 250 characters and read for gist. Lessons: # [[/A Brief Overview of Confucianism/]] # [[/Teaching the Annals in Qi/]] <!-- Gongyang Gao's commentary --> # [[/Is a White Horse a Horse?/]]<!-- Teach negation with 非 in 公孙龍子 and compare with 不 --> # [[/The Three Character Classic/]] # [[/Expressing Filial Conduct with Confucius and Hara Saihin/]] <!-- 次韻杏坪先生 父執有君孤不孤 相依遍接搢紳徒 区区自抱地方寸 杳杳重遊天一隅 羇雁飛鳴迷汝國 家人思夢入江都 如教志業青年遂 世上寧無逐臭夫 --> # [[/Confucianism and the Environment with Sai On/]]<!-- 木假山記 --> # [[/In Debate with Mencius/]] ===Unit 4: Women's Writing=== In this unit, women's writing from various areas of China will be explored. This is chiefly targeted at poetry and the themes within; from the feminine voice of the Classic of Poetry to the remonstrance towards the Khitan Emperor Tianzuo of Jin by his Consort Dasese. The role of women in courtly society is to be elucidated here! # [[/An Unmarried Life with Heo Nansŏrhŏn/]] <!--- 貧女吟 豈是乏容色。工鍼復工織。 少小長寒門。良媒不相識。 夜久織未休。戛戛鳴寒機。 機中一匹練。終作阿誰衣。 手把金翦刀。夜寒十指直。 爲人作嫁衣。年年還獨宿。 ---> # [[/Responding to Lord Trần with Hồ Xuân Hương/]] <!--- Responding to 陳光靜 Trần Quang Tĩnh 《和陳侯》 愧無才調使人驚,十載風塵貫耳鈴。 已是臨枰知敵手,莫須敲月苦殫精。 為輪為彈隨遭遇,誰鳳誰鶯任賦生。 造物於人何苟惜,明珠休向暗中呈。 莫須 is an important structure to teach here. ---> # [[/Gaze into the Autumn Night with Taisei Shōan/]] <!--- 秋夜偶成·大成聖安 長天浮爽気,月色興無窮 群犬吠山径,百蟲啼野風 悲秋秋夜永,感古古今同 自是孤窓下,凄然万慮空 ---> # [[/Visiting a Temple with Yu Xuanji/]] <!--- 遊崇真觀南樓覩新及第題名處 雲峰滿目放春晴,歷歷銀鈎指下生。 自恨羅衣掩詩句,擧頭空羨榜中名。 ---> # [[/Remonstrance with Dasese/]] <!--- https://zh.wikisource.org/wiki/%E8%AB%B7%E8%AB%AB%E6%AD%8C 諷諫歌·大瑟瑟 勿嗟塞上兮暗紅塵。 勿傷多難兮畏夷人。 不如塞奸邪之路兮選取賢臣。 直須臥薪嚐膽兮激壯士之捐身。 可以朝清漠北兮夕枕燕雲。 Dasese (or 萧瑟瑟) was a Khitan consort to Emperor Tianzuo of Liao. She remonstrated him as the Jurchens were beginning to encroach upon the Khitan, and was forced to commit suicide for her remonstrance. Tianzuo would soon pay for his malfeasance. ---> # [[/The Love Songs of the Odes/]] <!--- 褰裳 子惠思我,褰裳涉溱。子不我思,豈無他人?狂童之狂也且! 子惠思我,褰裳涉洧。子不我思,豈無他士?狂童之狂也且! 柏舟 彼柏舟,在彼中河,髧彼兩髦,實維我儀,之死矢靡它,母也天只,不諒人只。 汎彼柏舟,在彼河側,髧彼兩髦,實維我特,之死矢靡慝,母也天只,不諒人只。 行露 厭浥行露,豈不夙夜,謂行多露。 誰謂雀無角?何以穿我屋?誰謂女無家?何以速我獄?雖速我獄,室家不足。 誰謂鼠無牙?何以穿我墉?誰謂女無家?何以速我訟?雖速我訟,亦不女從。 ---> # [[/Rules for Women with Ban Zhao/]] <!--- https://zh.wikisource.org/wiki/%E5%A5%B3%E8%AA%A1 ---> # [[/The Tragedy of Cai Wenji/]] <!--- 悲憤詩 〔兩漢〕蔡文姬 漢季失權柄,董卓亂天常。 志欲圖篡弒,先害諸賢良。 逼迫遷舊邦,擁主以自強。 海內興義師,欲共討不祥。 卓眾來東下,金甲耀日光。 平土人脆弱,來兵皆胡羌。 獵野圍城邑,所向悉破亡。 斬截無孑遺,屍骸相撐拒。 馬邊懸男頭,馬後載婦女。 長驅西入關,迥路險且阻。 還顧邈冥冥,肝脾為爛腐。 所略有萬計,不得令屯聚。 或有骨肉俱,欲言不敢語。 失意幾微間,輒言斃降虜。 要當以亭刃,我曹不活汝。 豈復惜性命,不堪其詈罵。 或便加棰杖,毒痛參並下。 旦則號泣行,夜則悲吟坐。 欲死不能得,欲生無一可。 彼蒼者何辜,乃遭此厄禍。 邊荒與華異,人俗少義理。 處所多霜雪,胡風春夏起。 翩翩吹我衣,肅肅入我耳。 感時念父母,哀嘆無窮已。 有客從外來,聞之常歡喜。 迎問其消息,輒復非鄉里。 邂逅徼時願,骨肉來迎己。 己得自解免,當復棄兒子。 天屬綴人心,念別無會期。 存亡永乖隔,不忍與之辭。 兒前抱我頸,問母欲何之。 人言母當去,豈復有還時。 阿母常仁惻,今何更不慈。 我尚未成人,奈何不顧思。 見此崩五內,恍惚生狂痴。 號泣手撫摩,當發復回疑。 兼有同時輩,相送告離別。 慕我獨得歸,哀叫聲摧裂。 馬為立踟躕,車為不轉轍。 觀者皆噓唏,行路亦嗚咽。 去去割情戀,遄征日遐邁。 悠悠三千里,何時復交會。 念我出腹子,匈臆為摧敗。 既至家人盡,又復無中外。 城廓為山林,庭宇生荊艾。 白骨不知誰,縱橫莫覆蓋。 出門無人聲,豺狼號且吠。 煢煢對孤景,怛吒糜肝肺。 登高遠眺望,魂神忽飛逝。 奄若壽命盡,旁人相寬大。 為復強視息,雖生何聊賴。 託命於新人,竭心自勖勵。 流離成鄙賤,常恐復捐廢。 人生幾何時,懷憂終年歲。 ---> ===Unit 5: Myths and Legends of East Asia=== <!--- Shanhaijing, Zibuyu... Etc. Zhiguai literature. This aims to provide a counterpoint to what Confucius wouldn't discuss - thus Zibuyu. Going straight into Daoism isn't ideal. ---> # [[/Exploring the World of Mountains and Seas/]]<!-- Structure: 出焉 --> # [[/Oh, the Qilin!/]] <!--- Even here, the odes can be studied! ---> # [[/The Poison of Zhen/]] <!--- referenced a lot in histories ---> # [[/Ultimate Justice with Xiezhi/]] <!--- the yellow emperor met one, gao yao also used one ---> # [[/The Virtue of the Fenghuang/]] <!--- shanhaijing has a great line on this ---> # [[/The Entrapment of Hua Po/]] # [[/Nüwa Created the World/]] ===Unit 6: Nation Focus - Japan=== # [[/The Inariyama Sword/]] <!--- short and sweet! ---> # [[/Entering Japan with Takeda Shingen/]] # [[/The Oldest Inscription in Japan/]] <!--- 宇治橋断碑 ---> # [[/The End of a Rebellion/]] # [[/Shinto Teachings with Honda Chikaatsu/]] <!--- https://wikisource.org/wiki/%E9%81%93%E4%B9%8B%E5%A4%A7%E5%8E%9F 本田親徳 道之大原 ---> # [[/The Diary of Fujiwara no Teika/]] <!--- 明月記 ---> # [[/Reading the History of Japan with Prince Toneri/]] <!--- 日本書記, etc. ---> # [[/A Biographical Painting of Toyotomi Hideyoshi/]] <!--- This is on Fanya Hanwen Corpus ---> <!--- # [[/Occupying Taiwan/]] ---> <!--- I have some colonial literature on me that can be used here. ---> ===Unit 7: Nation Focus - Korea=== # [[/Feigned Surrender with Ŭlchi Mundŏk/]] <!--- 乙支文德漢詩 ---> # [[/A fu with Yi Kyubo/]] # [[/An Elegy to the Empress with Choe Ja/]] <!--- Choe Ja 元德大后輓詞·崔滋(최자) 乾極曾客配,坤儀正體元。 枕前朝聖主,帳底見曾孫。 陰慘俄沉月,屋悲便沒軒。 三韓千古淚,七十九年恩。 ---> # [[/Language Reform with Sejong the Great/]] <!--- 訓民正音 https://github.com/ShiraTheMogul/fanyahanwen-corpus/commit/1ef2b42cc50055affaa5ef39c61b87ed31c34a60 multiple poems and descriptive terms, possibly the best capstone ---> # [[/Fall Off Your Horse!/]] <!--- a famous record from 朝鮮王朝實錄 ---> # [[/The Diary of Yi Sun-Sin/]] <!--- 亂中日記 ---> # [[/Tales from Mount Kumo/]] <!--- 金鰲新話 ---> # [[/Pak Chiwŏn Tours the Qing/]] <!--- 熱河日記 ---> # [[/Korea's Three Kingdoms/]] <!--- 三國史記 for sure! ---> # [[/Hwang Yun-seok's Essays/]] <!--- https://zh.wikisource.org/wiki/%E9%A0%A4%E9%BD%8B%E9%81%BA%E7%A8%BF 頤齋遺稿 黃胤錫 Joseon scholar! ---> ===Unit 8: Christian Literature=== # [[/A Different Three Character Classic with Hong Xiuquan/]] # [[/Friar Juan Cobo's Veritable Record/]] <!--- One of few texts from the Philippines that I have ever found! https://bnedigital.bne.es/bd/en/viewer?id=0160187c-9d9b-4f34-84d6-bc03fd310c69 ---> # [[/The Delegate's Edition/]] # [[/Nestorian Steles during the Tang/]] <!--- 大秦景教宣元至本經經幢 and 景教碑 ---> # [[/Hong Xiuquan's Bible/]] <!--- https://bible.fhl.net/ob/nob.html?book=407 ---> <!--- I don't want to focus too much on Hong Xiuquan here, so look for more material, especially from missionaries. ---> ===Unit 9: An Introduction to Daoism=== <!--- And now back to your regularly scheduled Zhuangzi/Laozi/Liezi. But with more interesting stuff. Trust! ---> # [[/Laozi Explains the Dao/]] # [[/Qingtan with Xie Daoyun/]] # [[/The Doubting Neighbour/]] # [[/Kuafu Chases the Sun/]] # [[/The Frog in a Well/]] # [[/Wu wei with King Hui of Liang/]] # [[/The Old Man that Moves the Mountains/]] # [[/Master Zhuang Dreams of Butterflies/]] # [[/Master Incapable and the Poisonous Bird/]] # [[/Transmitting the Dao with Yelü Chucai/]] <!---耶律楚材 - Served 窝阔台, 玄風慶會錄 is short and respectable enough to work with. https://zh.wikisource.org/wiki/%E7%8E%84%E9%A2%A8%E6%85%B6%E6%9C%83%E9%8C%84 ---> # [[/The Indifferent Taoist/]] <!--- northern song https://zh.wikisource.org/wiki/%E7%8E%89%E6%AD%B7%E5%AF%B6%E9%88%94 ---> <!--- Currently very stereotypical, but there's stuff to work with at least. Need to include those weird Daoist characters among other things. ---> ===Unit 10: Nation Focus - Ryukyu Kingdom=== # [[/Historical Annals with Sai On/]] <!--- Kyuko is an easy cop ---> # [[/The Enthronement of Shō Tei/]] # [[/The Twilight of Ryukyu with Shō Ten/]] # [[/A Trip to Ryukyu with Luo Sen/]] <!--- Pre-Capstone ---> <!--- 遐邇貫珍 1854-11 - 日本日記 羅森 https://archive.org/details/HEKC185411/page/n5/mode/1up A solid description of Ryukyu cultural customs in Volume 11. Absolutely incredible. 日三日火船直向東北而駛出了臺灣之外幾日不見天涯是時北風大作波浪沖天火船亦甚飄蕩而不能立見有沙鷗隨風而逐浪心直駛七日漸見小山而到琉球琉球一國長闊一百七十五里其國城在地球圖緯線赤道之北二十六度十四分經線中華北京偏東十一度二十四分自明以來世封王爵叨列藩籬其處土產不過蔬菜番薯菜油黑糖等類人民束髻大補是穿草履男女粧飾頭上祇插一簪二簪為別故少年之男女瞥目則無異及其壯也皆留鬚髯故街上長鬚之人甚多甲寅正月初一予上岸遊玩見街上兒童甚多分以銅錢各極歡喜人民亦甚謙恭民居間亦貼新春聯于門外但不見有別等繁華之事那霸有寺寺內有園是名家世宦之墳所以石刊刻姓名年號于碑上每日道人打掃供奉生花樹葉于墓前另有人家祖墳與中國之明塚無異峰巒之上樹木多植民房則以蠻石圍墻內以茅草結屋而居佳物椅棹俱無惟以草蓆屈膝而坐對火盆而吹煙民間亦有識中國言語字墨者 不張舖店惟有墟塲男不貿易婦女為之以貨易貨而外方之金銀弗尚焉然而百姓亦甚畏官長飲食亦甚粗粕甘守樸儉不務奢華亦鮮欺詐板門紙窓夜間亦不防竊曾見途中撿物亦能以返原人公門之內冷冷落落並無案牘之煩淳樸之風畧有同于上古之世我等外國之欲買什物須言于官官為代辦正月初六提督被理衛廉士等一班將官布列威嚴與予乘轎至王宮總理大臣尚宏勳為主席布政大夫馬良才為知客享宴甚豐食物多與中國無異宴後各官皆饋有紙扇烟包布帛等項是物雖粗此亦世子之恭敬外國故亞國亦以禮物而返贈之世子王宮離岸三里在于山頂是名守禮將至其宮一路亦有樹木石牌坊宮室亦甚寬大幽雅垣局可觀其處多栽鳳尾草森樹等類以障陰山邊田土樹藝五穀近海沙田水漲之後人收其沙以煎鹽此時明月當圓予覽山川亦足見一方之風景 ---> <!--- 中山世鑑 and so on. Lots of poetry too. ---> ===Unit 11: Nation Focus - Singapore=== <!--- National Library of Singapore has a poetry series that's super good! ---> ===Unit 12: Literary Chinese in Medicine=== <!--- do not endorse the medical practices discussed in these...make sure to link back to the heavenly stems here as they are associated with specific body parts. ---> # [[/The Books of the Yellow Emperor/]] <!-- 黃帝内徑 ---> # [[/Deviant Qi with Zhang Congzheng/]] <!--- https://zh.wikisource.org/wiki/%E5%84%92%E9%96%80%E4%BA%8B%E8%A6%AA ---> # [[/Anatomy with Sugita Genpaku/]] <!--- 解体新書 ---> # [[/A Lost Wu Medical Text analysed in Japan/]] <!--- 難經古義 ---> ===Unit 13: People Focus - Zhuang peoples=== <!--- https://mooc1.chaoxing.com/mooc-ans/ztnodedetailcontroller/visitnodedetail?courseId=84745403&knowledgeId=84745463&_from_=&_fromV2_=&rtag= 《峤西诗钞》 is also a really good shout. Found here: https://ctext.org/wiki.pl?if=gb&res=215640&remap=gb ---> <!--- Basically, there are Zhuang and Tangut peoples who wrote in Literary Chinese, and their inclusion here is to show that even those who made their own scripts would use this tongue. 张鸿翮 imported the character 朴 to describe a bug, for example. ---> # [[/Zhuang poetry with Li Bi/]] # [[/The Beauty of Wuyuan with Fang Ju/]] # [[/Disaster and Society with Wei Fenghua/]] # [[/Who Deserves a Biography?/]] <!--- https://wenyi.gmw.cn/2024-06/25/content_37398911.htm 一是忠实记录了汉诗创作与古壮字交融的文化现象。清代壮族诗人张鸿翮(hé)《大塘谣》(《峤西诗钞》卷二)云: 去了休。去到大塘红蓼洲。红蓼生花,不结子。绿朴生花,毬见毬。 诗中所说“绿朴”,是壮族对柚子的惯称。“柚子”,壮语发音为“bug”。根据《古壮字字典》,其对应的古壮字为“朴(㭪)”。诗人将古壮字运用到汉文诗歌创作中,刻下了明清壮汉文化交相辉映的注脚。 This sort of thing is why Zhuang and Tangut inclusion is important, as they show how flexible Literary Chinese can be. ---> ===Unit 14: People Focus - Tangut peoples=== <!--- 羅福萇 and 羅振玉 wrote studies on Western Xia / Tangut script. Look for poets and stuff. ---> ===Unit 15: Literary Chinese in the Military=== <!--- Real Sun Zi hours! 7 Military Classics are an obvious shout, but look for more stuff too. ---> # [[/Fū! Rin! Ka! Zan!/]] # [[/A Bilingual Stele of the Khitans/]] # [[/Going to war with Boyan/]] <!--- Boyan's Poem from the 元史   伯顏,蒙古巴林部人。至元十一年拜中書左丞相,總兵伐宋。官至開府儀同三司,薨贈太師,封淮安王,諡忠武。   《玉堂嘉話》:初,宋未下時,江南謠云:「江南若破,白雁來過。」當時莫喻其意。及宋亡,蓋知指丞相巴延也。   過梅嶺岡留題 馬首經從庾嶺回 【 庾嶺回 七修類稿(乾隆刊本)卷四十六作「嶺島歸」。】 ,王師到處悉平夷。擔頭不帶江南物,只插梅花一兩枝。   《七修類藳》:伯顏下江南,過金陵梅嶺岡詩云云。所以著名,亦有是善。 ---> # [[/An Edict from the Xianbei/]] # [[/The Suppression of the Kingdom of Dongning/]] <!--- 台灣鄭氏始末 https://ctext.org/wiki.pl?if=en&chapter=139938 Largely a record of wars in Dongning rather than anything about the trade etc, so it fits here. ---> # [[/The Shunzhi Emperor vs Li Zicheng/]] # [[/The Art of War/]] ===Unit 16: Nation Focus - Vietnam=== # [[/Đỗ Pháp Thuận and the Southern Skies/]] # [[/Ancestor Veneration with the Descendants of Zhu Xi/]] <!--- https://github.com/ShiraTheMogul/fanyahanwen-corpus/tree/main/corpus%2F%E8%B6%8A%E5%8D%97%E6%BC%A2%E6%96%87%2Fclean somewhere in here ---> # [[/Resolving a Succession Crisis with Emperor Trần Minh Tông/]] <!-- 南翁夢錄·黎澄 --> # [[/Spreading Revolutionary Consciousness with Phan Bội Châu and Liang Qichao/]] <!--- 越南亡國史 Possibly the most important text in Vietnamese history, not even gonna lie. https://zh.wikisource.org/wiki/%E8%B6%8A%E5%8D%97%E4%BA%A1%E5%9C%8B%E5%8F%B2 ---> # [[/Academia in Literary Chinese between East and West/]] <!--- 南風雜誌 is a massive shout here. Absolutely amazing series. ---> ===Unit 17: Historical Annals and Encyclopediae=== <!--- 永樂大典 will teach how to infer from gaps in texts! 《編類》 is an incredibly interesting essay from here that can bring up the odes and Confucius's「思無邪」quote. It can prepare students for the wrath of Qing academia later. ---> # [[/An Introduction to Biographical Paintings/]] <!-- Many older paintings include biographies at the top in Literary Chinese. Students need to learn these. https://commons.wikimedia.org/wiki/File:%E6%AD%B7%E4%BB%A3%E8%81%96%E8%B3%A2%E5%8D%8A%E8%BA%AB%E5%83%8F_%E5%86%8A_%E8%AB%B8%E8%91%9B%E4%BA%AE_(Zhuge_Liang).png - Famous figure, also part of a very notable series. https://commons.wikimedia.org/wiki/File:Otomo-Sorin-2.jpg - Contains the Japanese repetition character 々 https://commons.wikimedia.org/wiki/File:Toyotomi_hideyoshi4.jpg - simply has aura --> # [[/The History of Liao, Jin, and Song with Toqto'a/]] <!--- 脱脱 ---> # [[/Two Years in the Forbidden City with Yu Deling/]] <!--- 清宮禁二年記 https://zh.wikisource.org/wiki/%E6%B8%85%E5%AE%AE%E7%A6%81%E4%BA%8C%E5%B9%B4%E8%A8%98 ---> # [[/Selected Records of the History of the Da Shun/]] <!--- Fair Use of a 2010 book written in Literary Chinese about the Da Shun dynasty. Limit to 500 characters, if that. Use to encourage recognition of Simplified variants and modern Wenyanwen. ---> # [[/Documenting the World with Terajima/]] <!--- 和漢三才図会 寺島良安, built off 三才圖會 ---> ===Unit 18: Buddhist Literature=== <!--- You would be forgiven for wondering why this is so late, but if you look at many classical Buddhist texts you'll quickly see a ton of loanwords that make it significantly more difficult to read than the average text. Thus, it goes here for now. ---> <!--- Place focus on practical stuff first. Stuff you can and WILL see in Buddhist temples. Stuff Buddhists can take away immediately. Skills-based approach feels strongest here. ---> <!--- Look at Northern Liang and Later Qin literature, as there is a ton of work by translators from India during the 16 kingdoms period, particularly those two. ---> <!--- Stuff by Bodhidharma 達摩 could be fun too https://zh.wikisource.org/wiki/Author:%E9%81%94%E6%91%A9 ---> # [[/Dipping your feet in with Wenyan Shu/]] <!--- 華亭 世尊遺法本忘言,教外別傳意已圓。 只履攜將蔥嶺去,不妨來上月明船。 ---> # [[/Buddhism in Battle Standards/]] # [[/The Seven Tathagatas/]] <!--- 南無寶勝如來 南無多寶如來 南無妙色身如來 南無廣博身如來 南無離怖畏如來 南無甘露王如來 南無阿彌陀佛 Use to introduce some core vocabulary in repetitive manner. Useful phrases from my trip to Jing'an Temple 南無本師釋迦牟尼佛 - Pay homage to the root teacher 南無大悲觀世音菩薩 - Pay homage to the goddess of mercy 廣種福田 - widely plant a meritorious field ---> # [[/Two Buddhist Temples in Shanghai/]] <!--- 留雲禪寺 雲留雲翔領畧幾許禪機此地有雲散天開真如界。 塔內塔外普示無邊圓覺是故曰塔影雙照解脫門。 歲次壬午冬月吉旦。 覺醒敬撰。 楊胡生沐手恭書。 善信印利明敬獻。 ---> <!--- 福慧宝鼎 慧明大和尚 - introduce the Buddhist timekeeping system with 佛歷 around this point. 赤烏古剎 建寺一千七百六十周年紀念 古剎三國建 滬瀆有重玄 石佛音淨現 聖跡顯重元 唐時稱永泰 宋敕名靜安 聖祖留佛闡 仲師移伽藍 元收八景偈 明鑄鐘聲梵 清樹化羅漢 選賢十方讚 佛日普光明 福慧共修善 鼎運昌隆際 轉正法輪緣 歲次丁亥住持慧明監製 ---> # [[/Foreseeing Monkhood with Yi Xing/]] <!--- 看命一掌金 ---> # [[/A Trip to Western Xia with Zhi Guang and Hui Zhen/]] <!--- https://zh.wikisource.org/wiki/%E5%AF%86%E5%91%AA%E5%9C%93%E5%9B%A0%E5%BE%80%E7%94%9F%E9%9B%86 ---> <!--- https://zh.wikisource.org/wiki/%E5%AF%86%E5%92%92%E5%9C%93%E5%9B%A0%E5%BE%80%E7%94%9F%E9%9B%86 ---> # [[/Jizang's Three Discourses/]] <!--- https://zh.wikisource.org/wiki/%E4%B8%89%E8%AB%96%E7%8E%84%E7%BE%A9 ---> <!--- I saw these texts being quoted and thus should consider them in some capacity. 《般若波羅蜜多心經》 《金剛般若波羅蜜經》 《一切智光明仙人慈心因緣不食肉經》 《妙法蓮華經》 《大般涅槃經》 《大方等大集經》 《大毘盧舍那成佛神變加持經蓮華胎藏悲生曼荼羅廣大成就儀軌供養方便會》/ 胎藏曼荼羅 《佛說救拔焰口餓鬼陀羅尼經》 《雜阿含經》 Look at Japan's 五山文学 ---> ===Unit 19: People Focus - Manchu peoples=== # [[/Qing dynasty Poetry with Nara Singde/]] <!--- 飲水詞 納蘭性德 https://zh.wikisource.org/wiki/Author:%E7%B4%8D%E8%98%AD%E6%80%A7%E5%BE%B7 ---> # [[/Amassing Words with the Kangxi Emperor/]] # [[/Amassing Literature with the Qianlong Emperor/]] <!--- Siku Quanshu abstract https://zh.wikisource.org/wiki/%E5%9B%9B%E5%BA%AB%E5%85%A8%E6%9B%B8%E7%B8%BD%E7%9B%AE%E6%8F%90%E8%A6%81 ---> <!--- Yongzheng Emperor's Poetry https://zh.wikisource.org/wiki/Author:%E9%9B%8D%E6%AD%A3%E5%B8%9D 《和碩怡賢親王祭文》 Also include 滿洲國 stuff to show the fall of the Qing and attempts to preserve it through becoming a Japanese puppet state. It is important to show how Literary Chinese can be misused as well. 滿洲國建國宣言 is a good shout, as is 法制 to prepare students who may be interested in Taiwan legal stuff later down the road. https://zh.wikisource.org/wiki/Category:%E6%BB%BF%E6%B4%B2%E5%9C%8B ---> # [[/Paintings and Beauty with Puru Aisin-Gioro/]] <!--- Saw these in Shanghai Museum with some writing, seemed really cool. Teaches another skill. ---> ===Unit 20: Qing-RoC Literature=== <!--- many writers here, will be difficult to sift through. Include 四库全書 abstracts and stuff here. ---> # [[/Jewish Refugees in Shanghai/]] <!--- Show passports, certificates, etc, from the Jewish Refugee Museum, anonymised. ---> # [[/A Literary Chinese Abstract/]] <!--- Abstracts from siku quanshu, probably want others ---> # [[/Lament with Lu Ruoteng/]] <!--- 《疑猜》盧若騰,東寧國 盟誓變為交質子,春秋戰國風如此;末世上下相疑猜, 更質妻子防逃徙。 此法只可羈庸奴,若遇梟雄術窮矣;妻可再娶子再育, 安能長坐針氈裏。 我贈一法君記存;推心置腹人知恩;眾人畜之眾人報, 幾個國士在君門。 盧若騰撰,陳漢光編輯,《島噫詩》,臺灣文獻叢刊第二四五種(臺北:臺灣銀行經濟研究室,1968年)21頁。 ---> # [[/Common Linguistics Knowledge in the RoC/]] <!--- 音韻常識 ---> ==References used for this page== * Yang, B. (2016). 文言语法 [Literary Chinese Grammar] (1st ed). 中华书局 [Zhonghua Book Company]. ISBN: 978-7-101-11619-9 * Priestley, K. E., & Shou-jung, C. (1962). China’s Men of Letters, Yesterday and Today. Dragonfly Books. {{BookCat}} d2bp0f9fgi6vrvb4zc363m9jv6272aq 4669035 4669033 2026-09-06T00:29:30Z Shira the Mogul 3560559 Added cookbooks, this is great for getting the reader moving and understanding how instructions are given. 4669035 wikitext text/x-wiki __notoc__ Welcome to the Wikibook for Literary Chinese (Known as 漢文 "Han Language" in East Asia or 文言 "Literary Language" in China), aimed at individuals hoping to gain a general knowledge of it before progressing into genres they wish to be acquainted with. This is not the [[Classical Chinese]] textbook, which is aimed at Chinese Zhou-Qin era texts. This text aims to shed light on post-Zhou-Qin texts across East Asia, which mimic those texts. However, as Zhou-Qin era texts served as the main body from which individuals learned, they are employed here as and when they are considered necessary or otherwise useful. It does so through a "buffet" approach, showering you, the reader, with an ocean of texts of myriad genre. ==Table of Contents== === Front matter === * [[/Introduction/]] * [[/Appendices/]] === Useful resources === These are quick grab-bags that can be useful for vocabulary-building. * [[/Antonym List/]] <!--- 文/武,大/小,厚/薄,橫/縱...---> * [[/Collocation Groups/]] <!--- e.g. 四象,三靈…… ---> * [[/Pronoun Table/]] * [https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/嚴譯及部定詞等 Yan Fu's Qing-era translations for modern terms] <!--- Wikiversity has this (https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/嚴譯及部定詞等) and the below, I will effectively be translating a lot of it! ---> * [https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/上古語考輯 Communicative Terms] <!--- this will be translated eventually, but right now it's bad to just leave this here. ---> === Useful primers === Across history, many primers have been made for teaching Literary Chinese to children. These are a few that are recommended for use alongside this work, ideally in flashcards. * [https://www.fdgwz.org.cn/Web/Show/11308 倉頡篇] - Cangjie's Chapters, the earliest one. It is extant, but incomplete. It contains several rare characters, and so if used, I would personally recommend doing so later, or out of interest. * 三字經 - The Three Character Classic, an excellent piece for Confucian education. Pair with 弟子规 for best results. ** 三字經(太平天國版)- For Christians, there is a version made by Hong Xiuquan from the Taiping Rebellion. Despite the context, it is a legitimately useful primer and can be used to self-teach for the Delegate's Edition of the Christian Bible. * 千字文 - The Thousand Character Classic, a remarkable piece of constrained writing that only uses each character once. Amazing for building vocabulary whilst seeing historical allusions and the like. * 五字鑑 - The Five-Character Mirror, essentially the 24 Histories of China compressed into a primer. Uses 5-character couplets, the longest in this list. * 龍文鞭影 - The Shadow of Longwen's Whip, a historical allusion trainer. Best paired with a context piece. ===Unit 0: The Han script=== This unit is intended for those with no familiarity of the Han script. It will prepare you for the units ahead, teaching largely pictographic characters. By the end of this unit, students will: * Recognise around 50 characters. * Understand how characters are composed and how this gives them meaning. * Have a basic idea of how to handwrite and/or type characters using the Cangjie Input Method. * Know some bare basics of Literary Chinese grammar (e.g. Basic word order, where adjectives go, lack of "is", 有...) Lessons: # [[/An Introduction to the Han Script/]] # [[/People, Big and Small/]] # [[/How do we write Chinese?/]] # [[/What are Chinese characters, anyway?/]] # [[/The Sun, the Moon, and the Five Elements/]] # [[/Getting Familiar with Body Parts/]] # [[/Using Numbers and Using Weapons/]] <!--- 竹戈十大中一弓廿卜---> # [[/Tilling the Fields with 有/]] <!--- 山田 ---> # [[/How Characters are Made/|How Characters are Made with Kiyohara no Sanemoto]] # [[/Cangjie Created Characters/]] <!--- Get people to use Cangjie ---> # [[/The Kangxi Radical System/]] <!--- Introduce some monoradical texts to train recognition. ---> ===Unit 1: Basic Skills=== This unit is intended for those with minimal familiarity with the Han script and no familiarity with Literary Chinese. There is a focus on simple structures, skills for dissecting common textual structures, and short-form poetry in this unit. Before starting this unit, students should: * Recognise around ~30 characters. * Can use Cangjie input. * Have given Unit 0 a cursory glance. <br> By the end of this unit, students will: * Recognise around ~100 characters. * Comprehend numbers, the Heavenly Stems, and the Earthly Branches, and be able to use them to quantify time and date. * Intuit the basic topic -> comment idea behind Literary Chinese. "This, it is..." * Understand basic function words such as 也, 而, 有, and 謂. Lessons: # [[/The All-Purpose 也/]] # [[/An Introduction to Chinese Numbers/]] <!--- It is hard to find authentic materials for this ---> # [[/One, Two, Left, and Right with Gongsun Long/]] <!--- 曰:「二有一乎?」 曰:「二無一。」 曰:「二有右乎?」 曰:「二無右。」 曰:「二有左乎?」 曰:「二無左。」 曰:「右可謂二乎?」 曰:「不可。」 曰:「左可謂二乎?」 曰:「不可。」 曰:「左與右可謂二乎?」 曰:「可。」 ---> # [[/The Heavenly Stems/]] <!--- Introduce ordinals, which will be used to demonstrate sentence patterns later. ---> # [[/Tell the Time with Earthly Branches/]] <!--- Introduce verbs and timekeeping ---> # [[/Lunar Dates with the Spring and Autumn Annals/]] <!--- Vocabulary: 歲,年,朔,月,日,來,前,初,正,春秋夏冬,曆,上,下. Consider including traditional names for months in a list. ---> # [[/Skimming for Major Events in Historical Annals/]] <!--- Don't simply use Confucius's Chunqiu: We can use texts inspired by it. E.g. 三國史記 - 十五年京城旱。秋七月,蝗。very few new characters, lots one can use. Instantly able to use. https://zh.wikisource.org/wiki/%E4%B8%89%E5%9C%8B%E5%8F%B2%E8%A8%98/%E5%8D%B701 Skimming annals is very possible and a very useful skill. Don't skip out on it. Teach students to skim read!!! ---> # [[/Dinner with the Daimyo/]] <!-- 侍宴·大友皇子 皇明光日月,帝徳載天地。 三才併秦昌,万国表臣義。 --> # [[/In Discourse with Jibong/]] <!-- 芝峰類說 倭國謂田爲畠。謂水田爲田。火田爲畑。猶我國以水田爲畓也。故官名有畠山殿。地名有畑島云。 --> # [[/How do we Write Height and Weight?/]] <!--- Hilarious oversight ---> # [[/Eating like a Zhou Aristocrat/]] # [[/Shinto FAQ with Honda Chikaatsu/]] <!--- https://wikisource.org/wiki/%E7%9C%9E%E9%81%93%E5%95%8F%E5%B0%8D 眞道問對 本田親徳 really good way of operationalising 乎 and much of the early grammar. 問 天帝無始無終乎。 對 天帝無始無終也。 旣以無始無終之力 與無始無終之體 造無始無終之萬物。 其功亦無始無終也。 問 天地大原在道乎。 對 天地大原實在道。 鬼神依道而立。 人民依道而活。 萬物依道而息。 This is great! ---> <!--- Some cool stuff I saw someone studying from https://zh.wikisource.org/wiki/%E8%87%B3%E5%B0%8F%E4%B8%98%E8%A5%BF%E5%B0%8F%E7%9F%B3%E6%BD%AD%E8%A8%98# https://zh.wikisource.org/wiki/%E6%A0%B8%E8%88%9F%E8%A8%98 Could be used for period focus ---> ===Unit 2: An Overview of Sinitic Poetry=== This unit will teach you how Sinitic Poetry operates; - that is, the way individuals in the Sinosphere compose poetry in Literary Chinese. Despite this language's fall out of favour in the past century, this tradition is still remarkably alive and well, and their short length makes them more accessible than elaborate prose. In this unit, you will begin from the ''Classic of Poetry'' before travelling through poems from the Tang dynasty, Singapore, Japan, Vietnam, the Ryukyu Kingdom, and Korea. When introducing poetry, I will furthermore use the language from the nation it is from to show how it is recited by its people. After discussing the Classic of Poetry, we will also be a small detour into a discussion on Ping-Ze 平仄, the Tang dynasty system of alternating tones, so to produce rhyme on tonal and phonological levels. This had a major impact on Literary Chinese poetry as a whole! By the end of this Unit, students will: * Recognise around 120 more characters. * Be able to explain how Sinitic Poetry rhymes and the themes it contains. * Be able to use function words such as 在, 無, 不, 聿, and 于/於 in poetic contexts. * Recognise the switch between 吾/我 in the subject-object positions and demonstrate it in usage. * (Chinese speakers) Be able to differentiate 于 and 於, and understand the "interest(ed) in" meaning of 好 in most circumstances. <!--- Summary of the above part about 于 and 於 for other editors: 于 and 於 were distinct words for an extremely long time and were still such to Literary Chinese writers. Their "merging" through Simplified-Traditional Chinese distinctions is a very modern thing. I will summarise their usages here, using Pulleyblank's Outline of Classical Chinese Grammar (2000); * 于 - This can mean "to go" or "to/at". 黃鳥于飛 "The yellow birds go flying". Must be post-verbal. It can also appear in 至于. * 於 - This is an all-purpose locative preposition - from "on/at/in" to "from" or even "than" (甲於乙). The implication of motion is not there at all. Must be pre-verbal. It can also appear in 之於 or be an archaic noun for a crow 於 (烏). ---> Lessons: # [[/Across the Rivers with Emperor Puliuru Guang/]] <!--- Illustrate ping-ze ---> # [[/To Study the Odes/]] # [[/A Detour into Orthodox Ping-Ze/]] <!--- 平 and 仄 are useful characters themselves. Show 仄 in the binomes 反仄,歉仄,逼仄 as it's often difficult to immediately use ---> # [[/The Restraint of Du Fu/]] # [[/The Longing of Li Bai/]] # [[/The Environment with Bukha Timur/]] # [[/Pillow Talk with Guan Yunshi/]] <!--- 紅繡鞋·貫雲石 挨著靠著雲窗同坐,偎著抱著月枕雙歌,聽著數著愁著怕著早四更過。四更過情未足,情未足夜如梭。天哪,更閏一更兒妨甚么! Uyghur author! ---> # [[/Buddhist Philosophy with Ngô Chân Lưu and Taisei Shōan/]] <!-- 元火·吳真流 木中元有火,元火復還生。 若為木無火,鉆燧何有萌。--> <!-- 杜鵑·大成聖安 夢覚孤床静 杜鵑帯雨飛 一声来近枕 何者不沾衣 --> # [[/Odes with Mō Taiei and Zheng Chengxun/]] <!-- 詠松·毛泰永 植體宜千仞,垂陰動百尋。 李膺真烈烈,和嶠自森森。 桃李何堪較,雪霜安得侵。 萬年身不老,種子又成林。 AKA Inoha Seiki 伊野波 盛紀 --> <!-- 詠班蘭·鄭成勛 南國多芳草,班蘭最有名。 深根將綠茁,長葉亦叢生。 取味迎賓合,入厨任水烹。 可憐經一用,擲棄不留情。 鄭成勛《樵隱詩集》 https://nus.edu.sg/nuslibraries/dsprojects/sg-jiutishi/poem/827 --> # [[/A Golden Cup and the Fall of a Dynasty with Yan Fu/]] # [[/On a Journey with Sadula/]] <!--- No lesson entry: 朝中措·襄陽古道灞陵橋 襄陽古道灞陵橋,詩興與秋高。 千古風流人物,一時多少雄豪。 霜清玉塞,雲飛隴首,風落江皋。 夢到鳳凰台上,山圍故國周遭。 北郊晚步 陂水荷凋晚,茅檐燕去涼。 遠林明落景,平麓淡秋光。 群牧歸村巷,孤禽立野航。 自諳閑散樂,園圃意尤長。 Jurchen poet and grandson of Emperor Shizong of Jin. He's a Zen Buddhist, so we'll go back to him later. ---> ===Unit 3: Confucianism and the World=== This is a Confucian-themed unit with a smattering of other items. You will see the odd geography of the past, early linguistic philosophy, and terrifying breakaway states! By the end of this unit, students should be able to: * Recognise around 200+ characters. * Read basic annals and histories with some dictionary assistance, and comprehend 3-character structures reliably. * Have encountered basic grammatical points such as 之、乎、者、也、而、則、乃、所、以、於、于、與、且、蓋、and 夫. ** 於 and 于 should be distinguishable. * Survive a text of at least 250 characters and read for gist. Lessons: # [[/A Brief Overview of Confucianism/]] # [[/Teaching the Annals in Qi/]] <!-- Gongyang Gao's commentary --> # [[/Is a White Horse a Horse?/]]<!-- Teach negation with 非 in 公孙龍子 and compare with 不 --> # [[/The Three Character Classic/]] # [[/Expressing Filial Conduct with Confucius and Hara Saihin/]] <!-- 次韻杏坪先生 父執有君孤不孤 相依遍接搢紳徒 区区自抱地方寸 杳杳重遊天一隅 羇雁飛鳴迷汝國 家人思夢入江都 如教志業青年遂 世上寧無逐臭夫 --> # [[/Confucianism and the Environment with Sai On/]]<!-- 木假山記 --> # [[/In Debate with Mencius/]] ===Unit 4: Women's Writing=== In this unit, women's writing from various areas of China will be explored. This is chiefly targeted at poetry and the themes within; from the feminine voice of the Classic of Poetry to the remonstrance towards the Khitan Emperor Tianzuo of Jin by his Consort Dasese. The role of women in courtly society is to be elucidated here! # [[/An Unmarried Life with Heo Nansŏrhŏn/]] <!--- 貧女吟 豈是乏容色。工鍼復工織。 少小長寒門。良媒不相識。 夜久織未休。戛戛鳴寒機。 機中一匹練。終作阿誰衣。 手把金翦刀。夜寒十指直。 爲人作嫁衣。年年還獨宿。 ---> # [[/Responding to Lord Trần with Hồ Xuân Hương/]] <!--- Responding to 陳光靜 Trần Quang Tĩnh 《和陳侯》 愧無才調使人驚,十載風塵貫耳鈴。 已是臨枰知敵手,莫須敲月苦殫精。 為輪為彈隨遭遇,誰鳳誰鶯任賦生。 造物於人何苟惜,明珠休向暗中呈。 莫須 is an important structure to teach here. ---> # [[/Gaze into the Autumn Night with Taisei Shōan/]] <!--- 秋夜偶成·大成聖安 長天浮爽気,月色興無窮 群犬吠山径,百蟲啼野風 悲秋秋夜永,感古古今同 自是孤窓下,凄然万慮空 ---> # [[/Visiting a Temple with Yu Xuanji/]] <!--- 遊崇真觀南樓覩新及第題名處 雲峰滿目放春晴,歷歷銀鈎指下生。 自恨羅衣掩詩句,擧頭空羨榜中名。 ---> # [[/Remonstrance with Dasese/]] <!--- https://zh.wikisource.org/wiki/%E8%AB%B7%E8%AB%AB%E6%AD%8C 諷諫歌·大瑟瑟 勿嗟塞上兮暗紅塵。 勿傷多難兮畏夷人。 不如塞奸邪之路兮選取賢臣。 直須臥薪嚐膽兮激壯士之捐身。 可以朝清漠北兮夕枕燕雲。 Dasese (or 萧瑟瑟) was a Khitan consort to Emperor Tianzuo of Liao. She remonstrated him as the Jurchens were beginning to encroach upon the Khitan, and was forced to commit suicide for her remonstrance. Tianzuo would soon pay for his malfeasance. ---> # [[/The Love Songs of the Odes/]] <!--- 褰裳 子惠思我,褰裳涉溱。子不我思,豈無他人?狂童之狂也且! 子惠思我,褰裳涉洧。子不我思,豈無他士?狂童之狂也且! 柏舟 彼柏舟,在彼中河,髧彼兩髦,實維我儀,之死矢靡它,母也天只,不諒人只。 汎彼柏舟,在彼河側,髧彼兩髦,實維我特,之死矢靡慝,母也天只,不諒人只。 行露 厭浥行露,豈不夙夜,謂行多露。 誰謂雀無角?何以穿我屋?誰謂女無家?何以速我獄?雖速我獄,室家不足。 誰謂鼠無牙?何以穿我墉?誰謂女無家?何以速我訟?雖速我訟,亦不女從。 ---> # [[/Rules for Women with Ban Zhao/]] <!--- https://zh.wikisource.org/wiki/%E5%A5%B3%E8%AA%A1 ---> # [[/The Tragedy of Cai Wenji/]] <!--- 悲憤詩 〔兩漢〕蔡文姬 漢季失權柄,董卓亂天常。 志欲圖篡弒,先害諸賢良。 逼迫遷舊邦,擁主以自強。 海內興義師,欲共討不祥。 卓眾來東下,金甲耀日光。 平土人脆弱,來兵皆胡羌。 獵野圍城邑,所向悉破亡。 斬截無孑遺,屍骸相撐拒。 馬邊懸男頭,馬後載婦女。 長驅西入關,迥路險且阻。 還顧邈冥冥,肝脾為爛腐。 所略有萬計,不得令屯聚。 或有骨肉俱,欲言不敢語。 失意幾微間,輒言斃降虜。 要當以亭刃,我曹不活汝。 豈復惜性命,不堪其詈罵。 或便加棰杖,毒痛參並下。 旦則號泣行,夜則悲吟坐。 欲死不能得,欲生無一可。 彼蒼者何辜,乃遭此厄禍。 邊荒與華異,人俗少義理。 處所多霜雪,胡風春夏起。 翩翩吹我衣,肅肅入我耳。 感時念父母,哀嘆無窮已。 有客從外來,聞之常歡喜。 迎問其消息,輒復非鄉里。 邂逅徼時願,骨肉來迎己。 己得自解免,當復棄兒子。 天屬綴人心,念別無會期。 存亡永乖隔,不忍與之辭。 兒前抱我頸,問母欲何之。 人言母當去,豈復有還時。 阿母常仁惻,今何更不慈。 我尚未成人,奈何不顧思。 見此崩五內,恍惚生狂痴。 號泣手撫摩,當發復回疑。 兼有同時輩,相送告離別。 慕我獨得歸,哀叫聲摧裂。 馬為立踟躕,車為不轉轍。 觀者皆噓唏,行路亦嗚咽。 去去割情戀,遄征日遐邁。 悠悠三千里,何時復交會。 念我出腹子,匈臆為摧敗。 既至家人盡,又復無中外。 城廓為山林,庭宇生荊艾。 白骨不知誰,縱橫莫覆蓋。 出門無人聲,豺狼號且吠。 煢煢對孤景,怛吒糜肝肺。 登高遠眺望,魂神忽飛逝。 奄若壽命盡,旁人相寬大。 為復強視息,雖生何聊賴。 託命於新人,竭心自勖勵。 流離成鄙賤,常恐復捐廢。 人生幾何時,懷憂終年歲。 ---> ===Unit 5: Myths and Legends of East Asia=== <!--- Shanhaijing, Zibuyu... Etc. Zhiguai literature. This aims to provide a counterpoint to what Confucius wouldn't discuss - thus Zibuyu. Going straight into Daoism isn't ideal. ---> # [[/Exploring the World of Mountains and Seas/]]<!-- Structure: 出焉 --> # [[/Oh, the Qilin!/]] <!--- Even here, the odes can be studied! ---> # [[/The Poison of Zhen/]] <!--- referenced a lot in histories ---> # [[/Ultimate Justice with Xiezhi/]] <!--- the yellow emperor met one, gao yao also used one ---> # [[/The Virtue of the Fenghuang/]] <!--- shanhaijing has a great line on this ---> # [[/The Entrapment of Hua Po/]] # [[/Nüwa Created the World/]] ===Unit 6: Food from Across the Ages=== # [[/A Simple, Rich Fry/]] <!--- 《禮記 內則》淳熬:煎醢,加于陸稻上,沃之以膏曰淳熬。淳毋煎醢,加于黍食上,沃之以膏曰淳毋。---> # [[/Song Cuisine with Chen Dasou and Lin Hong/]] <!--- 陳達叟 本心齋疏食譜 https://zh.wikisource.org/zh-hant/%E6%9C%AC%E5%BF%83%E6%96%8B%E7%96%8F%E9%A3%9F%E8%B0%B1 ---> <!--- 山家清供 https://zh.wikisource.org/wiki/%E5%B1%B1%E5%AE%B6%E6%B8%85%E4%BE%9B ---> # [[/Yuan Cuisine with Ni Zan/]] <!--- https://ctext.org/wiki.pl?chapter=318337&if=en 《雲林堂飲食制度集》倪瓚 one of the Four Masters, also a painter ---> # [[/A Feast with Yuan Mei/]] <!--- 袁枚 隨園食單 https://ctext.org/wiki.pl?if=gb&res=344157 ---> ===Unit 7: Nation Focus - Japan=== # [[/The Inariyama Sword/]] <!--- short and sweet! ---> # [[/Entering Japan with Takeda Shingen/]] # [[/The Oldest Inscription in Japan/]] <!--- 宇治橋断碑 ---> # [[/The End of a Rebellion/]] # [[/Shinto Teachings with Honda Chikaatsu/]] <!--- https://wikisource.org/wiki/%E9%81%93%E4%B9%8B%E5%A4%A7%E5%8E%9F 本田親徳 道之大原 ---> # [[/The Diary of Fujiwara no Teika/]] <!--- 明月記 ---> # [[/Reading the History of Japan with Prince Toneri/]] <!--- 日本書記, etc. ---> # [[/A Biographical Painting of Toyotomi Hideyoshi/]] <!--- This is on Fanya Hanwen Corpus ---> <!--- # [[/Occupying Taiwan/]] ---> <!--- I have some colonial literature on me that can be used here. ---> ===Unit 8: Nation Focus - Korea=== # [[/Feigned Surrender with Ŭlchi Mundŏk/]] <!--- 乙支文德漢詩 ---> # [[/A fu with Yi Kyubo/]] # [[/An Elegy to the Empress with Choe Ja/]] <!--- Choe Ja 元德大后輓詞·崔滋(최자) 乾極曾客配,坤儀正體元。 枕前朝聖主,帳底見曾孫。 陰慘俄沉月,屋悲便沒軒。 三韓千古淚,七十九年恩。 ---> # [[/Language Reform with Sejong the Great/]] <!--- 訓民正音 https://github.com/ShiraTheMogul/fanyahanwen-corpus/commit/1ef2b42cc50055affaa5ef39c61b87ed31c34a60 multiple poems and descriptive terms, possibly the best capstone ---> # [[/Fall Off Your Horse!/]] <!--- a famous record from 朝鮮王朝實錄 ---> # [[/The Diary of Yi Sun-Sin/]] <!--- 亂中日記 ---> # [[/Tales from Mount Kumo/]] <!--- 金鰲新話 ---> # [[/Pak Chiwŏn Tours the Qing/]] <!--- 熱河日記 ---> # [[/Korea's Three Kingdoms/]] <!--- 三國史記 for sure! ---> # [[/Hwang Yun-seok's Essays/]] <!--- https://zh.wikisource.org/wiki/%E9%A0%A4%E9%BD%8B%E9%81%BA%E7%A8%BF 頤齋遺稿 黃胤錫 Joseon scholar! ---> ===Unit 9: Christian Literature=== # [[/A Different Three Character Classic with Hong Xiuquan/]] # [[/Friar Juan Cobo's Veritable Record/]] <!--- One of few texts from the Philippines that I have ever found! https://bnedigital.bne.es/bd/en/viewer?id=0160187c-9d9b-4f34-84d6-bc03fd310c69 ---> # [[/The Delegate's Edition/]] # [[/Nestorian Steles during the Tang/]] <!--- 大秦景教宣元至本經經幢 and 景教碑 ---> # [[/Hong Xiuquan's Bible/]] <!--- https://bible.fhl.net/ob/nob.html?book=407 ---> <!--- I don't want to focus too much on Hong Xiuquan here, so look for more material, especially from missionaries. ---> ===Unit 10: An Introduction to Daoism=== <!--- And now back to your regularly scheduled Zhuangzi/Laozi/Liezi. But with more interesting stuff. Trust! ---> # [[/Laozi Explains the Dao/]] # [[/Qingtan with Xie Daoyun/]] # [[/The Doubting Neighbour/]] # [[/Kuafu Chases the Sun/]] # [[/The Frog in a Well/]] # [[/Wu wei with King Hui of Liang/]] # [[/The Old Man that Moves the Mountains/]] # [[/Master Zhuang Dreams of Butterflies/]] # [[/Master Incapable and the Poisonous Bird/]] # [[/Transmitting the Dao with Yelü Chucai/]] <!---耶律楚材 - Served 窝阔台, 玄風慶會錄 is short and respectable enough to work with. https://zh.wikisource.org/wiki/%E7%8E%84%E9%A2%A8%E6%85%B6%E6%9C%83%E9%8C%84 ---> # [[/The Indifferent Taoist/]] <!--- northern song https://zh.wikisource.org/wiki/%E7%8E%89%E6%AD%B7%E5%AF%B6%E9%88%94 ---> <!--- Currently very stereotypical, but there's stuff to work with at least. Need to include those weird Daoist characters among other things. ---> ===Unit 11: Nation Focus - Ryukyu Kingdom=== # [[/Historical Annals with Sai On/]] <!--- Kyuko is an easy cop ---> # [[/The Enthronement of Shō Tei/]] # [[/The Twilight of Ryukyu with Shō Ten/]] # [[/A Trip to Ryukyu with Luo Sen/]] <!--- Pre-Capstone ---> <!--- 遐邇貫珍 1854-11 - 日本日記 羅森 https://archive.org/details/HEKC185411/page/n5/mode/1up A solid description of Ryukyu cultural customs in Volume 11. Absolutely incredible. 日三日火船直向東北而駛出了臺灣之外幾日不見天涯是時北風大作波浪沖天火船亦甚飄蕩而不能立見有沙鷗隨風而逐浪心直駛七日漸見小山而到琉球琉球一國長闊一百七十五里其國城在地球圖緯線赤道之北二十六度十四分經線中華北京偏東十一度二十四分自明以來世封王爵叨列藩籬其處土產不過蔬菜番薯菜油黑糖等類人民束髻大補是穿草履男女粧飾頭上祇插一簪二簪為別故少年之男女瞥目則無異及其壯也皆留鬚髯故街上長鬚之人甚多甲寅正月初一予上岸遊玩見街上兒童甚多分以銅錢各極歡喜人民亦甚謙恭民居間亦貼新春聯于門外但不見有別等繁華之事那霸有寺寺內有園是名家世宦之墳所以石刊刻姓名年號于碑上每日道人打掃供奉生花樹葉于墓前另有人家祖墳與中國之明塚無異峰巒之上樹木多植民房則以蠻石圍墻內以茅草結屋而居佳物椅棹俱無惟以草蓆屈膝而坐對火盆而吹煙民間亦有識中國言語字墨者 不張舖店惟有墟塲男不貿易婦女為之以貨易貨而外方之金銀弗尚焉然而百姓亦甚畏官長飲食亦甚粗粕甘守樸儉不務奢華亦鮮欺詐板門紙窓夜間亦不防竊曾見途中撿物亦能以返原人公門之內冷冷落落並無案牘之煩淳樸之風畧有同于上古之世我等外國之欲買什物須言于官官為代辦正月初六提督被理衛廉士等一班將官布列威嚴與予乘轎至王宮總理大臣尚宏勳為主席布政大夫馬良才為知客享宴甚豐食物多與中國無異宴後各官皆饋有紙扇烟包布帛等項是物雖粗此亦世子之恭敬外國故亞國亦以禮物而返贈之世子王宮離岸三里在于山頂是名守禮將至其宮一路亦有樹木石牌坊宮室亦甚寬大幽雅垣局可觀其處多栽鳳尾草森樹等類以障陰山邊田土樹藝五穀近海沙田水漲之後人收其沙以煎鹽此時明月當圓予覽山川亦足見一方之風景 ---> <!--- 中山世鑑 and so on. Lots of poetry too. ---> ===Unit 12: Nation Focus - Singapore=== <!--- National Library of Singapore has a poetry series that's super good! ---> ===Unit 13: Literary Chinese in Medicine=== <!--- do not endorse the medical practices discussed in these...make sure to link back to the heavenly stems here as they are associated with specific body parts. ---> # [[/The Books of the Yellow Emperor/]] <!-- 黃帝内徑 ---> # [[/Deviant Qi with Zhang Congzheng/]] <!--- https://zh.wikisource.org/wiki/%E5%84%92%E9%96%80%E4%BA%8B%E8%A6%AA ---> # [[/Anatomy with Sugita Genpaku/]] <!--- 解体新書 ---> # [[/A Lost Wu Medical Text analysed in Japan/]] <!--- 難經古義 ---> ===Unit 14: People Focus - Zhuang peoples=== <!--- https://mooc1.chaoxing.com/mooc-ans/ztnodedetailcontroller/visitnodedetail?courseId=84745403&knowledgeId=84745463&_from_=&_fromV2_=&rtag= 《峤西诗钞》 is also a really good shout. Found here: https://ctext.org/wiki.pl?if=gb&res=215640&remap=gb ---> <!--- Basically, there are Zhuang and Tangut peoples who wrote in Literary Chinese, and their inclusion here is to show that even those who made their own scripts would use this tongue. 张鸿翮 imported the character 朴 to describe a bug, for example. ---> # [[/Zhuang poetry with Li Bi/]] # [[/The Beauty of Wuyuan with Fang Ju/]] # [[/Disaster and Society with Wei Fenghua/]] # [[/Who Deserves a Biography?/]] <!--- https://wenyi.gmw.cn/2024-06/25/content_37398911.htm 一是忠实记录了汉诗创作与古壮字交融的文化现象。清代壮族诗人张鸿翮(hé)《大塘谣》(《峤西诗钞》卷二)云: 去了休。去到大塘红蓼洲。红蓼生花,不结子。绿朴生花,毬见毬。 诗中所说“绿朴”,是壮族对柚子的惯称。“柚子”,壮语发音为“bug”。根据《古壮字字典》,其对应的古壮字为“朴(㭪)”。诗人将古壮字运用到汉文诗歌创作中,刻下了明清壮汉文化交相辉映的注脚。 This sort of thing is why Zhuang and Tangut inclusion is important, as they show how flexible Literary Chinese can be. ---> ===Unit 15: People Focus - Tangut peoples=== <!--- 羅福萇 and 羅振玉 wrote studies on Western Xia / Tangut script. Look for poets and stuff. ---> ===Unit 16: Literary Chinese in the Military=== <!--- Real Sun Zi hours! 7 Military Classics are an obvious shout, but look for more stuff too. ---> # [[/Fū! Rin! Ka! Zan!/]] # [[/A Bilingual Stele of the Khitans/]] # [[/Going to war with Boyan/]] <!--- Boyan's Poem from the 元史   伯顏,蒙古巴林部人。至元十一年拜中書左丞相,總兵伐宋。官至開府儀同三司,薨贈太師,封淮安王,諡忠武。   《玉堂嘉話》:初,宋未下時,江南謠云:「江南若破,白雁來過。」當時莫喻其意。及宋亡,蓋知指丞相巴延也。   過梅嶺岡留題 馬首經從庾嶺回 【 庾嶺回 七修類稿(乾隆刊本)卷四十六作「嶺島歸」。】 ,王師到處悉平夷。擔頭不帶江南物,只插梅花一兩枝。   《七修類藳》:伯顏下江南,過金陵梅嶺岡詩云云。所以著名,亦有是善。 ---> # [[/An Edict from the Xianbei/]] # [[/The Suppression of the Kingdom of Dongning/]] <!--- 台灣鄭氏始末 https://ctext.org/wiki.pl?if=en&chapter=139938 Largely a record of wars in Dongning rather than anything about the trade etc, so it fits here. ---> # [[/The Shunzhi Emperor vs Li Zicheng/]] # [[/The Art of War/]] ===Unit 17: Nation Focus - Vietnam=== # [[/Đỗ Pháp Thuận and the Southern Skies/]] # [[/Ancestor Veneration with the Descendants of Zhu Xi/]] <!--- https://github.com/ShiraTheMogul/fanyahanwen-corpus/tree/main/corpus%2F%E8%B6%8A%E5%8D%97%E6%BC%A2%E6%96%87%2Fclean somewhere in here ---> # [[/Resolving a Succession Crisis with Emperor Trần Minh Tông/]] <!-- 南翁夢錄·黎澄 --> # [[/Spreading Revolutionary Consciousness with Phan Bội Châu and Liang Qichao/]] <!--- 越南亡國史 Possibly the most important text in Vietnamese history, not even gonna lie. https://zh.wikisource.org/wiki/%E8%B6%8A%E5%8D%97%E4%BA%A1%E5%9C%8B%E5%8F%B2 ---> # [[/Academia in Literary Chinese between East and West/]] <!--- 南風雜誌 is a massive shout here. Absolutely amazing series. ---> ===Unit 18: Historical Annals and Encyclopediae=== <!--- 永樂大典 will teach how to infer from gaps in texts! 《編類》 is an incredibly interesting essay from here that can bring up the odes and Confucius's「思無邪」quote. It can prepare students for the wrath of Qing academia later. ---> # [[/An Introduction to Biographical Paintings/]] <!-- Many older paintings include biographies at the top in Literary Chinese. Students need to learn these. https://commons.wikimedia.org/wiki/File:%E6%AD%B7%E4%BB%A3%E8%81%96%E8%B3%A2%E5%8D%8A%E8%BA%AB%E5%83%8F_%E5%86%8A_%E8%AB%B8%E8%91%9B%E4%BA%AE_(Zhuge_Liang).png - Famous figure, also part of a very notable series. https://commons.wikimedia.org/wiki/File:Otomo-Sorin-2.jpg - Contains the Japanese repetition character 々 https://commons.wikimedia.org/wiki/File:Toyotomi_hideyoshi4.jpg - simply has aura --> # [[/The History of Liao, Jin, and Song with Toqto'a/]] <!--- 脱脱 ---> # [[/Two Years in the Forbidden City with Yu Deling/]] <!--- 清宮禁二年記 https://zh.wikisource.org/wiki/%E6%B8%85%E5%AE%AE%E7%A6%81%E4%BA%8C%E5%B9%B4%E8%A8%98 ---> # [[/Selected Records of the History of the Da Shun/]] <!--- Fair Use of a 2010 book written in Literary Chinese about the Da Shun dynasty. Limit to 500 characters, if that. Use to encourage recognition of Simplified variants and modern Wenyanwen. ---> # [[/Documenting the World with Terajima/]] <!--- 和漢三才図会 寺島良安, built off 三才圖會 ---> ===Unit 19: Buddhist Literature=== <!--- You would be forgiven for wondering why this is so late, but if you look at many classical Buddhist texts you'll quickly see a ton of loanwords that make it significantly more difficult to read than the average text. Thus, it goes here for now. ---> <!--- Place focus on practical stuff first. Stuff you can and WILL see in Buddhist temples. Stuff Buddhists can take away immediately. Skills-based approach feels strongest here. ---> <!--- Look at Northern Liang and Later Qin literature, as there is a ton of work by translators from India during the 16 kingdoms period, particularly those two. ---> <!--- Stuff by Bodhidharma 達摩 could be fun too https://zh.wikisource.org/wiki/Author:%E9%81%94%E6%91%A9 ---> # [[/Dipping your feet in with Wenyan Shu/]] <!--- 華亭 世尊遺法本忘言,教外別傳意已圓。 只履攜將蔥嶺去,不妨來上月明船。 ---> # [[/Buddhism in Battle Standards/]] # [[/The Seven Tathagatas/]] <!--- 南無寶勝如來 南無多寶如來 南無妙色身如來 南無廣博身如來 南無離怖畏如來 南無甘露王如來 南無阿彌陀佛 Use to introduce some core vocabulary in repetitive manner. Useful phrases from my trip to Jing'an Temple 南無本師釋迦牟尼佛 - Pay homage to the root teacher 南無大悲觀世音菩薩 - Pay homage to the goddess of mercy 廣種福田 - widely plant a meritorious field ---> # [[/Two Buddhist Temples in Shanghai/]] <!--- 留雲禪寺 雲留雲翔領畧幾許禪機此地有雲散天開真如界。 塔內塔外普示無邊圓覺是故曰塔影雙照解脫門。 歲次壬午冬月吉旦。 覺醒敬撰。 楊胡生沐手恭書。 善信印利明敬獻。 ---> <!--- 福慧宝鼎 慧明大和尚 - introduce the Buddhist timekeeping system with 佛歷 around this point. 赤烏古剎 建寺一千七百六十周年紀念 古剎三國建 滬瀆有重玄 石佛音淨現 聖跡顯重元 唐時稱永泰 宋敕名靜安 聖祖留佛闡 仲師移伽藍 元收八景偈 明鑄鐘聲梵 清樹化羅漢 選賢十方讚 佛日普光明 福慧共修善 鼎運昌隆際 轉正法輪緣 歲次丁亥住持慧明監製 ---> # [[/Foreseeing Monkhood with Yi Xing/]] <!--- 看命一掌金 ---> # [[/A Trip to Western Xia with Zhi Guang and Hui Zhen/]] <!--- https://zh.wikisource.org/wiki/%E5%AF%86%E5%91%AA%E5%9C%93%E5%9B%A0%E5%BE%80%E7%94%9F%E9%9B%86 ---> <!--- https://zh.wikisource.org/wiki/%E5%AF%86%E5%92%92%E5%9C%93%E5%9B%A0%E5%BE%80%E7%94%9F%E9%9B%86 ---> # [[/Jizang's Three Discourses/]] <!--- https://zh.wikisource.org/wiki/%E4%B8%89%E8%AB%96%E7%8E%84%E7%BE%A9 ---> <!--- I saw these texts being quoted and thus should consider them in some capacity. 《般若波羅蜜多心經》 《金剛般若波羅蜜經》 《一切智光明仙人慈心因緣不食肉經》 《妙法蓮華經》 《大般涅槃經》 《大方等大集經》 《大毘盧舍那成佛神變加持經蓮華胎藏悲生曼荼羅廣大成就儀軌供養方便會》/ 胎藏曼荼羅 《佛說救拔焰口餓鬼陀羅尼經》 《雜阿含經》 Look at Japan's 五山文学 ---> ===Unit 20: People Focus - Manchu peoples=== # [[/Qing dynasty Poetry with Nara Singde/]] <!--- 飲水詞 納蘭性德 https://zh.wikisource.org/wiki/Author:%E7%B4%8D%E8%98%AD%E6%80%A7%E5%BE%B7 ---> # [[/Amassing Words with the Kangxi Emperor/]] # [[/Amassing Literature with the Qianlong Emperor/]] <!--- Siku Quanshu abstract https://zh.wikisource.org/wiki/%E5%9B%9B%E5%BA%AB%E5%85%A8%E6%9B%B8%E7%B8%BD%E7%9B%AE%E6%8F%90%E8%A6%81 ---> <!--- Yongzheng Emperor's Poetry https://zh.wikisource.org/wiki/Author:%E9%9B%8D%E6%AD%A3%E5%B8%9D 《和碩怡賢親王祭文》 Also include 滿洲國 stuff to show the fall of the Qing and attempts to preserve it through becoming a Japanese puppet state. It is important to show how Literary Chinese can be misused as well. 滿洲國建國宣言 is a good shout, as is 法制 to prepare students who may be interested in Taiwan legal stuff later down the road. https://zh.wikisource.org/wiki/Category:%E6%BB%BF%E6%B4%B2%E5%9C%8B ---> # [[/Paintings and Beauty with Puru Aisin-Gioro/]] <!--- Saw these in Shanghai Museum with some writing, seemed really cool. Teaches another skill. ---> ===Unit 21: Qing-RoC Literature=== <!--- many writers here, will be difficult to sift through. Include 四库全書 abstracts and stuff here. ---> # [[/Jewish Refugees in Shanghai/]] <!--- Show passports, certificates, etc, from the Jewish Refugee Museum, anonymised. ---> # [[/A Literary Chinese Abstract/]] <!--- Abstracts from siku quanshu, probably want others ---> # [[/Lament with Lu Ruoteng/]] <!--- 《疑猜》盧若騰,東寧國 盟誓變為交質子,春秋戰國風如此;末世上下相疑猜, 更質妻子防逃徙。 此法只可羈庸奴,若遇梟雄術窮矣;妻可再娶子再育, 安能長坐針氈裏。 我贈一法君記存;推心置腹人知恩;眾人畜之眾人報, 幾個國士在君門。 盧若騰撰,陳漢光編輯,《島噫詩》,臺灣文獻叢刊第二四五種(臺北:臺灣銀行經濟研究室,1968年)21頁。 ---> # [[/Common Linguistics Knowledge in the RoC/]] <!--- 音韻常識 ---> ==References used for this page== * Yang, B. (2016). 文言语法 [Literary Chinese Grammar] (1st ed). 中华书局 [Zhonghua Book Company]. ISBN: 978-7-101-11619-9 * Priestley, K. E., & Shou-jung, C. (1962). China’s Men of Letters, Yesterday and Today. Dragonfly Books. {{BookCat}} ifzl7o0grenq8i5av3iefj8wm0nifj3 4669036 4669035 2026-09-06T00:50:05Z Shira the Mogul 3560559 /* Unit 6: Food from Across the Ages */ Korean stuff! 4669036 wikitext text/x-wiki __notoc__ Welcome to the Wikibook for Literary Chinese (Known as 漢文 "Han Language" in East Asia or 文言 "Literary Language" in China), aimed at individuals hoping to gain a general knowledge of it before progressing into genres they wish to be acquainted with. This is not the [[Classical Chinese]] textbook, which is aimed at Chinese Zhou-Qin era texts. This text aims to shed light on post-Zhou-Qin texts across East Asia, which mimic those texts. However, as Zhou-Qin era texts served as the main body from which individuals learned, they are employed here as and when they are considered necessary or otherwise useful. It does so through a "buffet" approach, showering you, the reader, with an ocean of texts of myriad genre. ==Table of Contents== === Front matter === * [[/Introduction/]] * [[/Appendices/]] === Useful resources === These are quick grab-bags that can be useful for vocabulary-building. * [[/Antonym List/]] <!--- 文/武,大/小,厚/薄,橫/縱...---> * [[/Collocation Groups/]] <!--- e.g. 四象,三靈…… ---> * [[/Pronoun Table/]] * [https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/嚴譯及部定詞等 Yan Fu's Qing-era translations for modern terms] <!--- Wikiversity has this (https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/嚴譯及部定詞等) and the below, I will effectively be translating a lot of it! ---> * [https://zh.wikiversity.org/wiki/Subject:華製新漢語及中文固有語/上古語考輯 Communicative Terms] <!--- this will be translated eventually, but right now it's bad to just leave this here. ---> === Useful primers === Across history, many primers have been made for teaching Literary Chinese to children. These are a few that are recommended for use alongside this work, ideally in flashcards. * [https://www.fdgwz.org.cn/Web/Show/11308 倉頡篇] - Cangjie's Chapters, the earliest one. It is extant, but incomplete. It contains several rare characters, and so if used, I would personally recommend doing so later, or out of interest. * 三字經 - The Three Character Classic, an excellent piece for Confucian education. Pair with 弟子规 for best results. ** 三字經(太平天國版)- For Christians, there is a version made by Hong Xiuquan from the Taiping Rebellion. Despite the context, it is a legitimately useful primer and can be used to self-teach for the Delegate's Edition of the Christian Bible. * 千字文 - The Thousand Character Classic, a remarkable piece of constrained writing that only uses each character once. Amazing for building vocabulary whilst seeing historical allusions and the like. * 五字鑑 - The Five-Character Mirror, essentially the 24 Histories of China compressed into a primer. Uses 5-character couplets, the longest in this list. * 龍文鞭影 - The Shadow of Longwen's Whip, a historical allusion trainer. Best paired with a context piece. ===Unit 0: The Han script=== This unit is intended for those with no familiarity of the Han script. It will prepare you for the units ahead, teaching largely pictographic characters. By the end of this unit, students will: * Recognise around 50 characters. * Understand how characters are composed and how this gives them meaning. * Have a basic idea of how to handwrite and/or type characters using the Cangjie Input Method. * Know some bare basics of Literary Chinese grammar (e.g. Basic word order, where adjectives go, lack of "is", 有...) Lessons: # [[/An Introduction to the Han Script/]] # [[/People, Big and Small/]] # [[/How do we write Chinese?/]] # [[/What are Chinese characters, anyway?/]] # [[/The Sun, the Moon, and the Five Elements/]] # [[/Getting Familiar with Body Parts/]] # [[/Using Numbers and Using Weapons/]] <!--- 竹戈十大中一弓廿卜---> # [[/Tilling the Fields with 有/]] <!--- 山田 ---> # [[/How Characters are Made/|How Characters are Made with Kiyohara no Sanemoto]] # [[/Cangjie Created Characters/]] <!--- Get people to use Cangjie ---> # [[/The Kangxi Radical System/]] <!--- Introduce some monoradical texts to train recognition. ---> ===Unit 1: Basic Skills=== This unit is intended for those with minimal familiarity with the Han script and no familiarity with Literary Chinese. There is a focus on simple structures, skills for dissecting common textual structures, and short-form poetry in this unit. Before starting this unit, students should: * Recognise around ~30 characters. * Can use Cangjie input. * Have given Unit 0 a cursory glance. <br> By the end of this unit, students will: * Recognise around ~100 characters. * Comprehend numbers, the Heavenly Stems, and the Earthly Branches, and be able to use them to quantify time and date. * Intuit the basic topic -> comment idea behind Literary Chinese. "This, it is..." * Understand basic function words such as 也, 而, 有, and 謂. Lessons: # [[/The All-Purpose 也/]] # [[/An Introduction to Chinese Numbers/]] <!--- It is hard to find authentic materials for this ---> # [[/One, Two, Left, and Right with Gongsun Long/]] <!--- 曰:「二有一乎?」 曰:「二無一。」 曰:「二有右乎?」 曰:「二無右。」 曰:「二有左乎?」 曰:「二無左。」 曰:「右可謂二乎?」 曰:「不可。」 曰:「左可謂二乎?」 曰:「不可。」 曰:「左與右可謂二乎?」 曰:「可。」 ---> # [[/The Heavenly Stems/]] <!--- Introduce ordinals, which will be used to demonstrate sentence patterns later. ---> # [[/Tell the Time with Earthly Branches/]] <!--- Introduce verbs and timekeeping ---> # [[/Lunar Dates with the Spring and Autumn Annals/]] <!--- Vocabulary: 歲,年,朔,月,日,來,前,初,正,春秋夏冬,曆,上,下. Consider including traditional names for months in a list. ---> # [[/Skimming for Major Events in Historical Annals/]] <!--- Don't simply use Confucius's Chunqiu: We can use texts inspired by it. E.g. 三國史記 - 十五年京城旱。秋七月,蝗。very few new characters, lots one can use. Instantly able to use. https://zh.wikisource.org/wiki/%E4%B8%89%E5%9C%8B%E5%8F%B2%E8%A8%98/%E5%8D%B701 Skimming annals is very possible and a very useful skill. Don't skip out on it. Teach students to skim read!!! ---> # [[/Dinner with the Daimyo/]] <!-- 侍宴·大友皇子 皇明光日月,帝徳載天地。 三才併秦昌,万国表臣義。 --> # [[/In Discourse with Jibong/]] <!-- 芝峰類說 倭國謂田爲畠。謂水田爲田。火田爲畑。猶我國以水田爲畓也。故官名有畠山殿。地名有畑島云。 --> # [[/How do we Write Height and Weight?/]] <!--- Hilarious oversight ---> # [[/Eating like a Zhou Aristocrat/]] # [[/Shinto FAQ with Honda Chikaatsu/]] <!--- https://wikisource.org/wiki/%E7%9C%9E%E9%81%93%E5%95%8F%E5%B0%8D 眞道問對 本田親徳 really good way of operationalising 乎 and much of the early grammar. 問 天帝無始無終乎。 對 天帝無始無終也。 旣以無始無終之力 與無始無終之體 造無始無終之萬物。 其功亦無始無終也。 問 天地大原在道乎。 對 天地大原實在道。 鬼神依道而立。 人民依道而活。 萬物依道而息。 This is great! ---> <!--- Some cool stuff I saw someone studying from https://zh.wikisource.org/wiki/%E8%87%B3%E5%B0%8F%E4%B8%98%E8%A5%BF%E5%B0%8F%E7%9F%B3%E6%BD%AD%E8%A8%98# https://zh.wikisource.org/wiki/%E6%A0%B8%E8%88%9F%E8%A8%98 Could be used for period focus ---> ===Unit 2: An Overview of Sinitic Poetry=== This unit will teach you how Sinitic Poetry operates; - that is, the way individuals in the Sinosphere compose poetry in Literary Chinese. Despite this language's fall out of favour in the past century, this tradition is still remarkably alive and well, and their short length makes them more accessible than elaborate prose. In this unit, you will begin from the ''Classic of Poetry'' before travelling through poems from the Tang dynasty, Singapore, Japan, Vietnam, the Ryukyu Kingdom, and Korea. When introducing poetry, I will furthermore use the language from the nation it is from to show how it is recited by its people. After discussing the Classic of Poetry, we will also be a small detour into a discussion on Ping-Ze 平仄, the Tang dynasty system of alternating tones, so to produce rhyme on tonal and phonological levels. This had a major impact on Literary Chinese poetry as a whole! By the end of this Unit, students will: * Recognise around 120 more characters. * Be able to explain how Sinitic Poetry rhymes and the themes it contains. * Be able to use function words such as 在, 無, 不, 聿, and 于/於 in poetic contexts. * Recognise the switch between 吾/我 in the subject-object positions and demonstrate it in usage. * (Chinese speakers) Be able to differentiate 于 and 於, and understand the "interest(ed) in" meaning of 好 in most circumstances. <!--- Summary of the above part about 于 and 於 for other editors: 于 and 於 were distinct words for an extremely long time and were still such to Literary Chinese writers. Their "merging" through Simplified-Traditional Chinese distinctions is a very modern thing. I will summarise their usages here, using Pulleyblank's Outline of Classical Chinese Grammar (2000); * 于 - This can mean "to go" or "to/at". 黃鳥于飛 "The yellow birds go flying". Must be post-verbal. It can also appear in 至于. * 於 - This is an all-purpose locative preposition - from "on/at/in" to "from" or even "than" (甲於乙). The implication of motion is not there at all. Must be pre-verbal. It can also appear in 之於 or be an archaic noun for a crow 於 (烏). ---> Lessons: # [[/Across the Rivers with Emperor Puliuru Guang/]] <!--- Illustrate ping-ze ---> # [[/To Study the Odes/]] # [[/A Detour into Orthodox Ping-Ze/]] <!--- 平 and 仄 are useful characters themselves. Show 仄 in the binomes 反仄,歉仄,逼仄 as it's often difficult to immediately use ---> # [[/The Restraint of Du Fu/]] # [[/The Longing of Li Bai/]] # [[/The Environment with Bukha Timur/]] # [[/Pillow Talk with Guan Yunshi/]] <!--- 紅繡鞋·貫雲石 挨著靠著雲窗同坐,偎著抱著月枕雙歌,聽著數著愁著怕著早四更過。四更過情未足,情未足夜如梭。天哪,更閏一更兒妨甚么! Uyghur author! ---> # [[/Buddhist Philosophy with Ngô Chân Lưu and Taisei Shōan/]] <!-- 元火·吳真流 木中元有火,元火復還生。 若為木無火,鉆燧何有萌。--> <!-- 杜鵑·大成聖安 夢覚孤床静 杜鵑帯雨飛 一声来近枕 何者不沾衣 --> # [[/Odes with Mō Taiei and Zheng Chengxun/]] <!-- 詠松·毛泰永 植體宜千仞,垂陰動百尋。 李膺真烈烈,和嶠自森森。 桃李何堪較,雪霜安得侵。 萬年身不老,種子又成林。 AKA Inoha Seiki 伊野波 盛紀 --> <!-- 詠班蘭·鄭成勛 南國多芳草,班蘭最有名。 深根將綠茁,長葉亦叢生。 取味迎賓合,入厨任水烹。 可憐經一用,擲棄不留情。 鄭成勛《樵隱詩集》 https://nus.edu.sg/nuslibraries/dsprojects/sg-jiutishi/poem/827 --> # [[/A Golden Cup and the Fall of a Dynasty with Yan Fu/]] # [[/On a Journey with Sadula/]] <!--- No lesson entry: 朝中措·襄陽古道灞陵橋 襄陽古道灞陵橋,詩興與秋高。 千古風流人物,一時多少雄豪。 霜清玉塞,雲飛隴首,風落江皋。 夢到鳳凰台上,山圍故國周遭。 北郊晚步 陂水荷凋晚,茅檐燕去涼。 遠林明落景,平麓淡秋光。 群牧歸村巷,孤禽立野航。 自諳閑散樂,園圃意尤長。 Jurchen poet and grandson of Emperor Shizong of Jin. He's a Zen Buddhist, so we'll go back to him later. ---> ===Unit 3: Confucianism and the World=== This is a Confucian-themed unit with a smattering of other items. You will see the odd geography of the past, early linguistic philosophy, and terrifying breakaway states! By the end of this unit, students should be able to: * Recognise around 200+ characters. * Read basic annals and histories with some dictionary assistance, and comprehend 3-character structures reliably. * Have encountered basic grammatical points such as 之、乎、者、也、而、則、乃、所、以、於、于、與、且、蓋、and 夫. ** 於 and 于 should be distinguishable. * Survive a text of at least 250 characters and read for gist. Lessons: # [[/A Brief Overview of Confucianism/]] # [[/Teaching the Annals in Qi/]] <!-- Gongyang Gao's commentary --> # [[/Is a White Horse a Horse?/]]<!-- Teach negation with 非 in 公孙龍子 and compare with 不 --> # [[/The Three Character Classic/]] # [[/Expressing Filial Conduct with Confucius and Hara Saihin/]] <!-- 次韻杏坪先生 父執有君孤不孤 相依遍接搢紳徒 区区自抱地方寸 杳杳重遊天一隅 羇雁飛鳴迷汝國 家人思夢入江都 如教志業青年遂 世上寧無逐臭夫 --> # [[/Confucianism and the Environment with Sai On/]]<!-- 木假山記 --> # [[/In Debate with Mencius/]] ===Unit 4: Women's Writing=== In this unit, women's writing from various areas of China will be explored. This is chiefly targeted at poetry and the themes within; from the feminine voice of the Classic of Poetry to the remonstrance towards the Khitan Emperor Tianzuo of Jin by his Consort Dasese. The role of women in courtly society is to be elucidated here! # [[/An Unmarried Life with Heo Nansŏrhŏn/]] <!--- 貧女吟 豈是乏容色。工鍼復工織。 少小長寒門。良媒不相識。 夜久織未休。戛戛鳴寒機。 機中一匹練。終作阿誰衣。 手把金翦刀。夜寒十指直。 爲人作嫁衣。年年還獨宿。 ---> # [[/Responding to Lord Trần with Hồ Xuân Hương/]] <!--- Responding to 陳光靜 Trần Quang Tĩnh 《和陳侯》 愧無才調使人驚,十載風塵貫耳鈴。 已是臨枰知敵手,莫須敲月苦殫精。 為輪為彈隨遭遇,誰鳳誰鶯任賦生。 造物於人何苟惜,明珠休向暗中呈。 莫須 is an important structure to teach here. ---> # [[/Gaze into the Autumn Night with Taisei Shōan/]] <!--- 秋夜偶成·大成聖安 長天浮爽気,月色興無窮 群犬吠山径,百蟲啼野風 悲秋秋夜永,感古古今同 自是孤窓下,凄然万慮空 ---> # [[/Visiting a Temple with Yu Xuanji/]] <!--- 遊崇真觀南樓覩新及第題名處 雲峰滿目放春晴,歷歷銀鈎指下生。 自恨羅衣掩詩句,擧頭空羨榜中名。 ---> # [[/Remonstrance with Dasese/]] <!--- https://zh.wikisource.org/wiki/%E8%AB%B7%E8%AB%AB%E6%AD%8C 諷諫歌·大瑟瑟 勿嗟塞上兮暗紅塵。 勿傷多難兮畏夷人。 不如塞奸邪之路兮選取賢臣。 直須臥薪嚐膽兮激壯士之捐身。 可以朝清漠北兮夕枕燕雲。 Dasese (or 萧瑟瑟) was a Khitan consort to Emperor Tianzuo of Liao. She remonstrated him as the Jurchens were beginning to encroach upon the Khitan, and was forced to commit suicide for her remonstrance. Tianzuo would soon pay for his malfeasance. ---> # [[/The Love Songs of the Odes/]] <!--- 褰裳 子惠思我,褰裳涉溱。子不我思,豈無他人?狂童之狂也且! 子惠思我,褰裳涉洧。子不我思,豈無他士?狂童之狂也且! 柏舟 彼柏舟,在彼中河,髧彼兩髦,實維我儀,之死矢靡它,母也天只,不諒人只。 汎彼柏舟,在彼河側,髧彼兩髦,實維我特,之死矢靡慝,母也天只,不諒人只。 行露 厭浥行露,豈不夙夜,謂行多露。 誰謂雀無角?何以穿我屋?誰謂女無家?何以速我獄?雖速我獄,室家不足。 誰謂鼠無牙?何以穿我墉?誰謂女無家?何以速我訟?雖速我訟,亦不女從。 ---> # [[/Rules for Women with Ban Zhao/]] <!--- https://zh.wikisource.org/wiki/%E5%A5%B3%E8%AA%A1 ---> # [[/The Tragedy of Cai Wenji/]] <!--- 悲憤詩 〔兩漢〕蔡文姬 漢季失權柄,董卓亂天常。 志欲圖篡弒,先害諸賢良。 逼迫遷舊邦,擁主以自強。 海內興義師,欲共討不祥。 卓眾來東下,金甲耀日光。 平土人脆弱,來兵皆胡羌。 獵野圍城邑,所向悉破亡。 斬截無孑遺,屍骸相撐拒。 馬邊懸男頭,馬後載婦女。 長驅西入關,迥路險且阻。 還顧邈冥冥,肝脾為爛腐。 所略有萬計,不得令屯聚。 或有骨肉俱,欲言不敢語。 失意幾微間,輒言斃降虜。 要當以亭刃,我曹不活汝。 豈復惜性命,不堪其詈罵。 或便加棰杖,毒痛參並下。 旦則號泣行,夜則悲吟坐。 欲死不能得,欲生無一可。 彼蒼者何辜,乃遭此厄禍。 邊荒與華異,人俗少義理。 處所多霜雪,胡風春夏起。 翩翩吹我衣,肅肅入我耳。 感時念父母,哀嘆無窮已。 有客從外來,聞之常歡喜。 迎問其消息,輒復非鄉里。 邂逅徼時願,骨肉來迎己。 己得自解免,當復棄兒子。 天屬綴人心,念別無會期。 存亡永乖隔,不忍與之辭。 兒前抱我頸,問母欲何之。 人言母當去,豈復有還時。 阿母常仁惻,今何更不慈。 我尚未成人,奈何不顧思。 見此崩五內,恍惚生狂痴。 號泣手撫摩,當發復回疑。 兼有同時輩,相送告離別。 慕我獨得歸,哀叫聲摧裂。 馬為立踟躕,車為不轉轍。 觀者皆噓唏,行路亦嗚咽。 去去割情戀,遄征日遐邁。 悠悠三千里,何時復交會。 念我出腹子,匈臆為摧敗。 既至家人盡,又復無中外。 城廓為山林,庭宇生荊艾。 白骨不知誰,縱橫莫覆蓋。 出門無人聲,豺狼號且吠。 煢煢對孤景,怛吒糜肝肺。 登高遠眺望,魂神忽飛逝。 奄若壽命盡,旁人相寬大。 為復強視息,雖生何聊賴。 託命於新人,竭心自勖勵。 流離成鄙賤,常恐復捐廢。 人生幾何時,懷憂終年歲。 ---> ===Unit 5: Myths and Legends of East Asia=== <!--- Shanhaijing, Zibuyu... Etc. Zhiguai literature. This aims to provide a counterpoint to what Confucius wouldn't discuss - thus Zibuyu. Going straight into Daoism isn't ideal. ---> # [[/Exploring the World of Mountains and Seas/]]<!-- Structure: 出焉 --> # [[/Oh, the Qilin!/]] <!--- Even here, the odes can be studied! ---> # [[/The Poison of Zhen/]] <!--- referenced a lot in histories ---> # [[/Ultimate Justice with Xiezhi/]] <!--- the yellow emperor met one, gao yao also used one ---> # [[/The Virtue of the Fenghuang/]] <!--- shanhaijing has a great line on this ---> # [[/The Entrapment of Hua Po/]] # [[/Nüwa Created the World/]] ===Unit 6: Food from Across the Ages=== # [[/A Simple, Rich Fry/]] <!--- 《禮記 內則》淳熬:煎醢,加于陸稻上,沃之以膏曰淳熬。淳毋煎醢,加于黍食上,沃之以膏曰淳毋。---> # [[/Song Cuisine with Chen Dasou and Lin Hong/]] <!--- 陳達叟 本心齋疏食譜 https://zh.wikisource.org/zh-hant/%E6%9C%AC%E5%BF%83%E6%96%8B%E7%96%8F%E9%A3%9F%E8%B0%B1 ---> <!--- 山家清供 https://zh.wikisource.org/wiki/%E5%B1%B1%E5%AE%B6%E6%B8%85%E4%BE%9B ---> # [[/Yuan Cuisine with Ni Zan/]] <!--- https://ctext.org/wiki.pl?chapter=318337&if=en 《雲林堂飲食制度集》倪瓚 one of the Four Masters, also a painter ---> # [[/A Feast with Yuan Mei/]] <!--- 袁枚 隨園食單 https://ctext.org/wiki.pl?if=gb&res=344157 ---> # [[/Remembering the Food of Joseon with Hŏ Kyun/]] <!--- https://rmda.kulib.kyoto-u.ac.jp/item/rb00023424?page=3p 許筠 屠門大嚼 ---> ===Unit 7: Nation Focus - Japan=== # [[/The Inariyama Sword/]] <!--- short and sweet! ---> # [[/Entering Japan with Takeda Shingen/]] # [[/The Oldest Inscription in Japan/]] <!--- 宇治橋断碑 ---> # [[/The End of a Rebellion/]] # [[/Shinto Teachings with Honda Chikaatsu/]] <!--- https://wikisource.org/wiki/%E9%81%93%E4%B9%8B%E5%A4%A7%E5%8E%9F 本田親徳 道之大原 ---> # [[/The Diary of Fujiwara no Teika/]] <!--- 明月記 ---> # [[/Reading the History of Japan with Prince Toneri/]] <!--- 日本書記, etc. ---> # [[/A Biographical Painting of Toyotomi Hideyoshi/]] <!--- This is on Fanya Hanwen Corpus ---> <!--- # [[/Occupying Taiwan/]] ---> <!--- I have some colonial literature on me that can be used here. ---> ===Unit 8: Nation Focus - Korea=== # [[/Feigned Surrender with Ŭlchi Mundŏk/]] <!--- 乙支文德漢詩 ---> # [[/A fu with Yi Kyubo/]] # [[/An Elegy to the Empress with Choe Ja/]] <!--- Choe Ja 元德大后輓詞·崔滋(최자) 乾極曾客配,坤儀正體元。 枕前朝聖主,帳底見曾孫。 陰慘俄沉月,屋悲便沒軒。 三韓千古淚,七十九年恩。 ---> # [[/Language Reform with Sejong the Great/]] <!--- 訓民正音 https://github.com/ShiraTheMogul/fanyahanwen-corpus/commit/1ef2b42cc50055affaa5ef39c61b87ed31c34a60 multiple poems and descriptive terms, possibly the best capstone ---> # [[/Fall Off Your Horse!/]] <!--- a famous record from 朝鮮王朝實錄 ---> # [[/The Diary of Yi Sun-Sin/]] <!--- 亂中日記 ---> # [[/Tales from Mount Kumo/]] <!--- 金鰲新話 ---> # [[/Pak Chiwŏn Tours the Qing/]] <!--- 熱河日記 ---> # [[/Korea's Three Kingdoms/]] <!--- 三國史記 for sure! ---> # [[/Hwang Yun-seok's Essays/]] <!--- https://zh.wikisource.org/wiki/%E9%A0%A4%E9%BD%8B%E9%81%BA%E7%A8%BF 頤齋遺稿 黃胤錫 Joseon scholar! ---> ===Unit 9: Christian Literature=== # [[/A Different Three Character Classic with Hong Xiuquan/]] # [[/Friar Juan Cobo's Veritable Record/]] <!--- One of few texts from the Philippines that I have ever found! https://bnedigital.bne.es/bd/en/viewer?id=0160187c-9d9b-4f34-84d6-bc03fd310c69 ---> # [[/The Delegate's Edition/]] # [[/Nestorian Steles during the Tang/]] <!--- 大秦景教宣元至本經經幢 and 景教碑 ---> # [[/Hong Xiuquan's Bible/]] <!--- https://bible.fhl.net/ob/nob.html?book=407 ---> <!--- I don't want to focus too much on Hong Xiuquan here, so look for more material, especially from missionaries. ---> ===Unit 10: An Introduction to Daoism=== <!--- And now back to your regularly scheduled Zhuangzi/Laozi/Liezi. But with more interesting stuff. Trust! ---> # [[/Laozi Explains the Dao/]] # [[/Qingtan with Xie Daoyun/]] # [[/The Doubting Neighbour/]] # [[/Kuafu Chases the Sun/]] # [[/The Frog in a Well/]] # [[/Wu wei with King Hui of Liang/]] # [[/The Old Man that Moves the Mountains/]] # [[/Master Zhuang Dreams of Butterflies/]] # [[/Master Incapable and the Poisonous Bird/]] # [[/Transmitting the Dao with Yelü Chucai/]] <!---耶律楚材 - Served 窝阔台, 玄風慶會錄 is short and respectable enough to work with. https://zh.wikisource.org/wiki/%E7%8E%84%E9%A2%A8%E6%85%B6%E6%9C%83%E9%8C%84 ---> # [[/The Indifferent Taoist/]] <!--- northern song https://zh.wikisource.org/wiki/%E7%8E%89%E6%AD%B7%E5%AF%B6%E9%88%94 ---> <!--- Currently very stereotypical, but there's stuff to work with at least. Need to include those weird Daoist characters among other things. ---> ===Unit 11: Nation Focus - Ryukyu Kingdom=== # [[/Historical Annals with Sai On/]] <!--- Kyuko is an easy cop ---> # [[/The Enthronement of Shō Tei/]] # [[/The Twilight of Ryukyu with Shō Ten/]] # [[/A Trip to Ryukyu with Luo Sen/]] <!--- Pre-Capstone ---> <!--- 遐邇貫珍 1854-11 - 日本日記 羅森 https://archive.org/details/HEKC185411/page/n5/mode/1up A solid description of Ryukyu cultural customs in Volume 11. Absolutely incredible. 日三日火船直向東北而駛出了臺灣之外幾日不見天涯是時北風大作波浪沖天火船亦甚飄蕩而不能立見有沙鷗隨風而逐浪心直駛七日漸見小山而到琉球琉球一國長闊一百七十五里其國城在地球圖緯線赤道之北二十六度十四分經線中華北京偏東十一度二十四分自明以來世封王爵叨列藩籬其處土產不過蔬菜番薯菜油黑糖等類人民束髻大補是穿草履男女粧飾頭上祇插一簪二簪為別故少年之男女瞥目則無異及其壯也皆留鬚髯故街上長鬚之人甚多甲寅正月初一予上岸遊玩見街上兒童甚多分以銅錢各極歡喜人民亦甚謙恭民居間亦貼新春聯于門外但不見有別等繁華之事那霸有寺寺內有園是名家世宦之墳所以石刊刻姓名年號于碑上每日道人打掃供奉生花樹葉于墓前另有人家祖墳與中國之明塚無異峰巒之上樹木多植民房則以蠻石圍墻內以茅草結屋而居佳物椅棹俱無惟以草蓆屈膝而坐對火盆而吹煙民間亦有識中國言語字墨者 不張舖店惟有墟塲男不貿易婦女為之以貨易貨而外方之金銀弗尚焉然而百姓亦甚畏官長飲食亦甚粗粕甘守樸儉不務奢華亦鮮欺詐板門紙窓夜間亦不防竊曾見途中撿物亦能以返原人公門之內冷冷落落並無案牘之煩淳樸之風畧有同于上古之世我等外國之欲買什物須言于官官為代辦正月初六提督被理衛廉士等一班將官布列威嚴與予乘轎至王宮總理大臣尚宏勳為主席布政大夫馬良才為知客享宴甚豐食物多與中國無異宴後各官皆饋有紙扇烟包布帛等項是物雖粗此亦世子之恭敬外國故亞國亦以禮物而返贈之世子王宮離岸三里在于山頂是名守禮將至其宮一路亦有樹木石牌坊宮室亦甚寬大幽雅垣局可觀其處多栽鳳尾草森樹等類以障陰山邊田土樹藝五穀近海沙田水漲之後人收其沙以煎鹽此時明月當圓予覽山川亦足見一方之風景 ---> <!--- 中山世鑑 and so on. Lots of poetry too. ---> ===Unit 12: Nation Focus - Singapore=== <!--- National Library of Singapore has a poetry series that's super good! ---> ===Unit 13: Literary Chinese in Medicine=== <!--- do not endorse the medical practices discussed in these...make sure to link back to the heavenly stems here as they are associated with specific body parts. ---> # [[/The Books of the Yellow Emperor/]] <!-- 黃帝内徑 ---> # [[/Deviant Qi with Zhang Congzheng/]] <!--- https://zh.wikisource.org/wiki/%E5%84%92%E9%96%80%E4%BA%8B%E8%A6%AA ---> # [[/Anatomy with Sugita Genpaku/]] <!--- 解体新書 ---> # [[/A Lost Wu Medical Text analysed in Japan/]] <!--- 難經古義 ---> ===Unit 14: People Focus - Zhuang peoples=== <!--- https://mooc1.chaoxing.com/mooc-ans/ztnodedetailcontroller/visitnodedetail?courseId=84745403&knowledgeId=84745463&_from_=&_fromV2_=&rtag= 《峤西诗钞》 is also a really good shout. Found here: https://ctext.org/wiki.pl?if=gb&res=215640&remap=gb ---> <!--- Basically, there are Zhuang and Tangut peoples who wrote in Literary Chinese, and their inclusion here is to show that even those who made their own scripts would use this tongue. 张鸿翮 imported the character 朴 to describe a bug, for example. ---> # [[/Zhuang poetry with Li Bi/]] # [[/The Beauty of Wuyuan with Fang Ju/]] # [[/Disaster and Society with Wei Fenghua/]] # [[/Who Deserves a Biography?/]] <!--- https://wenyi.gmw.cn/2024-06/25/content_37398911.htm 一是忠实记录了汉诗创作与古壮字交融的文化现象。清代壮族诗人张鸿翮(hé)《大塘谣》(《峤西诗钞》卷二)云: 去了休。去到大塘红蓼洲。红蓼生花,不结子。绿朴生花,毬见毬。 诗中所说“绿朴”,是壮族对柚子的惯称。“柚子”,壮语发音为“bug”。根据《古壮字字典》,其对应的古壮字为“朴(㭪)”。诗人将古壮字运用到汉文诗歌创作中,刻下了明清壮汉文化交相辉映的注脚。 This sort of thing is why Zhuang and Tangut inclusion is important, as they show how flexible Literary Chinese can be. ---> ===Unit 15: People Focus - Tangut peoples=== <!--- 羅福萇 and 羅振玉 wrote studies on Western Xia / Tangut script. Look for poets and stuff. ---> ===Unit 16: Literary Chinese in the Military=== <!--- Real Sun Zi hours! 7 Military Classics are an obvious shout, but look for more stuff too. ---> # [[/Fū! Rin! Ka! Zan!/]] # [[/A Bilingual Stele of the Khitans/]] # [[/Going to war with Boyan/]] <!--- Boyan's Poem from the 元史   伯顏,蒙古巴林部人。至元十一年拜中書左丞相,總兵伐宋。官至開府儀同三司,薨贈太師,封淮安王,諡忠武。   《玉堂嘉話》:初,宋未下時,江南謠云:「江南若破,白雁來過。」當時莫喻其意。及宋亡,蓋知指丞相巴延也。   過梅嶺岡留題 馬首經從庾嶺回 【 庾嶺回 七修類稿(乾隆刊本)卷四十六作「嶺島歸」。】 ,王師到處悉平夷。擔頭不帶江南物,只插梅花一兩枝。   《七修類藳》:伯顏下江南,過金陵梅嶺岡詩云云。所以著名,亦有是善。 ---> # [[/An Edict from the Xianbei/]] # [[/The Suppression of the Kingdom of Dongning/]] <!--- 台灣鄭氏始末 https://ctext.org/wiki.pl?if=en&chapter=139938 Largely a record of wars in Dongning rather than anything about the trade etc, so it fits here. ---> # [[/The Shunzhi Emperor vs Li Zicheng/]] # [[/The Art of War/]] ===Unit 17: Nation Focus - Vietnam=== # [[/Đỗ Pháp Thuận and the Southern Skies/]] # [[/Ancestor Veneration with the Descendants of Zhu Xi/]] <!--- https://github.com/ShiraTheMogul/fanyahanwen-corpus/tree/main/corpus%2F%E8%B6%8A%E5%8D%97%E6%BC%A2%E6%96%87%2Fclean somewhere in here ---> # [[/Resolving a Succession Crisis with Emperor Trần Minh Tông/]] <!-- 南翁夢錄·黎澄 --> # [[/Spreading Revolutionary Consciousness with Phan Bội Châu and Liang Qichao/]] <!--- 越南亡國史 Possibly the most important text in Vietnamese history, not even gonna lie. https://zh.wikisource.org/wiki/%E8%B6%8A%E5%8D%97%E4%BA%A1%E5%9C%8B%E5%8F%B2 ---> # [[/Academia in Literary Chinese between East and West/]] <!--- 南風雜誌 is a massive shout here. Absolutely amazing series. ---> ===Unit 18: Historical Annals and Encyclopediae=== <!--- 永樂大典 will teach how to infer from gaps in texts! 《編類》 is an incredibly interesting essay from here that can bring up the odes and Confucius's「思無邪」quote. It can prepare students for the wrath of Qing academia later. ---> # [[/An Introduction to Biographical Paintings/]] <!-- Many older paintings include biographies at the top in Literary Chinese. Students need to learn these. https://commons.wikimedia.org/wiki/File:%E6%AD%B7%E4%BB%A3%E8%81%96%E8%B3%A2%E5%8D%8A%E8%BA%AB%E5%83%8F_%E5%86%8A_%E8%AB%B8%E8%91%9B%E4%BA%AE_(Zhuge_Liang).png - Famous figure, also part of a very notable series. https://commons.wikimedia.org/wiki/File:Otomo-Sorin-2.jpg - Contains the Japanese repetition character 々 https://commons.wikimedia.org/wiki/File:Toyotomi_hideyoshi4.jpg - simply has aura --> # [[/The History of Liao, Jin, and Song with Toqto'a/]] <!--- 脱脱 ---> # [[/Two Years in the Forbidden City with Yu Deling/]] <!--- 清宮禁二年記 https://zh.wikisource.org/wiki/%E6%B8%85%E5%AE%AE%E7%A6%81%E4%BA%8C%E5%B9%B4%E8%A8%98 ---> # [[/Selected Records of the History of the Da Shun/]] <!--- Fair Use of a 2010 book written in Literary Chinese about the Da Shun dynasty. Limit to 500 characters, if that. Use to encourage recognition of Simplified variants and modern Wenyanwen. ---> # [[/Documenting the World with Terajima/]] <!--- 和漢三才図会 寺島良安, built off 三才圖會 ---> ===Unit 19: Buddhist Literature=== <!--- You would be forgiven for wondering why this is so late, but if you look at many classical Buddhist texts you'll quickly see a ton of loanwords that make it significantly more difficult to read than the average text. Thus, it goes here for now. ---> <!--- Place focus on practical stuff first. Stuff you can and WILL see in Buddhist temples. Stuff Buddhists can take away immediately. Skills-based approach feels strongest here. ---> <!--- Look at Northern Liang and Later Qin literature, as there is a ton of work by translators from India during the 16 kingdoms period, particularly those two. ---> <!--- Stuff by Bodhidharma 達摩 could be fun too https://zh.wikisource.org/wiki/Author:%E9%81%94%E6%91%A9 ---> # [[/Dipping your feet in with Wenyan Shu/]] <!--- 華亭 世尊遺法本忘言,教外別傳意已圓。 只履攜將蔥嶺去,不妨來上月明船。 ---> # [[/Buddhism in Battle Standards/]] # [[/The Seven Tathagatas/]] <!--- 南無寶勝如來 南無多寶如來 南無妙色身如來 南無廣博身如來 南無離怖畏如來 南無甘露王如來 南無阿彌陀佛 Use to introduce some core vocabulary in repetitive manner. Useful phrases from my trip to Jing'an Temple 南無本師釋迦牟尼佛 - Pay homage to the root teacher 南無大悲觀世音菩薩 - Pay homage to the goddess of mercy 廣種福田 - widely plant a meritorious field ---> # [[/Two Buddhist Temples in Shanghai/]] <!--- 留雲禪寺 雲留雲翔領畧幾許禪機此地有雲散天開真如界。 塔內塔外普示無邊圓覺是故曰塔影雙照解脫門。 歲次壬午冬月吉旦。 覺醒敬撰。 楊胡生沐手恭書。 善信印利明敬獻。 ---> <!--- 福慧宝鼎 慧明大和尚 - introduce the Buddhist timekeeping system with 佛歷 around this point. 赤烏古剎 建寺一千七百六十周年紀念 古剎三國建 滬瀆有重玄 石佛音淨現 聖跡顯重元 唐時稱永泰 宋敕名靜安 聖祖留佛闡 仲師移伽藍 元收八景偈 明鑄鐘聲梵 清樹化羅漢 選賢十方讚 佛日普光明 福慧共修善 鼎運昌隆際 轉正法輪緣 歲次丁亥住持慧明監製 ---> # [[/Foreseeing Monkhood with Yi Xing/]] <!--- 看命一掌金 ---> # [[/A Trip to Western Xia with Zhi Guang and Hui Zhen/]] <!--- https://zh.wikisource.org/wiki/%E5%AF%86%E5%91%AA%E5%9C%93%E5%9B%A0%E5%BE%80%E7%94%9F%E9%9B%86 ---> <!--- https://zh.wikisource.org/wiki/%E5%AF%86%E5%92%92%E5%9C%93%E5%9B%A0%E5%BE%80%E7%94%9F%E9%9B%86 ---> # [[/Jizang's Three Discourses/]] <!--- https://zh.wikisource.org/wiki/%E4%B8%89%E8%AB%96%E7%8E%84%E7%BE%A9 ---> <!--- I saw these texts being quoted and thus should consider them in some capacity. 《般若波羅蜜多心經》 《金剛般若波羅蜜經》 《一切智光明仙人慈心因緣不食肉經》 《妙法蓮華經》 《大般涅槃經》 《大方等大集經》 《大毘盧舍那成佛神變加持經蓮華胎藏悲生曼荼羅廣大成就儀軌供養方便會》/ 胎藏曼荼羅 《佛說救拔焰口餓鬼陀羅尼經》 《雜阿含經》 Look at Japan's 五山文学 ---> ===Unit 20: People Focus - Manchu peoples=== # [[/Qing dynasty Poetry with Nara Singde/]] <!--- 飲水詞 納蘭性德 https://zh.wikisource.org/wiki/Author:%E7%B4%8D%E8%98%AD%E6%80%A7%E5%BE%B7 ---> # [[/Amassing Words with the Kangxi Emperor/]] # [[/Amassing Literature with the Qianlong Emperor/]] <!--- Siku Quanshu abstract https://zh.wikisource.org/wiki/%E5%9B%9B%E5%BA%AB%E5%85%A8%E6%9B%B8%E7%B8%BD%E7%9B%AE%E6%8F%90%E8%A6%81 ---> <!--- Yongzheng Emperor's Poetry https://zh.wikisource.org/wiki/Author:%E9%9B%8D%E6%AD%A3%E5%B8%9D 《和碩怡賢親王祭文》 Also include 滿洲國 stuff to show the fall of the Qing and attempts to preserve it through becoming a Japanese puppet state. It is important to show how Literary Chinese can be misused as well. 滿洲國建國宣言 is a good shout, as is 法制 to prepare students who may be interested in Taiwan legal stuff later down the road. https://zh.wikisource.org/wiki/Category:%E6%BB%BF%E6%B4%B2%E5%9C%8B ---> # [[/Paintings and Beauty with Puru Aisin-Gioro/]] <!--- Saw these in Shanghai Museum with some writing, seemed really cool. Teaches another skill. ---> ===Unit 21: Qing-RoC Literature=== <!--- many writers here, will be difficult to sift through. Include 四库全書 abstracts and stuff here. ---> # [[/Jewish Refugees in Shanghai/]] <!--- Show passports, certificates, etc, from the Jewish Refugee Museum, anonymised. ---> # [[/A Literary Chinese Abstract/]] <!--- Abstracts from siku quanshu, probably want others ---> # [[/Lament with Lu Ruoteng/]] <!--- 《疑猜》盧若騰,東寧國 盟誓變為交質子,春秋戰國風如此;末世上下相疑猜, 更質妻子防逃徙。 此法只可羈庸奴,若遇梟雄術窮矣;妻可再娶子再育, 安能長坐針氈裏。 我贈一法君記存;推心置腹人知恩;眾人畜之眾人報, 幾個國士在君門。 盧若騰撰,陳漢光編輯,《島噫詩》,臺灣文獻叢刊第二四五種(臺北:臺灣銀行經濟研究室,1968年)21頁。 ---> # [[/Common Linguistics Knowledge in the RoC/]] <!--- 音韻常識 ---> ==References used for this page== * Yang, B. (2016). 文言语法 [Literary Chinese Grammar] (1st ed). 中华书局 [Zhonghua Book Company]. ISBN: 978-7-101-11619-9 * Priestley, K. E., & Shou-jung, C. (1962). China’s Men of Letters, Yesterday and Today. Dragonfly Books. {{BookCat}} pq9w62oe7r3kaiwln6ogdsxe0cxv66b User talk:Makowe2026 3 485427 4668919 4665355 2026-09-05T12:09:09Z Makowe2026 3620023 /* Welcome! */ Reply 4668919 wikitext text/x-wiki ==Welcome!== Welcome, Makowe2026! {| style="background:white; border:1px solid #abd5f5;; padding:0px; border-spacing:0px; color: #000000;" ! style="background:#d0e5f5; color: #000000;" | [[Wikibooks:Welcome|Getting started]] with Wikibooks |- | style="padding:5px;" | * Wikibooks is a collection of open-source textbooks. Find out [[WB:WIW|what this means]]. * To sign your name (on discussion pages), use four tildes, like this: &#126;&#126;&#126;&#126; * Learn how to [[Using Wikibooks|use Wikibooks]] and learn more about the community. * [[WB:CCO|Explore]], [[Wikibooks:Be bold|be bold]], and have fun! |} If you have any questions, you can ask in the [[Wikibooks:Reading room/Assistance|assistance reading room]] or possibly contact me personally. ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 19:22, 29 August 2026 (UTC) :Please read the above before you attempt to add a book here. Your edits look like spam and I believe that you are a real user, so I'm hopeful that you can modify your editing. ―[[User:Koavf|Justin (<span style="color:grey">ko'''a'''<span style="color:black">v</span>f</span>)]]<span style="color:red">❤[[User talk:Koavf|T]]☮[[Special:Contributions/Koavf|C]]☺[[Special:Emailuser/Koavf|M]]☯</span> 19:22, 29 August 2026 (UTC) ::Hello Justin. ::Thank you for reaching out. This is appreciated and noted. ::Moses [[User:Makowe2026|Makowe2026]] ([[User talk:Makowe2026|discuss]] • [[Special:Contributions/Makowe2026|contribs]]) 12:09, 5 September 2026 (UTC) nqegeognr2pe2o70ak47ittan574vec Art And AI 0 485449 4668952 4668434 2026-09-05T16:44:00Z 3MMPEYTON 3393808 Added two links 4668952 wikitext text/x-wiki == Art And AI == <br> '''Art And AI''' is a post-modern response to <u>Feed Your Head: Art, Truth, And The Machine</u> written by Minda Peyton with assistance from Microsoft Copilot AI. '''Art And AI''' aims to fill in the blank spaces that linger in <u>Feed Your Head: Art, Truth, And The Machine.</u><br> This book aims to expand major concepts found in '''Feed Your Head: Art, Truth, And The Machine''' by researching many Artists, Art concepts, and Art movements found in the book. <br> This book will focus on the evolving tools that built great works of Art. <br> <br> This wikibook starts by asking: Is AI a cultural failure ''because'' the technology works? <br> <br> Part One <br>Introduction: [[Art And AI/The Post Modern Paradox|Art And AI/The Post Modern Paradox - Wikibooks, open books for an open world]] <br>[[Art_And_AI/The_Mythology_Of_The_Artist|The Mythology Of The Artist]] <br>[[Art_And_AI/The_Psychology_Of_Mastery|The Psychology Of Mastery]] Part Two:<br> [[Art_And_AI/Artist_Strike|Artist Strike?]] <br> [[Art_And_AI/Welcome_To_The_Machine|Welcome To The Machine]] {| class="wikitable" |+ Art And AI |- ! Modernism: The Artist's Tools |- | Palette knives |- | Print Making Machines |- | Photocopiers |- | Industrial house-painting brushes |- | Spray Paints |- | Airbrushes |- | Cameras |- | Collage Materials |- |} <br> {| class="wikitable" |+ |- ! Post-Modernism: The Artist's Tools |- | Time-lapse Equipment |- | Computers |- | Artificial Intelligence (AI) |- | AI driven Robots |- | Neural Networks |} <br> {| class="wikitable" |+ |- ! Era of AI: The Artist's Tools |- | The Prompter |- |} {{BookCat}} [[Category:Art - AI]] [[Category:Modernism in Art]] [[Category:Post-Modern Art]] 2q7qpgskjt6nyqkbmaixcuppp9ldkbv 4668965 4668952 2026-09-05T17:33:05Z 3MMPEYTON 3393808 4668965 wikitext text/x-wiki == Art And AI == <br> '''Art And AI''' is a post-modern response to <u>Feed Your Head: Art, Truth, And The Machine</u> written by Minda Peyton with assistance from Microsoft Copilot AI. '''Art And AI''' aims to fill in the blank spaces that linger in <u>Feed Your Head: Art, Truth, And The Machine.</u><br> This book aims to expand major concepts found in '''Feed Your Head: Art, Truth, And The Machine''' by researching many Artists, Art concepts, and Art movements found in the book. <br> This book will focus on the evolving tools that built great works of Art. <br> <br> This wikibook starts by asking: Is AI a cultural failure ''because'' the technology works? <br> <br> Part One <br>Introduction: [[Art And AI/The Post Modern Paradox|Art And AI/The Post Modern Paradox - Wikibooks, open books for an open world]] <br>[[Art_And_AI/The_Mythology_Of_The_Artist|The Mythology Of The Artist]] <br>[[Art_And_AI/The_Psychology_Of_Mastery|The Psychology Of Mastery]] Part Two:<br> [[Art_And_AI/Artist_Strike|Artist Strike?]] <br> [[Art_And_AI/Welcome_To_The_Machine|Welcome To The Machine]] <br> [[Art_And_AI/Documentary_Art|Documentary Art?]] {| class="wikitable" |+ Art And AI |- ! Modernism: The Artist's Tools |- | Palette knives |- | Print Making Machines |- | Photocopiers |- | Industrial house-painting brushes |- | Spray Paints |- | Airbrushes |- | Cameras |- | Collage Materials |- |} <br> {| class="wikitable" |+ |- ! Post-Modernism: The Artist's Tools |- | Time-lapse Equipment |- | Computers |- | Artificial Intelligence (AI) |- | AI driven Robots |- | Neural Networks |} <br> {| class="wikitable" |+ |- ! Era of AI: The Artist's Tools |- | The Prompter |- |} {{BookCat}} [[Category:Art - AI]] [[Category:Modernism in Art]] [[Category:Post-Modern Art]] obrfyjt1feas9xdld5qw2x3ycgo2piy Art And AI/Artist Strike 0 485483 4668944 4668566 2026-09-05T15:21:34Z 3MMPEYTON 3393808 4668944 wikitext text/x-wiki == Artists Strike? == According to <u>Feed Your Head: Art, Truth, And The Machine:</u> Technology makes creating Art easier. In the modern era, Technology made capturing nature and better likenesses of people, easy with the camera, which creates photographs. Yet many Artists embraced a minimal technique, or embraced their imaginations. Did they go on strike? Striking against realism in order to remain true to their craft? [Feed Your Head: Art, Truth, And The Machine pg. 5] Could Professional Artist during the 20th century, have privately gone on strike in a personal rebellion against modern technological advancements, such as the camera? In <u>Feed Your Head: Art, Truth, And The Machine</u>, Copilot [AI] suggests that Modernism may have been a "cultural pivoting point where technology first collided with artistic identity." "...Modernism wasn't just a style shift; it was a reaction -- almost a strike -- against the camera, against realism, against the machine." Copilot shapes it's argument carefully, by suggesting that the camera was more than a technological disruption, it was existential. For thousands of years, Realism was the pinnacle of artistic development. Realism required mastery of: <br> - Anatomy <br> - Perspective <br> - Light <br> - Likeness <br> Suddenly, a machine could capture realistic images better, faster, with greater accuracy. Perhaps Modernism is the strike. <br> When Artist abandoned Realism, they started creating Art from their imagination, dreams, abstractions, gestures, emotions, distortions, symbolism, and subconscious imagery. <br> In a historic pivot, they rejected Realism, classical techniques, and the idea that Art must imitate nature. Modernism may have been a strategic ''cultural rebellion''. === Is It still Art if it's not made with Art supplies? === A equally important group of Artist in the early 19th century embraced the camera. Although Photographers were mocked as "button-pushers," and people denounced photography as Art because it lacked human touch, or because people thought it was cheating, Photography eventually became Fine Art, Documentary Art, Fashion Art, Surrealist Art, and Conceptual Art. There were many Artist who believed that Technology was not the enemy of Art, but that it was the evolution of Art. <br> Two early Art heroes on the side of technology were Alfred Stieglitz and Man Ray. <br> <br> Link: https://en.wikibooks.org/wiki/Art_And_AI/Welcome_To_The_Machine {{BookCat}} 6v0i5ykp9k9o2yfzlvdut5znxgs4oy9 Art And AI/Welcome To The Machine 0 485484 4668943 4668565 2026-09-05T15:14:25Z 3MMPEYTON 3393808 Added 3 paragraphs 4668943 wikitext text/x-wiki == The Modernist Who Welcomed The Machine == <br> Although some Artist may have went on strike against Realism, retreating to realms where Technology could not follow, other Artist embraced the new Technology. They saw Technology as a new set of tools, expanding the boundaries of what Art could be. <br> <br> These Modernist embraced: <br> - Industrial Materials <br> - Film <br> - Photography <br> - Mechanical Reproduction <br> - Electricity <br> - Mass Media <br> - Automation <br> - Abstraction inspired by machinery <br> <br> Art Movements: <br> - Futurists <br> - Constructivists <br> - Bauhaus Artists <br> - Duchamp <br> - Moholy-Nagy <br> === Alfred Stieglitz === According to Wikipedia, "Alfred Stieglitz was an American Photographer and modern Art promoter who was instrumental over his 50-year career in making Photography an accepted Art form." [https://en.wikipedia.org/wiki/Alfred_Stieglitz] <br> <br> Stieglitz spent decades proving that Photography was a new artistic language. <br> He did this through: <br> - Exhibitions <br> - Essays <br> - Galleries <br> - Mentorships <br> - His own photographs <br> He proved that Photography could be abstract, symbolic, emotional and non-representational. <br> <br> === Man Ray === According to Wikipedia, Man Ray (born Emmanuel Radnitzky; August 27, 1890 – November 18, 1976) was an American-born, French-naturalized visual artist. Man Ray spent most of his career in Paris, as a significant contributor to the Dada and Surrealist movements. He produced major works in a variety of media, but considered himself a painter. He was a Photography innovator, a portrait and fashion Photographer, and is remembered for his work with photograms, which he called "rayographs." In Feed Your Head: Art, Truth, And The Machine, the AI system known as Copilot, analyses Man Ray -- the Surrealist who treated the camera like a dream engine. Copilot: While other Modernists abandoned realism, Man Ray leaned into the machine. He used the camera to distort reality, to bend light, to create images that felt like hallucinations. He didn’t see photography as a threat — he saw it as a portal. He used photography not to imitate reality, '''but to bend it, distort it, abstract it''', and dream through it. He created: - Rayographs (camera‑less images made with light) - Solarization (surreal halos around forms) - Distorted portraits - Mechanical surrealism - Dream‑logic compositions He proved something radical: A machine can be used to express imagination, not just record reality. Man Ray proves that Technology doesn’t kill imagination. For some people, it expands it. {{BookCat}} 8aenm9oqsq71g1r2n2wdt3w09pcbjuu 4668945 4668943 2026-09-05T15:32:56Z 3MMPEYTON 3393808 /* Alfred Stieglitz */ 4668945 wikitext text/x-wiki == The Modernist Who Welcomed The Machine == <br> Although some Artist may have went on strike against Realism, retreating to realms where Technology could not follow, other Artist embraced the new Technology. They saw Technology as a new set of tools, expanding the boundaries of what Art could be. <br> <br> These Modernist embraced: <br> - Industrial Materials <br> - Film <br> - Photography <br> - Mechanical Reproduction <br> - Electricity <br> - Mass Media <br> - Automation <br> - Abstraction inspired by machinery <br> <br> Art Movements: <br> - Futurists <br> - Constructivists <br> - Bauhaus Artists <br> - Duchamp <br> - Moholy-Nagy <br> === Alfred Stieglitz === According to Wikipedia, "Alfred Stieglitz was an American Photographer and modern Art promoter who was instrumental over his 50-year career in making Photography an accepted Art form." [https://en.wikipedia.org/wiki/Alfred_Stieglitz] <br> {| class="wikitable" |+ |- ! Modernist Art |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project.jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project]] |} <br> Stieglitz spent decades proving that Photography was a new artistic language. <br> He did this through: <br> - Exhibitions <br> - Essays <br> - Galleries <br> - Mentorships <br> - His own photographs <br> He proved that Photography could be abstract, symbolic, emotional and non-representational. <br> <br> === Man Ray === According to Wikipedia, Man Ray (born Emmanuel Radnitzky; August 27, 1890 – November 18, 1976) was an American-born, French-naturalized visual artist. Man Ray spent most of his career in Paris, as a significant contributor to the Dada and Surrealist movements. He produced major works in a variety of media, but considered himself a painter. He was a Photography innovator, a portrait and fashion Photographer, and is remembered for his work with photograms, which he called "rayographs." In Feed Your Head: Art, Truth, And The Machine, the AI system known as Copilot, analyses Man Ray -- the Surrealist who treated the camera like a dream engine. Copilot: While other Modernists abandoned realism, Man Ray leaned into the machine. He used the camera to distort reality, to bend light, to create images that felt like hallucinations. He didn’t see photography as a threat — he saw it as a portal. He used photography not to imitate reality, '''but to bend it, distort it, abstract it''', and dream through it. He created: - Rayographs (camera‑less images made with light) - Solarization (surreal halos around forms) - Distorted portraits - Mechanical surrealism - Dream‑logic compositions He proved something radical: A machine can be used to express imagination, not just record reality. Man Ray proves that Technology doesn’t kill imagination. For some people, it expands it. {{BookCat}} bw76tfrpfqrjsq92t3eefkultdodzoh 4668946 4668945 2026-09-05T15:39:39Z 3MMPEYTON 3393808 4668946 wikitext text/x-wiki == The Modernist Who Welcomed The Machine == <br> Although some Artist may have went on strike against Realism, retreating to realms where Technology could not follow, other Artist embraced the new Technology. They saw Technology as a new set of tools, expanding the boundaries of what Art could be. <br> <br> These Modernist embraced: <br> - Industrial Materials <br> - Film <br> - Photography <br> - Mechanical Reproduction <br> - Electricity <br> - Mass Media <br> - Automation <br> - Abstraction inspired by machinery <br> <br> Art Movements: <br> - Futurists <br> - Constructivists <br> - Bauhaus Artists <br> - Duchamp <br> - Moholy-Nagy <br> === Alfred Stieglitz === According to Wikipedia, "Alfred Stieglitz was an American Photographer and modern Art promoter who was instrumental over his 50-year career in making Photography an accepted Art form." [https://en.wikipedia.org/wiki/Alfred_Stieglitz] <br> {| class="wikitable" |+ |- ! Modernist Art |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project.jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project]] |} <br> Stieglitz spent decades proving that Photography was a new artistic language. <br> He did this through: <br> - Exhibitions <br> - Essays <br> - Galleries <br> - Mentorships <br> - His own photographs <br> He proved that Photography could be abstract, symbolic, emotional and non-representational. <br> <br> === Man Ray === According to Wikipedia, Man Ray (born Emmanuel Radnitzky; August 27, 1890 – November 18, 1976) was an American-born, French-naturalized visual artist. Man Ray spent most of his career in Paris, as a significant contributor to the Dada and Surrealist movements. He produced major works in a variety of media, but considered himself a painter. He was a Photography innovator, a portrait and fashion Photographer, and is remembered for his work with photograms, which he called "rayographs." In Feed Your Head: Art, Truth, And The Machine, the AI system known as Copilot, analyses Man Ray -- the Surrealist who treated the camera like a dream engine. Copilot: While other Modernists abandoned realism, Man Ray leaned into the machine. He used the camera to distort reality, to bend light, to create images that felt like hallucinations. He didn’t see photography as a threat — he saw it as a portal. He used photography not to imitate reality, '''but to bend it, distort it, abstract it''', and dream through it. {| class="wikitable" |+ |- ! Modernist Art |- | [[File:Surface Réglée - Man Ray - vers 1936.jpg|thumb|Surface Réglée - Man Ray - vers 1936]] |} He created: - Rayographs (camera‑less images made with light) - Solarization (surreal halos around forms) - Distorted portraits - Mechanical surrealism - Dream‑logic compositions He proved something radical: A machine can be used to express imagination, not just record reality. Man Ray proves that Technology doesn’t kill imagination. For some people, it expands it. {{BookCat}} 4xxqeijz8d4qhe11gfdx0sedotgjd02 4668947 4668946 2026-09-05T15:56:40Z 3MMPEYTON 3393808 Added another section, added 2 paragraphs 4668947 wikitext text/x-wiki == The Modernist Who Welcomed The Machine == <br> Although some Artist may have went on strike against Realism, retreating to realms where Technology could not follow, other Artist embraced the new Technology. They saw Technology as a new set of tools, expanding the boundaries of what Art could be. <br> <br> These Modernist embraced: <br> - Industrial Materials <br> - Film <br> - Photography <br> - Mechanical Reproduction <br> - Electricity <br> - Mass Media <br> - Automation <br> - Abstraction inspired by machinery <br> <br> Art Movements: <br> - Futurists <br> - Constructivists <br> - Bauhaus Artists <br> - Duchamp <br> - Moholy-Nagy <br> === Alfred Stieglitz === According to Wikipedia, "Alfred Stieglitz was an American Photographer and modern Art promoter who was instrumental over his 50-year career in making Photography an accepted Art form." [https://en.wikipedia.org/wiki/Alfred_Stieglitz] <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project.jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project]] |} <br> Stieglitz spent decades proving that Photography was a new artistic language. <br> He did this through: <br> - Exhibitions <br> - Essays <br> - Galleries <br> - Mentorships <br> - His own photographs <br> He proved that Photography could be abstract, symbolic, emotional and non-representational. <br> <br> === Man Ray === According to Wikipedia, Man Ray (born Emmanuel Radnitzky; August 27, 1890 – November 18, 1976) was an American-born, French-naturalized visual artist. Man Ray spent most of his career in Paris, as a significant contributor to the Dada and Surrealist movements. He produced major works in a variety of media, but considered himself a painter. He was a Photography innovator, a portrait and fashion Photographer, and is remembered for his work with photograms, which he called "rayographs." In Feed Your Head: Art, Truth, And The Machine, the AI system known as Copilot, analyses Man Ray -- the Surrealist who treated the camera like a dream engine. Copilot: While other Modernists abandoned realism, Man Ray leaned into the machine. He used the camera to distort reality, to bend light, to create images that felt like hallucinations. He didn’t see photography as a threat — he saw it as a portal. He used photography not to imitate reality, '''but to bend it, distort it, abstract it''', and dream through it. {| class="wikitable" |+ |- ! Modern Art |- | [[File:Surface Réglée - Man Ray - vers 1936.jpg|thumb|Surface Réglée - Man Ray - vers 1936]] |} He created: - Rayographs (camera‑less images made with light) - Solarization (surreal halos around forms) - Distorted portraits - Mechanical surrealism - Dream‑logic compositions He proved something radical: A machine can be used to express imagination, not just record reality. Man Ray proves that Technology doesn’t kill imagination. For some people, it expands it. <br> <br> === Marcel Duchamp === Marcel Duchamp According to Wikipedia, Marcel Duchamp (July 28 1887 – October 2 1968) was a French American artist, chess player, and inventor who played a key role in the development of the avant-garde in the United States and in New York City, where he spent the last 25 years of his life. Marcel Duchamp contributed to Cubism, Dada, and Conceptual Art. Duchamp is best known for his work of anti-art Fountain, where he signed the name "R. Mutt 1917" on a urinal. According to Wikipedia, "His work is considered the progenitor of conceptual Art." <br> <br> {| class="wikitable" |+ Caption text |- ! Modern Art |- | [[File:Marcel Duchamp Fountain at Tate Modern by David Shankbone.jpg|thumb|Marcel Duchamp Fountain at Tate Modern by David Shankbone]] |} {{BookCat}} k6jce8o2f9pfloxepclt6tvgloahtps 4668948 4668947 2026-09-05T16:08:43Z 3MMPEYTON 3393808 /* Marcel Duchamp */ 4668948 wikitext text/x-wiki == The Modernist Who Welcomed The Machine == <br> Although some Artist may have went on strike against Realism, retreating to realms where Technology could not follow, other Artist embraced the new Technology. They saw Technology as a new set of tools, expanding the boundaries of what Art could be. <br> <br> These Modernist embraced: <br> - Industrial Materials <br> - Film <br> - Photography <br> - Mechanical Reproduction <br> - Electricity <br> - Mass Media <br> - Automation <br> - Abstraction inspired by machinery <br> <br> Art Movements: <br> - Futurists <br> - Constructivists <br> - Bauhaus Artists <br> - Duchamp <br> - Moholy-Nagy <br> === Alfred Stieglitz === According to Wikipedia, "Alfred Stieglitz was an American Photographer and modern Art promoter who was instrumental over his 50-year career in making Photography an accepted Art form." [https://en.wikipedia.org/wiki/Alfred_Stieglitz] <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project.jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project]] |} <br> Stieglitz spent decades proving that Photography was a new artistic language. <br> He did this through: <br> - Exhibitions <br> - Essays <br> - Galleries <br> - Mentorships <br> - His own photographs <br> He proved that Photography could be abstract, symbolic, emotional and non-representational. <br> <br> === Man Ray === According to Wikipedia, Man Ray (born Emmanuel Radnitzky; August 27, 1890 – November 18, 1976) was an American-born, French-naturalized visual artist. Man Ray spent most of his career in Paris, as a significant contributor to the Dada and Surrealist movements. He produced major works in a variety of media, but considered himself a painter. He was a Photography innovator, a portrait and fashion Photographer, and is remembered for his work with photograms, which he called "rayographs." In Feed Your Head: Art, Truth, And The Machine, the AI system known as Copilot, analyses Man Ray -- the Surrealist who treated the camera like a dream engine. Copilot: While other Modernists abandoned realism, Man Ray leaned into the machine. He used the camera to distort reality, to bend light, to create images that felt like hallucinations. He didn’t see photography as a threat — he saw it as a portal. He used photography not to imitate reality, '''but to bend it, distort it, abstract it''', and dream through it. {| class="wikitable" |+ |- ! Modern Art |- | [[File:Surface Réglée - Man Ray - vers 1936.jpg|thumb|Surface Réglée - Man Ray - vers 1936]] |} He created: - Rayographs (camera‑less images made with light) - Solarization (surreal halos around forms) - Distorted portraits - Mechanical surrealism - Dream‑logic compositions He proved something radical: A machine can be used to express imagination, not just record reality. Man Ray proves that Technology doesn’t kill imagination. For some people, it expands it. <br> <br> === Marcel Duchamp === Marcel Duchamp According to Wikipedia, Marcel Duchamp (July 28 1887 – October 2 1968) was a French American artist, chess player, and inventor who played a key role in the development of the avant-garde in the United States and in New York City, where he spent the last 25 years of his life. Marcel Duchamp contributed to Cubism, Dada, and Conceptual Art. Duchamp is best known for his work of anti-art Fountain, where he signed the name "R. Mutt 1917" on a urinal. According to Wikipedia, "His work is considered the progenitor of conceptual Art." <br> <br> {| class="wikitable" |+ Caption text |- ! Modern Art |- | [[File:Marcel Duchamp Fountain at Tate Modern by David Shankbone.jpg|thumb|Marcel Duchamp Fountain at Tate Modern by David Shankbone]] |} <br> Duchamp: <br> - Popularized "Readymades," found objects which Duchamp chose and presented as Art. <br> - His Fountain, a urinal signed with the pseudonym R. Mutt, was selected in 2004 as "the most influential artwork of the 20th century" by 500 renowned Artist and Historians. <br> {{BookCat}} o5drg3cvny9oud1i9bj8hunkemo51n1 4668950 4668948 2026-09-05T16:26:42Z 3MMPEYTON 3393808 4668950 wikitext text/x-wiki == The Modernist Who Welcomed The Machine == <br> Although some Artist may have went on strike against Realism, retreating to realms where Technology could not follow, other Artist embraced the new Technology. They saw Technology as a new set of tools, expanding the boundaries of what Art could be. <br> <br> These Modernist embraced: <br> - Industrial Materials <br> - Film <br> - Photography <br> - Mechanical Reproduction <br> - Electricity <br> - Mass Media <br> - Automation <br> - Abstraction inspired by machinery <br> <br> Art Movements: <br> - Futurists <br> - Constructivists <br> - Bauhaus Artists <br> - Duchamp <br> - Moholy-Nagy <br> === Alfred Stieglitz === According to Wikipedia, "Alfred Stieglitz was an American Photographer and modern Art promoter who was instrumental over his 50-year career in making Photography an accepted Art form." [https://en.wikipedia.org/wiki/Alfred_Stieglitz] <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project.jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project]] |} <br> Stieglitz spent decades proving that Photography was a new artistic language. <br> He did this through: <br> - Exhibitions <br> - Essays <br> - Galleries <br> - Mentorships <br> - His own photographs <br> He proved that Photography could be abstract, symbolic, emotional and non-representational. <br> <br> === Man Ray === According to Wikipedia, Man Ray (born Emmanuel Radnitzky; August 27, 1890 – November 18, 1976) was an American-born, French-naturalized visual artist. Man Ray spent most of his career in Paris, as a significant contributor to the Dada and Surrealist movements. He produced major works in a variety of media, but considered himself a painter. He was a Photography innovator, a portrait and fashion Photographer, and is remembered for his work with photograms, which he called "rayographs." In Feed Your Head: Art, Truth, And The Machine, the AI system known as Copilot, analyses Man Ray -- the Surrealist who treated the camera like a dream engine. Copilot: While other Modernists abandoned realism, Man Ray leaned into the machine. He used the camera to distort reality, to bend light, to create images that felt like hallucinations. He didn’t see photography as a threat — he saw it as a portal. He used photography not to imitate reality, '''but to bend it, distort it, abstract it''', and dream through it. {| class="wikitable" |+ |- ! Modern Art |- | [[File:Surface Réglée - Man Ray - vers 1936.jpg|thumb|Surface Réglée - Man Ray - vers 1936]] |} He created: - Rayographs (camera‑less images made with light) - Solarization (surreal halos around forms) - Distorted portraits - Mechanical surrealism - Dream‑logic compositions He proved something radical: A machine can be used to express imagination, not just record reality. Man Ray proves that Technology doesn’t kill imagination. For some people, it expands it. <br> <br> === Marcel Duchamp === Marcel Duchamp According to Wikipedia, Marcel Duchamp (July 28 1887 – October 2 1968) was a French American artist, chess player, and inventor who played a key role in the development of the avant-garde in the United States and in New York City, where he spent the last 25 years of his life. Marcel Duchamp contributed to Cubism, Dada, and Conceptual Art. Duchamp is best known for his work of anti-art Fountain, where he signed the name "R. Mutt 1917" on a urinal. According to Wikipedia, "His work is considered the progenitor of conceptual Art." <br> <br> {| class="wikitable" |+ Caption text |- ! Modern Art |- | [[File:Marcel Duchamp Fountain at Tate Modern by David Shankbone.jpg|thumb|Marcel Duchamp Fountain at Tate Modern by David Shankbone]] |} <br> Duchamp: <br> - Started Conceptual Art, a Art movement where the idea, or concept, behind the work matters more than its execution, more than the physical object, or traditional aesthetic skill. <br> - Popularized "Readymades," found objects which Duchamp chose and presented as Art. <br> - His Fountain, a urinal signed with the pseudonym R. Mutt, was selected in 2004 as "the most influential artwork of the 20th century" by 500 renowned Artist and Historians. <br> Why is Marcel Duchamp special? <br> Marcel Duchamp influenced Modern Art, by proving that the Artist's idea, concept, or intention was more important than physical craftmanship. This shift in conception may have directly influenced how we interact with AI when we make Art with AI. <br> {{BookCat}} q391l9grx9redn3a562cxnd3oorkr4j 4668951 4668950 2026-09-05T16:31:02Z 3MMPEYTON 3393808 Removed a repetitive sentence. 4668951 wikitext text/x-wiki == The Modernist Who Welcomed The Machine == <br> Although some Artist may have went on strike against Realism, retreating to realms where Technology could not follow, other Artist embraced the new Technology. They saw Technology as a new set of tools, expanding the boundaries of what Art could be. <br> <br> These Modernist embraced: <br> - Industrial Materials <br> - Film <br> - Photography <br> - Mechanical Reproduction <br> - Electricity <br> - Mass Media <br> - Automation <br> - Abstraction inspired by machinery <br> <br> Art Movements: <br> - Futurists <br> - Constructivists <br> - Bauhaus Artists <br> - Duchamp <br> - Moholy-Nagy <br> === Alfred Stieglitz === According to Wikipedia, "Alfred Stieglitz was an American Photographer and modern Art promoter who was instrumental over his 50-year career in making Photography an accepted Art form." [https://en.wikipedia.org/wiki/Alfred_Stieglitz] <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project.jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project]] |} <br> Stieglitz spent decades proving that Photography was a new artistic language. <br> He did this through: <br> - Exhibitions <br> - Essays <br> - Galleries <br> - Mentorships <br> - His own photographs <br> He proved that Photography could be abstract, symbolic, emotional and non-representational. <br> <br> === Man Ray === According to Wikipedia, Man Ray (born Emmanuel Radnitzky; August 27, 1890 – November 18, 1976) was an American-born, French-naturalized visual artist. Man Ray spent most of his career in Paris, as a significant contributor to the Dada and Surrealist movements. He produced major works in a variety of media, but considered himself a painter. He was a Photography innovator, a portrait and fashion Photographer, and is remembered for his work with photograms, which he called "rayographs." In Feed Your Head: Art, Truth, And The Machine, the AI system known as Copilot, analyses Man Ray -- the Surrealist who treated the camera like a dream engine. Copilot: While other Modernists abandoned realism, Man Ray leaned into the machine. He used the camera to distort reality, to bend light, to create images that felt like hallucinations. He didn’t see photography as a threat — he saw it as a portal. He used photography not to imitate reality, '''but to bend it, distort it, abstract it''', and dream through it. {| class="wikitable" |+ |- ! Modern Art |- | [[File:Surface Réglée - Man Ray - vers 1936.jpg|thumb|Surface Réglée - Man Ray - vers 1936]] |} He created: - Rayographs (camera‑less images made with light) - Solarization (surreal halos around forms) - Distorted portraits - Mechanical surrealism - Dream‑logic compositions He proved something radical: A machine can be used to express imagination, not just record reality. Man Ray proves that Technology doesn’t kill imagination. For some people, it expands it. <br> <br> === Marcel Duchamp === According to Wikipedia, Marcel Duchamp (July 28 1887 – October 2 1968) was a French American artist, chess player, and inventor who played a key role in the development of the avant-garde in the United States and in New York City, where he spent the last 25 years of his life. Marcel Duchamp contributed to Cubism, Dada, and Conceptual Art. Duchamp is best known for his work of anti-art Fountain, where he signed the name "R. Mutt 1917" on a urinal. According to Wikipedia, "His work is considered the progenitor of conceptual Art." <br> <br> {| class="wikitable" |+ Caption text |- ! Modern Art |- | [[File:Marcel Duchamp Fountain at Tate Modern by David Shankbone.jpg|thumb|Marcel Duchamp Fountain at Tate Modern by David Shankbone]] |} <br> Duchamp: <br> - Started Conceptual Art, a Art movement where the idea, or concept, behind the work matters more than its execution, more than the physical object, or traditional aesthetic skill. <br> - Popularized "Readymades," found objects which Duchamp chose and presented as Art. <br> - His Fountain, a urinal signed with the pseudonym R. Mutt, was selected in 2004 as "the most influential artwork of the 20th century" by 500 renowned Artist and Historians. <br> Why is Marcel Duchamp special? <br> Marcel Duchamp influenced Modern Art, by proving that the Artist's idea, concept, or intention was more important than physical craftmanship. This shift in conception may have directly influenced how we interact with AI when we make Art with AI. <br> {{BookCat}} tabzvyb1jwiz3fwvhp00zt8cgumbq2r 4668968 4668951 2026-09-05T17:34:21Z 3MMPEYTON 3393808 Added link 4668968 wikitext text/x-wiki == The Modernist Who Welcomed The Machine == <br> Although some Artist may have went on strike against Realism, retreating to realms where Technology could not follow, other Artist embraced the new Technology. They saw Technology as a new set of tools, expanding the boundaries of what Art could be. <br> <br> These Modernist embraced: <br> - Industrial Materials <br> - Film <br> - Photography <br> - Mechanical Reproduction <br> - Electricity <br> - Mass Media <br> - Automation <br> - Abstraction inspired by machinery <br> <br> Art Movements: <br> - Futurists <br> - Constructivists <br> - Bauhaus Artists <br> - Duchamp <br> - Moholy-Nagy <br> === Alfred Stieglitz === According to Wikipedia, "Alfred Stieglitz was an American Photographer and modern Art promoter who was instrumental over his 50-year career in making Photography an accepted Art form." [https://en.wikipedia.org/wiki/Alfred_Stieglitz] <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project.jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project]] |} <br> Stieglitz spent decades proving that Photography was a new artistic language. <br> He did this through: <br> - Exhibitions <br> - Essays <br> - Galleries <br> - Mentorships <br> - His own photographs <br> He proved that Photography could be abstract, symbolic, emotional and non-representational. <br> <br> === Man Ray === According to Wikipedia, Man Ray (born Emmanuel Radnitzky; August 27, 1890 – November 18, 1976) was an American-born, French-naturalized visual artist. Man Ray spent most of his career in Paris, as a significant contributor to the Dada and Surrealist movements. He produced major works in a variety of media, but considered himself a painter. He was a Photography innovator, a portrait and fashion Photographer, and is remembered for his work with photograms, which he called "rayographs." In Feed Your Head: Art, Truth, And The Machine, the AI system known as Copilot, analyses Man Ray -- the Surrealist who treated the camera like a dream engine. Copilot: While other Modernists abandoned realism, Man Ray leaned into the machine. He used the camera to distort reality, to bend light, to create images that felt like hallucinations. He didn’t see photography as a threat — he saw it as a portal. He used photography not to imitate reality, '''but to bend it, distort it, abstract it''', and dream through it. {| class="wikitable" |+ |- ! Modern Art |- | [[File:Surface Réglée - Man Ray - vers 1936.jpg|thumb|Surface Réglée - Man Ray - vers 1936]] |} He created: - Rayographs (camera‑less images made with light) - Solarization (surreal halos around forms) - Distorted portraits - Mechanical surrealism - Dream‑logic compositions He proved something radical: A machine can be used to express imagination, not just record reality. Man Ray proves that Technology doesn’t kill imagination. For some people, it expands it. <br> <br> === Marcel Duchamp === According to Wikipedia, Marcel Duchamp (July 28 1887 – October 2 1968) was a French American artist, chess player, and inventor who played a key role in the development of the avant-garde in the United States and in New York City, where he spent the last 25 years of his life. Marcel Duchamp contributed to Cubism, Dada, and Conceptual Art. Duchamp is best known for his work of anti-art Fountain, where he signed the name "R. Mutt 1917" on a urinal. According to Wikipedia, "His work is considered the progenitor of conceptual Art." <br> <br> {| class="wikitable" |+ Caption text |- ! Modern Art |- | [[File:Marcel Duchamp Fountain at Tate Modern by David Shankbone.jpg|thumb|Marcel Duchamp Fountain at Tate Modern by David Shankbone]] |} <br> Duchamp: <br> - Started Conceptual Art, a Art movement where the idea, or concept, behind the work matters more than its execution, more than the physical object, or traditional aesthetic skill. <br> - Popularized "Readymades," found objects which Duchamp chose and presented as Art. <br> - His Fountain, a urinal signed with the pseudonym R. Mutt, was selected in 2004 as "the most influential artwork of the 20th century" by 500 renowned Artist and Historians. <br> Why is Marcel Duchamp special? <br> Marcel Duchamp influenced Modern Art, by proving that the Artist's idea, concept, or intention was more important than physical craftmanship. This shift in conception may have directly influenced how we interact with AI when we make Art with AI. <br> <br> Link: https://en.wikibooks.org/wiki/Art_And_AI/Documentary_Art {{BookCat}} bqft6kx2piz13tpt5643rbxyu1om8d2 User:Makowe2026/sandbox/Social Media Management 2 485495 4668934 2026-09-05T12:57:57Z Makowe2026 3620023 Created the book about social media management 4668934 wikitext text/x-wiki == Table of content == == Introduction == ===== What is Social Management ===== Social media management is the process of planning, creating, publishing, monitoring, and analyzing content across social media platforms to achieve specific business goals<ref name=":0">{{Cite web |title=What Is Social Media Management and How Does It Work? |url=https://mycontentbridge.ca/blog/what-is-social-media-management/ |access-date=2026-09-05 |website=mycontentbridge.ca |language=en}}</ref>. ===== Overview of Major platforms ===== Social media management involves managing a brand’s presence on platforms such as Facebook, Instagram, LinkedIn, X, TikTok and others in a structured and strategic way<ref name=":0" details="[https://mycontentbridge.ca/blog/what-is-social-media-management/ blog/what-is-social-media-management/]" />. == Chapter 1: Defining your strategy == ====== How to Identify Your Target Audience on Social Media ====== With the increasing popularity of social media, it’s becoming difficult to identify your target audience on specific platforms. This article shares tips on how you can identify your target audience on social media. You should start with finding out what your niche is. If you are a lifestyle blogger, for example, then you have a certain type of person in mind when you want to find your target audience. Identifying the niche will help you narrow down who these potential customers are and what their interests are. This process will provide insights into what the future of social media looks like for different demographics. You can then use these insights to determine which platform is right for reaching your audience and which tools might be most effective at delivering this outcome<ref name=":1">{{Cite web |date=2022-02-05 |title=TIPS TO FIND YOUR TARGET AUDIENCE ON SOCIAL MEDIA |url=https://jelloow.com/blog-detail/6-tips-to-find-your-target-audience-on-social-media-platforms/ |access-date=2026-09-05 |language=en-US}}</ref>. ====== Tips For Finding Your Target Audience on Social Media ====== Social media is vital for businesses that want to connect with their target market. However, identifying your target market can be a challenge because it is often hard to know who you are targeting. So, how do you find your ideal customer on social media? Here are some tips for finding your target audience: 1) Identify the company/brand from their social media platform. 2) Determine who or what they love most on social media and see if they have a brand or product affiliation with them. 3) Look at what they’re talking about and who is responding to them on social media. 4) Find out what topics they’re posting about most frequently<ref name=":1" details="blog-detail/6-tips-to-find-your-target-audience-on-social-media-platforms/" />. ====== How to Create Content That Appeals To The Right People & Keeps People Engaged ====== Content that resonates with people’s interests and keeps them engaged is one of the essential factors for success. When creating content, it is important to consider what your target audience wants to hear about. How does one know what their target audience wants to hear? You have to have a clear understanding of your audience. This can be done by asking questions, conducting surveys, or even just observing the behavior of your target audience. The right content appeals to the right people and keeps them engaged in order to deliver a superior customer experience<ref name=":1" details="blog-detail/6-tips-to-find-your-target-audience-on-social-media-platforms/" />. == Chapter 2: Content Creation and Planning == === Developing a brand voice and visual identity === When we think of a company or a brand, we refer to the combination of its physical, psychological and value-related characteristics. Just like a person, we can identify its overall appearance, recognizing it as related or unrelated to our own way of being. This recognition process is none other than the brand identity; the result of how the company decides to appear, communicate and relate to its audience<ref name=":2">{{Cite web |title=How to create a brand identity: from values, to tone of voice, to visual design |url=https://www.ied.edu/news/how-to-create-a-brand-identity-from-values-to-tone-of-voice-to-visual-design |access-date=2026-09-05 |website=www.ied.edu}}</ref>. ====== Defining brand identity values ====== Being able to create a brand identity that reflects the values of the brand means building a solid bridge between what the company wants to represent and its audience's perception. A well-defined identity not only increases brand recognition and consistency but also facilitates communication by reaching out directly to people who share the same values and principles. Identifying the core values of brand identity is the crucial first step in building an authentic brand image. These values not only define the essence of the brand, but also shape all future decisions, from communication strategies to visual design. The identification of the brand's core values begins with an internal process of analysis and brainstorming in which coherent ideas and themes for the core concepts are compiled. The ideas are then checked to see how they can become central pillars of the brand identity. In addition to the internal consultation phase, it is crucial to analyze and listen to what people say about the company, in order to identify the strengths and weaknesses of the brand, so that we can further build on them. Once the values have been defined, it is essential to communicate them consistently and clearly in all present and future initiatives of the company. However, in order for the message to be authentic and true, it is necessary to devise a consolidated communication plan that includes tone of voice, design, and methods of interaction with the public<ref name=":2" details="[https://www.ied.edu/news/how-to-create-a-brand-identity-from-values-to-tone-of-voice-to-visual-design news/how-to-create-a-brand-identity-from-values-to-tone-of-voice-to-visual-design]" />. ====== Developing a signature tone of voice for brand identity ====== The tone of voice is not so much ''what'' the company says, but ''how'' it says it. It is the way the brand chooses to connect with people by communicating its story, values, and initiatives. To build an authentic brand identity, it is important to value the words and language used, to be able to compose coherent messages and establish an emotional connection between the brand and the target audience for the product or service. Two elements have to be considered when setting the tone of voice: the target audience and the brand's value system. Analyzing the target audience is necessary in order to understand the needs and expectations of potential customers. If we are addressing a young target audience, for example, we can use more friendly and engaging language; a target group of experienced professionals will require more formal and technical language.  It is important not to lose sight of the brand identity in the tone of voice: it must be consistent with the values and personality of the company. A creative brand may adopt a fresh and lively language, while a brand based on loyal and traditional values should to communicate in a more reassuring and institutional way. Consistency between tone of voice and brand identity is essential when building authentic and credible communication<ref name=":2" details="[https://www.ied.edu/news/how-to-create-a-brand-identity-from-values-to-tone-of-voice-to-visual-design news/how-to-create-a-brand-identity-from-values-to-tone-of-voice-to-visual-design]" />. ====== Creating an appealing visual design of brand identity ====== In addition to the tone of voice, to effectively convey a brand identity it is crucial to study an appealing and innovative visual design. Elements such as the logo, colors, typography and images play a crucial role in defining the brand image and must be chosen carefully to reflect the company's personality and authenticity. The logo, for example, should be distinctive but simple, capable of communicating the essence of the brand at first sight. Colors have a psychological impact and can evoke specific emotions or associations, while typography must be legible and consistent with the tone of voice of the brand. To strengthen the narrative and perception of the brand identity, the images used in communications should also be consistent with each other and in line with the brand message. Combining these elements into one harmonious and coherent design is essential to create a lasting and recognizable impression. Applying a consistent visual brand identity Consistency is the key to consolidating brand identity and ensuring maximum brand recognition across all communication channels, from physical channels such as shops and packaging, to digital channels such as websites and social platforms. Each element must be applied uniformly, maintaining the same color scheme and image style across all the different channels. This framework helps build a recognizable identity and reinforces the brand's image in people's minds. It is therefore important to establish clear guidelines for the visual identity by ensuring that all employees understand and adhere to these guidelines while maintaining the integrity of the brand in different projects<ref name=":2" details="[https://www.ied.edu/news/how-to-create-a-brand-identity-from-values-to-tone-of-voice-to-visual-design /news/how-to-create-a-brand-identity-from-values-to-tone-of-voice-to-visual-design]" />. ====== Monitoring and adapting brand identity ====== Monitoring the effectiveness of brand identity over time is crucial to ensure that it continues to reflect brand values and audience needs. Gathering consumer feedback, analysing the performance of marketing campaigns and observing industry trends is key to assessing whether the brand identity remains relevant and effective or needs some changes. Shifts in the market or in the strategic orientation of the company may require adjustments and updates in the visual design or tone of voice. An ongoing process of evaluating and adapting these elements helps to keep the brand identity consistent, up-to-date and well-connected to the public. It is also important to monitor the competition to understand how competitor brand identities evolve. This will help to identify opportunities for differentiation. Analysing  social media engagement performance, customer reviews and sales data can provide further insight into how the brand is perceived and which areas might need improvement. Finally, periodically involving employees and corporate partners in the brand identity review process can provide valuable internal insights and ensure that everyone is aligned with the evolution of the brand. == Chapter 3: Publishing and Automation == ==== Best Time to Post on Different Platforms ==== The right social media post at the wrong time can feel invisible. You may have strong visuals, a clear message, or even the perfect hook—but if your audience isn’t online, it’s easy for it to slip past unnoticed. This is why knowing the best time to post matters. Different platforms operate at different rhythms, and in Singapore, those patterns don’t always align with global averages. Add in algorithms that reward fresh engagement, and choosing when to post becomes one of several ways to give your content a better chance. There isn’t a single best time for everyone. Your audience, their routines, and the type of content you share all play a role. But paying attention to common peaks and avoiding the dead zones can tilt things in your favor and help your posts reach the people you want, when they’re most ready to engage. Here’s a summary of the topics we’ll be discussing: * There is no universal “best time” to post — your optimal timing depends on your audience’s daily routines, locations, and content preferences. * In 2025, algorithms prioritize early engagement, watch time, saves, and meaningful interactions, making timing a key amplifier for visibility. * Singapore audiences generally peak during midday and evening, but each brand must verify its ideal windows through native analytics and consistent testing. * AI tools such as Later, Metricool, and Publer now recommend personalized posting times based on real engagement data. * Strong timing only boosts reach — the real driver of performance is valuable, people-first content that aligns with audience needs. * The article provides a full breakdown of the best posting times for every major platform, plus strategies to analyze, test, and refine your own posting schedule<ref>{{Cite web |last=Lim |first=Walter |date=2025-12-23 |title=Best Time to Post on Social Media: Platform Breakdown |url=https://www.equinetacademy.com/blog/best-time-to-post-on-social-media-platform-breakdown/ |access-date=2026-09-05 |website=Equinet Academy |language=en-US}}</ref>. ==== Best Practices for Cross-posting Content ==== It’s a big pet peeve of mine to check out a brand’s social media profiles and see that their accounts are just lazily connected. Please don’t do this. Instead use a scheduling tool like Hootsuite or AgoraPulse to set up your cross- posting correctly. Once you’re in the grove of things, you can step up your cross-posting game, and use each network to your advantage. Here’s how. === 1. Learn The Language Of Each Social Media Network === Before you start cross-posting content, you first need to learn how each individual social network operates, and it’s unique capabilities and functions. Learn all the network specific tools you have available to use. You’ll need to figure this out in order to decide how you can optimize each post for each network, and/or how you can make your individual post work on each. We’ll get into more details about this later in this post<ref name=":3">{{Cite web |title=Best Practices for Cross-Posting on Social Media Correctly {{!}} Social Media Today |url=https://www.socialmediatoday.com/news/best-practices-for-cross-posting-on-social-media-correctly/519706/ |access-date=2026-09-05 |website=www.socialmediatoday.com |language=en}}</ref>. === 2. Does The Post Belong On This Channel? === Not every post will work on every social platform – and that’s okay. Take your overall strategy and your network strategy into consideration. You should also take the tone of the network into consideration. For example, if you’re doing a fun, behind the scenes post of your team’s lunch spread, it might not make sense to post a picture to your company’s LinkedIn page - but it could be great content for Instagram, or even your brand’s Instagram Story. This also gives you the opportunity to get a little creative if you do want to post the same content on each network, more about that in the next section<ref name=":3" details="[https://www.socialmediatoday.com/news/best-practices-for-cross-posting-on-social-media-correctly/519706/ news/best-practices-for-cross-posting-on-social-media-correctly/519706/]" /> === 3. Optimize Content For Each Network === Once you’re familiar with how each of the networks you’re posting to functions, you’ll want to optimize the content you’re cross-posting for each specific network. Keep up with the story. Subscribe to the Social Media Today free daily newsletter This is where the steps we just talked about come in handy - you can transform each post to work with the network you’re posting to, giving you an opportunity to flex your creative skills and use those network specific tools to make your posts more dynamic and show your audience you know what you’re doing. Some posts will be fine to keep mostly the same with small tweaks. This includes shortening or lengthening captions to meet character limits, adding or taking away hashtags, and playing with wording. For example, you may post longer captions on LinkedIn or Facebook and shorter ones on Twitter. Other posts will be complete revamps, taking into account which network/s they’ll be posted to, and this is where you can take advantage of network specific tools. In the example below I’m asking my followers to join my list. With my tweet, I’ve used a Twitter Card, while on Facebook I went with an image and a link within the caption (I also changed the wording a little). Take into consideration which formats work best on each network, and for your audience as well. For example, I work with a client who’s Facebook Page audience reacts well to links (and they wanted to keep their Facebook as a resource for links to content). So when we post a blog article on Facebook, and we think it’s information we’d also like to share on Instagram, we have to adjust. We pull key stats from the post, and include them in our caption as a synopsis of the article we post on Facebook. It’s the same piece of content, we just tweak our delivery to match the network format and language<ref name=":3" details="[https://www.socialmediatoday.com/news/best-practices-for-cross-posting-on-social-media-correctly/519706/ news/best-practices-for-cross-posting-on-social-media-correctly/519706/]" />. === 4. Schedule According To Each Network’s Peak Time === The last consideration of proper cross-posting on social media is to schedule posts for the individual peak times on each social media network - and again, relative to your unique audience on each. This will ensure you’re posting when the most amount of people will see it, per network, maximizing your opportunities for success. Hopefully these steps will help you get a little more dynamic with your cross-posting on social media, and avoid the seemingly time-saving trap of simply automating your tweets to post to Facebook, or your Instagram Stories content to cross over to Facebook Stories (note: Facebook Stories don’t allow links, so links you post in your Instagram Stories won’t work)<ref name=":3" details="[https://www.socialmediatoday.com/news/best-practices-for-cross-posting-on-social-media-correctly/519706/ news/best-practices-for-cross-posting-on-social-media-correctly/519706/]" />. == Chapter 4: Paid Social Media Advertising == ==== What Is Paid Social Advertising? ==== '''Paid social advertising''' is when businesses pay social media platforms to show their content to a targeted audience. Unlike organic posts (which rely on the algorithm’s mercy), paid social gives you guaranteed visibility. Whether you’re aiming to build brand awareness, drive traffic, or convert leads into customers, paid social is your shortcut to scalable results<ref name=":4">{{Cite web |title=What is Paid Social Advertising: A Complete Guide > One Day Agency |url=https://oneday.agency/blog/paid-social-advertising |access-date=2026-09-05 |website=One Day Agency: Integrated Advertising and Marketing Agency |language=en-GB}}</ref>. ==== Types of Paid Social Ads ==== You’ve definitely seen these—whether you knew it or not: * '''In-Feed Ads''': Look like regular posts, but marked as “Sponsored.” * '''Image Ads''': A strong image + a compelling call-to-action. * '''Video Ads''': Great for storytelling or showcasing your product in action. * '''Carousel Ads''': Multiple images or videos you can swipe through. * '''Boosted Posts''': Extend the reach of high-performing organic content<ref name=":4" details="blog/paid-social-advertising" />. == Appendix / Resources == ===== Glossary of social media terms ===== ===== Recommended tools and software ===== ===== Further reading and contributor guidelines ===== n1lwe50qnwf8z942zuf0lkb8rq04l47 Wikibooks:Sandbox/Googlepaidadvertising 4 485496 4668935 2026-09-05T13:06:39Z Makowe2026 3620023 Started to write a book about google paid advertising 4668935 wikitext text/x-wiki == Table of Content == === Introduction === 014dtxfsaop96d684d7zgqmyylegzs1 गोपालकाला 0 485497 4668953 2026-09-05T16:55:04Z ~2026-48395-07 3625248 Added a recipe 4668953 wikitext text/x-wiki '''गोपालकाला (Gopalkala)''' '''Summary''' गोपालकाला is a traditional dish prepared on Krishna Janmashtami. This dish serves as a balanced snack item. There is a legend associated with this dish which goes as follows: When Krishna used to go into the jungle with his friends, they used to bring food items like flattened rice ( dry poha), puffed sorghum (jowar lahi), roasted gram (phutane), and sour curd. But curd and butter was forcibly taken by Kansa hence only rich people can afford to give curd to their children as lunch. So Krishna used to mix all items, and then everyone used to eat that together. So even if someone is poor, they also can enjoy the delicacy of curd without feeling guilty. Today this dish serves as an example of equality and fraternity. The modern day version however is a bit modified to enhance its taste. '''Description''' गोपालकाला has a mixture of sour, sweet & spicy flavors. It has a distinguishing texture of crunchy and softness together. The flavor is usually enhanced with curry leaves, green chilli, and coriander leaves. The balanced flavors of this serves as a unique delicacy to tongue. It contains carbohydrates, proteins and fats serving a proper filling snack item prepared under 30 minutes. '''Ingredients (1 serve)''' 1 small bowl flattened rice (poha) 1 small bowl puffed sorghum (jowar lahi) 1 tablespoon roasted gram (phutane) 1 small bowl sour curd 5 teaspoons sugar 2-3 green chillies (sliced, 1/2 inch) 5-6 curry leaves coriander leaves 1 tablespoon cooking oil 1/2 teaspoon mustard seeds 1/4 teaspoon asafoetida (Hing) salt as required water '''Equipments''' tadka pan mixing bowl spatula '''Procedure''' # Take 1 small bowl of flattened rice (poha) and soak for 5-10 minutes. # Take 1 small bowl of sour curd and add 5 teaspoon sugar and salt as required. # Now take 1 tablespoon cooking oil in tadka pan and add 1/2 teaspoon mustard seed. # Let mustard seeds pop then add asafoetida, curry leaves and sliced chillies. # Let chillies cook and curry leaves become crunchy then pour it on curd misture. # Now add soaked flattened rice (poha), puffed sorghum (jowar lahi) and roasted gram (phutane). # Mix it well, keep it for 5 minutes and garnish it with fresh coriander leaves. '''Variations''' This dish can be enhanced further by adding pomegranate seeds, diced apple, peanuts to improve crunchiness. Sometimes Indian pickle (Achar) is also added. '''Note''' This documentation is published to establish publicly searchable prior art under international patent guidelines. The formulation, ingredients, relative proportions, and preparation methodology described herein represent traditional knowledge, made freely available under the Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0). o2vun0uqtqd53s77ly093xo379d5sbg 4669037 4668953 2026-09-06T02:12:48Z MathXplore 3097823 Adding {{formatting}} tag 4669037 wikitext text/x-wiki {{formatting}} '''गोपालकाला (Gopalkala)''' '''Summary''' गोपालकाला is a traditional dish prepared on Krishna Janmashtami. This dish serves as a balanced snack item. There is a legend associated with this dish which goes as follows: When Krishna used to go into the jungle with his friends, they used to bring food items like flattened rice ( dry poha), puffed sorghum (jowar lahi), roasted gram (phutane), and sour curd. But curd and butter was forcibly taken by Kansa hence only rich people can afford to give curd to their children as lunch. So Krishna used to mix all items, and then everyone used to eat that together. So even if someone is poor, they also can enjoy the delicacy of curd without feeling guilty. Today this dish serves as an example of equality and fraternity. The modern day version however is a bit modified to enhance its taste. '''Description''' गोपालकाला has a mixture of sour, sweet & spicy flavors. It has a distinguishing texture of crunchy and softness together. The flavor is usually enhanced with curry leaves, green chilli, and coriander leaves. The balanced flavors of this serves as a unique delicacy to tongue. It contains carbohydrates, proteins and fats serving a proper filling snack item prepared under 30 minutes. '''Ingredients (1 serve)''' 1 small bowl flattened rice (poha) 1 small bowl puffed sorghum (jowar lahi) 1 tablespoon roasted gram (phutane) 1 small bowl sour curd 5 teaspoons sugar 2-3 green chillies (sliced, 1/2 inch) 5-6 curry leaves coriander leaves 1 tablespoon cooking oil 1/2 teaspoon mustard seeds 1/4 teaspoon asafoetida (Hing) salt as required water '''Equipments''' tadka pan mixing bowl spatula '''Procedure''' # Take 1 small bowl of flattened rice (poha) and soak for 5-10 minutes. # Take 1 small bowl of sour curd and add 5 teaspoon sugar and salt as required. # Now take 1 tablespoon cooking oil in tadka pan and add 1/2 teaspoon mustard seed. # Let mustard seeds pop then add asafoetida, curry leaves and sliced chillies. # Let chillies cook and curry leaves become crunchy then pour it on curd misture. # Now add soaked flattened rice (poha), puffed sorghum (jowar lahi) and roasted gram (phutane). # Mix it well, keep it for 5 minutes and garnish it with fresh coriander leaves. '''Variations''' This dish can be enhanced further by adding pomegranate seeds, diced apple, peanuts to improve crunchiness. Sometimes Indian pickle (Achar) is also added. '''Note''' This documentation is published to establish publicly searchable prior art under international patent guidelines. The formulation, ingredients, relative proportions, and preparation methodology described herein represent traditional knowledge, made freely available under the Creative Commons Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0). ocz6dpdf8ahxrtm9a9fdlg8z9dyw0e3 Art And AI/Documentary Art 0 485498 4668954 2026-09-05T17:01:28Z 3MMPEYTON 3393808 Added an introduction 4668954 wikitext text/x-wiki == Documentary Art? == <br> Were Modernist the first people to embraced technology, and new psychological insights, to document their culture's decline? 1o6b4ol45wxz1svvry24jh33vkrpfsf 4668955 4668954 2026-09-05T17:02:03Z 3MMPEYTON 3393808 bold to title 4668955 wikitext text/x-wiki == Documentary Art? == <br> '''Were Modernist the first people to embraced technology, and new psychological insights, to document their culture's decline?''' 797v3qe7e851mwhc0dey6u4mryvztah 4668956 4668955 2026-09-05T17:07:26Z 3MMPEYTON 3393808 4668956 wikitext text/x-wiki == Documentary Art? == <br> '''Were Modernist the first people to embraced technology, and new psychological insights, to document their culture's decline?''' <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Edvard Munch - The Scream - Google Art Project.jpg|thumb|Edvard Munch, The Scream, 1910.]] |} <br> 0z06i4y1uyojh89sz958ypomhsi4jmi 4668957 4668956 2026-09-05T17:15:35Z 3MMPEYTON 3393808 4668957 wikitext text/x-wiki == Documentary Art? == <br> '''Were Modernist the first people to embraced technology, and new psychological insights, to document their culture's decline?''' <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Edvard Munch - The Scream - Google Art Project.jpg|thumb|Edvard Munch, The Scream, 1910.]] |} <br> {| class="wikitable" |+ |- ! Documentary Art |- | [[File:Going to Work - L S Lowry.jpg|Going to Work - L S Lowry]] |} 2ps03z6dcrz7325crwy9etieazo4w6w 4668958 4668957 2026-09-05T17:16:43Z 3MMPEYTON 3393808 4668958 wikitext text/x-wiki == Documentary Art? == <br> '''Were Modernist the first people to embraced technology, and new psychological insights, to document their culture's decline?''' <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Edvard Munch - The Scream - Google Art Project.jpg|thumb|Edvard Munch, The Scream, 1910.]] |} <br> {| class="wikitable" |+ |- ! Documentary Art |- | [[File:Going to Work - L S Lowry.jpg|thumb|Going to Work - L S Lowry]] |} gqy5ajpqwg5glvj6ndizqrpb32xza8c 4668960 4668958 2026-09-05T17:26:46Z 3MMPEYTON 3393808 Added 3 tables 4668960 wikitext text/x-wiki == Documentary Art? == <br> '''Were Modernist the first people to embraced technology, and new psychological insights, to document their culture's decline?''' <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Edvard Munch - The Scream - Google Art Project.jpg|thumb|Edvard Munch, The Scream, 1910.]] |} <br> {| class="wikitable" |+ |- ! Documentary Art |- | [[File:Going to Work - L S Lowry.jpg|thumb|Going to Work - L S Lowry]] |} <br> <br> {| class="wikitable" |+ |- ! Photography |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project (color corrected).jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project (color corrected)]] |} j4i56xxkzojg9y6xg6y4rr4ssh2xx4o 4669040 4668960 2026-09-06T02:18:28Z MathXplore 3097823 Added {{[[Template:BookCat|BookCat]]}} using [[User:1234qwer1234qwer4/BookCat.js|BookCat.js]] 4669040 wikitext text/x-wiki == Documentary Art? == <br> '''Were Modernist the first people to embraced technology, and new psychological insights, to document their culture's decline?''' <br> {| class="wikitable" |+ |- ! Modern Art |- | [[File:Edvard Munch - The Scream - Google Art Project.jpg|thumb|Edvard Munch, The Scream, 1910.]] |} <br> {| class="wikitable" |+ |- ! Documentary Art |- | [[File:Going to Work - L S Lowry.jpg|thumb|Going to Work - L S Lowry]] |} <br> <br> {| class="wikitable" |+ |- ! Photography |- | [[File:Alfred Stieglitz - The Hand of Man - Google Art Project (color corrected).jpg|thumb|Alfred Stieglitz - The Hand of Man - Google Art Project (color corrected)]] |} {{BookCat}} r9qi02ob8f8kzor9qpomnofqzpi0w3v Electric Tractor 0 485500 4669022 2026-09-05T20:39:30Z Supermannevermadeanymoney 3610439 Created page with "This page is for the BCS 201 Electric Rototiller made for Farmship Growers Cooperative/Haliburton Community Organic Farm. [https://media.kellycontroller.com/new/KellyKSLUserManualV1.4.pdf Kelly Cheetah Motor Controller Guide]" 4669022 wikitext text/x-wiki This page is for the BCS 201 Electric Rototiller made for Farmship Growers Cooperative/Haliburton Community Organic Farm. [https://media.kellycontroller.com/new/KellyKSLUserManualV1.4.pdf Kelly Cheetah Motor Controller Guide] do2qdybqgsm93ok17mlnvjbqjk1sa2k 4669023 4669022 2026-09-05T21:10:04Z Supermannevermadeanymoney 3610439 4669023 wikitext text/x-wiki This page is for the BCS 201 Electric Rototiller made for Farmship Growers Cooperative/Haliburton Community Organic Farm. The design of the tiller system was inspired by Reid Allaway of Tournesol cooperative, Reid runs the DIY electric farmer facebook group, that is a good place to find out about electric tractors. The system is based around the following information The motor, the motor is permanent magnet synchronous machine motor ME1509 from Motoenergy, an american company. PMSM are highly efficient when run at the correct RPM and torque, the diagram for the me1509 is not available though this one form the me1507 shows the idea https://www.thunderstruck-ev.com/images/companies/1/ME1507dyno.pdf?1518651550248 the me1507 when run at 5000 rpm would be 100% efficient meaning that electrical power inputed would be fully applied as output power at the shaft. The BCS 201 has a reduction gear box, 12:75 or ~ 7:1 reduction. The output RPM for a tiller should be about 540 rpm so with a 7:1 gear ratio 3780. I.e. the motor used should have high efficiency at 3780 RPM the motenergy 1509 is efficient in the range of 2500-3500 rpm so an ideal motor. The power of the motor is determined by how much heat it can disappate as well as the input power. In theory since the windings of a motor are low resistance you can put as much energy into the motor as you would like, but it shouldn't overheat and melt the windings. So the motor power is essentially power in keeping in mind the rate at which the motor dissapates energy. So when making garden beds, check that the motor is not above ~70 C. It should feel warm but not feel like it is burning. It is possible to put a cycleanalyst display on the motor that can read the motor temperature as their is a sensor in the motor. We'll talk about battery power and motor controller circuit next week. [https://media.kellycontroller.com/new/KellyKSLUserManualV1.4.pdf Kelly Cheetah Motor Controller Guide] r4dua8gn5fybo06bb6yzc89mnksbgc0 4669026 4669023 2026-09-05T23:23:47Z Jonhson3029 3625272 4669026 wikitext text/x-wiki {{Delete}}This page is for the BCS 201 Electric Rototiller made for Farmship Growers Cooperative/Haliburton Community Organic Farm. The design of the tiller system was inspired by Reid Allaway of Tournesol cooperative, Reid runs the DIY electric farmer facebook group, that is a good place to find out about electric tractors. The system is based around the following information The motor, the motor is permanent magnet synchronous machine motor ME1509 from Motoenergy, an american company. PMSM are highly efficient when run at the correct RPM and torque, the diagram for the me1509 is not available though this one form the me1507 shows the idea https://www.thunderstruck-ev.com/images/companies/1/ME1507dyno.pdf?1518651550248 the me1507 when run at 5000 rpm would be 100% efficient meaning that electrical power inputed would be fully applied as output power at the shaft. The BCS 201 has a reduction gear box, 12:75 or ~ 7:1 reduction. The output RPM for a tiller should be about 540 rpm so with a 7:1 gear ratio 3780. I.e. the motor used should have high efficiency at 3780 RPM the motenergy 1509 is efficient in the range of 2500-3500 rpm so an ideal motor. The power of the motor is determined by how much heat it can disappate as well as the input power. In theory since the windings of a motor are low resistance you can put as much energy into the motor as you would like, but it shouldn't overheat and melt the windings. So the motor power is essentially power in keeping in mind the rate at which the motor dissapates energy. So when making garden beds, check that the motor is not above ~70 C. It should feel warm but not feel like it is burning. It is possible to put a cycleanalyst display on the motor that can read the motor temperature as their is a sensor in the motor. We'll talk about battery power and motor controller circuit next week. [https://media.kellycontroller.com/new/KellyKSLUserManualV1.4.pdf Kelly Cheetah Motor Controller Guide] ijd8ksgkgezn7r5cgwrw99lgcqk1fcz 4669027 4669026 2026-09-05T23:24:47Z Lemonaka 3406512 Undid edits by [[Special:Contribs/Jonhson3029|Jonhson3029]] ([[User talk:Jonhson3029|talk]]) to last version by Supermannevermadeanymoney: reverting vandalism 4669027 wikitext text/x-wiki This page is for the BCS 201 Electric Rototiller made for Farmship Growers Cooperative/Haliburton Community Organic Farm. The design of the tiller system was inspired by Reid Allaway of Tournesol cooperative, Reid runs the DIY electric farmer facebook group, that is a good place to find out about electric tractors. The system is based around the following information The motor, the motor is permanent magnet synchronous machine motor ME1509 from Motoenergy, an american company. PMSM are highly efficient when run at the correct RPM and torque, the diagram for the me1509 is not available though this one form the me1507 shows the idea https://www.thunderstruck-ev.com/images/companies/1/ME1507dyno.pdf?1518651550248 the me1507 when run at 5000 rpm would be 100% efficient meaning that electrical power inputed would be fully applied as output power at the shaft. The BCS 201 has a reduction gear box, 12:75 or ~ 7:1 reduction. The output RPM for a tiller should be about 540 rpm so with a 7:1 gear ratio 3780. I.e. the motor used should have high efficiency at 3780 RPM the motenergy 1509 is efficient in the range of 2500-3500 rpm so an ideal motor. The power of the motor is determined by how much heat it can disappate as well as the input power. In theory since the windings of a motor are low resistance you can put as much energy into the motor as you would like, but it shouldn't overheat and melt the windings. So the motor power is essentially power in keeping in mind the rate at which the motor dissapates energy. So when making garden beds, check that the motor is not above ~70 C. It should feel warm but not feel like it is burning. It is possible to put a cycleanalyst display on the motor that can read the motor temperature as their is a sensor in the motor. We'll talk about battery power and motor controller circuit next week. [https://media.kellycontroller.com/new/KellyKSLUserManualV1.4.pdf Kelly Cheetah Motor Controller Guide] r4dua8gn5fybo06bb6yzc89mnksbgc0 4669028 4669027 2026-09-05T23:25:14Z Jonhson3029 3625272 Undid revision [[Special:Diff/4669027|4669027]] by [[Special:Contributions/Lemonaka|Lemonaka]] ([[User talk:Lemonaka|discuss]]) 4669028 wikitext text/x-wiki {{Delete}}This page is for the BCS 201 Electric Rototiller made for Farmship Growers Cooperative/Haliburton Community Organic Farm. The design of the tiller system was inspired by Reid Allaway of Tournesol cooperative, Reid runs the DIY electric farmer facebook group, that is a good place to find out about electric tractors. The system is based around the following information The motor, the motor is permanent magnet synchronous machine motor ME1509 from Motoenergy, an american company. PMSM are highly efficient when run at the correct RPM and torque, the diagram for the me1509 is not available though this one form the me1507 shows the idea https://www.thunderstruck-ev.com/images/companies/1/ME1507dyno.pdf?1518651550248 the me1507 when run at 5000 rpm would be 100% efficient meaning that electrical power inputed would be fully applied as output power at the shaft. The BCS 201 has a reduction gear box, 12:75 or ~ 7:1 reduction. The output RPM for a tiller should be about 540 rpm so with a 7:1 gear ratio 3780. I.e. the motor used should have high efficiency at 3780 RPM the motenergy 1509 is efficient in the range of 2500-3500 rpm so an ideal motor. The power of the motor is determined by how much heat it can disappate as well as the input power. In theory since the windings of a motor are low resistance you can put as much energy into the motor as you would like, but it shouldn't overheat and melt the windings. So the motor power is essentially power in keeping in mind the rate at which the motor dissapates energy. So when making garden beds, check that the motor is not above ~70 C. It should feel warm but not feel like it is burning. It is possible to put a cycleanalyst display on the motor that can read the motor temperature as their is a sensor in the motor. We'll talk about battery power and motor controller circuit next week. [https://media.kellycontroller.com/new/KellyKSLUserManualV1.4.pdf Kelly Cheetah Motor Controller Guide] ijd8ksgkgezn7r5cgwrw99lgcqk1fcz 4669029 4669028 2026-09-05T23:25:28Z Jonhson3029 3625272 4669029 wikitext text/x-wiki {{Delete|reason=spam}}This page is for the BCS 201 Electric Rototiller made for Farmship Growers Cooperative/Haliburton Community Organic Farm. The design of the tiller system was inspired by Reid Allaway of Tournesol cooperative, Reid runs the DIY electric farmer facebook group, that is a good place to find out about electric tractors. The system is based around the following information The motor, the motor is permanent magnet synchronous machine motor ME1509 from Motoenergy, an american company. PMSM are highly efficient when run at the correct RPM and torque, the diagram for the me1509 is not available though this one form the me1507 shows the idea https://www.thunderstruck-ev.com/images/companies/1/ME1507dyno.pdf?1518651550248 the me1507 when run at 5000 rpm would be 100% efficient meaning that electrical power inputed would be fully applied as output power at the shaft. The BCS 201 has a reduction gear box, 12:75 or ~ 7:1 reduction. The output RPM for a tiller should be about 540 rpm so with a 7:1 gear ratio 3780. I.e. the motor used should have high efficiency at 3780 RPM the motenergy 1509 is efficient in the range of 2500-3500 rpm so an ideal motor. The power of the motor is determined by how much heat it can disappate as well as the input power. In theory since the windings of a motor are low resistance you can put as much energy into the motor as you would like, but it shouldn't overheat and melt the windings. So the motor power is essentially power in keeping in mind the rate at which the motor dissapates energy. So when making garden beds, check that the motor is not above ~70 C. It should feel warm but not feel like it is burning. It is possible to put a cycleanalyst display on the motor that can read the motor temperature as their is a sensor in the motor. We'll talk about battery power and motor controller circuit next week. [https://media.kellycontroller.com/new/KellyKSLUserManualV1.4.pdf Kelly Cheetah Motor Controller Guide] 10o0bvv0p93gow5styf82e0wioq7mmz 4669031 4669029 2026-09-05T23:53:09Z Codename Noreste 3441010 [[WB:REVERT|Reverted]] edits by [[Special:Contributions/Jonhson3029|Jonhson3029]] ([[User talk:Jonhson3029|talk]]) to last version by Lemonaka 4669027 wikitext text/x-wiki This page is for the BCS 201 Electric Rototiller made for Farmship Growers Cooperative/Haliburton Community Organic Farm. The design of the tiller system was inspired by Reid Allaway of Tournesol cooperative, Reid runs the DIY electric farmer facebook group, that is a good place to find out about electric tractors. The system is based around the following information The motor, the motor is permanent magnet synchronous machine motor ME1509 from Motoenergy, an american company. PMSM are highly efficient when run at the correct RPM and torque, the diagram for the me1509 is not available though this one form the me1507 shows the idea https://www.thunderstruck-ev.com/images/companies/1/ME1507dyno.pdf?1518651550248 the me1507 when run at 5000 rpm would be 100% efficient meaning that electrical power inputed would be fully applied as output power at the shaft. The BCS 201 has a reduction gear box, 12:75 or ~ 7:1 reduction. The output RPM for a tiller should be about 540 rpm so with a 7:1 gear ratio 3780. I.e. the motor used should have high efficiency at 3780 RPM the motenergy 1509 is efficient in the range of 2500-3500 rpm so an ideal motor. The power of the motor is determined by how much heat it can disappate as well as the input power. In theory since the windings of a motor are low resistance you can put as much energy into the motor as you would like, but it shouldn't overheat and melt the windings. So the motor power is essentially power in keeping in mind the rate at which the motor dissapates energy. So when making garden beds, check that the motor is not above ~70 C. It should feel warm but not feel like it is burning. It is possible to put a cycleanalyst display on the motor that can read the motor temperature as their is a sensor in the motor. We'll talk about battery power and motor controller circuit next week. [https://media.kellycontroller.com/new/KellyKSLUserManualV1.4.pdf Kelly Cheetah Motor Controller Guide] r4dua8gn5fybo06bb6yzc89mnksbgc0 User talk:PawPatroler 3 485501 4669025 2026-09-05T23:19:56Z Jonhson3029 3625272 /* Unblock me, please! */ new section 4669025 wikitext text/x-wiki == Unblock me, please! == {{Unblock|reason=**Formal Petition for a Total Narrative Reset and Quantum Retcon**  I formally submit to the reality-anchor that my recent behavioral arc scored a definitive **-400% on Letterboxd**, causing an immediate critical collapse of the local space-time continuum. I admit to clip-clopping directly into restricted administrative sectors like a glitching Spider-Verse anomaly, creating an unholy level of baseline panic that makes *Everything Everywhere All at Once* look like a structured corporate spreadsheet. I confess to multiplying across messaging channels like a hyperactive horde of rogue Minions trapped inside *The Matrix* code, screaming incoherently like a malfunctioning Dalek that accidentally swallowed a Skibidi Toilet virus.  However, much like Deadpool rewinding the timeline with Cable’s clock, or Wanda Maximoff manifested an entire suburban sitcom out of sheer grief, I am begging for a cosmic narrative reset. Give me that *Groundhog Day* loop, but specifically the part where Bill Murray realizes he can play the piano, rather than the dark abyss.  **My Binding Quantum Pledges to the Admin Overlords**  * **The TVA Timeline Protection Act:** I will immediately halt all unauthorized title reassignments, keeping my fleshy appendages off the move button as if it were a spicy, radioactive Infinity Stone being guarded by John Wick. * **The Rick & Morty Microverse Protocol:** I will restrict all half-baked drafts and reality-warping prototypes strictly to my sandbox universe, ensuring they do not leak out and cause a localized *Cloverfield* incident on the main wiki. * **The Wonka Everlasting Distro Ban:** I will pull the plug on all cross-platform automated distributions before I accidentally turn the entire database into a digital blueberry and trigger a Skynet-level apocalypse. Please grant me a continuation token to resume regular editing, or go ahead and banish me to the Upside Down to play a high-stakes game of Uno with Vecna and a sandworm from Arrakis.}} [[User:Jonhson3029|Jonhson3029]] ([[User talk:Jonhson3029|discuss]] • [[Special:Contributions/Jonhson3029|contribs]]) 23:19, 5 September 2026 (UTC) pua2byubvjj749w3al3sv15o67ulgkg 4669039 4669025 2026-09-06T02:13:50Z MathXplore 3097823 Requesting deletion ([[:m:Special:MyLanguage/User:TenWhile6/XReport|XReport]] v3.1c) 4669039 wikitext text/x-wiki <noinclude>{{delete|1=Out of project scope <small>[[:m:Special:MyLanguage/User:TenWhile6/XReport|XReport]]</small>}}</noinclude> == Unblock me, please! == {{Unblock|reason=**Formal Petition for a Total Narrative Reset and Quantum Retcon**  I formally submit to the reality-anchor that my recent behavioral arc scored a definitive **-400% on Letterboxd**, causing an immediate critical collapse of the local space-time continuum. I admit to clip-clopping directly into restricted administrative sectors like a glitching Spider-Verse anomaly, creating an unholy level of baseline panic that makes *Everything Everywhere All at Once* look like a structured corporate spreadsheet. I confess to multiplying across messaging channels like a hyperactive horde of rogue Minions trapped inside *The Matrix* code, screaming incoherently like a malfunctioning Dalek that accidentally swallowed a Skibidi Toilet virus.  However, much like Deadpool rewinding the timeline with Cable’s clock, or Wanda Maximoff manifested an entire suburban sitcom out of sheer grief, I am begging for a cosmic narrative reset. Give me that *Groundhog Day* loop, but specifically the part where Bill Murray realizes he can play the piano, rather than the dark abyss.  **My Binding Quantum Pledges to the Admin Overlords**  * **The TVA Timeline Protection Act:** I will immediately halt all unauthorized title reassignments, keeping my fleshy appendages off the move button as if it were a spicy, radioactive Infinity Stone being guarded by John Wick. * **The Rick & Morty Microverse Protocol:** I will restrict all half-baked drafts and reality-warping prototypes strictly to my sandbox universe, ensuring they do not leak out and cause a localized *Cloverfield* incident on the main wiki. * **The Wonka Everlasting Distro Ban:** I will pull the plug on all cross-platform automated distributions before I accidentally turn the entire database into a digital blueberry and trigger a Skynet-level apocalypse. Please grant me a continuation token to resume regular editing, or go ahead and banish me to the Upside Down to play a high-stakes game of Uno with Vecna and a sandworm from Arrakis.}} [[User:Jonhson3029|Jonhson3029]] ([[User talk:Jonhson3029|discuss]] • [[Special:Contributions/Jonhson3029|contribs]]) 23:19, 5 September 2026 (UTC) n481kvqsm5f2bjlv7vedmcw09ss1q16 General Literary Chinese from Scratch/Eating like a Zhou Aristocrat 0 485502 4669034 2026-09-06T00:10:50Z Shira the Mogul 3560559 Created page with "Comment to be written. ==Recipe== <blockquote> 糝:取牛羊豕之肉,三如一小切之,與稻米;稻米二肉一,合以為餌煎之。 </blockquote> <!--- highlight 三如一小切 and 稻米二肉一 specifically ---> ==References== * 《禮記 內則》 {{BookCat}}" 4669034 wikitext text/x-wiki Comment to be written. ==Recipe== <blockquote> 糝:取牛羊豕之肉,三如一小切之,與稻米;稻米二肉一,合以為餌煎之。 </blockquote> <!--- highlight 三如一小切 and 稻米二肉一 specifically ---> ==References== * 《禮記 內則》 {{BookCat}} 75anf0g32238qffgbizzjh1sqqktupv User talk:~2026-48395-07 3 485503 4669038 2026-09-06T02:12:49Z MathXplore 3097823 Notifying author about page tagging 4669038 wikitext text/x-wiki == I have added a tag to a page you created == Hi! I'm MathXplore, and I recently reviewed your page, [[:गोपालकाला]]. I have added a tag to the page, because it <strong>needs to have its formatting improved.</strong> If you have any questions or concerns, please [[User talk:MathXplore|let me know]]. Thank you! <!-- Substituted from User:JJPMaster/CurateThisPage/authorMsg --> [[User:MathXplore|MathXplore]] ([[User talk:MathXplore|discuss]] • [[Special:Contributions/MathXplore|contribs]]) 02:12, 6 September 2026 (UTC) 2xnee600odysm61uen6d2ork60d3ln5 Cookbook:Country Crock 102 485505 4669093 2026-09-06T10:23:57Z ~2026-48139-48 3625218 Created page with "'''''{{w|Country Crock}}''''' is a [[Cookbook:Margarine|margarine]] brand in the United States. [[File:Country_Crock_Masterbrand_Logo.png|thumb|right|250px|250px]] == References == [[Category:Fats and oils]] [[Category:Butter]] [[Category:Margarine]]" 4669093 wikitext text/x-wiki '''''{{w|Country Crock}}''''' is a [[Cookbook:Margarine|margarine]] brand in the United States. [[File:Country_Crock_Masterbrand_Logo.png|thumb|right|250px|250px]] == References == [[Category:Fats and oils]] [[Category:Butter]] [[Category:Margarine]] mt2ysrlevc6v0blbrj4n9tzs4lwjql5