Moje aktivity v roku 2023 s PMD-85
V marci 2023 som sa zúčastnil po dlhých rokoch stretnutia zberateľov a priateľov starých počítačov v Suchej nad Parnou (Pri dvoch PMD85 v družnej debate s Liborom LA):

Moja 1/2 stolíka na byteFeste v Prahe 2023 (vľavo, vpravo prísediaci Libor LA):

PMD-85 verzia MIF85 + colorAce
Fungujúca 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 je segaMegaDrive2.
PS/2 Konektor - pripojenie PS/2 myši, alebo PS/2 klávesnice
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 HW
Recenzia na hardvérový emulátor/simulátor/opravná sada/klon PMD-85.
Je to staronový 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 hranie pokračuje. 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 problém s interným oscilátorom pri vyšších frekvenciách ako 18.432 MHz. Niektoré ATMEGA8515-16PU nechcú ísť stabilne na 20 MHz. Áno, overclocknuté o 25%. 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 originálny č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 ktorej 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.