PMD-85 verzia MIF85 + colorAce 2023
Výzva... ale keď dáte fulltime, výsledky sa dostavili. Koncom júla 2023 funguje verzia ktorá snúbi 8bitového veterána ATMEGA8515-16, taktovanú na 18.432 MHz s farebným 3 bitovým RGB výstupom na SCART. Onboard je aj MIF85, obvod Philips SAA 1099.
Pár poznámok:
zapojenie len 5 integrovaných obvodov...
procesor ATMEGA8515-16PU (všimnite substring 85, to nie je náhoda)
Ram 128KB IS61C1024
register 74373 (expandér IO)
Eprom 27080 alebo 27801. Možnosť osadiť obe EPROM. Pracuje sa aj na verzii s 27C160.
zvuk SAA 1099
SCART DIN7 - TV výstup RGB + je vyvedený aj stereo zvuk z MIF85. Kábel som použil segaMegaDrive2. Čistá práca.
PS/2 Konektor - pripojenie PS/2 myši, alebo PS/2 klávensice
Power connector - DIN5 - napájanie +5V, GND
PMD85 FRB20 konektor na zabudovanie do pôvodnej krabice PMD85
Joystick interface
Emuluje sa PMD85-1 a PMD85-2A, vrátane ALLRAM režimu.
Na taktovanie MIF85 je použitý 8 MHz oscilátor... Dlho som nad tým premýšľaľ, ako sa mu vyhnúť... napr 24/3=8... alebo dynamicky prepočítavať frekvencie a taktovať napr. 9 Mhz. Ale manuál nepustí. MIF85 samozrejme funguje s prerušeniami od časovača, a po resete sa softvérovo vynulujú registre, aby nepískal posledný tón donekonečna.
ColorAce - áno funguje krásne. Nie je úplne ideálne, pár MHz procesorového výkonu by som potreboval ešte. Zobrazovanie ide krásne, 36 KB videoram, 3bity na pixel, všetko atmel zvláda. Problém je pri zápise do videoram, rutina má 140 bajtov = 140 clocks. Zmiešavanie farieb z dvoch bajtov nad sebou, robím "poctivo"... Na zápis 1 bajtu do videoram sa 2 bajty načítajú a zapíše sa 6 bajtov. Každý pixel má 4bity, z toho 3 sú RGB zložky. Výkon pri bežných hrách je dostatočný, možno pri listingu DUMP 1234 trošku vidieť oneskorenie voči originálu PMD85, nič vážne.
režim RGBW by samozrejme problém s výkonom vyriešil. Ale zase 4 vs 8 farieb... no neviem... Ak to nepojde podobrotky, potajme som v Eagle nakreslil verziu s dvoma ATMEGA8515. Jeden ako grafický koprocesor pre RGB.
BITSOUND - momentálne nefunguje optimálne, zvuk sa sampluje len každých 64 mikrosekúnd. Tzv. 15625Hz, frekvenčne ohraničuje výstup na tých max 7-8 kHz. Zvažujem zneužiť MIF85 na generovanie bitového zvuku, ako koprocesor k atmelu.
Poznámka:
PMD85 v roku 2023 rozvíjajú tieto dielne:
RM Team
Sindik.at
Libor LA
Zdenek6
Wex
PMD-85 verzia 2023 + 16 Mbit EPROM
V júli 2023, medziobdobí, keď bola hotový PCB už MIF85 verzie, sa mi zacnelo, miniatúrna, ešte monochrom, krásna trojintegráčová verzia PMD85 so 16 Mbit EPROM 27C160. Na tejto verzii som aj odladil Mouse602. Na 35 GPIO a 8bitový Atmel slušný výkon. Kryštál 18.432 MHz. Ako vidieť mixér na ČB sa na poslednú chvíľu invertor s tranzistorom spáchal. BITSOUND samplovaný každých 8 mikrosekúnd, tj. 125 kHz.
V novembri 2023 sa mi podarilo, po byteFeste doladiť úplnú binárnu kompatibilitu s originálnym INTEL 8080. Problém bol v hraničných situáciach pri inštrukcií DAA a pri nastavovaní AC bitu pri ANA operáciach. Podobne nastavovanie AC bitu pri dekrementácií DCR. Tu mi pomohlo ako to v 8080 asi funguje. Obsahuje totiž len jednu 8bitovú úplnú sčítačku. Pri odčítaní (SUB alebo SBB) sa druhý operand invertuje, CARRY-IN sa invertuje (tj. CIN=1 pri SUB a CIN=not CY pri SBB). Potom prebehne len 8bitové sčítanie. AC bit sa zoberie prenos C3, a CY sa zoberie negácia CarryOUT=C7 zo 7.bitu. Podobne dekremenácia je pripočítanie registra a hodnoty -1, tj. 0FFh. Vtedy sa AC bit nastaví zadarmo sám správne. Pri inštrukciách AND sa AC bit nastavuje podivne, ako logický súčet tretích bitov operandov. Takže exerciser aj na implementácií na architektúre ATMEL AVR už ide bez akejkoľvek odchýlky.
Pri inčtrukcií DAA ale Exerciser 8080/85 mi hlásil CRC error. Exerciser testuje zjavne na všetkých kombináciach AC+CY+A. A zistil som, že nie je úplne presný výklad inštrukcie DAA v originálnom 8080 Programmers Manual.
Konkrétne v bode 2, ked sa rozhoduje kedy má pripočítať hodnotu 60h. Nestačí len podmienka CY=1 alebo horný nibble (po prípadnom pripočítani 6) má hodnotu vyššiu ako 9...
Napríklad keď je situácia AC=C=0 a A=FFh. Síce neviem ako pri BCD aritmetike dôjdeme do takého sympatického stavu, avšak inštrukcia DAA môže byť vykonaná kedykoľvek, pri ľubovoľnom stave procesora, on sa ho nezľakne. Dokonca aj po inštrukcií ktorá nenastavuje AC flag.
Tu podľa bodu 1 sa pripocita 6. Ale už nepripočíta 60h (medzivýsledok je totiž 05h, horný nibble je 0). Mne zafungovalo to, ze v bode 2 testujem hodnotu A este pred pripocitanim 6, a porovnavam s hodnotou 99h. V pripade AC=C=0 a A=FFh po DAA ocakavam v A=65 a to asi aj správna hodnota na fyzickom 8080, ktorú aj Exerciser80/85 očakáva.
Tiež si myslím, že 8080 určite interne nerobí 2 sekvenčné korekcie pri DAA, ale len jeden súčet s hodnotami 0, 6 alebo 66h, ktoré získa z jednoduchej kombinačnej logiky. Viac času tam ani nemá, keďže DAA trvá 4T, čo ju radí k najrýchlejším operáciam, trvá kratšie o 1T ako MOV r,r. Takže určite sa tam procesor veľa nelopotí.
_daa: ; corrected version i8080 on AVR, 17 steps
clr tmp_reg2 ; correction
mov ZL,A
andi ZL,0x0f ; low nibble of A
cpi ZL,9 + 1 ; nibble is > 9, ... 10,11,12,13,14,15
sbrs PSW,ATMEL_H ; or AC=1
brlo noadd6
ori tmp_reg2,0x06
noadd6:
bst PSW,ATMEL_C ; load old CY into T bit
cpi A, 0x99+1 ; high nibble of A
sbrs PSW,ATMEL_C ; old CY
brlo noadd60 ; below A0... 00 az 9F
ori tmp_reg2, 0x60
set
noadd60:
add A, tmp_reg2 ; also AC is set, CY is set manually via T bit
out last_result,A ; for calculate Parity bit
in PSW, SREG ; load new SZ, later we copy new CY(bit T) and new AC ( tmp_reg2)
bld PSW,ATMEL_C
Magická inštrukcia DAA sa používa napríklad aj pri konverzií 4bitové čísla na hexa ASCII reprezentáciu. To klobúk dolu, kto toto vymyslel:
PREVOD1: ; prevod monitor PMD85/2
ANI 0FH
CPI 10
SBB 2FH
DAA
PREVOD2:
ADI 90H
DAA
ACI 40H
DAA
PMD-85 verzia 2023
Rukavica bola hodená; rukavicu som zodvihol. A tak vznikol ďaľší hardvérový emulátor/simulátor/opravná sada/klon PMD-85 verzia 2023. Čiže je to vlastne nový mainboard pre PMD-85, vhodný na zabudovanie do pôvodného PMD85. Je to voľné pokračovanie Urob si sám PMD-85, ktoré beží na ATmega128. Určite nie som sám, ktorý snívame o novšom mainboarde pre PMD85. Nápad dobovej repliky-klonu však kazí istou odlišnosťou napr. 8085 (chýba paritný bit, iné časovanie), Z80 (zložitejšie pripojenie, tiež Parity/overflow bit). A procesor 8080 sa samozrejme nevyrába dnes, ale dá sa kúpiť, za rádovo 3-10 eur. Ale vyžaduje 3 napájacie úrovne (-5V, +12V, +5V) a minimálne 2 podporné IO. Ako som na vlastnej koži zistil, tak aj také hradlo MH7400 stojí 0.40-0.60 eur. Pri PMD85, obsahuje odhadom 25 TTL IO. No ak počítam čistú repliku PMD85, treba si pripravit aspoň 100 eur.
Ciele projektu:
* plne 8 bitový design
* DIL design
* napájanie +5 V
* doska plošného spoja 10 cmx10 cm (obmedzenie freeware Eagle)
* doska má mechanické rozmery a konektory napájania a RGB ako pôvodne PMD-85
* PS/2 konektor na pripojenie externej klávesnice (ala keyFace) + PS/2 mouse602
* 18.432 MHz XTAL ako pôvodné PMD-85
* 20 pin FRB konektor na klávesnicu pôvodného PMD85
* 2 MB EPROM 27C160 (mám aj verzie 27C080, 2x27C040).
* kvalitný zvukový výstup, schopný prehrať high-freq BITSOUND
* čo najmenej integrovaných obvodov
* ja som subjektívne zaťažený na PMD-85-1, takže monochrom + atribút blikania + atribút zvýšeného jasu (pardon, originál má byť 50% jas).
* AllRAM režim
* integrované MIF85.
Čo sa podarilo?
Mainboard je postavený na ATMEL (pardon, už Microchip) ATmega8515 taktovaný na 18.432 MHz. Verzia DIL40, má až 35 IO bitov/portov. Má skvelých 8KB FLASH, čo je naoko málo, ale stačí. Je však nádej, že Microchip časom vyrobí chip s veľkou FLASH aj SRAM. Momentálne skúmam aj nový AVR128DA28, ktorý má DIL28 púzdro a 128 KB FLASH a 16 KB SRAM a beží na 24 MHz.
Tých 20 MHz jednak poskytuje krajší obraz, kvôli tomu, že generujem lepší aspect ratio X:Y ako pôvodné PMD-85, kružnica konečne nevyzerá ako vajce či elipsa apod. Nie je problém ani s 18.432 MHz, vtedy je to ako originál. Ale 20 MHz umožňuje generovať zvuk v kvalite Libor L.A. BITSOUND. Napríklad nová hra Arkanoid. Pôvodné riešenie generovalo zvuk s maximálnou frekvenciou 7.8 kHz, keď tam Libor posielal frekvencie vyššie, už to viach chrčalo, ako lahodne hralo. Teraz som dokázal popri generovaní video výstupu v rýchlosti 6 Mbps, generovať aj zvuk o maximálnej frekvenci 62.5 kHz. Áno, ide to, v podstate počítam takty I8080, spomalené primerane o pôvodný videoprocesor a vzorkujem každých 8 µs. Vlastne 48 µs kreslím TV riadok, a v ďaľších voľných 16 µs simulujem beh procesora 8080, kde každých 2 µs vzorkujem sound port. Následne v ďaľších 64 µs odvysielam zvuk, spolu s obrazom.
Klávesnica PMD-85 je pripojená cez DIL 20 precíznu päticu, namiesto FRB konektora. Pätica by ideálne mala byť 90° ohnutá, ale stačí aj priama, káblik od pôvodnej PMD85 klávesnice sa tam v pohode zmestí.Stĺpec klávesnice sa scanuje každých 256µs, tj. každý 4 TV riadok. Celá klávesnica za 4096 µs. Vytrápil som sa tiež s tým, keďže je to pripojené len cez odpory na zbernicu, ala ZX Spectrum. Klávesnica samozrejme môže byť odpojená a pripojená externá PS/2. obe odpojená aj obe zapojené. Takže zvláda aj dvojhru Tankovej bitky. Pripojený je reproduktor, žltá LED, červená LED svieti len pri RESETE, kvôli nedostatku IO pinov.
Špeciálne funguje SHIFT+RESET+STOP, slúži na RESET a cyklické prepínanie verzií PMD-85-1, PMD-85/2A BASIC-G a PMD-85/2A MONITOR. Tj. držanie klávesy STOP počas RESET spôsobí prepnutie verzie PMD-85. Na PS/2 klávesnici sa prepína ALT+1, ALT+2, ALT+3 tieto tri verzie. ALT+S zobrazí screen s InfoScreenom. Samozrejme funguje aj BASIC G/1.0.
RAMka je ako inak statická 64 KB, úzka DIL32 ISSI IS61C512-15N (prípadne kompatibilné napr. UMC UM61512AK). Je to super ramka, rýchla ako raketa 15 ns (!), kedysi sa používala ako CACHE pre 386 a dá sa aj v roku 2023 kúpiť. Tak či onak, skrz buffrovanie vstupov/výstupov Mega8515 treba čakať 2 takty od vyslania adresy po načítanie dát. Čiže občas musím čakať s NOP. Kvôli nedostatku IO pinov, je odpor R11 pullup na pine PD3 a trvalo vyberá RAM, keď je pid PD3 prepnutý na vstup. Počas serializácie TV riadka sa rotáciou dát niči celý obsah portu PORTD, bit7 je jasová zložka BRIGHT, a bit1 je VIDEO.
FLASH/EPROM sú dve AMD 27C040 alebo takmer nezohnateľné AMD 29F040B. Čiže 2 * 512 KB = 1024 KB. Prepínač Eprom FLASH rieši rôznu funkciu pinu 31. U Flasky je to /WE a u EPROM je to A18. Pin číslo 1 je trvalo pripojený na A18, u EPROM je to V_PROG programovacie napätie, ale v bežnom režime je don't care.
Prepínanie RAM a ROMiek prebieha inak ako v predošlých verziach HW emulátora. RAMka je defaultne prepnutá na kontinuálne čítanie, aj počas práce videoprocesora. Ak sa má robiť zápis, checkuje sa 16bitový časovač TCNT1, či nepríde k prerušeniu od videoprocesora počas zápisu. Podobne čítanie z ROM, akurát si rezervujem viac času na operáciu. Aby sa zabránilo prestojom a blokovaniu zápisu do RAM videoprocesorom, niekedy sú 8080 inštrukcie načítané z RAM skorej ako je urobený zápis výsledku predošlej inštrukcie. A niekedy v normálnom poradí. Viď rutina writeMemoryExecute.
Magnetofón funguje aj vo verzií PMD-85-1, aj PMD-85-2A. Samozrejme ako rýchlik. Funguje aj časovanie cez UART, ala Hlípa, Arkanoid, Flappy2K.
Napájanie je kompatibilné so zdrojom PMD-10, cez male-male DIN5 adaptér, napr. mgf kábel. DIN5 male PCB 90 angle connector nezohnateľný.
Myš PS/2 ala Myš 602. Ide super; zatiaľ viem o Mínach a o FunnyFruits +gredit. Emulácia PS/2 myši ako mouse602 ide super. Už som si objednal z bazoša ďaľšie PS2 myši. Začal som s Mínami od Libora LA, a doladil som aj pre FunnyFruits myš. Tam len ide o to že ako rýchlo súkať dáta na port 8C. Mínam stačilo 1 read a pri ďaľšom reade už mohol snímač vykázať inkrementáciu. Pri funnyFruits hodnotu na porte podržím 3 čítania a ide super. Samozrejme že sa žiadne zmeny polohy nestrácajú... Implementačne je inkrementácia/dekrementácia gray kódu cez paritu, xor, rotácie. Takže míny na PMD85 s optickou myšou ... Bol to impulz, tieto nové programy a budem rád keď sa aj SOLITéR od Romana Bórika dočká upgradu ;) Myš funguje v pool režime, bez prerušení, tie sa neemulujú, ani PIT 8253, ani jeho prepojenia na systémovom konektore. Prerušenia na 8080 je iné kafé, ale u Atmela také čáry-máry...
EPROM 27C160 áno, poradilo sa. 16MBit. To je 2048krát viac ako pôvodná eprom 2708. +5V TTL úrovne. Je to najväčšia 5V 8bitová EPROM pamäť. Dokonca sa podarilo bez chyby na plošáku, keďže najskôr som kúpil pamäte až potom kreslil plošák. EPROM má púzdro DIL 42. zapojená v 8bitovom režime. Programovanie bol trošku experiment. Ale willem na LPT pomohol. Tam sa takmer všetok SW zmestil, čo sa zachovalo na PMD85. Čiže PMD85 tvorí svätá trojica IO 8080+8228+8224 a v klone PMD85 máme ATMEGA8515+61C512+27C160. Krása.
ColorAce práce pokračujú. Boli indície že multicolor verziu nemá šancu 8bitový Atmel utiahnúť.... ale má... opäť je srdcom ATMEGA8515-16, taktovaná na 18.432 MHz a vyššie. Hadrvérovo sa líši od monochromu. Je tam samozrejme potrebná zmena plošáku a softvéru. Namiesto 1 bitu RGB verzia posiela 3 bity. Inštrukciou ASR+OUT som dokázal vyslať naraz 2 bity (jasový atribút a video). Teraz potrebujem vyslať naraz 3 bity každé 3 takty (každých 3x52 ns=162 nanosekúnd). Túto treba vzdať hold prvolezcom (Ing Roman Kišš) a aj súputníkom (Dušky, rombor, Libor LA), ktorí v tejto nanosekundovej oblasti boli úspešní. Alebo tí, čo napália rovnice PMDčka do hradlového poľa a bude fungovať... A hlavne ich odladia... Inštrukciou ASR, LSR apod neurobím rotáciu naraz o 3 bity. Preto som vymyslel zapojenie 128 KB SRAM IS61C1024 (sestra IS61C512). Proste hrubá sila. Dušky si taktiež pomohol, navyše DRAMkami... Je to vymyslené tak, že PORTE, ktorý ma 3bity, sú bity RGB, pripojené cez odporový delič rovno na SCART RGB konektor. Pamäť IS61C1024 je rozdelená na 64 KB - klasika, adresný priestor 8080. A tá druhá 64 KB je videoram. True color to nie je. Na 288*256 by som potreboval 72 KB videoram. Pri 256 farbách, 8bpp. Keď sa uskromním so 16farbami, vystačí aj 36KB. A bingo! Použijem 4bity na pixel, z toho 3 bity sú RGB a 1bit je vata/alignment. No dobre, ale ako odrotujem register o 3 alebo 4 bity? hhhh, máme SWAP inštrukciu, rotácia o 4 bity doprava/doľava... To je naša rotácia. Dnes zobrazovanie už mám rozchodené, to ide 36KB * 50 Hz = 1800 KB/s, tj. 10,8 Mbps. Pri tomto riešení sa ťažisko presúva do zápisu do RGB videoram. Tam z jedného bajtu, čo je 6 pixelov, budem musieť do RGB videoram zapísať 3 bajty. Čo je horšie, realisticky budem musieť zapísať 6 bajtov, aj do mikroriadku nad/pod, ktorý zdieľa farbové atribúty.
No 14 rokov som odolával ColorAce, ... Máme tu však novú dobu, komunita vyvinula softvér, ktorý používa ColorAce ;) Deti už mám väčšie... Koronu som prežil... Ešte sa treba pohrať... Kríza stredného veku. Na PMD85 ide denne 8 hodín.
Prinajhošom hrozí že ColorAce bude pomalšia verzia (tj. vo výsledku pôjdeme do vyššej frekvencie CPU)...
Čo sa zatiaľ nepodarilo
* Vyladiť mixér composite video, hodnoty odporov.
* Vyvedenie zbernice na interný aplikačný konektor. Aby sa dalo pôvodné periférie PMD pripojiť.
* kopec detailov vernejšie emulovať :D :D :D
Na čom sa to momentálne zaseklo?
15. mája som zistil že mám problém s interným oscilátorom pri vyšších frekvenciách ako 18.432 MHz, pri výrobe ďaľších kusov PMD85 v2023. Mám kúpených zopár ATMEGA8515-16PU, ale nechcú ísť stabilne na aspoň 20 MHz. Áno, overclocknuté o 25%. Tie novšie mám kúpene s datecodom 2110, aj originál farnell 2235, čiže úplne nové z linky. Najviac frustrujúce je to, že prapôvodný 20 ročný ATMEGA8515-16PI s kódom 0313, čiže z roku 2003 ide aj na 24 MHz. To je overclock o 50%, a ide ako víno. Nehovoriac že išiel v zapojení aj po 20 rokoch (tj. nezistil som data retention problém, FLASH). Preto som nikdy neriešil toto ako problém. Proste tá prvovýroba bola kvalitnejšia, bezproblémová. Skúšam aj externý oscilátor (CKOPT=0, CKSEL0-3=0) a opäť ide stabilne len ten čip z roku 2003. Riešenia sú viaceré:
* taktovať len do 18.432 MHz (tam je problém len s chraplavejším zvukom)
* urobiť výskum oscilátora, fuses CKSEL0-CKSEL3, nájsť vhodné kombinácie kapacít a kryštálu na stabilný beh.
* zohnať lepšie čipy MEGA8515, staršie. Tie s bielou potlačou a pin1 označený trojuholníkom.
* použiť obdobný čip čo podporuje 20MHz natívne, napr ATMEGA644 DIL40, ATMEGA1284 DIL40, z novších MEGA4908 alebo AVR128DA DIL28..... To však znamená prekresliť plošák, a pravdepodobne použiť ďaľší pomocný register. Tie novšie majú totiž ADC na sebe, a to je minimálne o 2 piny menej voľných. * priamy nástupca ATMEGA8515 v prevedení DIL40 je ATMEGA162... porty, púzdro totožné, len SRAM a FLASH dvojnásobná. Má pekných 35 GPIO, organizovaných 4*8+3. Plus navyše periférie ako 3xPWM. Tu treba povedať že ATMEL vyrába/vyrábal rádovo stovky modelov procesorov AVR.
Čo tak použiť ESP32 Lolin S3, Raspberry-pi pico, STM board?... No ešte to s AVR skúsme :D Zase kedy som si vyskúšal za chodu procesora a aplikácie vybrať/vymeniť kryštál a program išiel bez vady ďalej.... Objednal som ATmega162, čo nie je žiadny výkrik techniky v roku 2023, ale má DIL40 púzdro a 35 GPIO.
16 may
Úprava loadovania programov - počas nahrávania programov do PMD85, ak stlačíte SHIFT, dôjte k načítavaniu hlavičiek len, tj. preskakuje telá súborov.
20 máj
Stále ma láka pôvodná veľkosť kryštálu 18.432 MHz. Výkon je postačujúci, ale pri počítaní taktov a presnom časovaní (samplovaní) zvuku je ho stále málo. Doteraz sa PMDčko emulovalo len 16 us z každých 64 us (TV riadok). Spravil sa veľký pokrok, že aj 55 nezobrazovaných TV riadkoch, ktoré využívam plne na emuláciu. Zvuk sa plní do buffra 2048 bitov, a odosiela každých 8 us. časovač TCNT0 generuje prerušenie každých 8us. To je teda aždých 147 taktov AVR, resp. každých 16 taktov 8080. Nedostatok výkonu sa čiastočne vyriešil, ale stále bolo počuť že občas jitter - chrapot, keď nestíha AVR a buffer je prázdny. Napr. v hre AUTO, sa čakacia slučka je z inštrukcií LHLD a SHLD. Zápis v AVR podstatne pomalší ako čítanie, musím vždy zistiť či zápis stihnem, potom prepnúť zbernicu, vykonať zápis. Sekvencia/ signálov na zápis je postatne zložitejšia.
23 máj
Hardvérový stack implementovaný. ide ako delo. Delo ako delo. Ide len o zrýchlenie emulácie, keď súvisiace PUSH a POP ( resp. CALL a RET) sa vykonajú bez reálneho zápisu do RAM pamäti, do zásobnika. Kľudne si môžete SP nastaviť aj do pamäte ROM, aj tak inštrukcie PUSH+POP budú fungovať ako predpokladáte. Na slušné používanie to funguje slušne a rýchlo. Ale samozrejme má to prekonateľné muchy. Napr. samospúšťacie programy, ktoré prepíšu stack apod. Ten koncept PUSH/POP a CALL/RET prípadne XTHL fungujú elegantne. Horšie prípady nastávajú keď sa zásobník zneužíva, napr. sa z neho číta viacej ako sa zapíše, alebo na zápis do videoram. Ďaľšia možnosť je, zápis viacej dát do zásobnika, ako je v ATMELi na to určený buffer, momentálne 160 bajtov. Citeľné zrýchlenie je už aj pri pár bajtovom buffri, najväčšia prevádzka je vždy na vrchole zásobníka.
Konkrétne napr. hra KURA, používa elegantný scroll obrazovky takto:
XTHL
DCX SP
DCX SP
XTHL
DCX SP
DCX SP
XTHL
DCX SP
DCX SP
XTHL
DCX SP
DCX SP
XTHL
DCX SP
DCX SP
Tento kúsok kódu preniesol 10 bajtov vo videoram o 2 bajty doľava. Tento funguje vďaka tomu že pri akejkoľvek nútenej zmene SP registra zapíšem hardvérový stack do reálnej RAM. Tuto konktétne treba poznamenať že inštrukcia DCX SP a INX SP narúša integritu stacku, že posúva SP len o jedna, namiesto o dva bajty.
Scroll 10 bajtov doprava, bol implementovaný takto:
XTHL
POP PSW
XTHL
POP PSW
XTHL
POP PSW
XTHL
POP PSW
XTHL
POP PSW
tento kúsok kódu sprvoti nechcel ísť, a Kuriatko išlo len na ľavej časti obrazovky, lebo pravá ostávala vždy len prázdna. Z hľadisla emulácie ide o dve najdlhšie trvajúce inštrukcie, aj z hľadiska toho že PSW musím pracne vypočítať, aj paritný bit, ktorý u ATMEL chýba.
Trošku som sa vytrápil aj s hrou BLUDISKO, tam začala zase hudba chrčať. Tam bolo v časovacej slučke zvuku použité 6*XHTL
XTHL
XTHL
XTHL
XTHL
XTHL
XTHL
Mal som však len chybu, že po vykonaní XTHL sa takty len spočítavali a netestovalo sa 8 us.
Taktiež som opravil časovanie inštrukcií, počítam takty, spomaľovanie podľa videoprocesora, podľa článku Takty i8080 v PMD85. Pre istotu som tu tabuľku s predĺžením taktov aj uložil k sebe. Snáď mi Zdeněk autorské práva prepáči, bola to práca prepočítať a celé to spísať.
Čo sa týka zásobniku, tak emulátor čo spustí kód BASICu sa dá považovať za dokonale správny :D Sú tam zásobnikové skvosty, napočítal som 52 x XTHL a 3x INX SP. A tá posledná inštrukcia INX SP, o ktroej som si myslel že sa používa v páre, tak v BASICu:
PUSH PSW
INX SP
PUSH B
PUSH B
XTHL
POP B
jún 2023
Vrátil som sa k pôvodnému riešeniu keď pri zápise do RAM sa nepoužíva TCNT1. Celkovo to vychádza rýchlejší a kratší kód. Zápis do pamäte RAM je časovo najnáročnejšia operácia, kvôli synchronizácií s videoprocesorom.
* oprava jasového atribútu. Tu som zistil že nie je také ľahké urobiť dokonalý mixér na generovanie composite video (len z diód a odporov). Jasový atribút má význam 50% jasu a preto skúmam spraviť tranzistorový invertor. Komplikácia je samozrejme, že čierna s 50% jasom má byť stále tá istá čierna. Aj tranzistory KSY71 majú oneskorenie rádovo 20 ns, čo je cca 1/2 inštrukcie atmelu a na TV je to vidieť, že obraz nie je dokonale ostrý. Hodnoty odporov R1 = 1 - 1.2 kOhm, R2=560 Ohm, R3 = 100 Ohmov, sú empirické. Testujem aj mixér s dokonalými a vedeckými hodnotami R1 = 390 Ohm, R2= 220 Ohm, R3 = 180 Ohmov, ktoré by mali generovať správnu amplitúdu bielej, čiernej aj sync úrovne pri záťaži 75 Ohm.
* optimalizácia generovania paritného bitu. Áno oproti klasike (rotácie, swap, xor), ušetril som 1 inštrukciu (9%). Prinajhoršom by sa dala pripojiť 74180 ako koprocesor. Tu treba povedať, že mnohí sme zastali, v klonoch sa nedajú priamo použiť procesory 8085 ani Z80. Procesor 8085 nemá paritný bit, takže PMD85 BASIC-G nespustí. No neviem, netradičné použitie paritného bitu na testovanie typu premennej. Rovnako Z80 okrem iného časovania inštrukcií, má inak nastavovanie flag-ov.
* skúmanie ako naprogramovať pamäť 27C160, ktorá je síce DIL42, 16bitová eprom, ale je dostupná a má 8bitový režim čítania, a 16 Mbit = 2 MB kapacitu. ELNEC odporúča na hobby použitie WILLEM Programmer, absolútna klasika na LPT port !!!. Tak čakám čo príde z aliexpressu. Plus adaptér 16 bitové epromky
* keď som si spustil pôvodné PMD85 a implementáciu v ATMega8515, nie som si istý, či taktovanie je identické, preto som posunul časovanie inštrukcie POP z 12 na 10 taktov. Testujem na PMD-85/2A, príkaz DUMP 0000... Alebo bude opäť dakde neodhalená nedokonalosť alebo preklep.
júl 2023
* implementácia myši602, fyzicky pripojená je akákoľvek PS2 myš - optická, guličková. Zopár bajtov kódu ;)
* Eprom 16MBit 27C160 !!!
* doladiť - ROM0 - demko v BASIC-G
* 0x30 narodeniny Ikon
* doladený BASIC-2A. ALLRAM režim, menší problém. doladené.
september 2023
Optimalizácia - zapnutím bootloaderu na adresu 0xC00 a presunutím RESETu a obsluhy prerušení od časovačov som získal to, že register ZH=0. Register ZH je trvalo nula a adresuje mi aj rozskokovú tabuľku 256 inštrukcií cez pamäť programu IJMP a rovnako adresujem zmenou ZL, aj nultú stránku internej SRAM 0x60 - 0xFF. Tým sa mi aj uvoľnil jeden register a zároveň zrýchlil a skrátil kód, keďže nemusím načítavať vyššiu časť adresy, tá je stále 0. V SRAM pri ZH=0 sídlia všetky premenné, tabuľky typu rgb_table. Dokonca pekne funguje aj skátené ldd r0,Z+5 . Po 20 rokoch pochopím tento procesor m8515, že register Z adresuješ adresy 0x60-0xff, registrom Y 0x100-0x1FF a registrom X adresy 0x200-0x25F. Procesom mega162 má SRAM pamät zarovnanú od 0x100, ... má zase až 1 KB.
** pálim EPROMky 27C801 ** 8 Mbit = 1 MegaByte.
** Implementácia ROMMegaModulu ** Kôli spusteniu Bad Apple demu a hry Šach. Tu som si to vyžral do dna. A otravoval autora dema Libora LA. Tu som si to oddebugoval a zistil som že po odoslaní CW na 8255 nenulujem vyslanú hodnotu na PORTB, PORTC.
stalo sa toto:
1. monitor PMD85-2/2A na konci TRANFER rutiny nastavi port FAh na hodnotu FF - akoze odpoji PC7=1 ... +12V na epromkach.
2. spusti sa demo BA2 od 0000
3. inicializuje port FB na hodnotu 90. ... orientacia portov ROMPACKu. tu by som podotkol ze emulovana 8255 nenuluje hodnotu portov pri zapise CW (moja chyba)
4. nasledne DEMO bezi... a tam na adresach 1930h pri RST 1 cita z ROM modulu tak ze vysle na port F9 LSB adresy... a na port FA len ked pretecie.... Cize ak port 0xFA nie je vynulovany, tak je stale v nom hodnota z bodu 1 (FF) a cita z adresy nie 000000h, ale 007F00 resp., z vypnutej epromky :D v pripade pmd85-1 specifikacie :D fix:
pred spustenim dema, musim MVI A,0 + OUT FAh + JMP 0000h... Alebo pri zapise CW vynulovat 8255 porty.
ponaučenie: Naozaj existuje klon 8255, ktory nenuluje porty. Niesom prvý, čo to pokazil. Napri OKI 82C55:
MSM82C55A-5 After a write command is executed to the command register, the internal latch is cleared in PORTA PORTC (only). For instance, 00H is output at the beginning of a write command when the output port is assigned. However, if PORTB is not cleared at this time, PORTB is unstable. In other words, PORTB only outputs ineffective data (unstable value accordingto the device) during the period from after a write command is executed till the first datais written to PORTB.
Keď stavať ROMMegaModul, tak len poctivá stará INTEL-TESLA 8255. Temelín ani lietadlo neriadiť cez 8255.
október 2023
Vidíme sa na Bytefeste v Prahe. Kto chce vidieť čo dokáže 8KB kódu AVR assemblera.
mega8515
Procesorov tohto typu mi prišlo viacej kusov; no žiaden veľmi nechce ísť stabilne na 20 MHz, iba ten z roku 2003. V prospech mega8515 je, že má o 3 bity IO portov viac, tzv. PORTE. Iné 20 MHz procesory v DIL40 púzdre majú len 4*8=32 GPIO, vďaka ADC prevodníku.. Nieje problém prirobiť záchytny register. Problém je najmä ten, že prístup k nemu je pomalší. Atmel trošku pokazil AVR že CBI/SBI trvajú až 2takty, čiže zápis do externého registra trvá minimálne 5 taktov, čo je 5x pomalšie ako prístup k normálnemu portu. Nehovoriac o tom, ako pomaly je nastaviť/nulovať jeden bit v takomto registri. Ďaľší problém je, že potrebujem 3 8bitové porty(24 bitov=16 bit adresa, 8 bit dáta). Na zvyšnom 8-bitovom porte sa vylučuje generovanie VIDEO výstupu (rotácia spôsobuje zápis kadečoho aj do iných bitov), s generovaním SOUND signálu a rovnako s riadením /WR, /OE, /CS pamätí. Čiže sú potrebné aspoň 5 registrov, PORTA (D0-D7), PORTB (A0-A7)- PORTC (A8-A15)), PORTD (VIDEO, jas BRIGHT, KB_CLK, KB_DATA, SYNC, SELECT_RAM_OR_FLASH, časť adresy A16, A17), PORTE (SOUND, /OE, /WE). Inak neviem, už pomôžu len procesory v púzdre TQFP64. Je to taký veterán, ale stále je ** in production **. Má nástupcu, ATmega162...
Treba povedať že ATmega8515 z Číny vyzerá skorej ako neoriginálny čínsky klon, ako ten z FARNELL/MOUSER, ale šlape rovnako, má aj bootloader, aj som nenašiel žiadne léčky.
tajné inštrukcie a porty
Momentálne koncom mája 2023, v rámci zjednodušenia a zrýchlenia, priznávam že interne okrem povinnej základnej sady inštrukcií 8080, som si dorobil dve inštrukcie - kódy 0x08, 0x10. Jedna robí writeStack, akýsi flush zásobníka naspäť do RAMKy a je použitá len raz, pri pri zápise dát z magnetofónu, kvôli autostartu programov (z magnetofónu sa nahrá časť zásobníka). Druhá inštrukcia robí readByte z magnetofónu, podobne ako rutina 0x8B6C. Vrátane nastavenia PSW. Tu ide o to, že modely PMD85-1 a PMD85-2 majú úplne inak riešené čítanie dát z magnetofonu. V podstate pre PMD85 dvojku, port 1E funguje ako pre PMD85-1. Len som pre PMD85-2 potreboval občas takú skratku pre C3 6C 8B nahradiť kompaktnejším 10 C9. No celé to asi prikryjem nejakou perinkou, lebo niektoré programy detekujú jednotlivé verzie PMD85-2 podľa nejakého bajtu v romke, napr. 8B6C: C5 . Momentálne som si rutinku 8B6C napísal ako: 8B6C: C5 10 C1 C9.
Tajne ešte bežím ALLRAM režim non-stop, resp. stále bežím v RAMke, kde je len skopírovaná ROM 4K. To však robí problémy s detekciou ALLRAM, každý autor má svojský štýl ;) A robí skúšobné zápisy na rôzne adresy. Niektoré hry sa totiž neuspokoja s tým, že otestujú ALLRAM, ale testujú aj pripojiť ROM a zápis do ROM. V niektorých hrých napr. HLIPA, Highway Encounter som zmazal kontrolu na ALLRAM. Nieje to elegantné, ale funguje ;) Ale asi ma čaká to doklepať do transparentného stavu.
podivné použitie IO Atmelu
našiel som trojicu portov - EEDR, UBRR, EEARL, ktoré používam ako rýchle úložisko 3 bajtov, ako obyčajné registre. Nič viac, nič menej. Nuž 32 vnútorných registrov je málo...
A ako to vyzerá
a čo je v ATmega8515?
Áno, zatiaľ zdieľam plne funkčný kompilát, listing. Pre predstavu:
AVRASM ver. 1.56 pmd.asm Wed May 24 15:20:59 2023 warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive warning : Register already defined by the .DEF directive ; ; PMDEmu SMALL - AVR based emulator of Czechoslovak microcomputer PMD-85 originally based on I8080 ; Copyright (C) 2023 Peter Chrenko <stare********@gmail.com>, Topolcany, Slovakia ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; PMD.PHP .include "m8515def.inc" ;*************************************************************************** ;* A P P L I C A T I O N N O T E F O R T H E A V R F A M I L Y ;* ;* Number :AVR000 ;* File Name :"m8515def.inc" ;* Title :Register/Bit Definitions for the ATmega8515 ;* Date :April 16th, 2002 ;* Version :1.00 ;* Support telephone :+47 72 88 87 20 (ATMEL Norway) ;* Support fax :+47 72 88 87 18 (ATMEL Norway) ;* Support E-mail :[email protected] ;* Target MCU :ATmega8515 ;* ;* DESCRIPTION ;* When including this file in the assembly program file, all I/O register ;* names and I/O register bit names appearing in the data book can be used. ;* In addition, the six registers forming the three data pointers X, Y and ;* Z have been assigned names XL - ZH. Highest RAM address for Internal ;* SRAM is also defined ;* ;* The Register names are represented by their hexadecimal address. ;* ;* The Register Bit names are represented by their bit number (0-7). ;* ;* Please observe the difference in using the bit names with instructions ;* such as "sbr"/"cbr" (set/clear bit in register) and "sbrs"/"sbrc" ;* (skip if bit in register set/cleared). The following example illustrates ;* this: ;* ;* in r16,PORTB ;read PORTB latch ;* sbr r16,(1<<PB6)+(1<<PB5) ;set PB6 and PB5 (use masks, not bit#) ;* out PORTB,r16 ;output to PORTB ;* ;* in r16,TIFR ;read the Timer Interrupt Flag Register ;* sbrc r16,TOV0 ;test the overflow flag (use bit#) ;* rjmp TOV0_is_set ;jump if set ;* ... ;otherwise do something else ;*************************************************************************** ;***** Specify Device .device ATmega8515 ;***** I/O Register Definitions .equ SREG =$3f .equ SPH =$3e .equ SPL =$3d .equ GIMSK =$3b .equ GICR =$3b .equ GIFR =$3a .equ TIMSK =$39 .equ TIFR =$38 .equ SPMCR =$37 .equ EMCUCR =$36 .equ MCUCR =$35 .equ MCUSR =$34 ; For compatibility, .equ MCUCSR =$34 ; keep both names until further .equ TCCR0 =$33 .equ TCNT0 =$32 .equ OCR0 =$31 .equ SFIOR =$30 .equ TCCR1A =$2f .equ TCCR1B =$2e .equ TCNT1H =$2d .equ TCNT1L =$2c .equ OCR1AH =$2b .equ OCR1AL =$2a .equ OCR1BH =$29 .equ OCR1BL =$28 .equ ICR1H =$25 .equ ICR1L =$24 .equ WDTCR =$21 .equ UCSRC =$20 ; Note! UCSRC equals UBRRH .equ UBRRH =$20 ; Note! UCSRC equals UBRRH .equ EEARH =$1f .equ EEARL =$1e .equ EEDR =$1d .equ EECR =$1c .equ PORTA =$1b .equ DDRA =$1a .equ PINA =$19 .equ PORTB =$18 .equ DDRB =$17 .equ PINB =$16 .equ PORTC =$15 .equ DDRC =$14 .equ PINC =$13 .equ PORTD =$12 .equ DDRD =$11 .equ PIND =$10 .equ SPDR =$0f .equ SPSR =$0e .equ SPCR =$0d .equ UDR =$0c .equ UCSRA =$0b .equ UCSRB =$0a .equ UBRR =$09 ; for AT90S8515 .equ UBRRL =$09 .equ ACSR =$08 .equ PORTE =$07 .equ DDRE =$06 .equ PINE =$05 .equ OSCCAL =$04 ; New ;***** Bit Definitions ;GIMSK .equ INT1 =7 .equ INT0 =6 .equ INT2 =5 .equ IVSEL =1 ; interrupt vector select .equ IVCE =0 ; interrupt vector change enable ;GIFR .equ INTF1 =7 .equ INTF0 =6 .equ INTF2 =5 ;TIMSK .equ TOIE1 =7 .equ OCIE1A =6 .equ OCIE1B =5 .equ TICIE1 =3 .equ TOIE0 =1 .equ OCIE0 =0 ;TIFR .equ TOV1 =7 .equ OCF1A =6 .equ OCF1B =5 .equ ICF1 =3 .equ TOV0 =1 .equ OCF0 =0 ;SPMCR .equ SPMIE =7 .equ RWWSB =6 .equ ASB =6 ; old .equ RWWSRE =4 .equ ASRE =4 ; old .equ BLBSET =3 .equ PGWRT =2 .equ PGERS =1 .equ SPMEN =0 ;EMCUCR .equ SM0 =7 .equ SRL2 =6 .equ SRL1 =5 .equ SRL0 =4 .equ SRW01 =3 .equ SRW00 =2 .equ SRW11 =1 .equ ISC2 =0 ;MCUCR .equ SRE =7 .equ SRW =6 .equ SRW10 =6 .equ SE =5 .equ SM =4 .equ SM1 =4 .equ ISC11 =3 .equ ISC10 =2 .equ ISC01 =1 .equ ISC00 =0 ;MCUSR .equ SM2 =5 .equ WDRF =3 .equ BORF =2 .equ EXTRF =1 .equ PORF =0 ;TCCR0 .equ FOC0 =7 .equ WGM00 =6 .equ COM01 =5 .equ COM00 =4 .equ WGM01 =3 .equ CS02 =2 .equ CS01 =1 .equ CS00 =0 ;TCCR1A .equ COM1A1 = 7 .equ COM1A0 = 6 .equ COM1B1 = 5 .equ COM1B0 = 4 .equ FOC1A = 3 .equ FOC1B = 2 .equ PWM11 = 1 ; OBSOLETE! Use WGM11 .equ PWM10 = 0 ; OBSOLETE! Use WGM10 .equ WGM11 = 1 .equ WGM10 = 0 ;TCCR1B .equ ICNC1 = 7 .equ ICES1 = 6 .equ CTC11 = 4 ; OBSOLETE! Use WGM13 .equ CTC10 = 3 ; OBSOLETE! Use WGM12 .equ WGM13 = 4 .equ WGM12 = 3 .equ CS12 = 2 .equ CS11 = 1 .equ CS10 = 0 ;SFIOR .equ TSM =7 .equ XMBK =6 .equ XMM2 =5 .equ XMM1 =4 .equ XMM0 =3 .equ PUD =2 .equ PSR10 =0 ;WDTCR .equ WDTOE =4 .equ WDCE =4 .equ WDE =3 .equ WDP2 =2 .equ WDP1 =1 .equ WDP0 =0 ;EECR .equ EERIE =3 .equ EEWEE =2 .equ EEMWE =2 .equ EEWE =1 .equ EERE =0 ;PORTA .equ PA7 =7 .equ PA6 =6 .equ PA5 =5 .equ PA4 =4 .equ PA3 =3 .equ PA2 =2 .equ PA1 =1 .equ PA0 =0 ;DDRA .equ DDA7 =7 .equ DDA6 =6 .equ DDA5 =5 .equ DDA4 =4 .equ DDA3 =3 .equ DDA2 =2 .equ DDA1 =1 .equ DDA0 =0 ;PINA .equ PINA7 =7 .equ PINA6 =6 .equ PINA5 =5 .equ PINA4 =4 .equ PINA3 =3 .equ PINA2 =2 .equ PINA1 =1 .equ PINA0 =0 ;PORTB .equ PB7 =7 .equ PB6 =6 .equ PB5 =5 .equ PB4 =4 .equ PB3 =3 .equ PB2 =2 .equ PB1 =1 .equ PB0 =0 ;DDRB .equ DDB7 =7 .equ DDB6 =6 .equ DDB5 =5 .equ DDB4 =4 .equ DDB3 =3 .equ DDB2 =2 .equ DDB1 =1 .equ DDB0 =0 ;PINB .equ PINB7 =7 .equ PINB6 =6 .equ PINB5 =5 .equ PINB4 =4 .equ PINB3 =3 .equ PINB2 =2 .equ PINB1 =1 .equ PINB0 =0 ;PORTC .equ PC7 =7 .equ PC6 =6 .equ PC5 =5 .equ PC4 =4 .equ PC3 =3 .equ PC2 =2 .equ PC1 =1 .equ PC0 =0 ;DDRC .equ DDC7 =7 .equ DDC6 =6 .equ DDC5 =5 .equ DDC4 =4 .equ DDC3 =3 .equ DDC2 =2 .equ DDC1 =1 .equ DDC0 =0 ;PINC .equ PINC7 =7 .equ PINC6 =6 .equ PINC5 =5 .equ PINC4 =4 .equ PINC3 =3 .equ PINC2 =2 .equ PINC1 =1 .equ PINC0 =0 ;PORTD .equ PD7 =7 .equ PD6 =6 .equ PD5 =5 .equ PD4 =4 .equ PD3 =3 .equ PD2 =2 .equ PD1 =1 .equ PD0 =0 ;DDRD .equ DDD7 =7 .equ DDD6 =6 .equ DDD5 =5 .equ DDD4 =4 .equ DDD3 =3 .equ DDD2 =2 .equ DDD1 =1 .equ DDD0 =0 ;PIND .equ PIND7 =7 .equ PIND6 =6 .equ PIND5 =5 .equ PIND4 =4 .equ PIND3 =3 .equ PIND2 =2 .equ PIND1 =1 .equ PIND0 =0 ;PORTE .equ PE2 =2 .equ PE1 =1 .equ PE0 =0 ;DDRE .equ DDE2 =2 .equ DDE1 =1 .equ DDE0 =0 ;PINE .equ PINE2 =2 .equ PINE1 =1 .equ PINE0 =0 ;UCSRA .equ RXC =7 .equ TXC =6 .equ UDRE =5 .equ FE =4 .equ OR =3 ; old name kept for compatibilty .equ DOR =3 .equ PE =2 .equ UPE =2 .equ U2X =1 .equ MPCM =0 ;UCSRB .equ RXCIE =7 .equ TXCIE =6 .equ UDRIE =5 .equ RXEN =4 .equ TXEN =3 .equ CHR9 =2 ; old name kept for compatibilty .equ UCSZ2 =2 .equ RXB8 =1 .equ TXB8 =0 ;UCSRC .equ URSEL =7 .equ UMSEL =6 .equ UPM1 =5 .equ UPM0 =4 .equ USBS =3 .equ UCSZ1 =2 .equ UCSZ0 =1 .equ UCPOL =0 ;SPCR .equ SPIE =7 .equ SPE =6 .equ DORD =5 .equ MSTR =4 .equ CPOL =3 .equ CPHA =2 .equ SPR1 =1 .equ SPR0 =0 ;SPSR .equ SPIF =7 .equ WCOL =6 .equ SPI2X =0 ;ACSR .equ ACD =7 .equ AINBG =6 .equ ACBG =6 .equ ACO =5 .equ ACI =4 .equ ACIE =3 .equ ACIC =2 .equ ACIS1 =1 .equ ACIS0 =0 .def XL =r26 .def XH =r27 .def YL =r28 .def YH =r29 .def ZL =r30 .def ZH =r31 .equ RAMEND =$25F .equ EEPROMEND = $1FF .equ FLASHEND = $FFF ; byte groups ; /\/--\/--\/--\ .equ SMALLBOOTSTART =0b00111110000000 ;($0F80) smallest boot block is 128W .equ SECONDBOOTSTART =0b00111100000000 ;($0F00) 2'nd boot block size is 256W .equ THIRDBOOTSTART =0b00111000000000 ;($0E00) third boot block size is 512W .equ LARGEBOOTSTART =0b00110000000000 ;($0C00) largest boot block is 1KW .equ BOOTSTART =THIRDBOOTSTART ;OBSOLETE!!! kept for compatibility .equ PAGESIZE =32 ;number of WORDS in a page .equ INT0addr=$001 ;External Interrupt0 Vector Address .equ INT1addr=$002 ;External Interrupt1 Vector Address .equ ICP1addr=$003 ;Input Capture1 Interrupt Vector Address .equ OC1Aaddr=$004 ;Output Compare1A Interrupt Vector Address .equ OC1Baddr=$005 ;Output Compare1B Interrupt Vector Address .equ OVF1addr=$006 ;Overflow1 Interrupt Vector Address .equ OVF0addr=$007 ;Overflow0 Interrupt Vector Address .equ SPIaddr =$008 ;SPI Interrupt Vector Address .equ URXCaddr=$009 ;UART Receive Complete Interrupt Vector Address .equ UDREaddr=$00a ;UART Data Register Empty Interrupt Vector Address .equ UTXCaddr=$00b ;UART Transmit Complete Interrupt Vector Address .equ ACIaddr =$00c ;Analog Comparator Interrupt Vector Address .equ INT2addr=$00d ;External Interrupt2 Vector Address .equ OC0addr= $00e ;Output Compare0 Interrupt Vector Address .equ ERDYaddr=$00f ; EEPROM Interrupt Vector Address .equ SPMaddr =$010 ; SPM complete Interrupt Vector Address .equ SPMRaddr =$010 ; SPM complete Interrupt Vector Address .listmac .include "macro.asm" ; PMDEmu - AVR based emulator of Czechoslovak microcomputer PMD-85 originally based on I8080 ; Copyright (C) 2023 Peter Chrenko <stare********@gmail.com>, Topolcany, Slovakia ; macro.asm ; A0-7 = PORTB ; A8-15 = PORTC .equ ADDRL = PORTB .equ ADDRH = PORTC .equ DATADIR = DDRA .equ DATAIN = PINA .equ DATAOUT = PORTA .equ CONTROLRAM = PORTD .equ VIDEOPORT = PORTD ; D0-D7 = PORTA(OUTPUT):PINA(INPUT) ; PORT D ; PD0 = KBD_DATA(RXD)(IN) ; PD1 = A18 (OUT) ; PD2 = A17 (OUT) ; PD3 = SRAM/FLASH SELECT (OUT) ; PD4 = KBD_CLK (IN) ; PD5 = BUZZER (OUT) ; PD6 = /WR (OUT) ; PD7 = /RD (OUT) ; PORT E ; PE0 = buzzer ; PE1 = CS1 (WE/slash1) ; PE2 = /OE .equ MEMWR = PE1 .equ MEMRD = PE2 .equ SOUND = PE0 .equ RAM_SELECT = PD3 ;flags .equ PMD_CY = 0 .equ PMD_P = 2 .equ PMD_AC = 4 .equ PMD_Z = 6 .equ PMD_S = 7 .equ PMD_PSW = 0b00000010 ; empty PSW .equ ATMEL_C = 0 .equ ATMEL_Z = 1 .equ ATMEL_N = 2 .equ ATMEL_V = 3 .equ ATMEL_S = 4 .equ ATMEL_H = 5 .equ ATMEL_T = 6 .equ ATMEL_I = 7 .macro SELECT_RAM sbi PORTE,MEMWR ; MEMWR_deactive cbi DDRD, RAM_SELECT ; PD3 na input -> pull up cbi PORTE,MEMRD ; MEMRD_active .endmacro .macro SELECT_FLASH0 sbi DDRD, RAM_SELECT cbi PORTD, RAM_SELECT .endmacro .macro SELECT_FLASH0_zeroPage sbi DDRD, RAM_SELECT out PORTD,_zero .endmacro .macro SELECT_FLASH1 sbi PORTE, MEMRD cbi PORTE, MEMWR .endmacro .macro MEMWR_pulse cbi PORTE,MEMWR sbi PORTE,MEMWR .endmacro .macro MEMRD_active cbi PORTE,MEMRD .endmacro .macro MEMRD_deactive sbi PORTE,MEMRD .endmacro .macro MEMWR_active cbi PORTE,MEMWR .endmacro .macro MEMWR_deactive sbi PORTE,MEMWR .endmacro .macro SEND_SOUND out PORTE,video_PORTE ; prepared sound port (via T bit) -> out .endmacro .macro RESTORE_ZH ldi ZH, high(i_table) .endmacro .macro INX_SP sub _SPL,_255 sbc _SPH,_255 ;sbiw _SPL, low(-1) .endmacro .macro DCX_SP add _SPL,_255 adc _SPH,_255 ;sbiw _SPL, 1 .endmacro ; kb_lookup .equ r0 = 1 ; definition of rows of PMD keyboard .equ r1 = 2 ; 2nd row .equ r2 = 4 ; 3rd row .equ r3 = 8 ; 4th row .equ r4 = 15 ; 5th row .equ rx = 0 ; mark - not used key .def m64 = r0 .def snd_reg = r1 .def portValue = r2 .def D = r3 .def E = r4 ; pair (kbd.asm uses movw) .def video_PORTE = r5 .def video_SREG = r6 .def mask_register = r7 .def _SPL = r8 .def video_ptr_l = r9 .def _zero = r10 .def _255 = r11 .def C = r12 ; pair .def B = r13 .def L = r14 ; pair register .def H = r15 .def clock = r16 .def tmp_reg = r17 .def video_tmp = r18 ; shared .def bit_position = r18 ; shared video_tmp .def video_ptr_h = r19 .def A = r20 ; pair register - musnt use ADDIW .def PSW = r21 .def HiReg = r21 .def snd_reg2 = r22 ; may use addiw _SPL,1 .def cntReg = r22 .def _SPH = r23 .def _PCL = r24 .def _PCH = r25 .def snd_pointerWR_lo = r26 ;XL .def snd_pointerWR_hi = r27 ;XH .def snd_pointerRD_lo = r28 ; YL .def snd_pointerRD_hi = r29 ; YH .def video_tmp2 = r29 ; shared ; Z is used by IJMP & LPM ; Z = 30:31 ; Y = 29:28 ; X = 27:26 .equ kbd_portC = EEARL .equ last_result = EEDR .equ STACK_MAX = 80 .dseg 000060 stack: .byte 160 stack_top: 000100 snd_buffer: .byte 0x100 000200 kb_cols: .byte 16 ; PMDs keyboard has 16 columns selected by 74154 000210 kb_cols_real: .byte 16 ; real PMD85 scanning 000220 blink_counter: .byte 1 000221 kbd_ports: .byte 4 ; keyboard 8255 state 000225 mgf_pointer: .byte 3 ; 3 bytes counter 000228 mgf_header: .byte 1 000229 _rom: .byte 4 ; external ROM modul 8255 state 00022d stop_flag: .byte 1 00022e pmd_version: .byte 1 00022f test_clock: .byte 1 000230 stack_pointer: .byte 1 000231 usart_cw_last: .byte 1 000232 kbd_flags: .byte 1 ; flags for KBD module ; 7 = F0 ; 6 = STOP ; 5 = SHIFT ; 4 = ALT ; 3 = ; 2 = ; 1 = ; 0 = .equ F0_bit = 7 .equ STOP_bit = 6 .equ SHIFT_bit = 5 .equ ALT_bit = 4 .cseg .org 0 ; use some bytes of memory to inicialization 000000 24aa clr _zero ; _zero := 0 000001 efef ldi r30,255 000002 2ebe mov _255,r30 000003 bab7 out DDRB,_255 ; portB vystup (address) 000004 c5bd rjmp after_reset ; PMDEmu - AVR based emulator of Czechoslo vak microcomputer PMD-85 originally based on I8080 ; Copyright (C) 2023 Peter Chrenko <stare********@gmail.com>, Topolcany, Slovakia ; video.php .equ total_lines = 312 .equ visible_lines = 256 .equ dark_lines = 36 .equ vsync_lines = 5 .equ lines1 = 31 .equ lines2 = 51 .equ lines3 = 56 .equ VIDEO_SOUND = 0x80 .equ VIDEO_BIT7_LINE=0x9b .macro TIMER0_START out TCNT0,_zero ldi video_tmp, 0b00001001 ; run TCCR0 at CLK, CTC mode 2 out TCCR0, video_tmp .endmacro .macro TIMER0_STOP out TCCR0,_zero .endmacro .org OC1Baddr interrupt_OCR1B: 000005 b66f in video_SREG,SREG 000006 fa10 bst snd_reg,0 000007 f850 bld video_PORTE,SOUND 000008 + SEND_SOUND 000008 b857 out PORTE,video_PORTE ; prepared sound port (via T bit) -> out .endmacro 000009 c020 rjmp OCR1B_continue .org OC0addr 00000e b66f in video_SREG,SREG 00000f 3027 cpi bit_position,7 000010 f440 brsh bit7 000011 9415 asr snd_reg 000012 fa10 bst snd_reg,0 000013 b1d7 in video_tmp2,PORTE 000014 f9d0 bld video_tmp2, SOUND 000015 b9d7 out PORTE,video_tmp2 000016 9523 inc bit_position 000017 be6f out SREG,video_SREG 000018 9518 reti bit7: 000019 + TIMER0_STOP 000019 bea3 out TCCR0,_zero .endmacro 00001a fa17 bst snd_reg,7 00001b b1d7 in video_tmp2,PORTE 00001c f9d0 bld video_tmp2, SOUND 00001d b9d7 out PORTE,video_tmp2 00001e e0d1 ldi snd_pointerRD_hi, high(snd_buffer) 00001f 9019 ld snd_reg, Y+ ; increment is modulo 256, snd_pointerRD_hi is always const 000020 b3de in video_tmp2, kbd_portC ; PC 000021 30d0 cpi video_tmp2, 0 000022 f029 breq snd_cnt 000023 2c1b mov snd_reg,_255 000024 9403 inc m64 000025 21d0 and video_tmp2, m64 000026 11da cpse video_tmp2, _zero 000027 2c1a mov snd_reg,_zero snd_cnt: 000028 be6f out SREG,video_SREG 000029 9518 reti OCR1B_continue: 00002a 3c30 cpi video_ptr_h, 0xc0 ;line 31 00002b f518 brsh normal_line 00002c 9533 inc video_ptr_h 00002d + TIMER0_START 00002d bea2 out TCNT0,_zero 00002e e029 ldi video_tmp, 0b00001001 ; run TCCR0 at CLK, CTC mode 2 00002f bf23 out TCCR0, video_tmp .endmacro 000030 3134 cpi video_ptr_h, 20 ;51 000031 f079 breq vertical_sync_begin 000032 3139 cpi video_ptr_h, 25 ;56 000033 f0a1 breq vertical_sync_end 000034 3337 cpi video_ptr_h, 55 ;56 000035 f449 brne return_sync ; setup "videoprocessor" position to left upper corner ; video address := 0xc000 000036 ec30 ldi video_ptr_h,0xc0 000037 9120 0220 lds video_tmp,blink_counter 000039 952a dec video_tmp 00003a f411 brne no_visibility_change 00003b 9470 com mask_register 00003c e322 ldi video_tmp,blink_period no_visibility_change: 00003d 9320 0220 sts blink_counter,video_tmp return_sync: 00003f e021 ldi bit_position,1 000040 c3a3 rjmp _reti vertical_sync_begin: ; first vertical sync signal 000041 ec22 ldi video_tmp,0b11000010 000042 bd2f out TCCR1A,video_tmp ; negacia 000043 e022 ldi video_tmp,high(590) ; when sync goes low 000044 bd2b out OCR1AH,video_tmp ; channel T1/A 000045 e42e ldi video_tmp,low(590) 000046 bd2a out OCR1AL,video_tmp 000047 cff7 rjmp return_sync vertical_sync_end: ; last vertical sync signal 000048 e822 ldi video_tmp,0b10000010 000049 bd2f out TCCR1A,video_tmp 00004a e024 ldi video_tmp,high(1097) ; when sync goes low 00004b bd2b out OCR1AH,video_tmp ; channel T1/A 00004c e429 ldi video_tmp,low(1097) 00004d bd2a out OCR1AL,video_tmp 00004e cff0 rjmp return_sync normal_line: ; show TV microline 00004f b328 in video_tmp,ADDRL 000050 932f push video_tmp 000051 b325 in video_tmp,ADDRH 000052 932f push video_tmp 000053 ba98 out ADDRL,video_ptr_l 000054 bb35 out ADDRH,video_ptr_h 000055 b52c in video_tmp,TCNT1L ;synchronize with 1 and 2 cycles interrupted instuction 000056 ff20 sbrs video_tmp,0 000057 c000 rjmp PC+1 000058 b329 in video_tmp,PINA ; B X 5 4 3 2 1 0 (B = blink, X = not implemented) 000059 fd27 sbrc video_tmp,7 ; 00005a 2127 and video_tmp,mask_register 00005b 0f22 lsl video_tmp ; 0. byte 00005c bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 00005d 9525 asr video_tmp 00005e 9493 inc video_ptr_l 00005f bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000060 9525 asr video_tmp 000061 ba98 out ADDRL,video_ptr_l ; output low address 000062 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 000063 9525 asr video_tmp 000064 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000065 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 000066 9525 asr video_tmp 000067 0000 nop ; ========= BITSOUND (NOP) === 000068 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000069 9525 asr video_tmp 00006a 0fdd lsl video_tmp2 00006b bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 00006c f408 brcc pc+2 00006d 21d7 and video_tmp2,mask_register ; 1.byte 00006e bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 00006f 95d5 asr video_tmp2 000070 9493 inc video_ptr_l 000071 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000072 95d5 asr video_tmp2 000073 ba98 out ADDRL,video_ptr_l ; output low address 000074 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000075 95d5 asr video_tmp2 000076 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000077 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000078 95d5 asr video_tmp2 000079 0000 nop ; ========= BITSOUND (NOP) === 00007a bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00007b 95d5 asr video_tmp2 00007c 0f22 lsl video_tmp 00007d bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00007e f408 brcc pc+2 00007f 2127 and video_tmp,mask_register ; 2. byte 000080 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000081 9525 asr video_tmp 000082 9493 inc video_ptr_l 000083 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000084 9525 asr video_tmp 000085 ba98 out ADDRL,video_ptr_l ; output low address 000086 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 000087 9525 asr video_tmp 000088 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000089 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 00008a 9525 asr video_tmp 00008b 0000 nop ; ========= BITSOUND (NOP) === 00008c bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 00008d 9525 asr video_tmp 00008e 0fdd lsl video_tmp2 00008f bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000090 f408 brcc pc+2 000091 21d7 and video_tmp2,mask_register ; 3.byte 000092 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 000093 95d5 asr video_tmp2 000094 9493 inc video_ptr_l 000095 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000096 95d5 asr video_tmp2 000097 ba98 out ADDRL,video_ptr_l ; output low address 000098 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000099 95d5 asr video_tmp2 00009a b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00009b bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 00009c 95d5 asr video_tmp2 00009d 0000 nop ; ========= BITSOUND (NOP) === 00009e bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00009f 95d5 asr video_tmp2 0000a0 0f22 lsl video_tmp 0000a1 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 0000a2 f408 brcc pc+2 0000a3 2127 and video_tmp,mask_register ; 4. byte 0000a4 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 0000a5 9525 asr video_tmp 0000a6 9493 inc video_ptr_l 0000a7 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0000a8 9525 asr video_tmp 0000a9 ba98 out ADDRL,video_ptr_l ; output low address 0000aa bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0000ab 9525 asr video_tmp 0000ac b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0000ad bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0000ae 9525 asr video_tmp 0000af 0000 nop ; ========= BITSOUND (NOP) === 0000b0 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0000b1 9525 asr video_tmp 0000b2 0fdd lsl video_tmp2 0000b3 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0000b4 f408 brcc pc+2 0000b5 21d7 and video_tmp2,mask_register ; 5.byte 0000b6 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0000b7 95d5 asr video_tmp2 0000b8 9493 inc video_ptr_l 0000b9 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0000ba 95d5 asr video_tmp2 0000bb ba98 out ADDRL,video_ptr_l ; output low address 0000bc bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 0000bd 95d5 asr video_tmp2 0000be b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0000bf bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 0000c0 95d5 asr video_tmp2 0000c1 fa11 bst snd_reg, 1 ; ========= BITSOUND (OP1: BIT 1) === 0000c2 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 0000c3 95d5 asr video_tmp2 0000c4 0f22 lsl video_tmp 0000c5 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 0000c6 f408 brcc pc+2 0000c7 2127 and video_tmp,mask_register ; 6. byte 0000c8 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 0000c9 9525 asr video_tmp 0000ca 9493 inc video_ptr_l 0000cb bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0000cc 9525 asr video_tmp 0000cd ba98 out ADDRL,video_ptr_l ; output low address 0000ce bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0000cf 9525 asr video_tmp 0000d0 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0000d1 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0000d2 9525 asr video_tmp 0000d3 f850 bld video_PORTE,SOUND ; ========= BITSOUND (OP2: BIT 1) === 0000d4 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0000d5 9525 asr video_tmp 0000d6 0fdd lsl video_tmp2 0000d7 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0000d8 f408 brcc pc+2 0000d9 21d7 and video_tmp2,mask_register ; 7.byte 0000da bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0000db 95d5 asr video_tmp2 0000dc 9493 inc video_ptr_l 0000dd bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0000de 95d5 asr video_tmp2 0000df ba98 out ADDRL,video_ptr_l ; output low address 0000e0 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 0000e1 95d5 asr video_tmp2 0000e2 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0000e3 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 0000e4 95d5 asr video_tmp2 0000e5 + SEND_SOUND ; ========= BITSOUND (OP3: BIT 1) === 0000e5 b857 out PORTE,video_PORTE ; prepared sound port (via T bit) -> out .endmacro 0000e6 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 0000e7 95d5 asr video_tmp2 0000e8 0f22 lsl video_tmp 0000e9 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 0000ea f408 brcc pc+2 0000eb 2127 and video_tmp,mask_register ; 8. byte 0000ec bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 0000ed 9525 asr video_tmp 0000ee 9493 inc video_ptr_l 0000ef bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0000f0 9525 asr video_tmp 0000f1 ba98 out ADDRL,video_ptr_l ; output low address 0000f2 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0000f3 9525 asr video_tmp 0000f4 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0000f5 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0000f6 9525 asr video_tmp 0000f7 0000 nop ; ========= BITSOUND (NOP) === 0000f8 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0000f9 9525 asr video_tmp 0000fa 0fdd lsl video_tmp2 0000fb bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0000fc f408 brcc pc+2 0000fd 21d7 and video_tmp2,mask_register ; 9.byte 0000fe bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0000ff 95d5 asr video_tmp2 000100 9493 inc video_ptr_l 000101 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000102 95d5 asr video_tmp2 000103 ba98 out ADDRL,video_ptr_l ; output low address 000104 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000105 95d5 asr video_tmp2 000106 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000107 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000108 95d5 asr video_tmp2 000109 0000 nop ; ========= BITSOUND (NOP) === 00010a bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00010b 95d5 asr video_tmp2 00010c 0f22 lsl video_tmp 00010d bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00010e f408 brcc pc+2 00010f 2127 and video_tmp,mask_register ; 10. byte 000110 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000111 9525 asr video_tmp 000112 9493 inc video_ptr_l 000113 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000114 9525 asr video_tmp 000115 ba98 out ADDRL,video_ptr_l ; output low address 000116 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 000117 9525 asr video_tmp 000118 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000119 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 00011a 9525 asr video_tmp 00011b 0000 nop ; ========= BITSOUND (NOP) === 00011c bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 00011d 9525 asr video_tmp 00011e 0fdd lsl video_tmp2 00011f bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000120 f408 brcc pc+2 000121 21d7 and video_tmp2,mask_register ; 11.byte 000122 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 000123 95d5 asr video_tmp2 000124 9493 inc video_ptr_l 000125 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000126 95d5 asr video_tmp2 000127 ba98 out ADDRL,video_ptr_l ; output low address 000128 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000129 95d5 asr video_tmp2 00012a b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00012b bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 00012c 95d5 asr video_tmp2 00012d 0000 nop ; ========= BITSOUND (NOP) === 00012e bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00012f 95d5 asr video_tmp2 000130 0f22 lsl video_tmp 000131 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 000132 f408 brcc pc+2 000133 2127 and video_tmp,mask_register ; 12. byte 000134 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000135 9525 asr video_tmp 000136 9493 inc video_ptr_l 000137 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000138 9525 asr video_tmp 000139 ba98 out ADDRL,video_ptr_l ; output low address 00013a bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 00013b 9525 asr video_tmp 00013c b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00013d bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 00013e 9525 asr video_tmp 00013f 0000 nop ; ========= BITSOUND (NOP) === 000140 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000141 9525 asr video_tmp 000142 0fdd lsl video_tmp2 000143 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000144 f408 brcc pc+2 000145 21d7 and video_tmp2,mask_register ; 13.byte 000146 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 000147 95d5 asr video_tmp2 000148 9493 inc video_ptr_l 000149 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 00014a 95d5 asr video_tmp2 00014b ba98 out ADDRL,video_ptr_l ; output low address 00014c bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 00014d 95d5 asr video_tmp2 00014e b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00014f bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000150 95d5 asr video_tmp2 000151 fa12 bst snd_reg, 2 ; ========= BITSOUND (OP1: BIT 2) === 000152 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 000153 95d5 asr video_tmp2 000154 0f22 lsl video_tmp 000155 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 000156 f408 brcc pc+2 000157 2127 and video_tmp,mask_register ; 14. byte 000158 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000159 9525 asr video_tmp 00015a 9493 inc video_ptr_l 00015b bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 00015c 9525 asr video_tmp 00015d ba98 out ADDRL,video_ptr_l ; output low address 00015e bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 00015f 9525 asr video_tmp 000160 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000161 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 000162 9525 asr video_tmp 000163 f850 bld video_PORTE,SOUND ; ========= BITSOUND (OP2: BIT 2) === 000164 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000165 9525 asr video_tmp 000166 0fdd lsl video_tmp2 000167 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000168 f408 brcc pc+2 000169 21d7 and video_tmp2,mask_register ; 15.byte 00016a bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 00016b 95d5 asr video_tmp2 00016c 9493 inc video_ptr_l 00016d bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 00016e 95d5 asr video_tmp2 00016f ba98 out ADDRL,video_ptr_l ; output low address 000170 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000171 95d5 asr video_tmp2 000172 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000173 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000174 95d5 asr video_tmp2 000175 + SEND_SOUND ; ========= BITSOUND (OP3: BIT 2) === 000175 b857 out PORTE,video_PORTE ; prepared sound port (via T bit) -> out .endmacro 000176 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 000177 95d5 asr video_tmp2 000178 0f22 lsl video_tmp 000179 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00017a f408 brcc pc+2 00017b 2127 and video_tmp,mask_register ; 16. byte 00017c bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 00017d 9525 asr video_tmp 00017e 9493 inc video_ptr_l 00017f bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000180 9525 asr video_tmp 000181 ba98 out ADDRL,video_ptr_l ; output low address 000182 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 000183 9525 asr video_tmp 000184 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000185 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 000186 9525 asr video_tmp 000187 0000 nop ; ========= BITSOUND (NOP) === 000188 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000189 9525 asr video_tmp 00018a 0fdd lsl video_tmp2 00018b bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 00018c f408 brcc pc+2 00018d 21d7 and video_tmp2,mask_register ; 17.byte 00018e bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 00018f 95d5 asr video_tmp2 000190 9493 inc video_ptr_l 000191 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000192 95d5 asr video_tmp2 000193 ba98 out ADDRL,video_ptr_l ; output low address 000194 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000195 95d5 asr video_tmp2 000196 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000197 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000198 95d5 asr video_tmp2 000199 0000 nop ; ========= BITSOUND (NOP) === 00019a bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00019b 95d5 asr video_tmp2 00019c 0f22 lsl video_tmp 00019d bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00019e f408 brcc pc+2 00019f 2127 and video_tmp,mask_register ; 18. byte 0001a0 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 0001a1 9525 asr video_tmp 0001a2 9493 inc video_ptr_l 0001a3 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0001a4 9525 asr video_tmp 0001a5 ba98 out ADDRL,video_ptr_l ; output low address 0001a6 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0001a7 9525 asr video_tmp 0001a8 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0001a9 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0001aa 9525 asr video_tmp 0001ab 0000 nop ; ========= BITSOUND (NOP) === 0001ac bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0001ad 9525 asr video_tmp 0001ae 0fdd lsl video_tmp2 0001af bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0001b0 f408 brcc pc+2 0001b1 21d7 and video_tmp2,mask_register ; 19.byte 0001b2 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0001b3 95d5 asr video_tmp2 0001b4 9493 inc video_ptr_l 0001b5 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0001b6 95d5 asr video_tmp2 0001b7 ba98 out ADDRL,video_ptr_l ; output low address 0001b8 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 0001b9 95d5 asr video_tmp2 0001ba b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0001bb bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 0001bc 95d5 asr video_tmp2 0001bd 0000 nop ; ========= BITSOUND (NOP) === 0001be bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 0001bf 95d5 asr video_tmp2 0001c0 0f22 lsl video_tmp 0001c1 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 0001c2 f408 brcc pc+2 0001c3 2127 and video_tmp,mask_register ; 20. byte 0001c4 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 0001c5 9525 asr video_tmp 0001c6 9493 inc video_ptr_l 0001c7 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0001c8 9525 asr video_tmp 0001c9 ba98 out ADDRL,video_ptr_l ; output low address 0001ca bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0001cb 9525 asr video_tmp 0001cc b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0001cd bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0001ce 9525 asr video_tmp 0001cf 0000 nop ; ========= BITSOUND (NOP) === 0001d0 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0001d1 9525 asr video_tmp 0001d2 0fdd lsl video_tmp2 0001d3 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0001d4 f408 brcc pc+2 0001d5 21d7 and video_tmp2,mask_register ; 21.byte 0001d6 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0001d7 95d5 asr video_tmp2 0001d8 9493 inc video_ptr_l 0001d9 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0001da 95d5 asr video_tmp2 0001db ba98 out ADDRL,video_ptr_l ; output low address 0001dc bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 0001dd 95d5 asr video_tmp2 0001de b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0001df bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 0001e0 95d5 asr video_tmp2 0001e1 fa13 bst snd_reg, 3 ; ========= BITSOUND (OP1: BIT 3) === 0001e2 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 0001e3 95d5 asr video_tmp2 0001e4 0f22 lsl video_tmp 0001e5 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 0001e6 f408 brcc pc+2 0001e7 2127 and video_tmp,mask_register ; 22. byte 0001e8 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 0001e9 9525 asr video_tmp 0001ea 9493 inc video_ptr_l 0001eb bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0001ec 9525 asr video_tmp 0001ed ba98 out ADDRL,video_ptr_l ; output low address 0001ee bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0001ef 9525 asr video_tmp 0001f0 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0001f1 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0001f2 9525 asr video_tmp 0001f3 f850 bld video_PORTE,SOUND ; ========= BITSOUND (OP2: BIT 3) === 0001f4 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0001f5 9525 asr video_tmp 0001f6 0fdd lsl video_tmp2 0001f7 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0001f8 f408 brcc pc+2 0001f9 21d7 and video_tmp2,mask_register ; 23.byte 0001fa bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0001fb 95d5 asr video_tmp2 0001fc 9493 inc video_ptr_l 0001fd bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0001fe 95d5 asr video_tmp2 0001ff ba98 out ADDRL,video_ptr_l ; output low address 000200 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000201 95d5 asr video_tmp2 000202 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000203 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000204 95d5 asr video_tmp2 000205 + SEND_SOUND ; ========= BITSOUND (OP3: BIT 3) === 000205 b857 out PORTE,video_PORTE ; prepared sound port (via T bit) -> out .endmacro 000206 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 000207 95d5 asr video_tmp2 000208 0f22 lsl video_tmp 000209 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00020a f408 brcc pc+2 00020b 2127 and video_tmp,mask_register ; 24. byte 00020c bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 00020d 9525 asr video_tmp 00020e 9493 inc video_ptr_l 00020f bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000210 9525 asr video_tmp 000211 ba98 out ADDRL,video_ptr_l ; output low address 000212 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 000213 9525 asr video_tmp 000214 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000215 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 000216 9525 asr video_tmp 000217 0000 nop ; ========= BITSOUND (NOP) === 000218 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000219 9525 asr video_tmp 00021a 0fdd lsl video_tmp2 00021b bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 00021c f408 brcc pc+2 00021d 21d7 and video_tmp2,mask_register ; 25.byte 00021e bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 00021f 95d5 asr video_tmp2 000220 9493 inc video_ptr_l 000221 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000222 95d5 asr video_tmp2 000223 ba98 out ADDRL,video_ptr_l ; output low address 000224 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000225 95d5 asr video_tmp2 000226 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000227 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000228 95d5 asr video_tmp2 000229 0000 nop ; ========= BITSOUND (NOP) === 00022a bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00022b 95d5 asr video_tmp2 00022c 0f22 lsl video_tmp 00022d bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00022e f408 brcc pc+2 00022f 2127 and video_tmp,mask_register ; 26. byte 000230 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000231 9525 asr video_tmp 000232 9493 inc video_ptr_l 000233 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000234 9525 asr video_tmp 000235 ba98 out ADDRL,video_ptr_l ; output low address 000236 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 000237 9525 asr video_tmp 000238 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000239 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 00023a 9525 asr video_tmp 00023b 0000 nop ; ========= BITSOUND (NOP) === 00023c bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 00023d 9525 asr video_tmp 00023e 0fdd lsl video_tmp2 00023f bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000240 f408 brcc pc+2 000241 21d7 and video_tmp2,mask_register ; 27.byte 000242 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 000243 95d5 asr video_tmp2 000244 9493 inc video_ptr_l 000245 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000246 95d5 asr video_tmp2 000247 ba98 out ADDRL,video_ptr_l ; output low address 000248 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000249 95d5 asr video_tmp2 00024a b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00024b bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 00024c 95d5 asr video_tmp2 00024d 0000 nop ; ========= BITSOUND (NOP) === 00024e bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00024f 95d5 asr video_tmp2 000250 0f22 lsl video_tmp 000251 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 000252 f408 brcc pc+2 000253 2127 and video_tmp,mask_register ; 28. byte 000254 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000255 9525 asr video_tmp 000256 9493 inc video_ptr_l 000257 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000258 9525 asr video_tmp 000259 ba98 out ADDRL,video_ptr_l ; output low address 00025a bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 00025b 9525 asr video_tmp 00025c b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00025d bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 00025e 9525 asr video_tmp 00025f 0000 nop ; ========= BITSOUND (NOP) === 000260 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000261 9525 asr video_tmp 000262 0fdd lsl video_tmp2 000263 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000264 f408 brcc pc+2 000265 21d7 and video_tmp2,mask_register ; 29.byte 000266 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 000267 95d5 asr video_tmp2 000268 9493 inc video_ptr_l 000269 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 00026a 95d5 asr video_tmp2 00026b ba98 out ADDRL,video_ptr_l ; output low address 00026c bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 00026d 95d5 asr video_tmp2 00026e b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00026f bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000270 95d5 asr video_tmp2 000271 fa14 bst snd_reg, 4 ; ========= BITSOUND (OP1: BIT 4) === 000272 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 000273 95d5 asr video_tmp2 000274 0f22 lsl video_tmp 000275 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 000276 f408 brcc pc+2 000277 2127 and video_tmp,mask_register ; 30. byte 000278 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000279 9525 asr video_tmp 00027a 9493 inc video_ptr_l 00027b bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 00027c 9525 asr video_tmp 00027d ba98 out ADDRL,video_ptr_l ; output low address 00027e bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 00027f 9525 asr video_tmp 000280 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000281 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 000282 9525 asr video_tmp 000283 f850 bld video_PORTE,SOUND ; ========= BITSOUND (OP2: BIT 4) === 000284 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000285 9525 asr video_tmp 000286 0fdd lsl video_tmp2 000287 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000288 f408 brcc pc+2 000289 21d7 and video_tmp2,mask_register ; 31.byte 00028a bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 00028b 95d5 asr video_tmp2 00028c 9493 inc video_ptr_l 00028d bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 00028e 95d5 asr video_tmp2 00028f ba98 out ADDRL,video_ptr_l ; output low address 000290 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000291 95d5 asr video_tmp2 000292 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000293 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000294 95d5 asr video_tmp2 000295 + SEND_SOUND ; ========= BITSOUND (OP3: BIT 4) === 000295 b857 out PORTE,video_PORTE ; prepared sound port (via T bit) -> out .endmacro 000296 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 000297 95d5 asr video_tmp2 000298 0f22 lsl video_tmp 000299 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00029a f408 brcc pc+2 00029b 2127 and video_tmp,mask_register ; 32. byte 00029c bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 00029d 9525 asr video_tmp 00029e 9493 inc video_ptr_l 00029f bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0002a0 9525 asr video_tmp 0002a1 ba98 out ADDRL,video_ptr_l ; output low address 0002a2 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0002a3 9525 asr video_tmp 0002a4 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0002a5 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0002a6 9525 asr video_tmp 0002a7 0000 nop ; ========= BITSOUND (NOP) === 0002a8 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0002a9 9525 asr video_tmp 0002aa 0fdd lsl video_tmp2 0002ab bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0002ac f408 brcc pc+2 0002ad 21d7 and video_tmp2,mask_register ; 33.byte 0002ae bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0002af 95d5 asr video_tmp2 0002b0 9493 inc video_ptr_l 0002b1 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0002b2 95d5 asr video_tmp2 0002b3 ba98 out ADDRL,video_ptr_l ; output low address 0002b4 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 0002b5 95d5 asr video_tmp2 0002b6 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0002b7 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 0002b8 95d5 asr video_tmp2 0002b9 0000 nop ; ========= BITSOUND (NOP) === 0002ba bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 0002bb 95d5 asr video_tmp2 0002bc 0f22 lsl video_tmp 0002bd bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 0002be f408 brcc pc+2 0002bf 2127 and video_tmp,mask_register ; 34. byte 0002c0 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 0002c1 9525 asr video_tmp 0002c2 9493 inc video_ptr_l 0002c3 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0002c4 9525 asr video_tmp 0002c5 ba98 out ADDRL,video_ptr_l ; output low address 0002c6 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0002c7 9525 asr video_tmp 0002c8 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0002c9 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0002ca 9525 asr video_tmp 0002cb 0000 nop ; ========= BITSOUND (NOP) === 0002cc bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0002cd 9525 asr video_tmp 0002ce 0fdd lsl video_tmp2 0002cf bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0002d0 f408 brcc pc+2 0002d1 21d7 and video_tmp2,mask_register ; 35.byte 0002d2 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0002d3 95d5 asr video_tmp2 0002d4 9493 inc video_ptr_l 0002d5 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0002d6 95d5 asr video_tmp2 0002d7 ba98 out ADDRL,video_ptr_l ; output low address 0002d8 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 0002d9 95d5 asr video_tmp2 0002da b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0002db bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 0002dc 95d5 asr video_tmp2 0002dd 0000 nop ; ========= BITSOUND (NOP) === 0002de bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 0002df 95d5 asr video_tmp2 0002e0 0f22 lsl video_tmp 0002e1 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 0002e2 f408 brcc pc+2 0002e3 2127 and video_tmp,mask_register ; 36. byte 0002e4 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 0002e5 9525 asr video_tmp 0002e6 9493 inc video_ptr_l 0002e7 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 0002e8 9525 asr video_tmp 0002e9 ba98 out ADDRL,video_ptr_l ; output low address 0002ea bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 0002eb 9525 asr video_tmp 0002ec b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0002ed bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0002ee 9525 asr video_tmp 0002ef 0000 nop ; ========= BITSOUND (NOP) === 0002f0 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0002f1 9525 asr video_tmp 0002f2 0fdd lsl video_tmp2 0002f3 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0002f4 f408 brcc pc+2 0002f5 21d7 and video_tmp2,mask_register ; 37.byte 0002f6 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0002f7 95d5 asr video_tmp2 0002f8 9493 inc video_ptr_l 0002f9 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0002fa 95d5 asr video_tmp2 0002fb ba98 out ADDRL,video_ptr_l ; output low address 0002fc bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 0002fd 95d5 asr video_tmp2 0002fe b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0002ff bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000300 95d5 asr video_tmp2 000301 fa15 bst snd_reg, 5 ; ========= BITSOUND (OP1: BIT 5) === 000302 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 000303 95d5 asr video_tmp2 000304 0f22 lsl video_tmp 000305 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 000306 f408 brcc pc+2 000307 2127 and video_tmp,mask_register ; 38. byte 000308 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000309 9525 asr video_tmp 00030a 9493 inc video_ptr_l 00030b bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 00030c 9525 asr video_tmp 00030d ba98 out ADDRL,video_ptr_l ; output low address 00030e bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 00030f 9525 asr video_tmp 000310 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000311 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 000312 9525 asr video_tmp 000313 f850 bld video_PORTE,SOUND ; ========= BITSOUND (OP2: BIT 5) === 000314 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000315 9525 asr video_tmp 000316 0fdd lsl video_tmp2 000317 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000318 f408 brcc pc+2 000319 21d7 and video_tmp2,mask_register ; 39.byte 00031a bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 00031b 95d5 asr video_tmp2 00031c 9493 inc video_ptr_l 00031d bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 00031e 95d5 asr video_tmp2 00031f ba98 out ADDRL,video_ptr_l ; output low address 000320 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000321 95d5 asr video_tmp2 000322 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000323 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000324 95d5 asr video_tmp2 000325 + SEND_SOUND ; ========= BITSOUND (OP3: BIT 5) === 000325 b857 out PORTE,video_PORTE ; prepared sound port (via T bit) -> out .endmacro 000326 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 000327 95d5 asr video_tmp2 000328 0f22 lsl video_tmp 000329 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00032a f408 brcc pc+2 00032b 2127 and video_tmp,mask_register ; 40. byte 00032c bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 00032d 9525 asr video_tmp 00032e 9493 inc video_ptr_l 00032f bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000330 9525 asr video_tmp 000331 ba98 out ADDRL,video_ptr_l ; output low address 000332 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 000333 9525 asr video_tmp 000334 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000335 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 000336 9525 asr video_tmp 000337 0000 nop ; ========= BITSOUND (NOP) === 000338 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000339 9525 asr video_tmp 00033a 0fdd lsl video_tmp2 00033b bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 00033c f408 brcc pc+2 00033d 21d7 and video_tmp2,mask_register ; 41.byte 00033e bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 00033f 95d5 asr video_tmp2 000340 9493 inc video_ptr_l 000341 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000342 95d5 asr video_tmp2 000343 ba98 out ADDRL,video_ptr_l ; output low address 000344 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000345 95d5 asr video_tmp2 000346 b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000347 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000348 95d5 asr video_tmp2 000349 0000 nop ; ========= BITSOUND (NOP) === 00034a bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00034b 95d5 asr video_tmp2 00034c 0f22 lsl video_tmp 00034d bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 00034e f408 brcc pc+2 00034f 2127 and video_tmp,mask_register ; 42. byte 000350 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000351 9525 asr video_tmp 000352 9493 inc video_ptr_l 000353 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000354 9525 asr video_tmp 000355 ba98 out ADDRL,video_ptr_l ; output low address 000356 bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 000357 9525 asr video_tmp 000358 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 000359 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 00035a 9525 asr video_tmp 00035b 0000 nop ; ========= BITSOUND (NOP) === 00035c bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 00035d 9525 asr video_tmp 00035e 0fdd lsl video_tmp2 00035f bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000360 f408 brcc pc+2 000361 21d7 and video_tmp2,mask_register ; 43.byte 000362 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 000363 95d5 asr video_tmp2 000364 9493 inc video_ptr_l 000365 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 000366 95d5 asr video_tmp2 000367 ba98 out ADDRL,video_ptr_l ; output low address 000368 bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 000369 95d5 asr video_tmp2 00036a b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00036b bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 00036c 95d5 asr video_tmp2 00036d 0000 nop ; ========= BITSOUND (NOP) === 00036e bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 00036f 95d5 asr video_tmp2 000370 0f22 lsl video_tmp 000371 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 000372 f408 brcc pc+2 000373 2127 and video_tmp,mask_register ; 44. byte 000374 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000375 9525 asr video_tmp 000376 9493 inc video_ptr_l 000377 bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 000378 9525 asr video_tmp 000379 ba98 out ADDRL,video_ptr_l ; output low address 00037a bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 00037b 9525 asr video_tmp 00037c b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00037d bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 00037e 9525 asr video_tmp 00037f 0000 nop ; ========= BITSOUND (NOP) === 000380 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 000381 9525 asr video_tmp 000382 0fdd lsl video_tmp2 000383 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 000384 f408 brcc pc+2 000385 21d7 and video_tmp2,mask_register ; 45.byte 000386 bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 000387 95d5 asr video_tmp2 000388 9493 inc video_ptr_l 000389 bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 00038a 95d5 asr video_tmp2 00038b ba98 out ADDRL,video_ptr_l ; output low address 00038c bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 00038d 95d5 asr video_tmp2 00038e b329 in video_tmp,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 00038f bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 000390 95d5 asr video_tmp2 000391 fa16 bst snd_reg, 6 ; ========= BITSOUND (OP1: BIT 6) === 000392 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 000393 95d5 asr video_tmp2 000394 0f22 lsl video_tmp 000395 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 000396 f408 brcc pc+2 000397 2127 and video_tmp,mask_register ; 46. byte 000398 bb22 out VIDEOPORT,video_tmp ; 0.bit first byte 000399 9525 asr video_tmp 00039a 9493 inc video_ptr_l 00039b bb22 out VIDEOPORT,video_tmp ; 1.bit first byte 00039c 9525 asr video_tmp 00039d ba98 out ADDRL,video_ptr_l ; output low address 00039e bb22 out VIDEOPORT,video_tmp ; 2.bit first byte 00039f 9525 asr video_tmp 0003a0 b3d9 in video_tmp2,PINA ; load next 6 pixels :X X 5 4 3 2 1 0 0003a1 bb22 out VIDEOPORT,video_tmp ; 3.bit first byte 0003a2 9525 asr video_tmp 0003a3 f850 bld video_PORTE,SOUND ; ========= BITSOUND (OP2: BIT 6) === 0003a4 bb22 out VIDEOPORT,video_tmp ; 4.bit first byte 0003a5 9525 asr video_tmp 0003a6 0fdd lsl video_tmp2 0003a7 bb22 out VIDEOPORT,video_tmp ; 5.bit first byte 0003a8 f408 brcc pc+2 0003a9 21d7 and video_tmp2,mask_register ; 47.byte ; last byte on microline 0003aa bbd2 out VIDEOPORT,video_tmp2 ; 0.bit second byte 0003ab 95d5 asr video_tmp2 0003ac 0000 nop 0003ad bbd2 out VIDEOPORT,video_tmp2 ; 1.bit second byte 0003ae 95d5 asr video_tmp2 0003af bbd2 out VIDEOPORT,video_tmp2 ; 2.bit second byte 0003b0 95d5 asr video_tmp2 0003b1 e121 ldi video_tmp,17 ; skip also next 16 bytes + normal increment => 17 ; after 48 shown bytes is 16 bytes video-memory gap 0003b2 bbd2 out VIDEOPORT,video_tmp2 ; 3.bit second byte 0003b3 95d5 asr video_tmp2 0003b4 + SEND_SOUND ; ========= BITSOUND (OP3: BIT 6) === 0003b4 b857 out PORTE,video_PORTE ; prepared sound port (via T bit) -> out .endmacro 0003b5 bbd2 out VIDEOPORT,video_tmp2 ; 4.bit second byte 0003b6 95d5 asr video_tmp2 0003b7 0e92 add video_ptr_l,video_tmp ; next microline in PMD videomemory 0003b8 bbd2 out VIDEOPORT,video_tmp2 ; 5.bit second byte 0003b9 f508 brcc fast_end 0003ba 1d3a adc video_ptr_h,_zero 0003bb baa2 out VIDEOPORT,_zero ; blank-> video_data:=0 0003bc + TIMER0_START 0003bc bea2 out TCNT0,_zero 0003bd e029 ldi video_tmp, 0b00001001 ; run TCCR0 at CLK, CTC mode 2 0003be bf23 out TCCR0, video_tmp .endmacro 0003bf 3d30 cpi video_ptr_h,0xc0+16 0003c0 f498 brsh skip_scan 0003c1 b3db in video_tmp2,PORTA 0003c2 + MEMRD_deactive 0003c2 9a3a sbi PORTE,MEMRD .endmacro 0003c3 babb out PORTA,_255 0003c4 c000 rjmp pc+1 0003c5 c000 rjmp pc+1 0003c6 c000 rjmp pc+1 0003c7 c000 rjmp pc+1 0003c8 c000 rjmp pc+1 0003c9 93cf push YL ; some time to pullup to drain capacitances on wires, if keyboard is off 0003ca b3c5 in YL, ADDRH 0003cb 70cf andi YL, 0b1111 ; low nibble (16 cols) 0003cc 5fc0 subi YL, low( -kb_cols_real ) 0003cd b329 in video_tmp,DATAIN 0003ce bbdb out PORTA, video_tmp2 0003cf + MEMRD_active 0003cf 983a cbi PORTE,MEMRD .endmacro 0003d0 e0d2 ldi YH, high( kb_cols_real ) 0003d1 772f andi video_tmp, 0x7f 0003d2 8328 st Y,video_tmp 0003d3 91cf pop YL skip_scan: 0003d4 912f pop video_tmp 0003d5 bb25 out ADDRH,video_tmp 0003d6 912f pop video_tmp 0003d7 bb28 out ADDRL,video_tmp 0003d8 be6f out SREG,video_SREG 0003d9 e027 ldi bit_position,7 0003da 9518 reti fast_end: 0003db baa2 out VIDEOPORT,_zero ; blank-> video_data:=0 0003dc + TIMER0_START 0003dc bea2 out TCNT0,_zero 0003dd e029 ldi video_tmp, 0b00001001 ; run TCCR0 at CLK, CTC mode 2 0003de bf23 out TCCR0, video_tmp .endmacro 0003df 912f pop video_tmp 0003e0 bb25 out ADDRH,video_tmp 0003e1 912f pop video_tmp 0003e2 bb28 out ADDRL,video_tmp 0003e3 e027 ldi bit_position,7 _reti: 0003e4 be6f out SREG,video_SREG 0003e5 9b5f sbis UCSRA,RXC ; USART received char from keyboard? 0003e6 9518 reti ; ; PMDEmu - AVR based emulator of Czechoslovak microcomputer PMD-85 originally based on I8080 ; Copyright (C) 2023 Peter Chrenko <stare********@gmail.com>, Topolcany, Slovakia ; ; KBD.PHP ; included from video.php .def kbd_reg = r20 ;kbd.asm shared with BC .def kbd_flags_reg = r21 ;kbd.asm .def kbd_tmp = r22 .macro STORE_KBD_REGS ; SREG is saved in video_SREG register push kbd_reg push kbd_flags_reg push ZH push ZL; save Z push kbd_tmp .endmacro .macro RESTORE_KBD_REGS pop kbd_tmp pop ZL pop ZH ; restore Z pop kbd_flags_reg pop kbd_reg out SREG,video_SREG ; must be .endmacro ;################################################################ ; routine executed if USART received some char 0003e7 + STORE_KBD_REGS 0003e7 934f push kbd_reg 0003e8 935f push kbd_flags_reg 0003e9 93ff push ZH 0003ea 93ef push ZL; save Z 0003eb 936f push kbd_tmp .endmacro 0003ec b16b in kbd_tmp,UCSRA 0003ed b14c in kbd_reg,UDR ; kb_data from USART 0003ee 7168 andi kbd_tmp, (1<<FE)|(1<<DOR) ; |(1<<UPE) 0003ef f5b9 brne kb_end ; USART receiver error detected 0003f0 9150 0232 lds kbd_flags_reg,kbd_flags 0003f2 3f40 cpi kbd_reg,0xf0 ; if 0xF0 received we know key is released, othervise is pressed. 0003f3 f1e9 breq f0_handle ; kbd_reg = scan code (PC keyboard) ; ideme urcit v ktorom riadku a ktorom stlpci sa ma nachadzat dana klavesa 0003f4 fb57 bst kbd_flags_reg,F0_bit ; 0 = pressed , 1 = released 0003f5 775f andi kbd_flags_reg, ~(1<< F0_bit); clear it 0003f6 3141 cpi kbd_reg,0x11 ; ALT ? 0003f7 f1e9 breq alt_handle 0003f8 fd54 sbrc kbd_flags_reg,ALT_bit 0003f9 c00b rjmp alt_isnt_pressed 0003fa f166 brts kb_end ; return if released ; in kbd_reg is scan code (PC keyboard) 0003fb e061 ldi kbd_tmp,1 ; PMD-85/1 0003fc 3146 cpi kbd_reg,0x16 ; ALT+1 ===> RESET PMD-85=2 0003fd f1e9 breq PMD_RESET1 ;reboot_pmd 0003fe 314e cpi kbd_reg,0x1e ; ALT+2 ===> RESET PMD-85=2 0003ff f1d1 breq PMD_RESET2 ;reboot_pmd 000400 3246 cpi kbd_reg,0x26 ; ALT+3 ===> RESET PMD-85=2 w/out basic 000401 f1b9 breq PMD_RESET3 ;reboot_pmd 000402 314b cpi kbd_reg,0x1b ; ALT+S ===> dynamic stop 000403 f1d1 breq alt_s_handle 000404 c022 rjmp kb_end alt_isnt_pressed: ;sts dynamic_stop,_zero 000405 3142 cpi kbd_reg,0x12 ; left shift ? 000406 f161 breq shift_handle 000407 3549 cpi kbd_reg,0x59 ; right shift ? 000408 f151 breq shift_handle 000409 3844 cpi kbd_reg,0x84 00040a f4e0 brsh kb_end ; not in look-up table --> ignore key 00040b 3144 cpi kbd_reg,0x14 ; CTRL ? 00040c f151 breq stop_handle ; kbd_reg = SCAN klavesy co bola prave zatlacena/pustena podla flagu T ; T <=> 0 == pressed , 1 == released 00040d e1fa ldi ZH, high( kb_lookup << 1) 00040e efee ldi ZL, low(kb_lookup << 1) 00040f 0fe4 add ZL,kbd_reg 000410 1dfa adc ZH,_zero ; Z je adresa kb_lookup + 1*SCAN_CODE 000411 9164 lpm kbd_tmp,Z 000412 e0e0 ldi ZL, low ( kb_cols ) 000413 e0f2 ldi ZH, high ( kb_cols ) 000414 354a cpi kbd_reg,0x5A ; second EOL(ENTER) handle 000415 f419 brne _no_enter_hit ; ative/deactive also EOL on r4:13 000416 8545 ldd kbd_reg, Z + 13 ; load 13th column 000417 f944 bld kbd_reg,4 ; copy bit , EOL2 (4.bit) 000418 8745 std Z + 13,kbd_reg ; store 13th column _no_enter_hit: 000419 2f46 mov kbd_reg,kbd_tmp 00041a 706f andi kbd_tmp,0x0f ; row mask : 0 invalid , 1,2,4,8 and 15 (must ---> 16) - valid 00041b f059 breq kb_nothing ; 0 == not used key 00041c 9542 swap kbd_reg 00041d 704f andi kbd_reg,0x0f ; now: ; kbd_tmp = part of row mask ; kbd_reg = column 00041e 306e cpi kbd_tmp,14 ; 5th row? => C := 0 if == 15, C:=1 if < 15 00041f 4f6f sbci kbd_tmp,-1 000420 0fe4 add ZL, kbd_reg ;Z = kb_cols + kbd_reg (column address) 000421 8140 ld kbd_reg,Z 000422 2b46 or kbd_reg,kbd_tmp 000423 f016 brts kb_write_one 000424 9560 com kbd_tmp 000425 2346 and kbd_reg,kbd_tmp 000426 8340 kb_write_one: st Z,kbd_reg kb_nothing: kb_end: 000427 9350 0232 sts kbd_flags,kbd_flags_reg 000429 + RESTORE_KBD_REGS 000429 916f pop kbd_tmp 00042a 91ef pop ZL 00042b 91ff pop ZH ; restore Z 00042c 915f pop kbd_flags_reg 00042d 914f pop kbd_reg 00042e be6f out SREG,video_SREG ; must be .endmacro 00042f be6f out SREG,video_SREG 000430 9518 reti f0_handle: 000431 6850 ori kbd_flags_reg, (1<< F0_bit) ; store it (released/pressed bit) 000432 cff4 rjmp kb_end shift_handle: 000433 f955 bld kbd_flags_reg,SHIFT_bit ; store SHIFT bit (5. bit) 000434 cff2 rjmp kb_end alt_handle: 000435 f954 bld kbd_flags_reg,ALT_bit ; store ALT bit, ALT := T 000436 cff0 rjmp kb_end stop_handle: 000437 f956 bld kbd_flags_reg,6 ; copy to STOP bit 000438 cfee rjmp kb_end ; end 000439 9563 PMD_RESET3: inc kbd_tmp 00043a 9563 PMD_RESET2: inc kbd_tmp PMD_RESET1: 00043b 9360 022e sts pmd_version,kbd_tmp ;ldi ZL,0 ;ldi ZH,0xb0 00043d cbc2 rjmp 0 ; change_pmd_type alt_s_handle: 00043e f346 brts kb_end 00043f 9140 022d lds kbd_reg,stop_flag 000441 9540 com kbd_reg 000442 9340 022d sts stop_flag,kbd_reg 000444 f311 breq kb_end ; if stop_flag is zero 000445 + RESTORE_KBD_REGS ; if stop_flag is non zero ===> dynamic stop 000445 916f pop kbd_tmp 000446 91ef pop ZL 000447 91ff pop ZH ; restore Z 000448 915f pop kbd_flags_reg 000449 914f pop kbd_reg 00044a be6f out SREG,video_SREG ; must be .endmacro 00044b 9478 sei 00044c d0b7 rcall video_osd ; print intro text 00044d 9518 reti 00044e text_info: .db " P= PST B AAA M= ETE U LLL D= TAL I TTT -= ER " 00044e 2020 00044f 2020 000450 2020 000451 2020 000452 2020 000453 2020 000454 2020 000455 5020 000456 203d 000457 5350 000458 2054 000459 2042 00045a 4141 00045b 2041 00045c 4d20 00045d 203d 00045e 5445 00045f 2045 000460 2055 000461 4c4c 000462 204c 000463 4420 000464 203d 000465 4154 000466 204c 000467 2049 000468 5454 000469 2054 00046a 2d20 00046b 203d 00046c 5245 00046d 2020 .db "L +++ 8= RE+ T 12S 5= P4 : , = CO2 P3T O= HC1 2 M H N= RI9 4 DPI = ET4 . -MS A= NA9 5 8D T= KC7 . 5-I -= OE3 2 /8N M= @3 0 15F E= G5 2 /O G= M0 3 2 A= A8 8= I 1 B 5= L 5 A 1= . : S 5= C 2 / O 0 O M S " 00046e 204c 00046f 2b2b 000470 202b 000471 3820 000472 203d 000473 4552 000474 202b 000475 2054 000476 3231 000477 2053 000478 3520 000479 203d 00047a 5020 00047b 2034 00047c 203a 00047d 2c20 00047e 2020 00047f 2020 000480 203d 000481 4f43 000482 2032 000483 2020 000484 3350 000485 2054 000486 4f20 000487 203d 000488 4348 000489 2031 00048a 2032 00048b 204d 00048c 2048 00048d 4e20 00048e 203d 00048f 4952 000490 2039 000491 2034 000492 5044 000493 2049 000494 2020 000495 203d 000496 5445 000497 2034 000498 202e 000499 4d2d 00049a 2053 00049b 4120 00049c 203d 00049d 414e 00049e 2039 00049f 2035 0004a0 4438 0004a1 2020 0004a2 5420 0004a3 203d 0004a4 434b 0004a5 2037 0004a6 202e 0004a7 2d35 0004a8 2049 0004a9 2d20 0004aa 203d 0004ab 454f 0004ac 2033 0004ad 2032 0004ae 382f 0004af 204e 0004b0 4d20 0004b1 203d 0004b2 4020 0004b3 2033 0004b4 2030 0004b5 3531 0004b6 2046 0004b7 4520 0004b8 203d 0004b9 4720 0004ba 2035 0004bb 2032 0004bc 2f20 0004bd 204f 0004be 4720 0004bf 203d 0004c0 4d20 0004c1 2030 0004c2 2033 0004c3 3220 0004c4 2020 0004c5 4120 0004c6 203d 0004c7 4120 0004c8 2038 0004c9 2020 0004ca 2020 0004cb 2020 0004cc 3820 0004cd 203d 0004ce 4920 0004cf 2020 0004d0 2031 0004d1 4220 0004d2 2020 0004d3 3520 0004d4 203d 0004d5 4c20 0004d6 2020 0004d7 2035 0004d8 4120 0004d9 2020 0004da 3120 0004db 203d 0004dc 2e20 0004dd 2020 0004de 203a 0004df 5320 0004e0 2020 0004e1 3520 0004e2 203d 0004e3 4320 0004e4 2020 0004e5 2032 0004e6 2f20 0004e7 2020 0004e8 2020 0004e9 2020 0004ea 4f20 0004eb 2020 0004ec 2030 0004ed 4f20 0004ee 2020 0004ef 2020 0004f0 2020 0004f1 4d20 0004f2 2020 0004f3 2020 0004f4 5320 0004f5 2020 0004f6 2020 0004f7 2020 0004f8 2020 0004f9 2020 0004fa 2020 0004fb 2020 0004fc 2020 0004fd 2020 0004fe 2020 0004ff 2020 000500 2020 000501 2020 000502 2020 000503 2020 ; OSD routines video_osd: .def OSDL = r20 .def OSDH = r21 .def ptrl = r22 .def ptrh = r23 .equ chr_space = 0x40 000504 936f push ptrl 000505 937f push ptrh 000506 934f push OSDL 000507 935f push OSDH 000508 93ef push ZL 000509 93ff push ZH 00050a 938f push r24 00050b 939f push r25 00050c b3ee in ZL,kbd_portC ; disable sound 00050d 93ef push ZL 00050e baae out kbd_portC,_zero 00050f b3e2 in ZL,CONTROLRAM 000510 93ef push ZL 000511 b3e8 in ZL,ADDRL 000512 93ef push ZL 000513 b3e5 in ZL,ADDRH 000514 93ef push ZL 000515 b3ea in ZL,DATADIR 000516 93ef push ZL 000517 b3eb in ZL,DATAOUT 000518 93ef push ZL 000519 b7ef in ZL,SREG 00051a 93ef push ZL osd_read: 00051b ec6b ldi ptrl,low( 0xCDCB ) 00051c ec7d ldi ptrh,high ( 0xCDCB ) 00051d baaa out DATADIR,_zero ; input for read operation 00051e + MEMRD_active 00051e 983a cbi PORTE,MEMRD .endmacro 00051f e85c ldi OSDH, 140 osd_read_y: 000520 e14a ldi OSDL, 26 osd_read_x: 000521 bb75 out ADDRH,ptrh 000522 bb68 out ADDRL,ptrl ; MDELAY(SPENT=0,ADD=2) 000523 c000 rjmp PC+1 ; MDELAY 000524 b3e9 in ZL,DATAIN 000525 537d subi ptrh, (high ( 0xCDCB )-0x90) 000526 bbeb out PORTA, ZL 000527 bb68 out ADDRL,ptrl ; output 16 bit address 000528 bb75 out ADDRH,ptrh busWait1: 000529 b51c in tmp_reg, TCNT1L 00052a 371f cpi tmp_reg,138 - 11 00052b f018 brlo busGo1 00052c b51d in tmp_reg, TCNT1H 00052d 3010 cpi tmp_reg,0 ; test 0 00052e f3d1 breq busWait1 busGo1: 00052f + MEMRD_deactive 00052f 9a3a sbi PORTE,MEMRD .endmacro 000530 baba out DDRA,_255 000531 + MEMWR_pulse 000531 9839 cbi PORTE,MEMWR 000532 9a39 sbi PORTE,MEMWR .endmacro 000533 baaa out DDRA,_zero ; PORTA input 000534 + MEMRD_active 000534 983a cbi PORTE,MEMRD .endmacro 000535 9563 inc ptrl 000536 5c73 subi ptrh, -(high ( 0xCDCB )-0x90) 000537 954a dec OSDL 000538 f741 brne osd_read_x 000539 5d6a subi ptrl,low(-38) 00053a 4f7f sbci ptrh,high(-38) 00053b 955a dec OSDH 00053c f719 brne osd_read_y ; here we print text 00053d ec6b ldi ptrl,low( 0xCDCB ) 00053e ec7d ldi ptrh,high ( 0xCDCB ) 00053f e9ec ldi ZL,low ( text_info * 2 ) 000540 e0f8 ldi ZH,high( text_info * 2 ) osd_print_char_loop: 000541 9145 lpm OSDL,Z+ ;compute char address 000542 2755 clr OSDH 000543 0f44 lsl OSDL ; char is always with 7th bit cleared 000544 0f44 lsl OSDL 000545 1f55 rol OSDH 000546 0f44 lsl OSDL 000547 1f55 rol OSDH ; Y *= 8 000548 575b subi OSDH,-133 ; Y += 0x8500 000549 e099 ldi r25,9 ; 9+1=10 microlines 00054a e480 ldi r24, chr_space 00054b c006 rjmp osd_blank osd_one_char: 00054c bb55 out ADDRH,OSDH 00054d bb48 out ADDRL,OSDL 00054e 5f4f subi OSDL, low(-1) 00054f 4f5f sbci OSDH, high(-1) ; MDELAY(SPENT=2,ADD=0) 000550 b389 in r24,DATAIN 000551 6480 ori r24,0x40 ; add bright attribute osd_blank: 000552 bb8b out PORTA, r24 000553 bb68 out ADDRL,ptrl ; output 16 bit address 000554 bb75 out ADDRH,ptrh busWait2: 000555 b51c in tmp_reg, TCNT1L 000556 371f cpi tmp_reg,138 - 11 000557 f018 brlo busGo2 000558 b51d in tmp_reg, TCNT1H 000559 3010 cpi tmp_reg,0 ; test 0 00055a f3d1 breq busWait2 busGo2: 00055b + MEMRD_deactive 00055b 9a3a sbi PORTE,MEMRD .endmacro 00055c baba out DDRA,_255 00055d + MEMWR_pulse 00055d 9839 cbi PORTE,MEMWR 00055e 9a39 sbi PORTE,MEMWR .endmacro 00055f baaa out DDRA,_zero ; PORTA input 000560 + MEMRD_active 000560 983a cbi PORTE,MEMRD .endmacro 000561 5c60 subi ptrl,low(-(64)) 000562 4f7f sbci ptrh,high(-(64)) 000563 959a dec r25 000564 f739 brne osd_one_char 000565 e480 ldi r24, chr_space ; 10th microline 000566 bb8b out PORTA, r24 000567 bb68 out ADDRL,ptrl ; output 16 bit address 000568 bb75 out ADDRH,ptrh busWait3: 000569 b51c in tmp_reg, TCNT1L 00056a 371f cpi tmp_reg,138 - 11 00056b f018 brlo busGo3 00056c b51d in tmp_reg, TCNT1H 00056d 3010 cpi tmp_reg,0 ; test 0 00056e f3d1 breq busWait3 busGo3: 00056f + MEMRD_deactive 00056f 9a3a sbi PORTE,MEMRD .endmacro 000570 baba out DDRA,_255 000571 + MEMWR_pulse 000571 9839 cbi PORTE,MEMWR 000572 9a39 sbi PORTE,MEMWR .endmacro 000573 baaa out DDRA,_zero ; PORTA input 000574 + MEMRD_active 000574 983a cbi PORTE,MEMRD .endmacro 000575 5c60 subi ptrl,low(-(64)) 000576 4f7f sbci ptrh,high(-(64)) 000577 3f70 cpi ptrh,high(0xCDCB + 14*64*10) 000578 f408 brsh obskok1 000579 cfc7 rjmp osd_print_char_loop obskok1: ;brlo osd_print_char_loop 00057a 5f6f subi ptrl, low(8959) 00057b 4272 sbci ptrh, high(8959) 00057c 3e65 cpi ptrl, low(0xCDCB + 26) 00057d f408 brsh obskok2 00057e cfc2 rjmp osd_print_char_loop obskok2: ; brne osd_print_char_loop dynamic_stop: 00057f 91e0 022d lds ZL,stop_flag 000581 92bc st X,_255 ; soud off 000582 95a3 inc snd_pointerWR_lo ; modulo 256 000583 11ea cpse ZL,_zero 000584 cffa rjmp dynamic_stop osd_write: 000585 ec6b ldi ptrl,low( 0xCDCB ) 000586 ec7d ldi ptrh,high ( 0xCDCB ) 000587 baaa out DATADIR,_zero ; input for read operation 000588 + MEMRD_active 000588 983a cbi PORTE,MEMRD .endmacro 000589 e85c ldi OSDH, 140 osd_write_y: 00058a e14a ldi OSDL, 26 osd_write_x: 00058b 537d subi ptrh, (high ( 0xCDCB )-0x90) 00058c bb75 out ADDRH,ptrh 00058d bb68 out ADDRL,ptrl 00058e 5c73 subi ptrh, -(high ( 0xCDCB )-0x90) ; MDELAY(SPENT=1,ADD=1) 00058f 0000 nop ; MDELAY 000590 b3e9 in ZL,DATAIN 000591 bbeb out PORTA, ZL 000592 bb68 out ADDRL,ptrl ; output 16 bit address 000593 bb75 out ADDRH,ptrh busWait4: 000594 b51c in tmp_reg, TCNT1L 000595 371f cpi tmp_reg,138 - 11 000596 f018 brlo busGo4 000597 b51d in tmp_reg, TCNT1H 000598 3010 cpi tmp_reg,0 ; test 0 000599 f3d1 breq busWait4 busGo4: 00059a + MEMRD_deactive 00059a 9a3a sbi PORTE,MEMRD .endmacro 00059b baba out DDRA,_255 00059c + MEMWR_pulse 00059c 9839 cbi PORTE,MEMWR 00059d 9a39 sbi PORTE,MEMWR .endmacro 00059e baaa out DDRA,_zero ; PORTA input 00059f + MEMRD_active 00059f 983a cbi PORTE,MEMRD .endmacro 0005a0 9563 inc ptrl 0005a1 954a dec OSDL 0005a2 f741 brne osd_write_x 0005a3 5d6a subi ptrl,low(-38) 0005a4 4f7f sbci ptrh,high(-38) 0005a5 955a dec OSDH 0005a6 f719 brne osd_write_y 0005a7 91ef pop ZL 0005a8 bfef out SREG,ZL 0005a9 91ef pop ZL 0005aa bbeb out DATAOUT,ZL 0005ab 91ef pop ZL 0005ac bbea out DATADIR,ZL 0005ad 91ef pop ZL 0005ae bbe5 out ADDRH,ZL 0005af 91ef pop ZL 0005b0 bbe8 out ADDRL,ZL 0005b1 91ef pop ZL 0005b2 bbe2 out CONTROLRAM,ZL 0005b3 91ef pop ZL 0005b4 bbee out kbd_portC,ZL 0005b5 919f pop r25 0005b6 918f pop r24 0005b7 91ff pop ZH 0005b8 91ef pop ZL 0005b9 915f pop OSDH 0005ba 914f pop OSDL 0005bb 917f pop ptrh 0005bc 916f pop ptrl 0005bd 9508 ret 0005be e26c wait1: ldi kbd_tmp,(8*6*3-10)/3 ; ; 3 = CALL ; 3 = RET ; 1 = LDI ; 3 = portD obsluha 0005bf 956a wait1_precise: dec kbd_tmp 0005c0 f7f1 brne wait1_precise 0005c1 9508 RET after_reset: ; PD0 = KBD_DATA(RXD)(IN) ; PD1 = VIDEO ; PD2 = A16 ; PD3 = /CS0 (RAM_FLASH0) ; PD4 = KBD_CLK(IN) ; PD5 = SYNC ; PD6 = A17 ; PD7 = BrighBright ; PE0 = BUZZER ; PE1 = /CS1 (/WE/FLASH1) ; PE2 = /OE 0005c2 b8b6 out DDRE,_255 0005c3 b8b7 out PORTE,_255 ; control bus = idle state 0005c4 bab4 out DDRC,_255 ; PORTC output (address) 0005c5 eeee ldi ZL,0b11101110 ; kbd in 0005c6 bbe1 out DDRD,ZL ; PORTD output (address,video,sync) ; ---------- inicialize PS/2 keyboard --------------------------------------------- 0005c7 e1e0 ldi r30,(1<<RXEN) 0005c8 b9ea out UCSRB,r30 0005c9 eee6 ldi r30,0b11100110 ; synchro mode enable 0005ca bde0 out UCSRC,r30 0005cb e7e0 ldi ZL,(1<<SHIFT_bit)|(1<<STOP_bit)|(1<<ALT_bit) ; all keys released 0005cc 93e0 0232 sts kbd_flags,ZL ; ---------- end of inicializing PS/2 keyboard --------------------------------------------- 0005ce 92a0 022d sts stop_flag, _zero ;---------------- inicialize video subsystem ------------------------------- 0005d0 e1e9 ldi r30,0b00011001 0005d1 bdee out TCCR1B,r30 0005d2 e8e2 ldi r30,0b10000010 0005d3 bdef out TCCR1A,r30 0005d4 e0e4 ldi r30,high(1180) ; ICR1 = TOP = 64 us 0005d5 bde5 out ICR1H,r30 0005d6 e9ec ldi r30,low(1180) 0005d7 bde4 out ICR1L,r30 0005d8 e0e4 ldi r30,high(1097) ; when sync goes active (low for PAL, high for NTSC) 0005d9 bdeb out OCR1AH,r30 0005da e4e9 ldi r30,low(1097) 0005db bdea out OCR1AL,r30 ; when start video generation routine ; TV LINE TOOK 1180 ticks 0005dc e020 ldi video_tmp,high(138) ; when interrupt for 0. bit 0005dd bd29 out OCR1BH,video_tmp 0005de e82a ldi video_tmp,low(138) 0005df bd28 out OCR1BL,video_tmp 0005e0 e9e3 ldi r30, 147 0005e1 bfe1 out OCR0,r30 ;prefill 0005e2 e2e1 ldi r30,0b00100001 ; enable interrupt on OCR1B (video routine) 0005e3 bfe9 out TIMSK,r30 ; Timer0 OCR0 enable int 0005e4 2499 clr video_ptr_l ; video address := 0xc000 0005e5 ec30 ldi video_ptr_h,0xc0 ; blink subsystem .equ blink_period = 50 ; 1 Hz 0005e6 2c7b mov mask_register,_255 0005e7 e3e2 ldi r30,blink_period 0005e8 93e0 0220 sts blink_counter,r30 0005ea e0b1 ldi XH, high(snd_buffer) 0005eb e0a0 ldi XL, low(snd_buffer) ; copy to snd_buffer, zeroes 0005ec 92ad st X+,_zero 0005ed 30a0 cpi XL, 0 0005ee f7e9 brne pc-2 ; inic: 0005ef e0b1 ldi XH, high(snd_buffer) 0005f0 2c2b mov portValue,_255 0005f1 27cc clr snd_pointerRD_lo 0005f2 e8e0 ldi ZL,0x80 0005f3 2fae mov snd_pointerWR_lo, ZL ;------------ USART 8251 transmitter speed emulation - for game HLIPA ;ldi ZL,165 ;out OCR0,ZL ;ldi ZL,0b00001101 ; run TCCR0 at CLK/1024, CTC mode ;out TCCR0,ZL ; this set TxRDY for first write UDR ; now setup stack 0005f4 e0e2 ldi ZL, 0b010 ; buzzer(pe0=0), /WE=1 (PE1=1), /OE=0 (PE2=1) 0005f5 2e5e mov video_PORTE,ZL 0005f6 92b0 0230 sts stack_pointer,_255 change_pmd_type: 0005f8 e5ef ldi r30, low(RAMEND) 0005f9 e0f2 ldi r31, high(RAMEND) 0005fa bfed out SPL,r30 0005fb bffe out SPH,r31 ; set STACK POINTER ;CHECK_PMD_VERSION 0005fc 91e0 022e lds ZL,pmd_version 0005fe 30e1 cpi ZL,1 0005ff f058 brlo set_pmd85_1 000600 30e4 cpi ZL,4 000601 f448 brsh set_pmd85_1 version_ok: 000602 + MEMRD_deactive 000602 9a3a sbi PORTE,MEMRD .endmacro 000603 babb out PORTA,_255 000604 dfb9 rcall WAIT1 000605 b3f9 in ZH, PINA 000606 74f0 andi ZH,64 ; test po resete na klavesu STOP 000607 f479 brne stop_ok 000608 95e3 inc ZL 000609 30e4 cpi ZL,4 00060a f451 brne inc_ok set_pmd85_1: 00060b efef ldi ZL,byte1(C_games_start-1) ;------------------- rewind tape 00060c 93e0 0225 sts mgf_pointer+0,ZL 00060e e6e7 ldi ZL,byte2(C_games_start-1) 00060f 93e0 0226 sts mgf_pointer+1,ZL 000611 e0e0 ldi ZL,byte3(C_games_start-1) 000612 93e0 0227 sts mgf_pointer+2,ZL 000614 e0e1 ldi ZL,1 000615 93e0 022e inc_ok: sts pmd_version,ZL stop_ok: 000617 + MEMRD_active 000617 983a cbi PORTE,MEMRD .endmacro 000618 9478 sei ; enable interrupt ; download ROM modul into SRAM from 0x8000 to 0x8ffff change_pmd_type2: .equ monitor_start = 0x8000 .equ monitor_go = 0x8000 .equ monitor_length = 0x1000 .equ C_monit1_start=0x00000 .equ C_monit2_start=0x01000 .equ C_basic1_start=0x02000 .equ C_basic2_start=0x04400 .equ C_games_start =0x06800 ; download monitor to SRAM from external FLASH ( 4KB ) 000619 e080 ldi _PCL,low(C_monit1_start) 00061a e090 ldi _PCH,high(C_monit1_start) 00061b 91e0 022e lds ZL, pmd_version 00061d fde1 sbrc ZL,1 00061e e190 ldi _PCH,high(C_monit2_start) 00061f e0e0 ldi ZL, low( monitor_start ) 000620 e8f0 ldi ZH, high( monitor_start ) ; _PC: source from first page in FLASH ; Z: destination in SRAM ; A: end source address ( high byte ) _monitor_download: 000621 bb88 out ADDRL,_PCL 000622 bb95 out ADDRH,_PCH busWait5: 000623 b51c in tmp_reg, TCNT1L 000624 371b cpi tmp_reg,138 - 15 000625 f018 brlo busGo5 000626 b51d in tmp_reg, TCNT1H 000627 3010 cpi tmp_reg,0 ; test 0 000628 f3d1 breq busWait5 busGo5: 000629 + SELECT_FLASH0_zeroPage 000629 9a8b sbi DDRD, RAM_SELECT 00062a baa2 out PORTD,_zero .endmacro 00062b c000 RJMP PC+1 ; FLASH is 90 ns, cycle is about 50 ns ==> must be 2 cycle delay 00062c c000 RJMP PC+1 ; FLASH is 90 ns, cycle is about 50 ns ==> must be 2 cycle delay 00062d c000 RJMP PC+1 ; EPROM is 120 ns, cycle is about 50 ns ==> must be 2 cycle delay ;RJMP PC+1 ; EPROM is 120 ns, cycle is about 50 ns ==> must be 2 cycle delay 00062e b349 in A,PINA 00062f 988b cbi DDRD, RAM_SELECT ; Select RAM 000630 9601 adiw _PCL,1 000631 bb4b out PORTA, A 000632 bbe8 out ADDRL,ZL ; output 16 bit address 000633 bbf5 out ADDRH,ZH busWait6: 000634 b51c in tmp_reg, TCNT1L 000635 371f cpi tmp_reg,138 - 11 000636 f018 brlo busGo6 000637 b51d in tmp_reg, TCNT1H 000638 3010 cpi tmp_reg,0 ; test 0 000639 f3d1 breq busWait6 busGo6: 00063a + MEMRD_deactive 00063a 9a3a sbi PORTE,MEMRD .endmacro 00063b baba out DDRA,_255 ; sbrc ZH,7 ; skip if address < 0x8000 ; sbrc ZH,6 ; skip if 6th bit is clear 00063c + MEMWR_pulse 00063c 9839 cbi PORTE,MEMWR 00063d 9a39 sbi PORTE,MEMWR .endmacro 00063e baaa out DDRA,_zero ; PORTA input 00063f + MEMRD_active 00063f 983a cbi PORTE,MEMRD .endmacro 000640 9631 adiw ZL,1 000641 39f0 cpi ZH, high(monitor_start+monitor_length) ; hi of ( end address + 1 ) 000642 f2f0 brlo _monitor_download ;lds ZL, pmd_version ;cpi ZL,1 ;breq PMD_RESET ; modifikacia monitoru PMD85/2 citanie mgf ;rcall pmd852_modification PMD_RESET: ; SHIFT & STOP & ALT released ; f0_received = false 000643 e0e0 ldi ZL, low ( kb_cols ) ; inicialize PMD keyboard model 000644 e0f2 ldi ZH, high ( kb_cols ) 000645 e14f ldi A, 0x1f ; 0b11111 000646 e75f ldi PSW, 0b1111111 ; kb_cols_real 000647 e110 ldi tmp_reg,16 ; 000648 8b50 kb_inic: std Z+16,PSW 000649 9341 st Z+,A ; 16 keyboard cols set to 0x1f 00064a 951a dec tmp_reg 00064b f7e1 brne kb_inic 00064c e080 ldi _PCL,low(monitor_go) 00064d e890 ldi _PCH,high(monitor_go) ; after RESET 00064e baaa out DDRA,_zero ; PORTA = vstup 00064f + SELECT_RAM 00064f 9a39 sbi PORTE,MEMWR ; MEMWR_deactive 000650 988b cbi DDRD, RAM_SELECT 000651 983a cbi PORTE,MEMRD ; MEMRD_active .endmacro 000652 baae out kbd_portC,_zero 000653 92a0 0223 sts kbd_ports + 2,_zero ; SPEAKER Off 000655 2c1b mov snd_reg,_255 000656 ee0f ldi clock,low(-17) ;clr clock 000657 e0c0 ldi snd_pointerRD_lo,0 000658 e8a0 ldi snd_pointerWR_lo,128 ;------------- begin of instruction cycle without handling PSW & flags ------ i_cycle: 000659 + RESTORE_ZH ; took some time 000659 e0fe ldi ZH, high(i_table) .endmacro i_cycle_turbo: 00065a bb88 out ADDRL,_PCL 00065b bb95 out ADDRH,_PCH 00065c 9601 adiw _PCL,1 ; wait a minute ; MDELAY(SPENT=2,ADD=0) 00065d b3e9 in ZL, PINA _hlt: ; forever loop (HALT) 00065e 9409 ijmp ; no -> make instruction cycles _mov_aa: _mov_bb: _mov_hh: _mov_ll: _mov_cc: _mov_dd: _mov_ee: i_cycle_turbo_6T: 00065f bb88 out ADDRL,_PCL 000660 bb95 out ADDRH,_PCH 000661 9601 adiw _PCL,1 ; wait a minute ; MDELAY(SPENT=2,ADD=0) 000662 b3e9 in ZL, PINA ; CLOCKS(6, 0) 000663 5f0a subi clock,low(-6) ; CLOCKS 000664 f52a brpl processSound 000665 9409 ijmp ; make instruction cycles i_cycle_turbo_8T: 000666 bb88 out ADDRL,_PCL 000667 bb95 out ADDRH,_PCH 000668 9601 adiw _PCL,1 ; wait a minute ; MDELAY(SPENT=2,ADD=0) 000669 b3e9 in ZL, PINA ; CLOCKS(8, 0) 00066a 5f08 subi clock,low(-8) ; CLOCKS 00066b f4f2 brpl processSound 00066c 9409 ijmp ; make instruction cycles i_cycle_turbo_20T: ; CLOCKS(10, 0) 00066d 5f06 subi clock,low(-10) ; CLOCKS i_cycle_turbo_10T: 00066e bb88 out ADDRL,_PCL 00066f bb95 out ADDRH,_PCH 000670 9601 adiw _PCL,1 ; wait a minute ; MDELAY(SPENT=2,ADD=0) 000671 b3e9 in ZL, PINA ; CLOCKS(10, 0) 000672 5f06 subi clock,low(-10) ; CLOCKS 000673 f4b2 brpl processSound 000674 9409 ijmp ; make instruction cycles i_cycle_turbo_12T: 000675 bb88 out ADDRL,_PCL 000676 bb95 out ADDRH,_PCH 000677 9601 adiw _PCL,1 ; wait a minute ; MDELAY(SPENT=2,ADD=0) 000678 b3e9 in ZL, PINA ; CLOCKS(12, 0) 000679 5f04 subi clock,low(-12) ; CLOCKS 00067a f47a brpl processSound 00067b 9409 ijmp ; make instruction cycles i_cycle_turbo_14T: 00067c bb88 out ADDRL,_PCL 00067d bb95 out ADDRH,_PCH 00067e 9601 adiw _PCL,1 ; wait a minute ; MDELAY(SPENT=2,ADD=0) 00067f b3e9 in ZL, PINA ; CLOCKS(14, 0) 000680 5f02 subi clock,low(-14) ; CLOCKS 000681 f442 brpl processSound 000682 9409 ijmp ; make instruction cycles _none: _nop: _di: _ei: i_cycle_turbo_4T: 000683 bb88 out ADDRL,_PCL 000684 bb95 out ADDRH,_PCH 000685 9601 adiw _PCL,1 ; wait a minute 000686 b3e9 in ZL, PINA ; CLOCKS(4, 0) 000687 5f0c subi clock,low(-4) ; CLOCKS 000688 f40a brpl processSound 000689 9409 ijmp ; make instruction cycles 00068a 5100 processSound: subi clock,16 ; 16=full speed, 15=videoprocesor lag ;brpl processSound2 ; save two bits 00068b 9425 asr portValue ; load CY and preserve portValue 00068c 9567 ror snd_reg2 00068d f028 brcs wr_continue 00068e 9409 ijmp ; make instruction cycles 00068f 9425 processSound2: asr portValue ; load CY and preserve portValue 000690 9567 ror snd_reg2 000691 f008 brcs wr_continue 000692 cff7 rjmp processSound wr_continue: 000693 936c st X,snd_reg2 000694 e860 ldi snd_reg2,0x80 ; CY=1 after 8x ror 000695 5faf subi snd_pointerWR_lo, -1 ; modulo 256 000696 17ca cp snd_pointerRD_lo, snd_pointerWR_lo 000697 f3f1 breq PC-1 ; wait 000698 9409 ijmp ; make instruction cycles ;------------- begin of instruction cycle with handling PSW & flags ------ set_flags_4T: 000699 b75f in PSW,SREG save_parity_4T: 00069a bb4d out last_result,A ; for calculate Parity bit 00069b bb88 out ADDRL,_PCL 00069c bb95 out ADDRH,_PCH 00069d 9601 adiw _PCL,1 ; wait a minute 00069e b3e9 in ZL, PINA ; CLOCKS(4, 0) 00069f 5f0c subi clock,low(-4) ; CLOCKS 0006a0 f74a brpl processSound 0006a1 9409 ijmp ; make instruction cycles clr_CH_4T: 0006a2 b75f in PSW,SREG 0006a3 7d5e andi PSW,~((1<<ATMEL_C)|(1<<ATMEL_H)) 0006a4 bb4d out last_result,A ; for calculate Parity bit 0006a5 bb88 out ADDRL,_PCL 0006a6 bb95 out ADDRH,_PCH 0006a7 9601 adiw _PCL,1 ; wait a minute 0006a8 b3e9 in ZL, PINA ; CLOCKS(4, 0) 0006a9 5f0c subi clock,low(-4) ; CLOCKS 0006aa f6fa brpl processSound 0006ab 9409 ijmp ; make instruction cycles ;------------- begin of instruction cycle with substractions handling PSW & flags ------ set_flags_sub_4T: 0006ac bb4d out last_result,A set_flags_cmp_4T: 0006ad b75f in PSW,SREG 0006ae e2e0 ldi ZL,1<< ATMEL_H ; after subtraction invert half-carry bit(H) 0006af 275e eor PSW,ZL 0006b0 bb88 out ADDRL,_PCL 0006b1 bb95 out ADDRH,_PCH 0006b2 9601 adiw _PCL,1 ; wait a minute ; MDELAY(SPENT=2,ADD=0) 0006b3 b3e9 in ZL, PINA ; CLOCKS(4, 0) 0006b4 5f0c subi clock,low(-4) ; CLOCKS 0006b5 f6a2 brpl processSound 0006b6 9409 ijmp ; make instruction cycles writeStack: ; write stack back to the RAM ... start from 0x60 to 0x100 or from 0x60 to stack_pointer 0006b7 e0f0 ldi ZH, high(stack) 0006b8 2deb mov ZL, _255 wrStack: 0006b9 9110 0230 lds tmp_reg, stack_pointer 0006bb 171e cp tmp_reg,ZL 0006bc f099 breq stop_copy 0006bd 9112 ld tmp_reg, -Z 0006be + DCX_SP 0006be 0c8b add _SPL,_255 0006bf 1d7b adc _SPH,_255 .endmacro 0006c0 bb1b out PORTA, tmp_reg 0006c1 ba88 out ADDRL,_SPL ; output 16 bit address 0006c2 bb75 out ADDRH,_SPH busWait7: 0006c3 b51c in tmp_reg, TCNT1L 0006c4 371f cpi tmp_reg,138 - 11 0006c5 f018 brlo busGo7 0006c6 b51d in tmp_reg, TCNT1H 0006c7 3010 cpi tmp_reg,0 ; test 0 0006c8 f3d1 breq busWait7 busGo7: 0006c9 + MEMRD_deactive 0006c9 9a3a sbi PORTE,MEMRD .endmacro 0006ca baba out DDRA,_255 ; sbrc _SPH,7 ; skip if address < 0x8000 ; sbrc _SPH,6 ; skip if 6th bit is clear 0006cb + MEMWR_pulse 0006cb 9839 cbi PORTE,MEMWR 0006cc 9a39 sbi PORTE,MEMWR .endmacro 0006cd baaa out DDRA,_zero ; PORTA input 0006ce + MEMRD_active 0006ce 983a cbi PORTE,MEMRD .endmacro 0006cf cfe9 rjmp wrStack stop_copy: 0006d0 92b0 0230 sts stack_pointer,_255 0006d2 91ff pop ZH 0006d3 91ef pop ZL 0006d4 9409 ijmp _inr_a: 0006d5 fb50 bst PSW,0 0006d6 194b sub A,_255 0006d7 b75f in PSW,SREG 0006d8 f950 bld PSW,0 ; copy old CY 0006d9 bb4d out last_result,A 0006da cf84 rjmp i_cycle_turbo_6T _dcr_a: 0006db fb50 bst PSW,0 ; save CY 0006dc 0d4b add A,_255 0006dd bb4d out last_result,A 0006de b75f in PSW,SREG 0006df f950 bld PSW,0 ; restore CY 0006e0 cf7e rjmp i_cycle_turbo_6T _mvi_a: 0006e1 bb88 out ADDRL,_PCL 0006e2 bb95 out ADDRH,_PCH 0006e3 9601 adiw _PCL,1 0006e4 b349 in A,PINA 0006e5 cf80 rjmp i_cycle_turbo_8T _mov_am: 0006e6 bae8 out ADDRL,L 0006e7 baf5 out ADDRH,H ; MDELAY(SPENT=0,ADD=2) 0006e8 c000 rjmp PC+1 ; MDELAY 0006e9 b349 in A,PINA 0006ea cf7b rjmp i_cycle_turbo_8T _mov_ma: 0006eb 389d cpi _PCH, 0x8D 0006ec f431 brne self_modified_skip 0006ed efe2 ldi ZL, low(ws1) 0006ee 93ef push ZL 0006ef e0e6 ldi ZL, high(ws1) 0006f0 93ef push ZL 0006f1 cfc5 rjmp writeStack ws1: 0006f2 + RESTORE_ZH 0006f2 e0fe ldi ZH, high(i_table) .endmacro self_modified_skip: no_collision_stack1: 0006f3 bae8 out ADDRL,L 0006f4 baf5 out ADDRH,H 0006f5 bb4b out PORTA, A ; CLOCKS(8, 0) 0006f6 5f08 subi clock,low(-8) ; CLOCKS 0006f7 b319 in tmp_reg, PINA 0006f8 1314 cpse tmp_reg, A 0006f9 c1c8 rjmp writeMemoryExecute 0006fa cf5f rjmp i_cycle_turbo _add_a: 0006fb 0f44 add A,A 0006fc cf9c rjmp set_flags_4T _adc_a: 0006fd 9557 ror PSW 0006fe 1f44 adc A,A 0006ff cf99 rjmp set_flags_4T _sub_a: 000700 1b44 sub A,A 000701 cfaa rjmp set_flags_sub_4T _sbb_a: 000702 9557 ror PSW 000703 9418 sez ; must be 000704 0b44 sbc A,A 000705 cfa6 rjmp set_flags_sub_4T _cmp_a: 000706 2f14 mov tmp_reg,A 000707 1b14 sub tmp_reg,A 000708 bb1d out last_result,tmp_reg 000709 cfa3 rjmp set_flags_cmp_4T _ana_a: 00070a 0d4a add A,_zero 00070b b75f in PSW,SREG 00070c bb4d out last_result,A 00070d cf75 rjmp i_cycle_turbo_4T _ora_a: 00070e 0d4a add A,_zero 00070f b75f in PSW,SREG 000710 bb4d out last_result,A 000711 cf71 rjmp i_cycle_turbo_4T _xra_a: 000712 1b44 sub A,A 000713 b75f in PSW,SREG 000714 bb4d out last_result,A 000715 cf6d rjmp i_cycle_turbo_4T _inr_b: 000716 fb50 bst PSW,0 000717 18db sub B,_255 000718 b75f in PSW,SREG 000719 f950 bld PSW,0 ; copy old CY 00071a badd out last_result,B 00071b cf43 rjmp i_cycle_turbo_6T _dcr_b: 00071c fb50 bst PSW,0 ; save CY 00071d 0cdb add B,_255 00071e badd out last_result,B 00071f b75f in PSW,SREG 000720 f950 bld PSW,0 ; restore CY 000721 cf3d rjmp i_cycle_turbo_6T _mvi_b: 000722 bb88 out ADDRL,_PCL 000723 bb95 out ADDRH,_PCH 000724 9601 adiw _PCL,1 000725 b2d9 in B,PINA 000726 cf3f rjmp i_cycle_turbo_8T _mov_bm: 000727 bae8 out ADDRL,L 000728 baf5 out ADDRH,H ; MDELAY(SPENT=0,ADD=2) 000729 c000 rjmp PC+1 ; MDELAY 00072a b2d9 in B,PINA 00072b cf3a rjmp i_cycle_turbo_8T _mov_mb: no_collision_stack2: 00072c bae8 out ADDRL,L 00072d baf5 out ADDRH,H 00072e badb out PORTA, B ; CLOCKS(8, 0) 00072f 5f08 subi clock,low(-8) ; CLOCKS 000730 b319 in tmp_reg, PINA 000731 111d cpse tmp_reg, B 000732 c18f rjmp writeMemoryExecute 000733 cf26 rjmp i_cycle_turbo _add_b: 000734 0d4d add A,B 000735 cf63 rjmp set_flags_4T _adc_b: 000736 9557 ror PSW 000737 1d4d adc A,B 000738 cf60 rjmp set_flags_4T _sub_b: 000739 194d sub A,B 00073a cf71 rjmp set_flags_sub_4T _sbb_b: 00073b 9557 ror PSW 00073c 9418 sez ; must be 00073d 094d sbc A,B 00073e cf6d rjmp set_flags_sub_4T _cmp_b: 00073f 2f14 mov tmp_reg,A 000740 191d sub tmp_reg,B 000741 bb1d out last_result,tmp_reg 000742 cf6a rjmp set_flags_cmp_4T _ana_b: 000743 214d and A,B 000744 cf5d rjmp clr_CH_4T _ora_b: 000745 294d or A,B 000746 cf5b rjmp clr_CH_4T _xra_b: 000747 254d eor A,B 000748 cf59 rjmp clr_CH_4T _inr_c: 000749 fb50 bst PSW,0 00074a 18cb sub C,_255 00074b b75f in PSW,SREG 00074c f950 bld PSW,0 ; copy old CY 00074d bacd out last_result,C 00074e cf10 rjmp i_cycle_turbo_6T _dcr_c: 00074f fb50 bst PSW,0 ; save CY 000750 0ccb add C,_255 000751 bacd out last_result,C 000752 b75f in PSW,SREG 000753 f950 bld PSW,0 ; restore CY 000754 cf0a rjmp i_cycle_turbo_6T _mvi_c: 000755 bb88 out ADDRL,_PCL 000756 bb95 out ADDRH,_PCH 000757 9601 adiw _PCL,1 000758 b2c9 in C,PINA 000759 cf0c rjmp i_cycle_turbo_8T _mov_cm: 00075a bae8 out ADDRL,L 00075b baf5 out ADDRH,H ; MDELAY(SPENT=0,ADD=2) 00075c c000 rjmp PC+1 ; MDELAY 00075d b2c9 in C,PINA 00075e cf07 rjmp i_cycle_turbo_8T _mov_mc: no_collision_stack3: 00075f bae8 out ADDRL,L 000760 baf5 out ADDRH,H 000761 bacb out PORTA, C ; CLOCKS(8, 0) 000762 5f08 subi clock,low(-8) ; CLOCKS 000763 b319 in tmp_reg, PINA 000764 111c cpse tmp_reg, C 000765 c15c rjmp writeMemoryExecute 000766 cef3 rjmp i_cycle_turbo _add_c: 000767 0d4c add A,C 000768 cf30 rjmp set_flags_4T _adc_c: 000769 9557 ror PSW 00076a 1d4c adc A,C 00076b cf2d rjmp set_flags_4T _sub_c: 00076c 194c sub A,C 00076d cf3e rjmp set_flags_sub_4T _sbb_c: 00076e 9557 ror PSW 00076f 9418 sez ; must be 000770 094c sbc A,C 000771 cf3a rjmp set_flags_sub_4T _cmp_c: 000772 2f14 mov tmp_reg,A 000773 191c sub tmp_reg,C 000774 bb1d out last_result,tmp_reg 000775 cf37 rjmp set_flags_cmp_4T _ana_c: 000776 214c and A,C 000777 cf2a rjmp clr_CH_4T _ora_c: 000778 294c or A,C 000779 cf28 rjmp clr_CH_4T _xra_c: 00077a 254c eor A,C 00077b cf26 rjmp clr_CH_4T _inr_d: 00077c fb50 bst PSW,0 00077d 183b sub D,_255 00077e b75f in PSW,SREG 00077f f950 bld PSW,0 ; copy old CY 000780 ba3d out last_result,D 000781 cedd rjmp i_cycle_turbo_6T _dcr_d: 000782 fb50 bst PSW,0 ; save CY 000783 0c3b add D,_255 000784 ba3d out last_result,D 000785 b75f in PSW,SREG 000786 f950 bld PSW,0 ; restore CY 000787 ced7 rjmp i_cycle_turbo_6T _mvi_d: 000788 bb88 out ADDRL,_PCL 000789 bb95 out ADDRH,_PCH 00078a 9601 adiw _PCL,1 00078b b239 in D,PINA 00078c ced9 rjmp i_cycle_turbo_8T _mov_dm: 00078d bae8 out ADDRL,L 00078e baf5 out ADDRH,H ; MDELAY(SPENT=0,ADD=2) 00078f c000 rjmp PC+1 ; MDELAY 000790 b239 in D,PINA 000791 ced4 rjmp i_cycle_turbo_8T _mov_md: no_collision_stack4: 000792 bae8 out ADDRL,L 000793 baf5 out ADDRH,H 000794 ba3b out PORTA, D ; CLOCKS(8, 0) 000795 5f08 subi clock,low(-8) ; CLOCKS 000796 b319 in tmp_reg, PINA 000797 1113 cpse tmp_reg, D 000798 c129 rjmp writeMemoryExecute 000799 cec0 rjmp i_cycle_turbo _add_d: 00079a 0d43 add A,D 00079b cefd rjmp set_flags_4T _adc_d: 00079c 9557 ror PSW 00079d 1d43 adc A,D 00079e cefa rjmp set_flags_4T _sub_d: 00079f 1943 sub A,D 0007a0 cf0b rjmp set_flags_sub_4T _sbb_d: 0007a1 9557 ror PSW 0007a2 9418 sez ; must be 0007a3 0943 sbc A,D 0007a4 cf07 rjmp set_flags_sub_4T _cmp_d: 0007a5 2f14 mov tmp_reg,A 0007a6 1913 sub tmp_reg,D 0007a7 bb1d out last_result,tmp_reg 0007a8 cf04 rjmp set_flags_cmp_4T _ana_d: 0007a9 2143 and A,D 0007aa cef7 rjmp clr_CH_4T _ora_d: 0007ab 2943 or A,D 0007ac cef5 rjmp clr_CH_4T _xra_d: 0007ad 2543 eor A,D 0007ae cef3 rjmp clr_CH_4T _inr_e: 0007af fb50 bst PSW,0 0007b0 184b sub E,_255 0007b1 b75f in PSW,SREG 0007b2 f950 bld PSW,0 ; copy old CY 0007b3 ba4d out last_result,E 0007b4 ceaa rjmp i_cycle_turbo_6T _dcr_e: 0007b5 fb50 bst PSW,0 ; save CY 0007b6 0c4b add E,_255 0007b7 ba4d out last_result,E 0007b8 b75f in PSW,SREG 0007b9 f950 bld PSW,0 ; restore CY 0007ba cea4 rjmp i_cycle_turbo_6T _mvi_e: 0007bb bb88 out ADDRL,_PCL 0007bc bb95 out ADDRH,_PCH 0007bd 9601 adiw _PCL,1 0007be b249 in E,PINA 0007bf cea6 rjmp i_cycle_turbo_8T _mov_em: 0007c0 bae8 out ADDRL,L 0007c1 baf5 out ADDRH,H ; MDELAY(SPENT=0,ADD=2) 0007c2 c000 rjmp PC+1 ; MDELAY 0007c3 b249 in E,PINA 0007c4 cea1 rjmp i_cycle_turbo_8T _mov_me: no_collision_stack5: 0007c5 bae8 out ADDRL,L 0007c6 baf5 out ADDRH,H 0007c7 ba4b out PORTA, E ; CLOCKS(8, 0) 0007c8 5f08 subi clock,low(-8) ; CLOCKS 0007c9 b319 in tmp_reg, PINA 0007ca 1114 cpse tmp_reg, E 0007cb c0f6 rjmp writeMemoryExecute 0007cc ce8d rjmp i_cycle_turbo _add_e: 0007cd 0d44 add A,E 0007ce ceca rjmp set_flags_4T _adc_e: 0007cf 9557 ror PSW 0007d0 1d44 adc A,E 0007d1 cec7 rjmp set_flags_4T _sub_e: 0007d2 1944 sub A,E 0007d3 ced8 rjmp set_flags_sub_4T _sbb_e: 0007d4 9557 ror PSW 0007d5 9418 sez ; must be 0007d6 0944 sbc A,E 0007d7 ced4 rjmp set_flags_sub_4T _cmp_e: 0007d8 2f14 mov tmp_reg,A 0007d9 1914 sub tmp_reg,E 0007da bb1d out last_result,tmp_reg 0007db ced1 rjmp set_flags_cmp_4T _ana_e: 0007dc 2144 and A,E 0007dd cec4 rjmp clr_CH_4T _ora_e: 0007de 2944 or A,E 0007df cec2 rjmp clr_CH_4T _xra_e: 0007e0 2544 eor A,E 0007e1 cec0 rjmp clr_CH_4T _inr_h: 0007e2 fb50 bst PSW,0 0007e3 18fb sub H,_255 0007e4 b75f in PSW,SREG 0007e5 f950 bld PSW,0 ; copy old CY 0007e6 bafd out last_result,H 0007e7 ce77 rjmp i_cycle_turbo_6T _dcr_h: 0007e8 fb50 bst PSW,0 ; save CY 0007e9 0cfb add H,_255 0007ea bafd out last_result,H 0007eb b75f in PSW,SREG 0007ec f950 bld PSW,0 ; restore CY 0007ed ce71 rjmp i_cycle_turbo_6T _mvi_h: 0007ee bb88 out ADDRL,_PCL 0007ef bb95 out ADDRH,_PCH 0007f0 9601 adiw _PCL,1 0007f1 b2f9 in H,PINA 0007f2 ce73 rjmp i_cycle_turbo_8T _mov_hm: 0007f3 bae8 out ADDRL,L 0007f4 baf5 out ADDRH,H ; MDELAY(SPENT=0,ADD=2) 0007f5 c000 rjmp PC+1 ; MDELAY 0007f6 b2f9 in H,PINA 0007f7 ce6e rjmp i_cycle_turbo_8T _mov_mh: no_collision_stack6: 0007f8 bae8 out ADDRL,L 0007f9 baf5 out ADDRH,H 0007fa bafb out PORTA, H ; CLOCKS(8, 0) 0007fb 5f08 subi clock,low(-8) ; CLOCKS 0007fc b319 in tmp_reg, PINA 0007fd 111f cpse tmp_reg, H 0007fe c0c3 rjmp writeMemoryExecute 0007ff ce5a rjmp i_cycle_turbo _add_h: 000800 0d4f add A,H 000801 ce97 rjmp set_flags_4T _adc_h: 000802 9557 ror PSW 000803 1d4f adc A,H 000804 ce94 rjmp set_flags_4T _sub_h: 000805 194f sub A,H 000806 cea5 rjmp set_flags_sub_4T _sbb_h: 000807 9557 ror PSW 000808 9418 sez ; must be 000809 094f sbc A,H 00080a cea1 rjmp set_flags_sub_4T _cmp_h: 00080b 2f14 mov tmp_reg,A 00080c 191f sub tmp_reg,H 00080d bb1d out last_result,tmp_reg 00080e ce9e rjmp set_flags_cmp_4T _ana_h: 00080f 214f and A,H 000810 ce91 rjmp clr_CH_4T _ora_h: 000811 294f or A,H 000812 ce8f rjmp clr_CH_4T _xra_h: 000813 254f eor A,H 000814 ce8d rjmp clr_CH_4T _inr_l: 000815 fb50 bst PSW,0 000816 18eb sub L,_255 000817 b75f in PSW,SREG 000818 f950 bld PSW,0 ; copy old CY 000819 baed out last_result,L 00081a ce44 rjmp i_cycle_turbo_6T _dcr_l: 00081b fb50 bst PSW,0 ; save CY 00081c 0ceb add L,_255 00081d baed out last_result,L 00081e b75f in PSW,SREG 00081f f950 bld PSW,0 ; restore CY 000820 ce3e rjmp i_cycle_turbo_6T _mvi_l: 000821 bb88 out ADDRL,_PCL 000822 bb95 out ADDRH,_PCH 000823 9601 adiw _PCL,1 000824 b2e9 in L,PINA 000825 ce40 rjmp i_cycle_turbo_8T _mov_lm: 000826 bae8 out ADDRL,L 000827 baf5 out ADDRH,H ; MDELAY(SPENT=0,ADD=2) 000828 c000 rjmp PC+1 ; MDELAY 000829 b2e9 in L,PINA 00082a ce3b rjmp i_cycle_turbo_8T _mov_ml: no_collision_stack7: 00082b bae8 out ADDRL,L 00082c baf5 out ADDRH,H 00082d baeb out PORTA, L ; CLOCKS(8, 0) 00082e 5f08 subi clock,low(-8) ; CLOCKS 00082f b319 in tmp_reg, PINA 000830 111e cpse tmp_reg, L 000831 c090 rjmp writeMemoryExecute 000832 ce27 rjmp i_cycle_turbo _add_l: 000833 0d4e add A,L 000834 ce64 rjmp set_flags_4T _adc_l: 000835 9557 ror PSW 000836 1d4e adc A,L 000837 ce61 rjmp set_flags_4T _sub_l: 000838 194e sub A,L 000839 ce72 rjmp set_flags_sub_4T _sbb_l: 00083a 9557 ror PSW 00083b 9418 sez ; must be 00083c 094e sbc A,L 00083d ce6e rjmp set_flags_sub_4T _cmp_l: 00083e 2f14 mov tmp_reg,A 00083f 191e sub tmp_reg,L 000840 bb1d out last_result,tmp_reg 000841 ce6b rjmp set_flags_cmp_4T _ana_l: 000842 214e and A,L 000843 ce5e rjmp clr_CH_4T _ora_l: 000844 294e or A,L 000845 ce5c rjmp clr_CH_4T _xra_l: 000846 254e eor A,L 000847 ce5a rjmp clr_CH_4T _add_m: 000848 bae8 out ADDRL,L 000849 baf5 out ADDRH,H ; CLOCKS(4, 1) 00084a 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 00084b 0000 nop ; MDELAY 00084c b3e9 in ZL,PINA 00084d 0f4e add A,ZL 00084e ce4a rjmp set_flags_4T _adc_m: 00084f bae8 out ADDRL,L 000850 baf5 out ADDRH,H ; CLOCKS(4, 1) 000851 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 000852 0000 nop ; MDELAY 000853 b3e9 in ZL,PINA 000854 9557 ror PSW 000855 1f4e adc A,ZL 000856 ce42 rjmp set_flags_4T _sub_m: 000857 bae8 out ADDRL,L 000858 baf5 out ADDRH,H ; CLOCKS(4, 1) 000859 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 00085a 0000 nop ; MDELAY 00085b b3e9 in ZL,PINA 00085c 1b4e sub A,ZL 00085d ce4e rjmp set_flags_sub_4T _sbb_m: 00085e bae8 out ADDRL,L 00085f baf5 out ADDRH,H ; CLOCKS(4, 1) 000860 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 000861 0000 nop ; MDELAY 000862 b3e9 in ZL,PINA 000863 9557 ror PSW 000864 9418 sez ; must be 000865 0b4e sbc A,ZL 000866 ce45 rjmp set_flags_sub_4T _cmp_m: 000867 bae8 out ADDRL,L 000868 baf5 out ADDRH,H ; CLOCKS(4, 1) 000869 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 00086a 0000 nop ; MDELAY 00086b b3e9 in ZL,PINA 00086c 2f14 mov tmp_reg,A 00086d 1b1e sub tmp_reg,ZL 00086e bb1d out last_result,tmp_reg 00086f ce3d rjmp set_flags_cmp_4T _ana_m: 000870 bae8 out ADDRL,L 000871 baf5 out ADDRH,H ; CLOCKS(4, 1) 000872 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 000873 0000 nop ; MDELAY 000874 b3e9 in ZL,PINA 000875 234e and A,ZL 000876 ce2b rjmp clr_CH_4T _ora_m: 000877 bae8 out ADDRL,L 000878 baf5 out ADDRH,H ; CLOCKS(4, 1) 000879 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 00087a 0000 nop ; MDELAY 00087b b3e9 in ZL,PINA 00087c 2b4e or A,ZL 00087d ce24 rjmp clr_CH_4T _xra_m: 00087e bae8 out ADDRL,L 00087f baf5 out ADDRH,H ; CLOCKS(4, 1) 000880 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 000881 0000 nop ; MDELAY 000882 b3e9 in ZL,PINA 000883 274e eor A,ZL 000884 ce1d rjmp clr_CH_4T _adi: 000885 bb88 out ADDRL,_PCL 000886 bb95 out ADDRH,_PCH 000887 9601 adiw _PCL,1 ; CLOCKS(4, 0) 000888 5f0c subi clock,low(-4) ; CLOCKS 000889 b3e9 in ZL,PINA 00088a 0f4e add A,ZL 00088b ce0d rjmp set_flags_4T _aci: 00088c bb88 out ADDRL,_PCL 00088d bb95 out ADDRH,_PCH 00088e 9601 adiw _PCL,1 ; CLOCKS(4, 0) 00088f 5f0c subi clock,low(-4) ; CLOCKS 000890 b3e9 in ZL,PINA 000891 9557 ror PSW 000892 1f4e adc A,ZL 000893 ce05 rjmp set_flags_4T _sui: 000894 bb88 out ADDRL,_PCL 000895 bb95 out ADDRH,_PCH 000896 9601 adiw _PCL,1 ; CLOCKS(4, 0) 000897 5f0c subi clock,low(-4) ; CLOCKS 000898 b3e9 in ZL,PINA 000899 1b4e sub A,ZL 00089a ce11 rjmp set_flags_sub_4T _sbi: 00089b bb88 out ADDRL,_PCL 00089c bb95 out ADDRH,_PCH 00089d 9601 adiw _PCL,1 ; CLOCKS(4, 0) 00089e 5f0c subi clock,low(-4) ; CLOCKS 00089f b3e9 in ZL,PINA 0008a0 9557 ror PSW 0008a1 9418 sez ; must be 0008a2 0b4e sbc A,ZL 0008a3 ce08 rjmp set_flags_sub_4T _cpi: 0008a4 bb88 out ADDRL,_PCL 0008a5 bb95 out ADDRH,_PCH 0008a6 9601 adiw _PCL,1 ; CLOCKS(4, 0) 0008a7 5f0c subi clock,low(-4) ; CLOCKS 0008a8 b3e9 in ZL,PINA 0008a9 2f14 mov tmp_reg,A 0008aa 1b1e sub tmp_reg,ZL 0008ab bb1d out last_result,tmp_reg 0008ac ce00 rjmp set_flags_cmp_4T _ani: 0008ad bb88 out ADDRL,_PCL 0008ae bb95 out ADDRH,_PCH 0008af 9601 adiw _PCL,1 ; CLOCKS(4, 0) 0008b0 5f0c subi clock,low(-4) ; CLOCKS 0008b1 b3e9 in ZL,PINA 0008b2 234e and A,ZL 0008b3 cdee rjmp clr_CH_4T _ori: 0008b4 bb88 out ADDRL,_PCL 0008b5 bb95 out ADDRH,_PCH 0008b6 9601 adiw _PCL,1 ; CLOCKS(4, 0) 0008b7 5f0c subi clock,low(-4) ; CLOCKS 0008b8 b3e9 in ZL,PINA 0008b9 2b4e or A,ZL 0008ba cde7 rjmp clr_CH_4T _xri: 0008bb bb88 out ADDRL,_PCL 0008bc bb95 out ADDRH,_PCH 0008bd 9601 adiw _PCL,1 ; CLOCKS(4, 0) 0008be 5f0c subi clock,low(-4) ; CLOCKS 0008bf b3e9 in ZL,PINA 0008c0 274e eor A,ZL 0008c1 cde0 rjmp clr_CH_4T writeMemoryExecute: 0008c2 b5ec in ZL, TCNT1L 0008c3 b51d in tmp_reg, TCNT1H 0008c4 3010 cpi tmp_reg,0 0008c5 f491 brne WME_firstWriteThenExecute 0008c6 37ed cpi ZL, low(138 - 11-2) 0008c7 f080 brlo WME_firstWriteThenExecute ; took 10 ticks -> so video_int occurs here 0008c8 b318 in tmp_reg, ADDRL 0008c9 b3f5 in ZH, ADDRH 0008ca bb95 out ADDRH,_PCH 0008cb bb88 out ADDRL,_PCL ; 0008cc 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 0008cd b3e9 in ZL, PINA ; known issue: self modification programs STA PC+3 can fails 0008ce bbf5 out ADDRH,ZH 0008cf bb18 out ADDRL,tmp_reg ; 0008d0 e0fe ldi ZH, high(i_table) ; 12T 0008d1 + MEMRD_deactive 0008d1 9a3a sbi PORTE,MEMRD .endmacro 0008d2 baba out DDRA,_255 0008d3 + MEMWR_pulse 0008d3 9839 cbi PORTE,MEMWR 0008d4 9a39 sbi PORTE,MEMWR .endmacro 0008d5 baaa out DDRA,_zero ; PORTA input 0008d6 + MEMRD_active 0008d6 983a cbi PORTE,MEMRD .endmacro 0008d7 9409 ijmp WME_firstWriteThenExecute: 0008d8 + MEMRD_deactive 0008d8 9a3a sbi PORTE,MEMRD .endmacro 0008d9 baba out DDRA,_255 0008da + MEMWR_pulse 0008da 9839 cbi PORTE,MEMWR 0008db 9a39 sbi PORTE,MEMWR .endmacro 0008dc baaa out DDRA,_zero ; PORTA input 0008dd + MEMRD_active 0008dd 983a cbi PORTE,MEMRD .endmacro 0008de bb88 out ADDRL,_PCL 0008df bb95 out ADDRH,_PCH 0008e0 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 0008e1 b3e9 in ZL, PINA 0008e2 9409 ijmp ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ _inr_m: 0008e3 bae8 out ADDRL,L 0008e4 baf5 out ADDRH,H 0008e5 fb50 bst PSW,0 ; wait a minute & save CY ; CLOCKS(10, 1) 0008e6 5f06 subi clock,low(-10) ; CLOCKS ; MDELAY(SPENT=2,ADD=0) 0008e7 b3e9 in ZL,PINA 0008e8 19eb sub ZL, _255 0008e9 b75f in PSW,SREG 0008ea f950 bld PSW,0 ; restore CY 0008eb bbeb out PORTA, ZL 0008ec bbed out last_result,ZL 0008ed cfd4 rjmp writeMemoryExecute _dcr_m: 0008ee bae8 out ADDRL,L 0008ef baf5 out ADDRH,H 0008f0 fb50 bst PSW,0 ; wait a minute & save CY ; CLOCKS(10, 1) 0008f1 5f06 subi clock,low(-10) ; CLOCKS ; MDELAY(SPENT=2,ADD=0) 0008f2 b3e9 in ZL,PINA 0008f3 0deb add ZL,_255 0008f4 b75f in PSW,SREG 0008f5 f950 bld PSW,0 ; restore CY 0008f6 bbeb out PORTA, ZL 0008f7 bbed out last_result,ZL 0008f8 cfc9 rjmp writeMemoryExecute _inx_b: 0008f9 18cb sub C,_255 0008fa 08db sbc B,_255 0008fb cd63 rjmp i_cycle_turbo_6T _inx_d: 0008fc 184b sub E,_255 0008fd 083b sbc D,_255 0008fe cd60 rjmp i_cycle_turbo_6T _inx_h: 0008ff 18eb sub L,_255 000900 08fb sbc H,_255 000901 cd5d rjmp i_cycle_turbo_6T _inx_sp: 000902 e0e7 ldi ZL, low(ws2) 000903 93ef push ZL 000904 e0e9 ldi ZL, high(ws2) 000905 93ef push ZL 000906 cdb0 rjmp writeStack ws2: 000907 + RESTORE_ZH 000907 e0fe ldi ZH, high(i_table) .endmacro 000908 + INX_SP 000908 188b sub _SPL,_255 000909 097b sbc _SPH,_255 .endmacro 00090a cd54 rjmp i_cycle_turbo_6T _dcx_b: 00090b 0ccb add C,_255 00090c 1cdb adc B,_255 00090d cd51 rjmp i_cycle_turbo_6T _dcx_d: 00090e 0c4b add E,_255 00090f 1c3b adc D,_255 000910 cd4e rjmp i_cycle_turbo_6T _dcx_h: 000911 0ceb add L,_255 000912 1cfb adc H,_255 000913 cd4b rjmp i_cycle_turbo_6T _dcx_sp: 000914 e1e9 ldi ZL, low(ws3) 000915 93ef push ZL 000916 e0e9 ldi ZL, high(ws3) 000917 93ef push ZL 000918 cd9e rjmp writeStack ws3: 000919 + RESTORE_ZH 000919 e0fe ldi ZH, high(i_table) .endmacro 00091a + DCX_SP 00091a 0c8b add _SPL,_255 00091b 1d7b adc _SPH,_255 .endmacro 00091c cd42 rjmp i_cycle_turbo_6T pmd852_modification: ;ret ; end of subroutine ;*********************** scitanie 16-bit ********** ; ovplynuje len CY _dad_b: ; high,low 00091d 9557 ror PSW 00091e 0cec add L,C 00091f 1cfd adc H,B 000920 1f55 rol PSW 000921 cd4c rjmp i_cycle_turbo_10T _lxi_b: 000922 bb88 out ADDRL,_PCL 000923 bb95 out ADDRH,_PCH 000924 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000925 b2c9 in C,PINA 000926 bb88 out ADDRL,_PCL 000927 bb95 out ADDRH,_PCH 000928 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000929 b2d9 in B,PINA 00092a cd4a rjmp i_cycle_turbo_12T _dad_d: ; high,low 00092b 9557 ror PSW 00092c 0ce4 add L,E 00092d 1cf3 adc H,D 00092e 1f55 rol PSW 00092f cd3e rjmp i_cycle_turbo_10T _lxi_d: 000930 bb88 out ADDRL,_PCL 000931 bb95 out ADDRH,_PCH 000932 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000933 b249 in E,PINA 000934 bb88 out ADDRL,_PCL 000935 bb95 out ADDRH,_PCH 000936 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000937 b239 in D,PINA 000938 cd3c rjmp i_cycle_turbo_12T _dad_h: ; high,low 000939 9557 ror PSW 00093a 0cee add L,L 00093b 1cff adc H,H 00093c 1f55 rol PSW 00093d cd30 rjmp i_cycle_turbo_10T _lxi_h: 00093e bb88 out ADDRL,_PCL 00093f bb95 out ADDRH,_PCH 000940 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000941 b2e9 in L,PINA 000942 bb88 out ADDRL,_PCL 000943 bb95 out ADDRH,_PCH 000944 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000945 b2f9 in H,PINA 000946 cd2e rjmp i_cycle_turbo_12T _dad_sp: 000947 e4ec ldi ZL, low(ws4) 000948 93ef push ZL 000949 e0e9 ldi ZL, high(ws4) 00094a 93ef push ZL 00094b cd6b rjmp writeStack ws4: 00094c + RESTORE_ZH 00094c e0fe ldi ZH, high(i_table) .endmacro ; high,low 00094d 9557 ror PSW 00094e 0ce8 add L,_SPL 00094f 1ef7 adc H,_SPH 000950 1f55 rol PSW 000951 cd1c rjmp i_cycle_turbo_10T _lxi_sp: 000952 e5e7 ldi ZL, low(ws5) 000953 93ef push ZL 000954 e0e9 ldi ZL, high(ws5) 000955 93ef push ZL 000956 cd60 rjmp writeStack ws5: 000957 + RESTORE_ZH 000957 e0fe ldi ZH, high(i_table) .endmacro 000958 bb88 out ADDRL,_PCL 000959 bb95 out ADDRH,_PCH 00095a 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 00095b b289 in _SPL,PINA 00095c bb88 out ADDRL,_PCL 00095d bb95 out ADDRH,_PCH 00095e 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 00095f b379 in _SPH,PINA 000960 cd14 rjmp i_cycle_turbo_12T ;**************************** MOV ra,rb ******** _mov_ab: 000961 2d4d mov A,B 000962 ccfc rjmp i_cycle_turbo_6T _mov_ac: 000963 2d4c mov A,C 000964 ccfa rjmp i_cycle_turbo_6T _mov_ad: 000965 2d43 mov A,D 000966 ccf8 rjmp i_cycle_turbo_6T _mov_ae: 000967 2d44 mov A,E 000968 ccf6 rjmp i_cycle_turbo_6T _mov_ah: 000969 2d4f mov A,H 00096a ccf4 rjmp i_cycle_turbo_6T _mov_al: 00096b 2d4e mov A,L 00096c ccf2 rjmp i_cycle_turbo_6T _mov_ba: 00096d 2ed4 mov B,A 00096e ccf0 rjmp i_cycle_turbo_6T _mov_bc: 00096f 2cdc mov B,C 000970 ccee rjmp i_cycle_turbo_6T _mov_bd: 000971 2cd3 mov B,D 000972 ccec rjmp i_cycle_turbo_6T _mov_be: 000973 2cd4 mov B,E 000974 ccea rjmp i_cycle_turbo_6T _mov_bh: 000975 2cdf mov B,H 000976 cce8 rjmp i_cycle_turbo_6T _mov_bl: 000977 2cde mov B,L 000978 cce6 rjmp i_cycle_turbo_6T _mov_ca: 000979 2ec4 mov C,A 00097a cce4 rjmp i_cycle_turbo_6T _mov_cb: 00097b 2ccd mov C,B 00097c cce2 rjmp i_cycle_turbo_6T _mov_cd: 00097d 2cc3 mov C,D 00097e cce0 rjmp i_cycle_turbo_6T _mov_ce: 00097f 2cc4 mov C,E 000980 ccde rjmp i_cycle_turbo_6T _mov_ch: 000981 2ccf mov C,H 000982 ccdc rjmp i_cycle_turbo_6T _mov_cl: 000983 2cce mov C,L 000984 ccda rjmp i_cycle_turbo_6T _mov_da: 000985 2e34 mov D,A 000986 ccd8 rjmp i_cycle_turbo_6T _mov_db: 000987 2c3d mov D,B 000988 ccd6 rjmp i_cycle_turbo_6T _mov_dc: 000989 2c3c mov D,C 00098a ccd4 rjmp i_cycle_turbo_6T _mov_de: 00098b 2c34 mov D,E 00098c ccd2 rjmp i_cycle_turbo_6T _mov_dh: 00098d 2c3f mov D,H 00098e ccd0 rjmp i_cycle_turbo_6T _mov_dl: 00098f 2c3e mov D,L 000990 ccce rjmp i_cycle_turbo_6T _mov_ea: 000991 2e44 mov E,A 000992 cccc rjmp i_cycle_turbo_6T _mov_eb: 000993 2c4d mov E,B 000994 ccca rjmp i_cycle_turbo_6T _mov_ec: 000995 2c4c mov E,C 000996 ccc8 rjmp i_cycle_turbo_6T _mov_ed: 000997 2c43 mov E,D 000998 ccc6 rjmp i_cycle_turbo_6T _mov_eh: 000999 2c4f mov E,H 00099a ccc4 rjmp i_cycle_turbo_6T _mov_el: 00099b 2c4e mov E,L 00099c ccc2 rjmp i_cycle_turbo_6T _mov_ha: 00099d 2ef4 mov H,A 00099e ccc0 rjmp i_cycle_turbo_6T _mov_hb: 00099f 2cfd mov H,B 0009a0 ccbe rjmp i_cycle_turbo_6T _mov_hc: 0009a1 2cfc mov H,C 0009a2 ccbc rjmp i_cycle_turbo_6T _mov_hd: 0009a3 2cf3 mov H,D 0009a4 ccba rjmp i_cycle_turbo_6T _mov_he: 0009a5 2cf4 mov H,E 0009a6 ccb8 rjmp i_cycle_turbo_6T _mov_hl: 0009a7 2cfe mov H,L 0009a8 ccb6 rjmp i_cycle_turbo_6T _mov_la: 0009a9 2ee4 mov L,A 0009aa ccb4 rjmp i_cycle_turbo_6T _mov_lb: 0009ab 2ced mov L,B 0009ac ccb2 rjmp i_cycle_turbo_6T _mov_lc: 0009ad 2cec mov L,C 0009ae ccb0 rjmp i_cycle_turbo_6T _mov_ld: 0009af 2ce3 mov L,D 0009b0 ccae rjmp i_cycle_turbo_6T _mov_le: 0009b1 2ce4 mov L,E 0009b2 ccac rjmp i_cycle_turbo_6T _mov_lh: 0009b3 2cef mov L,H 0009b4 ccaa rjmp i_cycle_turbo_6T ;******************************** bitove operacie ******************** .equ _CY = 1 .equ _Z = 2 .equ _S = 0x10 .equ _AC = 0x20 _cmc: 0009b5 e0e1 ldi ZL,_CY 0009b6 275e eor PSW,ZL ; C u Atmela je 0.bit 0009b7 cccb rjmp i_cycle_turbo_4T _stc: 0009b8 6051 ori PSW,1<<0 0009b9 ccc9 rjmp i_cycle_turbo_4T _cma: ; PSW unchanged 0009ba 9540 com A 0009bb ccc7 rjmp i_cycle_turbo_4T _rlca: ; affected only CY 0009bc 9557 ror PSW 0009bd fb47 bst A,7 0009be 1f44 rol A 0009bf f940 bld A,0 0009c0 1f55 rol PSW 0009c1 ccc1 rjmp i_cycle_turbo_4T _rrca: ; affected only CY 0009c2 9557 ror PSW 0009c3 fb40 bst A,0 0009c4 9547 ror A 0009c5 f947 bld A,7 0009c6 1f55 rol PSW 0009c7 ccbb rjmp i_cycle_turbo_4T _rla: ; affected only CY 0009c8 9557 ror PSW 0009c9 1f44 rol A 0009ca 1f55 rol PSW 0009cb ccb7 rjmp i_cycle_turbo_4T _rra: ; affected only CY 0009cc 9557 ror PSW 0009cd 9547 ror A 0009ce 1f55 rol PSW 0009cf ccb3 rjmp i_cycle_turbo_4T ;************************** STACK instructions ******************************* _push_h: 0009d0 e0f0 ldi ZH, high(stack) 0009d1 91e0 0230 lds ZL, stack_pointer 0009d3 92f2 st -Z, H 0009d4 92e2 st -Z, L 0009d5 93e0 0230 sts stack_pointer,ZL 0009d7 3c70 cpi _SPH,0xc0 0009d8 f410 brsh push_vram1 0009d9 37ef cpi ZL, 127 ; above 0x8000 - 0xffff , vram direct write 0009da f428 brsh pushOk1 push_vram1: 0009db eee0 ldi ZL, low(ws6) 0009dc 93ef push ZL 0009dd e0e9 ldi ZL, high(ws6) 0009de 93ef push ZL 0009df ccd7 rjmp writeStack ws6: pushOk1: 0009e0 e0fe ldi ZH, high(i_table) 0009e1 cc93 rjmp i_cycle_turbo_12T _push_d: 0009e2 e0f0 ldi ZH, high(stack) 0009e3 91e0 0230 lds ZL, stack_pointer 0009e5 9232 st -Z, D 0009e6 9242 st -Z, E 0009e7 93e0 0230 sts stack_pointer,ZL 0009e9 3c70 cpi _SPH,0xc0 0009ea f410 brsh push_vram2 0009eb 37ef cpi ZL, 127 ; above 0x8000 - 0xffff , vram direct write 0009ec f428 brsh pushOk2 push_vram2: 0009ed efe2 ldi ZL, low(ws7) 0009ee 93ef push ZL 0009ef e0e9 ldi ZL, high(ws7) 0009f0 93ef push ZL 0009f1 ccc5 rjmp writeStack ws7: pushOk2: 0009f2 e0fe ldi ZH, high(i_table) 0009f3 cc81 rjmp i_cycle_turbo_12T _push_b: 0009f4 e0f0 ldi ZH, high(stack) 0009f5 91e0 0230 lds ZL, stack_pointer 0009f7 92d2 st -Z, B 0009f8 92c2 st -Z, C 0009f9 93e0 0230 sts stack_pointer,ZL 0009fb 3c70 cpi _SPH,0xc0 0009fc f410 brsh push_vram3 0009fd 37ef cpi ZL, 127 ; above 0x8000 - 0xffff , vram direct write 0009fe f428 brsh pushOk3 push_vram3: 0009ff e0e4 ldi ZL, low(ws8) 000a00 93ef push ZL 000a01 e0ea ldi ZL, high(ws8) 000a02 93ef push ZL 000a03 ccb3 rjmp writeStack ws8: pushOk3: 000a04 e0fe ldi ZH, high(i_table) 000a05 cc6f rjmp i_cycle_turbo_12T _push_a: ; from PSW & last_result ---> ZL ; ZL & A --> STACK ; Calculate odd parity of register last_result; output is in bit SREG.T ; 8080 has odd parity ; destroy ZL,tmp_reg register, T = result parity bit 000a06 b3ed in ZL,last_result 000a07 2f1e mov tmp_reg,ZL 000a08 95e2 swap ZL 000a09 27e1 eor ZL,tmp_reg 000a0a 2f1e mov tmp_reg,ZL 000a0b 9516 lsr tmp_reg 000a0c 9516 lsr tmp_reg 000a0d 27e1 eor ZL,tmp_reg 000a0e 2f1e mov tmp_reg,ZL 000a0f 9516 lsr tmp_reg 000a10 27e1 eor ZL,tmp_reg 000a11 95e0 com ZL 000a12 fbe0 bst ZL,0 000a13 e012 ldi tmp_reg,PMD_PSW 000a14 f912 bld tmp_reg,2 ;P copied 000a15 fb50 bst PSW,0 000a16 f910 bld tmp_reg,0 ; CY copied 000a17 fb51 bst PSW,1 000a18 f916 bld tmp_reg,6 ; Z copied 000a19 fb52 bst PSW,2 000a1a f917 bld tmp_reg,7 ; S copied 000a1b fb55 bst PSW,5 000a1c f914 bld tmp_reg,4 ; A copied 000a1d e0f0 ldi ZH, high(stack) 000a1e 91e0 0230 lds ZL, stack_pointer 000a20 9342 st -Z, A 000a21 9312 st -Z, tmp_reg 000a22 93e0 0230 sts stack_pointer,ZL 000a24 3c70 cpi _SPH,0xc0 000a25 f410 brsh push_vram4 000a26 37ef cpi ZL, 127 ; above 0x8000 - 0xffff , vram direct write 000a27 f428 brsh pushOk4 push_vram4: 000a28 e2ed ldi ZL, low(ws9) 000a29 93ef push ZL 000a2a e0ea ldi ZL, high(ws9) 000a2b 93ef push ZL 000a2c cc8a rjmp writeStack ws9: pushOk4: 000a2d e0fe ldi ZH, high(i_table) 000a2e cc46 rjmp i_cycle_turbo_12T 000a2f 91e0 0230 _pop_h: lds ZL, stack_pointer 000a31 15eb cp ZL,_255 000a32 f459 brne rdMy1 000a33 ba88 out ADDRL,_SPL 000a34 bb75 out ADDRH,_SPH 000a35 + INX_SP 000a35 188b sub _SPL,_255 000a36 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000a37 b2e9 in L,PINA 000a38 ba88 out ADDRL,_SPL 000a39 bb75 out ADDRH,_SPH 000a3a + INX_SP 000a3a 188b sub _SPL,_255 000a3b 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000a3c b2f9 in H,PINA 000a3d cc37 rjmp i_cycle_turbo_12T rdMy1: 000a3e e0f0 ldi ZH, high(stack) 000a3f 90e1 ld L, Z+ 000a40 90f1 ld H, Z+ 000a41 93e0 0230 sts stack_pointer,ZL popOut1: 000a43 + RESTORE_ZH 000a43 e0fe ldi ZH, high(i_table) .endmacro 000a44 cc30 rjmp i_cycle_turbo_12T 000a45 91e0 0230 _pop_d: lds ZL, stack_pointer 000a47 15eb cp ZL,_255 000a48 f459 brne rdMy2 000a49 ba88 out ADDRL,_SPL 000a4a bb75 out ADDRH,_SPH 000a4b + INX_SP 000a4b 188b sub _SPL,_255 000a4c 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000a4d b249 in E,PINA 000a4e ba88 out ADDRL,_SPL 000a4f bb75 out ADDRH,_SPH 000a50 + INX_SP 000a50 188b sub _SPL,_255 000a51 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000a52 b239 in D,PINA 000a53 cc21 rjmp i_cycle_turbo_12T rdMy2: 000a54 e0f0 ldi ZH, high(stack) 000a55 9041 ld E, Z+ 000a56 9031 ld D, Z+ 000a57 93e0 0230 sts stack_pointer,ZL popOut2: 000a59 + RESTORE_ZH 000a59 e0fe ldi ZH, high(i_table) .endmacro 000a5a cc1a rjmp i_cycle_turbo_12T 000a5b 91e0 0230 _pop_b: lds ZL, stack_pointer 000a5d 15eb cp ZL,_255 000a5e f459 brne rdMy3 000a5f ba88 out ADDRL,_SPL 000a60 bb75 out ADDRH,_SPH 000a61 + INX_SP 000a61 188b sub _SPL,_255 000a62 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000a63 b2c9 in C,PINA 000a64 ba88 out ADDRL,_SPL 000a65 bb75 out ADDRH,_SPH 000a66 + INX_SP 000a66 188b sub _SPL,_255 000a67 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000a68 b2d9 in B,PINA 000a69 cc0b rjmp i_cycle_turbo_12T rdMy3: 000a6a e0f0 ldi ZH, high(stack) 000a6b 90c1 ld C, Z+ 000a6c 90d1 ld B, Z+ 000a6d 93e0 0230 sts stack_pointer,ZL popOut3: 000a6f + RESTORE_ZH 000a6f e0fe ldi ZH, high(i_table) .endmacro 000a70 cc04 rjmp i_cycle_turbo_12T 000a71 91e0 0230 _pop_a: lds ZL, stack_pointer 000a73 15eb cp ZL,_255 000a74 f459 brne rdMy4 000a75 ba88 out ADDRL,_SPL 000a76 bb75 out ADDRH,_SPH 000a77 + INX_SP 000a77 188b sub _SPL,_255 000a78 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000a79 b319 in tmp_reg,PINA 000a7a ba88 out ADDRL,_SPL 000a7b bb75 out ADDRH,_SPH 000a7c + INX_SP 000a7c 188b sub _SPL,_255 000a7d 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000a7e b349 in A,PINA 000a7f c005 rjmp popOut4 rdMy4: 000a80 e0f0 ldi ZH, high(stack) 000a81 9111 ld tmp_reg, Z+ 000a82 9141 ld A, Z+ 000a83 93e0 0230 sts stack_pointer,ZL popOut4: 000a85 + RESTORE_ZH 000a85 e0fe ldi ZH, high(i_table) .endmacro 000a86 e850 ldi PSW,0x80; I = 1 => mustbe !!! , interrupts must be enabled (display, keyboard, sound) 000a87 fb10 bst tmp_reg,0 ; CY copied 000a88 f950 bld PSW,0 000a89 fb16 bst tmp_reg,6 ; Z copied 000a8a f951 bld PSW,1 000a8b fb17 bst tmp_reg,7 ; S copied 000a8c f952 bld PSW,2 000a8d fb14 bst tmp_reg,4 ; A copied 000a8e f955 bld PSW,5 000a8f 27ee clr ZL 000a90 ff12 sbrs tmp_reg,2 ; T = P; if ZL.2 == 1 => skip next ; parity of zero is one, 0x01 => P=0; 0x5b => P = 0 000a91 95e3 inc ZL ; last_result := 1 000a92 bbed out last_result,ZL 000a93 cbe1 rjmp i_cycle_turbo_12T ;**************** calls & jumps & rets ***************************************** _rc: ; CLOCKS(2, 0) 000a94 5f0e subi clock,low(-2) ; CLOCKS 000a95 bf5f out SREG,PSW 000a96 f068 brbs 0,_ret ; bit 0 of SREG is C and if is set ( 1 ) do return 000a97 cbeb rjmp i_cycle_turbo_4T _rnc: ; CLOCKS(2, 0) 000a98 5f0e subi clock,low(-2) ; CLOCKS 000a99 bf5f out SREG,PSW 000a9a f448 brbc 0,_ret ; bit 0 of SREG is C and if is clear ( 0 ) do return 000a9b cbe7 rjmp i_cycle_turbo_4T _rp: ;return PLUS -> use N(negative) flag at atmel ; CLOCKS(2, 0) 000a9c 5f0e subi clock,low(-2) ; CLOCKS 000a9d bf5f out SREG,PSW 000a9e f42a brpl _ret ; bit 2 of SREG is N and if is CLEAR !!!! ( 0 ) do return 000a9f cbe3 rjmp i_cycle_turbo_4T _rm: ;call MINUS -> use N(negative) flag at atmel ; CLOCKS(2, 0) 000aa0 5f0e subi clock,low(-2) ; CLOCKS 000aa1 bf5f out SREG,PSW 000aa2 f00a brmi _ret ; bit 2 of SREG is N and if is SET !!!! ( 1 ) do return 000aa3 cbdf rjmp i_cycle_turbo_4T 000aa4 91e0 0230 _ret: lds ZL, stack_pointer 000aa6 15eb cp ZL,_255 000aa7 f459 brne rdMy5 000aa8 ba88 out ADDRL,_SPL 000aa9 bb75 out ADDRH,_SPH 000aaa + INX_SP 000aaa 188b sub _SPL,_255 000aab 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000aac b389 in _PCL,PINA 000aad ba88 out ADDRL,_SPL 000aae bb75 out ADDRH,_SPH 000aaf + INX_SP 000aaf 188b sub _SPL,_255 000ab0 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000ab1 b399 in _PCH,PINA 000ab2 cbc2 rjmp i_cycle_turbo_12T rdMy5: 000ab3 e0f0 ldi ZH, high(stack) 000ab4 9181 ld _PCL, Z+ 000ab5 9191 ld _PCH, Z+ 000ab6 93e0 0230 sts stack_pointer,ZL popOut5: 000ab8 + RESTORE_ZH 000ab8 e0fe ldi ZH, high(i_table) .endmacro 000ab9 cbbb rjmp i_cycle_turbo_12T _rz: ; CLOCKS(2, 0) 000aba 5f0e subi clock,low(-2) ; CLOCKS 000abb bf5f out SREG,PSW 000abc f339 brbs 1,_ret ; bit 1 of SREG is Z and if is set ( 1 ) do return 000abd cbc5 rjmp i_cycle_turbo_4T _rnz: ; CLOCKS(2, 0) 000abe 5f0e subi clock,low(-2) ; CLOCKS 000abf bf5f out SREG,PSW 000ac0 f719 brbc 1,_ret ; bit 1 of SREG is Z and if is clear ( 0 ) do return 000ac1 cbc1 rjmp i_cycle_turbo_4T _rpe: ; CLOCKS(2, 0) 000ac2 5f0e subi clock,low(-2) ; CLOCKS ; Calculate odd parity of register last_result; output is in bit SREG.T ; 8080 has odd parity ; destroy ZL,tmp_reg register, T = result parity bit, even parity 000ac3 b3ed in ZL,last_result 000ac4 2f1e mov tmp_reg,ZL 000ac5 95e2 swap ZL 000ac6 27e1 eor ZL,tmp_reg 000ac7 2f1e mov tmp_reg,ZL 000ac8 9516 lsr tmp_reg 000ac9 9516 lsr tmp_reg 000aca 27e1 eor ZL,tmp_reg 000acb 2f1e mov tmp_reg,ZL 000acc 9516 lsr tmp_reg 000acd 27e1 eor ZL,tmp_reg 000ace fbe0 bst ZL,0 000acf f6a6 brtc _ret ; EVEN = (PARITY == 1) 000ad0 cbb2 rjmp i_cycle_turbo_4T _rpo: ; CLOCKS(2, 0) 000ad1 5f0e subi clock,low(-2) ; CLOCKS ; Calculate odd parity of register last_result; output is in bit SREG.T ; 8080 has odd parity ; destroy ZL,tmp_reg register, T = result parity bit, even parity 000ad2 b3ed in ZL,last_result 000ad3 2f1e mov tmp_reg,ZL 000ad4 95e2 swap ZL 000ad5 27e1 eor ZL,tmp_reg 000ad6 2f1e mov tmp_reg,ZL 000ad7 9516 lsr tmp_reg 000ad8 9516 lsr tmp_reg 000ad9 27e1 eor ZL,tmp_reg 000ada 2f1e mov tmp_reg,ZL 000adb 9516 lsr tmp_reg 000adc 27e1 eor ZL,tmp_reg 000add fbe0 bst ZL,0 000ade f22e brts _ret ; ODD = (PARITY == 0) 000adf cba3 rjmp i_cycle_turbo_4T _cpo: ; Calculate odd parity of register last_result; output is in bit SREG.T ; 8080 has odd parity ; destroy ZL,tmp_reg register, T = result parity bit, even parity 000ae0 b3ed in ZL,last_result 000ae1 2f1e mov tmp_reg,ZL 000ae2 95e2 swap ZL 000ae3 27e1 eor ZL,tmp_reg 000ae4 2f1e mov tmp_reg,ZL 000ae5 9516 lsr tmp_reg 000ae6 9516 lsr tmp_reg 000ae7 27e1 eor ZL,tmp_reg 000ae8 2f1e mov tmp_reg,ZL 000ae9 9516 lsr tmp_reg 000aea 27e1 eor ZL,tmp_reg 000aeb fbe0 bst ZL,0 000aec f14e brts _call ; ODD = (PARITY == 0) 000aed 9602 adiw _PCL,2 000aee cb8d rjmp i_cycle_turbo_14T _cpe: ; Calculate odd parity of register last_result; output is in bit SREG.T ; 8080 has odd parity ; destroy ZL,tmp_reg register, T = result parity bit, even parity 000aef b3ed in ZL,last_result 000af0 2f1e mov tmp_reg,ZL 000af1 95e2 swap ZL 000af2 27e1 eor ZL,tmp_reg 000af3 2f1e mov tmp_reg,ZL 000af4 9516 lsr tmp_reg 000af5 9516 lsr tmp_reg 000af6 27e1 eor ZL,tmp_reg 000af7 2f1e mov tmp_reg,ZL 000af8 9516 lsr tmp_reg 000af9 27e1 eor ZL,tmp_reg 000afa fbe0 bst ZL,0 000afb f4d6 brtc _call ; EVEN = (PARITY == 1) 000afc 9602 adiw _PCL,2 000afd cb7e rjmp i_cycle_turbo_14T 000afe bf5f _cc: out SREG,PSW 000aff f0b0 brbs 0,_call ; bit 0 of SREG is C and if is set ( 1 ) do call 000b00 9602 adiw _PCL,2 000b01 cb7a rjmp i_cycle_turbo_14T 000b02 bf5f _cnc: out SREG,PSW 000b03 f490 brbc 0,_call ; bit 0 of SREG is C and if is clear ( 0 ) do call 000b04 9602 adiw _PCL,2 000b05 cb76 rjmp i_cycle_turbo_14T _cp: ;call PLUS -> use N(negative) flag at atmel 000b06 bf5f out SREG,PSW 000b07 f472 brpl _call ; bit 2 of SREG is N and if is CLEAR !!!! ( 0 ) do call 000b08 9602 adiw _PCL,2 000b09 cb72 rjmp i_cycle_turbo_14T 000b0a bf5f _cnz: out SREG,PSW 000b0b f451 brbc 1,_call ; bit 1 of SREG is Z and if is clear ( 0 ) do call 000b0c 9602 adiw _PCL,2 000b0d cb6e rjmp i_cycle_turbo_14T 000b0e bf5f _cz: out SREG,PSW 000b0f f031 brbs 1,_call ; bit 1 of SREG is Z and if is set ( 1 ) do call 000b10 9602 adiw _PCL,2 000b11 cb6a rjmp i_cycle_turbo_14T _cm: ;call MINUS -> use N(negative) flag at atmel 000b12 bf5f out SREG,PSW 000b13 f012 brmi _call ; bit 2 of SREG is N and if is SET !!!! ( 1 ) do call 000b14 9602 adiw _PCL,2 000b15 cb66 rjmp i_cycle_turbo_14T _call: 000b16 bb88 out ADDRL,_PCL 000b17 bb95 out ADDRH,_PCH 000b18 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000b19 b3e9 in ZL,PINA ; low 000b1a 93ef push ZL 000b1b bb88 out ADDRL,_PCL 000b1c bb95 out ADDRH,_PCH 000b1d 9601 adiw _PCL,1 ; CLOCKS(8, 0) 000b1e 5f08 subi clock,low(-8) ; CLOCKS ; MDELAY(SPENT=3,ADD=0) 000b1f b3e9 in ZL,PINA ; High 000b20 93ef push ZL _rst_entry: 000b21 e0f0 ldi ZH, high(stack) 000b22 91e0 0230 lds ZL, stack_pointer 000b24 9392 st -Z, _PCH 000b25 9382 st -Z, _PCL 000b26 93e0 0230 sts stack_pointer,ZL 000b28 3c70 cpi _SPH,0xc0 000b29 f410 brsh push_vram5 000b2a 37ef cpi ZL, 127 ; above 0x8000 - 0xffff , vram direct write 000b2b f428 brsh pushOk5 push_vram5: 000b2c e3e1 ldi ZL, low(ws10) 000b2d 93ef push ZL 000b2e e0eb ldi ZL, high(ws10) 000b2f 93ef push ZL 000b30 cb86 rjmp writeStack ws10: pushOk5: 000b31 e0fe ldi ZH, high(i_table) 000b32 919f pop _PCH 000b33 918f pop _PCL 000b34 cb40 rjmp i_cycle_turbo_12T _jm: ;JUMP MINUS -> use N(negative) flag at atmel 000b35 bf5f out SREG,PSW 000b36 f0ea brmi _jmp ; bit 2 of SREG is N and if is SET !!!! ( 1 ) do jump 000b37 9602 adiw _PCL,2 000b38 cb3c rjmp i_cycle_turbo_12T 000b39 bf5f _jc: out SREG,PSW 000b3a f0c8 brbs 0,_jmp ; bit 0 of SREG is C and if is set ( 1 ) do jump 000b3b 9602 adiw _PCL,2 000b3c cb38 rjmp i_cycle_turbo_12T 000b3d bf5f _jnc: out SREG,PSW 000b3e f4a8 brbc 0,_jmp ; bit 0 of SREG is C and if is clear ( 0 ) do jump 000b3f 9602 adiw _PCL,2 000b40 cb34 rjmp i_cycle_turbo_12T _jp: ;JUMP PLUS -> use N(negative) flag at atmel 000b41 bf5f out SREG,PSW 000b42 f48a brpl _jmp ; bit 2 of SREG is N and if is CLEAR !!!! ( 1 ) do jump 000b43 9602 adiw _PCL,2 000b44 cb30 rjmp i_cycle_turbo_12T _jpe: ; Calculate odd parity of register last_result; output is in bit SREG.T ; 8080 has odd parity ; destroy ZL,tmp_reg register, T = result parity bit, even parity 000b45 b3ed in ZL,last_result 000b46 2f1e mov tmp_reg,ZL 000b47 95e2 swap ZL 000b48 27e1 eor ZL,tmp_reg 000b49 2f1e mov tmp_reg,ZL 000b4a 9516 lsr tmp_reg 000b4b 9516 lsr tmp_reg 000b4c 27e1 eor ZL,tmp_reg 000b4d 2f1e mov tmp_reg,ZL 000b4e 9516 lsr tmp_reg 000b4f 27e1 eor ZL,tmp_reg 000b50 fbe0 bst ZL,0 000b51 f416 brtc _jmp ; EVEN = (PARITY == 1) 000b52 9602 adiw _PCL,2 000b53 cb21 rjmp i_cycle_turbo_12T _jmp: 000b54 bb88 out ADDRL,_PCL 000b55 bb95 out ADDRH,_PCH 000b56 9601 adiw _PCL,1 000b57 b3e9 in ZL,PINA 000b58 bb88 out ADDRL,_PCL 000b59 bb95 out ADDRH,_PCH 000b5a 2f8e mov _PCL,ZL 000b5b 0000 nop 000b5c b399 in _PCH,PINA 000b5d cb17 rjmp i_cycle_turbo_12T _jpo: ; Calculate odd parity of register last_result; output is in bit SREG.T ; 8080 has odd parity ; destroy ZL,tmp_reg register, T = result parity bit, even parity 000b5e b3ed in ZL,last_result 000b5f 2f1e mov tmp_reg,ZL 000b60 95e2 swap ZL 000b61 27e1 eor ZL,tmp_reg 000b62 2f1e mov tmp_reg,ZL 000b63 9516 lsr tmp_reg 000b64 9516 lsr tmp_reg 000b65 27e1 eor ZL,tmp_reg 000b66 2f1e mov tmp_reg,ZL 000b67 9516 lsr tmp_reg 000b68 27e1 eor ZL,tmp_reg 000b69 fbe0 bst ZL,0 000b6a f34e brts _jmp ; ODD = (PARITY == 0) 000b6b 9602 adiw _PCL,2 000b6c cb08 rjmp i_cycle_turbo_12T _jz: 000b6d bf5f out SREG,PSW 000b6e f329 brbs 1,_jmp ; bit 1 of SREG is Z and if is set ( 1 ) do jump 000b6f 9602 adiw _PCL,2 000b70 cb04 rjmp i_cycle_turbo_12T _jnz: 000b71 bf5f out SREG,PSW 000b72 f709 brbc 1,_jmp ; bit 1 of SREG is Z and if is clear ( 0 ) do jump 000b73 9602 adiw _PCL,2 000b74 cb00 rjmp i_cycle_turbo_12T _pchl: 000b75 01c7 movw _PCL,L 000b76 cae8 rjmp i_cycle_turbo_6T ;******************* RST instructions **************************************** _rst0: _rst1: _rst2: _rst3: _rst4: _rst5: _rst6: _rst7: 000b77 73e8 andi ZL,0b00111000 000b78 93ef push ZL 000b79 92af push _zero 000b7a cfa6 rjmp _rst_entry ;************************ Memory instructions ********************* _lda: 000b7b bb88 out ADDRL,_PCL 000b7c bb95 out ADDRH,_PCH 000b7d 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000b7e b3e9 in ZL,PINA 000b7f bb88 out ADDRL,_PCL 000b80 bb95 out ADDRH,_PCH 000b81 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000b82 b319 in tmp_reg,PINA 000b83 bbe8 out ADDRL,ZL 000b84 bb15 out ADDRH,tmp_reg ; CLOCKS(4, 1) 000b85 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 000b86 0000 nop ; MDELAY 000b87 b349 in A,PINA 000b88 caec rjmp i_cycle_turbo_12T _sta: 000b89 bb88 out ADDRL,_PCL 000b8a bb95 out ADDRH,_PCH 000b8b 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000b8c b3e9 in ZL,PINA 000b8d bb88 out ADDRL,_PCL 000b8e bb95 out ADDRH,_PCH 000b8f 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000b90 b319 in tmp_reg,PINA no_collision_stack8: 000b91 bbe8 out ADDRL,ZL 000b92 bb15 out ADDRH,tmp_reg 000b93 bb4b out PORTA, A ; CLOCKS(14, 0) 000b94 5f02 subi clock,low(-14) ; CLOCKS 000b95 b319 in tmp_reg, PINA 000b96 1314 cpse tmp_reg, A 000b97 cd2a rjmp writeMemoryExecute 000b98 cac1 rjmp i_cycle_turbo _mvi_m: 000b99 bb88 out ADDRL,_PCL 000b9a bb95 out ADDRH,_PCH 000b9b 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000b9c b3e9 in ZL,PINA no_collision_stack9: 000b9d bae8 out ADDRL,L 000b9e baf5 out ADDRH,H 000b9f bbeb out PORTA, ZL ; CLOCKS(8, 0) 000ba0 5f08 subi clock,low(-8) ; CLOCKS 000ba1 b319 in tmp_reg, PINA 000ba2 131e cpse tmp_reg, ZL 000ba3 cd1e rjmp writeMemoryExecute 000ba4 cab5 rjmp i_cycle_turbo ;************************ a := [ r16 ] indirect addressing ***** _ldax_b: 000ba5 bac8 out ADDRL,C 000ba6 bad5 out ADDRH,B ; CLOCKS(4, 1) 000ba7 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 000ba8 0000 nop ; MDELAY 000ba9 b349 in A,PINA 000baa cad8 rjmp i_cycle_turbo_4T _stax_d: no_collision_stack10: 000bab ba48 out ADDRL,E 000bac ba35 out ADDRH,D 000bad bb4b out PORTA, A ; CLOCKS(8, 0) 000bae 5f08 subi clock,low(-8) ; CLOCKS 000baf b319 in tmp_reg, PINA 000bb0 1314 cpse tmp_reg, A 000bb1 cd10 rjmp writeMemoryExecute 000bb2 caa7 rjmp i_cycle_turbo _stax_b: no_collision_stack11: 000bb3 bac8 out ADDRL,C 000bb4 bad5 out ADDRH,B 000bb5 bb4b out PORTA, A ; CLOCKS(8, 0) 000bb6 5f08 subi clock,low(-8) ; CLOCKS 000bb7 b319 in tmp_reg, PINA 000bb8 1314 cpse tmp_reg, A 000bb9 cd08 rjmp writeMemoryExecute 000bba ca9f rjmp i_cycle_turbo _ldax_d: 000bbb ba48 out ADDRL,E 000bbc ba35 out ADDRH,D ; CLOCKS(4, 1) 000bbd 5f0c subi clock,low(-4) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 000bbe 0000 nop ; MDELAY 000bbf b349 in A,PINA 000bc0 cac2 rjmp i_cycle_turbo_4T _lhld: 000bc1 bb88 out ADDRL,_PCL 000bc2 bb95 out ADDRH,_PCH 000bc3 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000bc4 b3e9 in ZL,PINA 000bc5 bb88 out ADDRL,_PCL 000bc6 bb95 out ADDRH,_PCH 000bc7 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000bc8 b3f9 in ZH,PINA 000bc9 bbe8 out ADDRL,ZL 000bca bbf5 out ADDRH,ZH 000bcb 9631 adiw ZL,1 ; MDELAY(SPENT=2,ADD=0) 000bcc b2e9 in L,PINA 000bcd bbe8 out ADDRL,ZL 000bce bbf5 out ADDRH,ZH ; CLOCKS(16, 1) 000bcf 5f00 subi clock,low(-16) ; CLOCKS 000bd0 e0fe ldi ZH, high(i_table) ; MDELAY(SPENT=2,ADD=0) 000bd1 b2f9 in H,PINA 000bd2 cab0 rjmp i_cycle_turbo_4T 000bd3 bb88 _shld: out ADDRL,_PCL 000bd4 bb95 out ADDRH,_PCH 000bd5 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000bd6 b3e9 in ZL,PINA 000bd7 bb88 out ADDRL,_PCL 000bd8 bb95 out ADDRH,_PCH 000bd9 9601 adiw _PCL,1 ; MDELAY(SPENT=2,ADD=0) 000bda b3f9 in ZH,PINA 000bdb baeb out PORTA, L 000bdc bbe8 out ADDRL,ZL ; output 16 bit address 000bdd bbf5 out ADDRH,ZH busWait8: 000bde b51c in tmp_reg, TCNT1L 000bdf 371f cpi tmp_reg,138 - 11 000be0 f018 brlo busGo8 000be1 b51d in tmp_reg, TCNT1H 000be2 3010 cpi tmp_reg,0 ; test 0 000be3 f3d1 breq busWait8 busGo8: 000be4 + MEMRD_deactive 000be4 9a3a sbi PORTE,MEMRD .endmacro 000be5 baba out DDRA,_255 ; sbrc ZH,7 ; skip if address < 0x8000 ; sbrc ZH,6 ; skip if 6th bit is clear 000be6 + MEMWR_pulse 000be6 9839 cbi PORTE,MEMWR 000be7 9a39 sbi PORTE,MEMWR .endmacro 000be8 baaa out DDRA,_zero ; PORTA input 000be9 + MEMRD_active 000be9 983a cbi PORTE,MEMRD .endmacro 000bea 9631 adiw ZL,1 000beb bbe8 out ADDRL,ZL 000bec bbf5 out ADDRH,ZH 000bed bafb out PORTA,H ; CLOCKS(18, 0) 000bee 5e0e subi clock,low(-18) ; CLOCKS 000bef e0fe ldi ZH, high(i_table) 000bf0 b319 in tmp_reg,PINA 000bf1 111f cpse tmp_reg,H 000bf2 cccf rjmp writeMemoryExecute 000bf3 ca66 rjmp i_cycle_turbo _sphl: 000bf4 efe9 ldi ZL, low(ws11) 000bf5 93ef push ZL 000bf6 e0eb ldi ZL, high(ws11) 000bf7 93ef push ZL 000bf8 cabe rjmp writeStack ws11: 000bf9 + RESTORE_ZH 000bf9 e0fe ldi ZH, high(i_table) .endmacro 000bfa 2c8e mov _SPL,L 000bfb 2d7f mov _SPH,H 000bfc ca62 rjmp i_cycle_turbo_6T _xthl: stack_empty_xthl: 000bfd 92df push B 000bfe 92cf push C 000bff 91e0 0230 lds ZL, stack_pointer 000c01 15eb cp ZL,_255 000c02 f459 brne rdMy6 000c03 ba88 out ADDRL,_SPL 000c04 bb75 out ADDRH,_SPH 000c05 + INX_SP 000c05 188b sub _SPL,_255 000c06 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000c07 b2c9 in C,PINA 000c08 ba88 out ADDRL,_SPL 000c09 bb75 out ADDRH,_SPH 000c0a + INX_SP 000c0a 188b sub _SPL,_255 000c0b 097b sbc _SPH,_255 .endmacro ; MDELAY(SPENT=2,ADD=0) 000c0c b2d9 in B,PINA 000c0d c005 rjmp popOut6 rdMy6: 000c0e e0f0 ldi ZH, high(stack) 000c0f 90c1 ld C, Z+ 000c10 90d1 ld B, Z+ 000c11 93e0 0230 sts stack_pointer,ZL popOut6: 000c13 + RESTORE_ZH 000c13 e0fe ldi ZH, high(i_table) .endmacro 000c14 e0f0 ldi ZH, high(stack) 000c15 91e0 0230 lds ZL, stack_pointer 000c17 92f2 st -Z, H 000c18 92e2 st -Z, L 000c19 93e0 0230 sts stack_pointer,ZL 000c1b 3c70 cpi _SPH,0xc0 000c1c f410 brsh push_vram6 000c1d 37ef cpi ZL, 127 ; above 0x8000 - 0xffff , vram direct write 000c1e f428 brsh pushOk6 push_vram6: 000c1f e2e4 ldi ZL, low(ws12) 000c20 93ef push ZL 000c21 e0ec ldi ZL, high(ws12) 000c22 93ef push ZL 000c23 ca93 rjmp writeStack ws12: pushOk6: 000c24 e0fe ldi ZH, high(i_table) 000c25 2cfd mov H,B 000c26 2cec mov L,C 000c27 90cf pop C 000c28 90df pop B 000c29 + RESTORE_ZH 000c29 e0fe ldi ZH, high(i_table) .endmacro 000c2a ca42 rjmp i_cycle_turbo_20T 000c2b ba88 out ADDRL,_SPL 000c2c bb75 out ADDRH,_SPH 000c2d 2dee mov ZL,L 000c2e 2dff mov ZH,H ; MDELAY(SPENT=2,ADD=0) 000c2f b2e9 in L,PINA 000c30 bbeb out PORTA, ZL busWait9: 000c31 b51c in tmp_reg, TCNT1L 000c32 371f cpi tmp_reg,138 - 11 000c33 f018 brlo busGo9 000c34 b51d in tmp_reg, TCNT1H 000c35 3010 cpi tmp_reg,0 ; test 0 000c36 f3d1 breq busWait9 busGo9: 000c37 + MEMRD_deactive 000c37 9a3a sbi PORTE,MEMRD .endmacro 000c38 baba out DDRA,_255 ; sbrc _SPH,7 ; skip if address < 0x8000 ; sbrc _SPH,6 ; skip if 6th bit is clear 000c39 + MEMWR_pulse 000c39 9839 cbi PORTE,MEMWR 000c3a 9a39 sbi PORTE,MEMWR .endmacro 000c3b baaa out DDRA,_zero ; PORTA input 000c3c + MEMRD_active 000c3c 983a cbi PORTE,MEMRD .endmacro 000c3d + INX_SP 000c3d 188b sub _SPL,_255 000c3e 097b sbc _SPH,_255 .endmacro 000c3f ba88 out ADDRL,_SPL 000c40 bb75 out ADDRH,_SPH ; CLOCKS(20, 1) 000c41 5e0c subi clock,low(-20) ; CLOCKS ; MDELAY(SPENT=1,ADD=1) 000c42 0000 nop ; MDELAY 000c43 b2f9 in H,PINA 000c44 ba88 out ADDRL,_SPL 000c45 bb75 out ADDRH,_SPH 000c46 bbfb out PORTA, ZH 000c47 e0fe ldi ZH, high(i_table) 000c48 + DCX_SP 000c48 0c8b add _SPL,_255 000c49 1d7b adc _SPH,_255 .endmacro 000c4a cc77 rjmp writeMemoryExecute _xchg: 000c4b 2dee mov ZL,L 000c4c 2ce4 mov L,E 000c4d 2e4e mov E,ZL 000c4e 2def mov ZL,H 000c4f 2cf3 mov H,D 000c50 2e3e mov D,ZL 000c51 ca31 rjmp i_cycle_turbo_4T _daa: 000c52 2711 clr tmp_reg ; add register 000c53 2fe4 mov ZL,A 000c54 70ef andi ZL,0x0f ; low nibble of A 000c55 30ea cpi ZL,9 + 1 000c56 f008 brlo _daa1 000c57 6016 ori tmp_reg,6 000c58 fd55 _daa1: sbrc PSW,ATMEL_H 000c59 6016 ori tmp_reg,6 000c5a fd50 sbrc PSW,ATMEL_C 000c5b 6610 ori tmp_reg,0x60 000c5c 2fe4 mov ZL,A 000c5d 3ae0 cpi ZL,0x9f+1 000c5e f008 brlo _daa2 000c5f 6610 ori tmp_reg,0x60 _daa2: 000c60 39ea cpi ZL,0x99+1 000c61 f010 brlo _daa3 000c62 9468 set 000c63 f950 bld PSW,ATMEL_C ; CY :=1 _daa3: 000c64 39e1 cpi ZL,0x90+1 000c65 f020 brlo _daa4 000c66 70ef andi ZL,0x0f ; low nibble of A 000c67 30ea cpi ZL,9 + 1 000c68 f008 brlo _daa4 000c69 6610 ori tmp_reg,0x60 _daa4: 000c6a 0f41 add A,tmp_reg 000c6b ca2e rjmp save_parity_4T ;********************************************************************* ;**** I/O subsystem **** ;********************************************************************* in_channels: 000c6c c0c4 rjmp in_channel0 000c6d c068 rjmp in_channel1 000c6e c0c2 rjmp in_channel2 000c6f c0c1 rjmp in_channel3 000c70 c0c0 rjmp in_channel4 000c71 c0bd rjmp in_channel5 000c72 c0be rjmp in_channel6 000c73 c0bd rjmp in_channel7 out_channels: 000c74 c0b9 rjmp out_channel0 000c75 c0ae rjmp out_channel1 000c76 c0b7 rjmp out_channel2 000c77 c0b6 rjmp out_channel3 000c78 c0b5 rjmp out_channel4 000c79 c0b4 rjmp out_channel5 000c7a c0b3 rjmp out_channel6 000c7b c0b2 rjmp out_channel7 rd_usart_status: 000c7c b7e8 in ZL,TIFR 000c7d fbe0 bst ZL,OCF0 ; T = TxRDY (1 = transmitter ready, 0 = transmitter busy) 000c7e e046 ldi A,6 ; receiver always ready; TxE = 1, RxRDY=1 000c7f 9110 022e lds tmp_reg, pmd_version 000c81 fd11 sbrc tmp_reg,1 000c82 2d4a mov A,_zero ; PMD-85/2 not received chars 000c83 f940 bld A,0 ; TxRDY (transmitted flag) T -> A[0.bit] 000c84 + RESTORE_ZH 000c84 e0fe ldi ZH, high(i_table) .endmacro 000c85 c9ef rjmp i_cycle_turbo_12T 000c86 91e0 0221 rd_kbd_pb: lds ZL,kbd_ports + 0 ; PA 000c88 70ef andi ZL,0b1111 ; low nibble (16 cols) 000c89 50e0 subi ZL, low( -kb_cols ) 000c8a e0f2 ldi ZH, high( kb_cols ) 000c8b 8140 ld A,Z ; compute col value => row value 000c8c 9110 0232 lds tmp_reg,kbd_flags 000c8e 7610 andi tmp_reg,(1<<SHIFT_bit)|(1<<STOP_bit) 000c8f 2b41 or A,tmp_reg ; store SHIFT + STOP 000c90 8910 ldd tmp_reg,Z+16 ; mix with kb_cols_real 000c91 2341 and A, tmp_reg 000c92 + RESTORE_ZH 000c92 e0fe ldi ZH, high(i_table) .endmacro 000c93 c9e1 rjmp i_cycle_turbo_12T 000c94 b3e9 rd_pmd_kbd: in ZL,PINA 000c95 70e3 andi ZL,0b11 ; internal port number in 8255 000c96 30e1 cpi ZL,1 ; PB ? 000c97 f371 breq rd_kbd_pb 000c98 5def subi ZL, low( -kbd_ports ) 000c99 e0f2 ldi ZH, high( kbd_ports ) 000c9a 8140 ld A,Z ; store to A 000c9b + RESTORE_ZH 000c9b e0fe ldi ZH, high(i_table) .endmacro 000c9c c9d8 rjmp i_cycle_turbo_12T 000c9d b3e9 rd_rom_modul: in ZL,PINA 000c9e 70e3 andi ZL,0b11 ; internal port number in 8255 000c9f f0b9 breq rd_rom_modul_from_flash 000ca0 5de7 subi ZL,low(-_rom) 000ca1 e0f2 ldi ZH,high(_rom) 000ca2 8140 ld A,Z 000ca3 + RESTORE_ZH 000ca3 e0fe ldi ZH, high(i_table) .endmacro 000ca4 c9d0 rjmp i_cycle_turbo_12T 000ca5 b3e9 rd_channel_0_7: in ZL,PINA 000ca6 95e2 swap ZL 000ca7 70e7 andi ZL,0x07 000ca8 e0fc ldi ZH,high(in_channels) 000ca9 59e4 subi ZL,low(-in_channels) 000caa 9409 ijmp _in: 000cab bb88 out ADDRL,_PCL 000cac bb95 out ADDRH,_PCH 000cad 9601 adiw _PCL,1 000cae b3e9 in ZL,PINA 000caf 78ec andi ZL,0b10001100 000cb0 38e4 cpi ZL,0b10000100 000cb1 f311 breq rd_pmd_kbd 000cb2 38e8 cpi ZL,0b10001000 000cb3 f349 breq rd_rom_modul 000cb4 30ec cpi ZL,0b00001100 000cb5 f379 breq rd_channel_0_7 000cb6 c9be rjmp i_cycle_turbo_12T ; read from other port (not implemented/not existss) rd_rom_modul_from_flash: 000cb7 e240 ldi A,high(C_basic1_start) 000cb8 e0e0 ldi ZL,low(C_basic1_start) 000cb9 9110 022e lds tmp_reg, pmd_version 000cbb 3012 cpi tmp_reg,2 000cbc f411 brne skip_modul_2 000cbd e444 ldi A,high(C_basic2_start) 000cbe e0e0 ldi ZL,low(C_basic2_start) skip_modul_2: 000cbf 9110 022a lds tmp_reg,_rom + 1 ; byte1 000cc1 0fe1 add ZL,tmp_reg 000cc2 9110 022b lds tmp_reg,_rom + 2 ; byte2 000cc4 771f andi tmp_reg,0b01111111 000cc5 1f41 adc A,tmp_reg 000cc6 bbe8 out ADDRL,ZL 000cc7 bb45 out ADDRH,A busWait10: 000cc8 b51c in tmp_reg, TCNT1L 000cc9 371b cpi tmp_reg,138 - 15 000cca f018 brlo busGo10 000ccb b51d in tmp_reg, TCNT1H 000ccc 3010 cpi tmp_reg,0 ; test 0 000ccd f3d1 breq busWait10 busGo10: 000cce + SELECT_FLASH0_zeroPage 000cce 9a8b sbi DDRD, RAM_SELECT 000ccf baa2 out PORTD,_zero .endmacro 000cd0 c000 RJMP PC+1 ; FLASH is 90 ns, cycle is about 50 ns ==> must be 2 cycle delay 000cd1 c000 RJMP PC+1 ; FLASH is 90 ns, cycle is about 50 ns ==> must be 2 cycle delay 000cd2 c000 RJMP PC+1 ; EPROM is 120 ns, cycle is about 50 ns ==> must be 2 cycle delay ;RJMP PC+1 ; EPROM is 120 ns, cycle is about 50 ns ==> must be 2 cycle delay 000cd3 b349 in A,PINA 000cd4 988b cbi DDRD, RAM_SELECT ; Select RAM 000cd5 c99f rjmp i_cycle_turbo_12T in_channel1: ;1C a 1E = DATA ; 1f = status register ;USART --> DATA/STATUS register 000cd6 99c8 sbic PINA,0 ; DATA/status ( 0 = DATA, 1 = STATUS ) 000cd7 cfa4 rjmp rd_usart_status rd_usart_data: ; output: reg. A = data from tape (and increment tape pointer) 000cd8 935f push HiReg 000cd9 936f push cntReg 000cda 92ef push L 000cdb 90e0 0225 lds L,mgf_pointer+0 000cdd 91f0 0226 lds ZH,mgf_pointer+1 000cdf 9150 0227 lds HiReg,mgf_pointer+2 000ce1 2766 load_next_clr: clr cntReg load_next: 000ce2 bae8 out ADDRL,L 000ce3 bbf5 out ADDRH,ZH 000ce4 27ee clr ZL 000ce5 fb50 bst HiReg,0 ; A16 000ce6 f9e2 bld ZL,2 000ce7 fb51 bst HiReg,1 ; A17 000ce8 f9e6 bld ZL,6 000ce9 fb52 bst HiReg,2 ; A18 000cea f9e7 bld ZL,7 busWait11: 000ceb b51c in tmp_reg, TCNT1L 000cec 3714 cpi tmp_reg,138 - 22 000ced f018 brlo busGo11 000cee b51d in tmp_reg, TCNT1H 000cef 3010 cpi tmp_reg,0 ; test 0 000cf0 f3d1 breq busWait11 busGo11: 000cf1 9a8b sbi DDRD, RAM_SELECT ; select FLASH0/1 (disable ram) 000cf2 fd53 sbrc HiReg, 3 ; A19=1 => FLASH1 000cf3 9a3a sbi PORTE, MEMRD 000cf4 fd53 sbrc HiReg, 3 ; A19=1 => FLASH1 000cf5 9839 cbi PORTE, MEMWR 000cf6 bbe2 out PORTD,ZL 000cf7 c000 RJMP PC+1 ; FLASH is 90 ns, cycle is about 50 ns ==> must be 2 cycle delay 000cf8 c000 RJMP PC+1 ; FLASH is 90 ns, cycle is about 50 ns ==> must be 2 cycle delay 000cf9 c000 RJMP PC+1 ; EPROM is 120 ns, cycle is about 50 ns ==> must be 2 cycle delay ;RJMP PC+1 ; EPROM is 120 ns, cycle is about 50 ns ==> must be 2 cycle delay 000cfa b349 in A,PINA 000cfb baa2 out PORTD,_zero ; avoid video issues 000cfc + SELECT_RAM 000cfc 9a39 sbi PORTE,MEMWR ; MEMWR_deactive 000cfd 988b cbi DDRD, RAM_SELECT 000cfe 983a cbi PORTE,MEMRD ; MEMRD_active .endmacro ; this char will be returned (A) 000cff 18eb sub L,_255 ; increment 000d00 09fb sbc ZH,_255 000d01 095b sbc HiReg,_255 000d02 705f andi HiReg, 0b1111 000d03 9110 0232 lds tmp_reg,kbd_flags 000d05 ff15 sbrs tmp_reg, SHIFT_bit 000d06 c004 rjmp mgf_shift_pressed 000d07 9110 0210 lds tmp_reg,kb_cols_real ; 0th column of real kbd 000d09 fd15 sbrc tmp_reg, 5 ; SHIFT 000d0a c00e rjmp finish mgf_shift_pressed: 000d0b 9110 0228 lds tmp_reg,mgf_header 000d0d 151a cp tmp_reg, _zero 000d0e f439 brne load1 000d0f 3f4f cpi A,0xff 000d10 f681 brne load_next_clr 000d11 9563 count_ff: inc cntReg 000d12 306f cpi cntReg, 15 000d13 f270 brlo load_next found_header: 000d14 e311 ldi tmp_reg,64-15 ; HEADER LENGTH 000d15 c001 rjmp load2 000d16 951a load1: dec tmp_reg 000d17 9310 0228 load2: sts mgf_header,tmp_reg 000d19 92e0 0225 finish: sts mgf_pointer+0,L 000d1b 93f0 0226 sts mgf_pointer+1,ZH 000d1d 9350 0227 sts mgf_pointer+2,HiReg 000d1f 90ef pop L 000d20 916f pop cntReg 000d21 915f pop HiReg 000d22 + RESTORE_ZH 000d22 e0fe ldi ZH, high(i_table) .endmacro 000d23 c951 rjmp i_cycle_turbo_12T out_channel1: ; some games i.e. HLIPA uses USART as a timer (write to data register and then ; read status. TxC will set in status word 11/1200 s = 9.16 ms (after 143 TV row scans) 000d24 fd10 sbrc tmp_reg,0 ; DATA/status (0 = DATA, 1 = STATUS) 000d25 c001 rjmp wr_usart_cw wr_usart_data: ;out TCCR0,_zero ; stop CTC2 ;out TCNT0,_zero ; count from 0 to OCR2 ;ldi ZL,1<<OCF0 ; clear TIFR.OCF2 (this is done by write one OCF2 bit!) ;out TIFR,ZL ;ldi ZL,0b00001101 ; run TCCR2 at CLK/1024, CTC mode ;out TCCR0,ZL 000d26 c932 rjmp i_cycle wr_usart_cw: 000d27 91e0 0231 lds ZL,usart_cw_last 000d29 34e0 cpi ZL,0x40 000d2a f401 brne no_usart_reset no_usart_reset: 000d2b 9310 0231 sts usart_cw_last,tmp_reg 000d2d c92b rjmp i_cycle ; go to i_cycle ---> go down out_channel0: out_channel2: out_channel3: out_channel4: out_channel5: out_channel6: out_channel7: 000d2e c92a rjmp i_cycle 000d2f e040 in_channel5: ldi A,0x00 ;arkanoid timer 000d30 c928 rjmp i_cycle in_channel7: ; TODO in_channel0: in_channel2: in_channel3: in_channel6: in_channel4: ; joystick disconnected ;-) 000d31 2d4b mov A,_255 ;lds A,test_clock 000d32 c926 rjmp i_cycle wr_rom_modul: 000d33 70e3 andi ZL,0b11 ; internal port number in IC 8255 000d34 5de7 subi ZL,low(-_rom) 000d35 e0f2 ldi ZH,high(_rom) 000d36 8340 st Z,A 000d37 c921 rjmp i_cycle wr_channel_0_7: 000d38 95e2 swap ZL 000d39 70e7 andi ZL,0x07 000d3a e0fc ldi ZH,high(out_channels) 000d3b 58ec subi ZL,low(-out_channels) 000d3c 9409 ijmp _out: 000d3d bb88 out ADDRL,_PCL 000d3e bb95 out ADDRH,_PCH 000d3f 9601 adiw _PCL,1 ; MDELAY(SPENT=3,ADD=0) 000d40 b319 in tmp_reg,PINA 000d41 781f andi tmp_reg,0b10001111 ; decode port number - ; internal port number in IC 8255 000d42 3816 cpi tmp_reg,0b10000110 ; original mask 0b10000100 000d43 f151 breq wr_kbd_pc ; sound port ; handle for PA, PB (0,1): 000d44 3814 test_portA_kbd: cpi tmp_reg,0b10000100 000d45 f419 brne test_portB_kbd 000d46 9340 0221 sts kbd_ports+0,A 000d48 c925 rjmp i_cycle_turbo_10T 000d49 3815 test_portB_kbd: cpi tmp_reg,0b10000101 000d4a f419 brne test_portCW_kbd 000d4b 9340 0222 sts kbd_ports+1,A 000d4d c920 rjmp i_cycle_turbo_10T 000d4e 3817 test_portCW_kbd: cpi tmp_reg,0b10000111 000d4f f039 breq wr_kbd_cw 000d50 b3e9 test_portROMM: in ZL,PINA 000d51 7f1c andi tmp_reg,0b11111100 000d52 3818 cpi tmp_reg,0b10001000 000d53 f2f9 breq wr_rom_modul 000d54 301c cpi tmp_reg,0b00001100 000d55 f311 breq wr_channel_0_7 000d56 c917 rjmp i_cycle_turbo_10T 000d57 3044 wr_kbd_cw: cpi A,0x04 ; L.A. fix to PC2:=0 000d58 f0e1 breq ton_0 000d59 9340 0224 sts kbd_ports+3,A 000d5b fd47 sbrc A,7 ; CW.7 == 0 is ADDRH bit set/reset instruction 000d5c c911 rjmp i_cycle_turbo_10T ; CW.7 == 1 is control word (not implemented) 000d5d 2f14 mov tmp_reg,A 000d5e 9516 lsr tmp_reg 000d5f 7017 andi tmp_reg,0b111 ; in tmp_reg is bit number(0..7) 000d60 9408 sec 000d61 27ee clr ZL 000d62 1fee mask_compute: rol ZL 000d63 951a dec tmp_reg 000d64 f7e9 brne mask_compute 000d65 9110 0223 lds tmp_reg,kbd_ports + 2 ; tmp_reg = port C of 8255 000d67 95e0 com ZL ; mask AND 000d68 231e and tmp_reg,ZL 000d69 95e0 com ZL ; mask OR 000d6a fd40 sbrc A,0 ; skip if zero bit must be written 000d6b 2b1e or tmp_reg,ZL 000d6c 2fe1 mov ZL,tmp_reg ; A dont change -> then software using CW, ie LiborLA fails 000d6d c001 rjmp direct_kbd_pc wr_kbd_pc: ; on port PC was connected LEDs a repro ; PC0 00 = repro vypnute 11=ton3 ; = 01 = ton1 ; PC1 10 = ton2 ; PC2 = zlta ledka - log.1 svieti a vypina repro ; PC3 = cervena ledka ; ton1 = 976 Hz ; ton2 = 1953 Hz ; ton3 = 3905 Hz ; sound options: ; 0=sound_off ; 1=ton1 ; 2=ton2 ; 3=ton3 ; 4=sound_on 000d6e 2fe4 mov ZL,A 000d6f 93e0 0223 direct_kbd_pc: sts kbd_ports+2,ZL 000d71 fde2 sbrc ZL,2 000d72 c00a rjmp ton_4 000d73 70e7 andi ZL,0b111 ; manic1 send 0xc 000d74 f419 brne classic_ton 000d75 baae ton_0: out kbd_portC,_zero 000d76 2c2b mov portValue,_255 000d77 c8f6 rjmp i_cycle_turbo_10T 000d78 fbe0 classic_ton: bst ZL,0 ; PC3 := PC0 000d79 f9e3 bld ZL,3 000d7a 70ea andi ZL,0b01010 ; 0 PC0 0 PC1 0 000d7b bbee out kbd_portC,ZL 000d7c c8f1 rjmp i_cycle_turbo_10T ton_4: 000d7d 2422 clr portValue 000d7e c8ef rjmp i_cycle_turbo_10T 000d7f kb_lookup: .include "kb_lookup.asm" ; ; PMDEmu - AVR based emulator of Czechoslovak microcomputer PMD-85 originally based on I8080 ; Copyright (C) 2023 Peter Chrenko <stare********@gmail.com>, Topolcany, Slovakia ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; ; kb_lookup.asm ; for each scan code (PC keyboard) assign pair numbers : column number & row number (PMD keyboard) ; PMD-85 has special keys K0-K11 mapped to F1-F12 000d7f kb_code00: .db (0<<4)|rx, (8<<4)|r0 ; ; f9 = k8 000d7f 8100 000d80 kb_code02: .db (0<<4)|rx, (4<<4)|r0 ; ; f5=k4 000d80 4100 000d81 kb_code04: .db (2<<4)|r0, (0<<4)|r0 ; F3(k2) ; F1(k0) 000d81 0121 000d82 kb_code06: .db (1<<4)|r0, (11<<4)|r0 ; F2(k1) ; f12=k11 000d82 b111 000d83 kb_code08: .db (6<<4)|r0, (9<<4)|r0 ; ; f10=k9 000d83 9161 000d84 kb_code0A: .db (7<<4)|r0, (5<<4)|r0 ; f8=k7 ; f6=k5 000d84 5171 000d85 kb_code0C: .db (3<<4)|r0, (14<<4)|r1 ; f4(k3); TAB 000d85 e231 000d86 kb_code0E: .db (14<<4)|r0, (0<<4)|rx ; ` = RCL 000d86 00e1 000d87 kb_code10: .db (0<<4)|rx, (0<<4)|rx ; 000d87 0000 000d88 kb_code12: .db (0<<4)|rx, (0<<4)|rx ; 000d88 0000 000d89 kb_code14: .db (0<<4)|rx, (0<<4)|r2 ; Q 000d89 0400 000d8a kb_code16: .db (0<<4)|r1, (0<<4)|rx ; 1 000d8a 0002 000d8b kb_code18: .db (0<<4)|rx, (0<<4)|rx ; 000d8b 0000 000d8c kb_code1A: .db (1<<4)|r4, (1<<4)|r3 ; Y S 000d8c 181f 000d8d kb_code1C: .db (0<<4)|r3, (1<<4)|r2 ; A W 000d8d 1408 000d8e kb_code1E: .db (1<<4)|r1, (0<<4)|rx ; 2 000d8e 0012 000d8f kb_code20: .db (0<<4)|rx, (3<<4)|r4 ; c 000d8f 3f00 000d90 kb_code22: .db (2<<4)|r4, (2<<4)|r3 ; x 000d90 282f 000d91 kb_code24: .db (2<<4)|r2, (3<<4)|r1 ; E 4 000d91 3224 000d92 kb_code26: .db (2<<4)|r1, (0<<4)|rx ; 3 000d92 0022 000d93 kb_code28: .db (0<<4)|rx, (0<<4)|r4 ; SPACE 000d93 0f00 000d94 kb_code2A: .db (4<<4)|r4, (3<<4)|r3 ; v F 000d94 384f 000d95 kb_code2C: .db (4<<4)|r2, (3<<4)|r2 ; T R 000d95 3444 000d96 kb_code2E: .db (4<<4)|r1, (0<<4)|rx ; 5 000d96 0042 000d97 kb_code30: .db (0<<4)|rx, (6<<4)|r4 ; n 000d97 6f00 000d98 kb_code32: .db (5<<4)|r4, (5<<4)|r3 ; b H 000d98 585f 000d99 kb_code34: .db (4<<4)|r3, (5<<4)|r2 ; G Y 000d99 5448 000d9a kb_code36: .db (5<<4)|r1, (0<<4)|rx ; 6 000d9a 0052 000d9b kb_code38: .db (0<<4)|rx, (0<<4)|rx ; 000d9b 0000 000d9c kb_code3A: .db (7<<4)|r4, (6<<4)|r3 ; M J 000d9c 687f 000d9d kb_code3C: .db (6<<4)|r2, (6<<4)|r1 ; U 7 000d9d 6264 000d9e kb_code3E: .db (7<<4)|r1, (0<<4)|rx ; 8 000d9e 0072 000d9f kb_code40: .db (0<<4)|rx, (8<<4)|r4 ; , 000d9f 8f00 000da0 kb_code42: .db (7<<4)|r3, (7<<4)|r2 ; K I 000da0 7478 000da1 kb_code44: .db (8<<4)|r2, (9<<4)|r1 ; O 0 000da1 9284 000da2 kb_code46: .db (8<<4)|r1, (0<<4)|rx ; 9 000da2 0082 000da3 kb_code48: .db (0<<4)|rx, (9<<4)|r4 ; . 000da3 9f00 000da4 kb_code4A: .db (10<<4)|r4, (8<<4)|r3 ; / L 000da4 88af 000da5 kb_code4C: .db (9<<4)|r3, (9<<4)|r2 ; P 000da5 9498 000da6 kb_code4E: .db (10<<4)|r1, (0<<4)|rx ; - 000da6 00a2 000da7 kb_code50: .db (0<<4)|rx, (0<<4)|rx ; 000da7 0000 000da8 kb_code52: .db (10<<4)|r3, (0<<4)|rx ; ' 000da8 00a8 000da9 kb_code54: .db (10<<4)|r2, (10<<4)|r3 ; [ = 000da9 a8a4 000daa kb_code56: .db (0<<4)|rx, (0<<4)|rx ; 000daa 0000 000dab kb_code58: .db (0<<4)|rx, (0<<4)|rx ; 000dab 0000 000dac kb_code5A: .db (14<<4)|r4, (11<<4)|r2 ; ENTER ] 000dac b4ef 000dad kb_code5C: .db (0<<4)|rx, (0<<4)|rx ; 000dad 0000 000dae kb_code5E: .db (0<<4)|rx, (0<<4)|rx ; 000dae 0000 000daf kb_code60: .db (0<<4)|rx, (0<<4)|rx ; 000daf 0000 000db0 kb_code62: .db (0<<4)|rx, (0<<4)|rx ; 000db0 0000 000db1 kb_code64: .db (0<<4)|rx, (0<<4)|rx ; 000db1 0000 000db2 kb_code66: .db (12<<4)|r2, (0<<4)|rx ; BACKSPACE 000db2 00c4 000db3 kb_code68: .db (0<<4)|rx, (12<<4)|r3 ; ; END <|-- rol arrow 000db3 c800 000db4 kb_code6A: .db (0<<4)|rx, (12<<4)|r2 ; ; left arrow 000db4 c400 000db5 kb_code6C: .db (13<<4)|r2, (0<<4)|rx ; HOME ; 000db5 00d4 000db6 kb_code6E: .db (0<<4)|rx, (0<<4)|rx ; 000db6 0000 000db7 kb_code70: .db (12<<4)|r1, (13<<4)|r1 ; INS, DEL 000db7 d2c2 000db8 kb_code72: .db (14<<4)|r3, (13<<4)|r2 ; down arrow ; home 000db8 d4e8 000db9 kb_code74: .db (14<<4)|r2, (12<<4)|r3 ; right arrow ; up arrow 000db9 c8e4 000dba kb_code76: .db (0<<4)|rx, (12<<4)|r0 ; ESC ; Numlock = WRK 000dba c100 000dbb kb_code78: .db (10<<4)|r0, (13<<4)|r3 ; f11=k10 ; sede(+) = END 000dbb d8a1 000dbc kb_code7A: .db (14<<4)|r3, (0<<4)|rx ; pgdn ; 000dbc 00e8 000dbd kb_code7C: .db (0<<4)|rx, (12<<4)|r3 ; * (on numpad) ; pgup 000dbd c800 000dbe kb_code7E: .db (0<<4)|rx, (0<<4)|rx ; 000dbe 0000 000dbf kb_code80: .db (0<<4)|rx, (0<<4)|rx ; 000dbf 0000 000dc0 kb_code82: .db (0<<4)|rx, (6<<4)|r0 ; ; f7=k6 000dc0 6100 .org (high(PC) + (low(PC) != 0) ) *256 ; alignment 256 words i_table: .include "8080.asm" ; ; PMDEmu - AVR based emulator of Czechoslovak microcomputer PMD-85 originally based on I8080 ; Copyright (C) 2023 Peter Chrenko <stare********@gmail.com>, Topolcany, Slovakia ; ; This program is free software; you can redistribute it and/or modify ; it under the terms of the GNU General Public License as published by ; the Free Software Foundation; either version 2 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ; 000e00 c882 rjmp _nop 000e01 cb20 rjmp _lxi_b 000e02 cdb0 rjmp _stax_b 000e03 caf5 rjmp _inx_b 000e04 c911 rjmp _inr_b 000e05 c916 rjmp _dcr_b 000e06 c91b rjmp _mvi_b 000e07 cbb4 rjmp _rlca 000e08 c87a rjmp _none 000e09 cb13 rjmp _dad_b 000e0a cd9a rjmp _ldax_b 000e0b caff rjmp _dcx_b 000e0c c93c rjmp _inr_c 000e0d c941 rjmp _dcr_c 000e0e c946 rjmp _mvi_c 000e0f cbb2 rjmp _rrca 000e10 c872 rjmp _none 000e11 cb1e rjmp _lxi_d 000e12 cd98 rjmp _stax_d 000e13 cae8 rjmp _inx_d 000e14 c967 rjmp _inr_d 000e15 c96c rjmp _dcr_d 000e16 c971 rjmp _mvi_d 000e17 cbb0 rjmp _rla 000e18 c86a rjmp _none 000e19 cb11 rjmp _dad_d 000e1a cda0 rjmp _ldax_d 000e1b caf2 rjmp _dcx_d 000e1c c992 rjmp _inr_e 000e1d c997 rjmp _dcr_e 000e1e c99c rjmp _mvi_e 000e1f cbac rjmp _rra 000e20 c862 rjmp _none 000e21 cb1c rjmp _lxi_h 000e22 cdb0 rjmp _shld 000e23 cadb rjmp _inx_h 000e24 c9bd rjmp _inr_h 000e25 c9c2 rjmp _dcr_h 000e26 c9c7 rjmp _mvi_h 000e27 ce2a rjmp _daa 000e28 c85a rjmp _none 000e29 cb0f rjmp _dad_h 000e2a cd96 rjmp _lhld 000e2b cae5 rjmp _dcx_h 000e2c c9e8 rjmp _inr_l 000e2d c9ed rjmp _dcr_l 000e2e c9f2 rjmp _mvi_l 000e2f cb8a rjmp _cma 000e30 c852 rjmp _none 000e31 cb20 rjmp _lxi_sp 000e32 cd56 rjmp _sta 000e33 cace rjmp _inx_sp 000e34 caae rjmp _inr_m 000e35 cab8 rjmp _dcr_m 000e36 cd62 rjmp _mvi_m 000e37 cb80 rjmp _stc 000e38 c84a rjmp _none 000e39 cb0d rjmp _dad_sp 000e3a cd40 rjmp _lda 000e3b cad8 rjmp _dcx_sp 000e3c c898 rjmp _inr_a 000e3d c89d rjmp _dcr_a 000e3e c8a2 rjmp _mvi_a 000e3f cb75 rjmp _cmc 000e40 c81e rjmp _mov_bb 000e41 cb2d rjmp _mov_bc 000e42 cb2e rjmp _mov_bd 000e43 cb2f rjmp _mov_be 000e44 cb30 rjmp _mov_bh 000e45 cb31 rjmp _mov_bl 000e46 c8e0 rjmp _mov_bm 000e47 cb25 rjmp _mov_ba 000e48 cb32 rjmp _mov_cb 000e49 c815 rjmp _mov_cc 000e4a cb32 rjmp _mov_cd 000e4b cb33 rjmp _mov_ce 000e4c cb34 rjmp _mov_ch 000e4d cb35 rjmp _mov_cl 000e4e c90b rjmp _mov_cm 000e4f cb29 rjmp _mov_ca 000e50 cb36 rjmp _mov_db 000e51 cb37 rjmp _mov_dc 000e52 c80c rjmp _mov_dd 000e53 cb37 rjmp _mov_de 000e54 cb38 rjmp _mov_dh 000e55 cb39 rjmp _mov_dl 000e56 c936 rjmp _mov_dm 000e57 cb2d rjmp _mov_da 000e58 cb3a rjmp _mov_eb 000e59 cb3b rjmp _mov_ec 000e5a cb3c rjmp _mov_ed 000e5b c803 rjmp _mov_ee 000e5c cb3c rjmp _mov_eh 000e5d cb3d rjmp _mov_el 000e5e c961 rjmp _mov_em 000e5f cb31 rjmp _mov_ea 000e60 cb3e rjmp _mov_hb 000e61 cb3f rjmp _mov_hc 000e62 cb40 rjmp _mov_hd 000e63 cb41 rjmp _mov_he 000e64 c7fa rjmp _mov_hh 000e65 cb41 rjmp _mov_hl 000e66 c98c rjmp _mov_hm 000e67 cb35 rjmp _mov_ha 000e68 cb42 rjmp _mov_lb 000e69 cb43 rjmp _mov_lc 000e6a cb44 rjmp _mov_ld 000e6b cb45 rjmp _mov_le 000e6c cb46 rjmp _mov_lh 000e6d c7f1 rjmp _mov_ll 000e6e c9b7 rjmp _mov_lm 000e6f cb39 rjmp _mov_la 000e70 c8bb rjmp _mov_mb 000e71 c8ed rjmp _mov_mc 000e72 c91f rjmp _mov_md 000e73 c951 rjmp _mov_me 000e74 c983 rjmp _mov_mh 000e75 c9b5 rjmp _mov_ml 000e76 c7e7 rjmp _hlt 000e77 c873 rjmp _mov_ma 000e78 cae8 rjmp _mov_ab 000e79 cae9 rjmp _mov_ac 000e7a caea rjmp _mov_ad 000e7b caeb rjmp _mov_ae 000e7c caec rjmp _mov_ah 000e7d caed rjmp _mov_al 000e7e c867 rjmp _mov_am 000e7f c7df rjmp _mov_aa 000e80 c8b3 rjmp _add_b 000e81 c8e5 rjmp _add_c 000e82 c917 rjmp _add_d 000e83 c949 rjmp _add_e 000e84 c97b rjmp _add_h 000e85 c9ad rjmp _add_l 000e86 c9c1 rjmp _add_m 000e87 c873 rjmp _add_a 000e88 c8ad rjmp _adc_b 000e89 c8df rjmp _adc_c 000e8a c911 rjmp _adc_d 000e8b c943 rjmp _adc_e 000e8c c975 rjmp _adc_h 000e8d c9a7 rjmp _adc_l 000e8e c9c0 rjmp _adc_m 000e8f c86d rjmp _adc_a 000e90 c8a8 rjmp _sub_b 000e91 c8da rjmp _sub_c 000e92 c90c rjmp _sub_d 000e93 c93e rjmp _sub_e 000e94 c970 rjmp _sub_h 000e95 c9a2 rjmp _sub_l 000e96 c9c0 rjmp _sub_m 000e97 c868 rjmp _sub_a 000e98 c8a2 rjmp _sbb_b 000e99 c8d4 rjmp _sbb_c 000e9a c906 rjmp _sbb_d 000e9b c938 rjmp _sbb_e 000e9c c96a rjmp _sbb_h 000e9d c99c rjmp _sbb_l 000e9e c9bf rjmp _sbb_m 000e9f c862 rjmp _sbb_a 000ea0 c8a2 rjmp _ana_b 000ea1 c8d4 rjmp _ana_c 000ea2 c906 rjmp _ana_d 000ea3 c938 rjmp _ana_e 000ea4 c96a rjmp _ana_h 000ea5 c99c rjmp _ana_l 000ea6 c9c9 rjmp _ana_m 000ea7 c862 rjmp _ana_a 000ea8 c89e rjmp _xra_b 000ea9 c8d0 rjmp _xra_c 000eaa c902 rjmp _xra_d 000eab c934 rjmp _xra_e 000eac c966 rjmp _xra_h 000ead c998 rjmp _xra_l 000eae c9cf rjmp _xra_m 000eaf c862 rjmp _xra_a 000eb0 c894 rjmp _ora_b 000eb1 c8c6 rjmp _ora_c 000eb2 c8f8 rjmp _ora_d 000eb3 c92a rjmp _ora_e 000eb4 c95c rjmp _ora_h 000eb5 c98e rjmp _ora_l 000eb6 c9c0 rjmp _ora_m 000eb7 c856 rjmp _ora_a 000eb8 c886 rjmp _cmp_b 000eb9 c8b8 rjmp _cmp_c 000eba c8ea rjmp _cmp_d 000ebb c91c rjmp _cmp_e 000ebc c94e rjmp _cmp_h 000ebd c980 rjmp _cmp_l 000ebe c9a8 rjmp _cmp_m 000ebf c846 rjmp _cmp_a 000ec0 cbfd rjmp _rnz 000ec1 cb99 rjmp _pop_b 000ec2 ccae rjmp _jnz 000ec3 cc90 rjmp _jmp 000ec4 cc45 rjmp _cnz 000ec5 cb2e rjmp _push_b 000ec6 c9be rjmp _adi 000ec7 ccaf rjmp _rst0 000ec8 cbf1 rjmp _rz 000ec9 cbda rjmp _ret 000eca cca2 rjmp _jz 000ecb c7b7 rjmp _none 000ecc cc41 rjmp _cz 000ecd cc48 rjmp _call 000ece c9bd rjmp _aci 000ecf cca7 rjmp _rst1 000ed0 cbc7 rjmp _rnc 000ed1 cb73 rjmp _pop_d 000ed2 cc6a rjmp _jnc 000ed3 ce69 rjmp _out 000ed4 cc2d rjmp _cnc 000ed5 cb0c rjmp _push_d 000ed6 c9bd rjmp _sui 000ed7 cc9f rjmp _rst2 000ed8 cbbb rjmp _rc 000ed9 c7a9 rjmp _none 000eda cc5e rjmp _jc 000edb cdcf rjmp _in 000edc cc21 rjmp _cc 000edd c7a5 rjmp _none 000ede c9bc rjmp _sbi 000edf cc97 rjmp _rst3 000ee0 cbf0 rjmp _rpo 000ee1 cb4d rjmp _pop_h 000ee2 cc7b rjmp _jpo 000ee3 cd19 rjmp _xthl 000ee4 cbfb rjmp _cpo 000ee5 caea rjmp _push_h 000ee6 c9c6 rjmp _ani 000ee7 cc8f rjmp _rst4 000ee8 cbd9 rjmp _rpe 000ee9 cc8b rjmp _pchl 000eea cc5a rjmp _jpe 000eeb cd5f rjmp _xchg 000eec cc02 rjmp _cpe 000eed c795 rjmp _none 000eee c9cc rjmp _xri 000eef cc87 rjmp _rst5 000ef0 cbab rjmp _rp 000ef1 cb7f rjmp _pop_a 000ef2 cc4e rjmp _jp 000ef3 c78f rjmp _di 000ef4 cc11 rjmp _cp 000ef5 cb10 rjmp _push_a 000ef6 c9bd rjmp _ori 000ef7 cc7f rjmp _rst6 000ef8 cba7 rjmp _rm 000ef9 ccfa rjmp _sphl 000efa cc3a rjmp _jm 000efb c787 rjmp _ei 000efc cc15 rjmp _cm 000efd c785 rjmp _none 000efe c9a5 rjmp _cpi 000eff cc77 rjmp _rst7 Assembly complete with no errors.