.. vim: noexpandtab fileencoding=utf-8 nomodified wrap textwidth=270 foldmethod=marker foldmarker={{{,}}} foldcolumn=4 ruler showcmd lcs=tab\:|- list tabstop=8 noexpandtab nosmarttab softtabstop=0 shiftwidth=0 :date: 2023.11.08 03:29:35 :tags: SW :authors: Gilhad :summary: ROM nápady - jak zorganizovat ROM, co by měla umět a jak :title: ROM nápady :nice_title: |logo| %title% |logo| %HEADER% ROM nápady -------------------------------------------------------------------------------- .. {{{ * Parametry * .. {{{ * pořadí - 8bit A,B 16bit X,Y,U v tomto pořadí * registry se zachovávají, pokud nejsou výstupní * DP se zachovává * příznaky se nezachovávají. Dává-li to smysl, BNE úspěch, BEQ fail/timeout/... * .. }}} * Funkce * Při startu nastavit Stack (8000, takže první byte se uloží na 7FFF)(a případně další defaulty, jako Input/Output, primární, sekundární) * Pokud má Expanduino, tak z něj stáhnout soubor BOOT.HEX a provést ho (tedy interpretovat i případný :\ **04**\ 0000\ **03**\ 0000\ **AAAA**\ cc záznam jako call na **AAAA** ) * následně (vrátí-li se výpočet) poskytovat shell pro * `:` zavedení :xxxx IHEXů (včetně okamžitého spouštění typu 03, segment se ignoruje) * skok/call adresy * RTS (pokud byla volána shell) * restart * wipe RAM+restart * dump memory (addr, hex, ascii - jako v MC) * modify memory * export memory (v IHEX) * nastavení timeoutu pro stdin/stdout (0 - čeká se furt, cokoli jiné udělá se jen max tolik pokusů, než se to vzdá) * nastavení primární/sekundární stdin/stdout (ACIA/Expanduino) (vypisuje se pouze na primární stdout, pokud není dostupný znak na stdin, čte se sekundární tak dlouho, dokud tam nějaký dostupný je) * nastavení, zda se sekundární stdin provádí, nebo jen vypisuje * `*` this and that (pošle this and that na sekundární výstup) * `#` cokoliv je komentář a ignorováno do konce řádky * Poskytované funkce * pro act i sec kanál * vstup: char->A, HH->A, HHHH->X * výstup: A->char, A->HH, XX->HHHH, (XX)->string, (SP+++)->string * konverze: * lower(A)->A * upper(A)->A * hex(A)->A,B * asc(A)->A (printable or .) * vyhledávání: * A,X->X `switch` * A,X->JMP(X) `switch_jmp` * Rezervovaná paměť * 00xx: * DF - 01 Expanduino detected, 00 not detected * E0..FF {sec_IN,sec_OUT,act_IN,act_OUT} * struct IO_channel {2 control_addr,1 control_mask,2 comm_addr,2 timeout, 1 config} * config * sec_IN * bit 0 - echo (0 off, 1 on ) - vypisování kopie na act_OUT * bit 1 - executable (0 off, 1 on ) - akceptuje ho LOOP jako vstup? * sec_OUT * bit 0 - echo (0 off, 1 on) vypisování kopie na act_OUT * Stack - IHEX operace může použít i víc než 256 B pro dočasná data * Vstupní body * Entry point C000 - začátek EEPROM - HW RESET, inicializuje se kdeco, detekuje Expanduino, a nastaví stdin/out, then loop * C003 - EEPROM loop - skok do shellu, po návratu * RESET - čili nastavení defaultů * Stack se nastaví na 8000, pak se na něj uloží C000 (RESET) * DP se nastaví na 0 * ORCC $50 - FIRQ Mask=1 disabled, IRQ Mask=1 disabled * do ACIA Control Registru se zapíše 0x15 (0 Receive Interrupt off, 00 :overline:`RTS` =low, Transmit Interrupt off, 1 01 8bit+1stop, 01 divide by 16) * nastaví se ACIA jako default a Expanduino_I jako sekundární * vypíše se verze EEPROM na ACIA * Detekce Expanduina: * pro kanály 1-3 se přečte registr a pak hned status - registr nesmí být povolen (Expanduino to nemůže stihnout doplnit tak rychle - doufám) * pokud to prošlo, následuje sekvence na Control (00 00 .. ) 00 FF 00 (přečtení portů naslepo) 00 00 01 - reset Expanduina s timeoutama (nesmí vytimeoutovat) * pokud ok, z kanálu 1 se opisuje na ACIA (s timeoutama) do znaku `\\0` a musí to být aspoň len("Expanduino") znaků a maximálně 128 a nesmí vytimeoutovat * pokud došlo k chybě, nastaví se ACIA i jako sekundární a vypíše se chyba/nedetekce Expanduina * následuje BOOT * BOOT * pokud je Expanduino nastaveno jako detekováno a sec_IN je executable, pošle na sec_OUT příkaz `EXEC /BOOT.HEX` * následuje LOOP * LOOP * v cyklu vždy přečte a provede řádku ukončenou jedním z `\\r\\n\\0` - prázdné řádky ignoruje * pokud poslední znak byl `\\0`, tak se nečeká na vstup a nepřipravenost vstupu je rovnou timeout .. }}} Komunikace s Expanduino_I -------------------------------------------------------------------------------- .. {{{ * Control: * 00 znamená konec zprávy (pokud je jí potřeba ukončovat), nadbytečné 00 se ignorují) * 01 na port 1 zapiš `\\r\\n# VERSION\\r\\n\\0` s aktuální VERSION * FF znamená restart Expanduina, zejména dropnutí všech FIFO * (00 00 .. ) 00 FF 00 (přečtení portů naslepo) 00 00 01 - reset Expanduina * sekvence 00 FF by měla Expanduino_I přimět k internímu resetu - (ale reset taky možná požere nějaká FIFO, takže pošleme víc nul) * přečtení portů naslepo vyklidí případné zbytky a nastaví LED správně * 01 nechá Expanduino_I vypsat verzi na port 1 * kanál 1: * `CoProcessor` základní komunikace, až na vyjímky text, odpovědi Expanduina začínají `:` pro IHEX přenosy a `#` pro komentáře a ostatní hodnoty a (pokud jsou textové, tak končí \\r\\n\\0) * příkazy: * `VERSION` * aktuální verze `# Expanduino_I v.0.1 (init+RTCx+flash+cmds+SD+Every)\\r\\n\\0` * `DATETIME` * aktuální čas `# 2023.12.31 12:34:56\\r\\n\\0` * `EXEC filename [@offset] [+lenght]` * **binárně** jednotlivé byty souboru (případně od `offset`\u a v maximální délce `lenght`) (alias pro `BDUMP`) * `BDUMP filename [@offset] [+lenght]` * **binárně** jednotlivé byty souboru (případně od `offset`\u a v maximální délce `lenght`) (alias pro `EXEC`) * `BSIZE filename [@offset] [+lenght]` * textově pošle 2 byty délku souboru (případně od `offset`\u a v maximální délce `lenght`) `# 1A5C\\r\\n\\0` * `IDUMP filename [@offset] [+lenght] [=place] [!entry]` * dumpne soubor jako IHEX, případně od `offset`\u a v maximální délce `lenght`, startovací adresa je 0000 nebo `place` a pokud je `entry`, je uvedeno jako spouštěcí bod * `TEMPERATURE` * teplota `# 23.25 C\\r\\n\\0` .. }}} Code -------------------------------------------------------------------------------- .. {{{ .. code:: ;------------------------------------------------------------------------; ; Funkce: switch ; ; Popis: Prohledává tabulku a vrátí dvoubytovou hodnotu ; ; Parametry: A - Hledaná hodnota ; ; X - Adresa tabulky ; ; Návratová hodnota: V registru X je dvoubytový výsledek (RetVal) ; ; Tabulka: trojice bytů: case, Ret, Val ; ; tabulka končí řádkem se stejnou hodotou case jako předcházející řádek: ; ; case, Def, Ault; ; ; takže při nenalezení shody je výsledek DefAult ; ;------------------------------------------------------------------------;