Autor Wątek: Tricki na Amstradzie  (Przeczytany 76319 razy)

ZbyniuR

  • *****
  • Wiadomości: 3333
  • Miejsce pobytu:
    Carlisle w UK
  • CPC AGA PSX
Tricki na Amstradzie
« dnia: 2013.02.06, 01:27:04 »
OVERSCAN

W tych nowszych grach obrazek startowy zajmujący także ramkę to nie taki rzadki widok, jest tez kilka pokazów slajdów z takimi większymi obrazkami.
Nie raz też ekranik się zmniejsza np do rozmiarów podobnych jak w Spectrum by łatwiej zrobić port gry na CPC, mamy wtedy szerokaśną ramkę. Za to procek się troszkę mniej męczy bo ma mniejszy obszar pamięci ekranu do "obrobienia". A np ARKANOID ma obraz bardziej wysoki niż szeroki.  Bo aby w CPC zmienić proporcje ekranu nie potrzeba przerwań ani kości z PLUSA, tylko trzeba zmienić zawartość kilku rejestrów w CRTC, a robi się to komendą OUT. OUT &BC00,(tu nr rejestru który chcesz zmienić):OUT &BD00,(tu wartość jaką chcesz tam wpisać). Overscan wymaga zmian w następujących rejestrach.

nr rejestru / co to zmienia / standardowa wartość / FullScreen
2 - pozycja lewej krawędzi ekranu - 46 - 50
1 - szerokość ekranu - 40 - 48
7 - pozycja górnej krawędzi ekranu - 30 - 35
6 - wysokość ekranu - 25 - 34

Pełny opis rejestrów http://www.cpcwiki.eu/index.php/CRTC#The_6845_Registers

Bawiąc się nimi można zmieniać na NTSC, włączać interlace, zmienić wygląd i mruganie kursora, zmieniać wysokość znaków w pikselach, zmieniać adres pamięci ekranu, rysować piórem świetlnym po ekranie.

Czyli OUT &BC00,2:OUT &BD00,50:OUT &BC00,1:OUT &BD00,48:OUT &BC00,7:OUT &BD00,35:OUT &BC00,6:OUT &BD00,34  daje FullScreen nie zostawiając ramki w rozdziałce 768x272 w 2kolorach, 384x272 w 4kol, lub 192x272 w 16. Ale jak łatwo policzyć taki ekran zajmuje dokładnie 25,5KB a jak widać w dolnych kilku linijkach powtarza się to co jest na górze ekranu. I tu się przydają przerwania, by w chwili gdy ma wyświetlić dolne linijki czytał je spod innego adresu, co trzeba przestawiać ileś tam razy na sekundę. ;)

Słyszałem że w dodatkowych niepublikowanych rejestrach można włączyć drugi obszar do wyświetlenia, (dzięki czemu np FullScreen nie wymagałoby przerwań) a widziałem to w paru gierkach. np w Prehistoric 2, ekran jest szerszy ale też niższy niż standardowo więc nie przekracza 16KB, ale kilka linijek odstępu pod nim jest jeszcze linijka z punktami i życiami, a pomiędzy nimi jest ramka.

Jako ciekawostkę podam że jedynym trybem ekranu w Amstradzie PCW który ma podobnego scalaka do grafy, jest 720x256 2kolory 22,5KB czyli zostawia wąziutką rameczkę.
« Ostatnia zmiana: 2013.02.26, 18:30:29 wysłana przez ZbyniuR »
- Jeśli masz w domu światło i wodę, tzn. że masz światłowód. ;)

ZbyniuR

  • *****
  • Wiadomości: 3333
  • Miejsce pobytu:
    Carlisle w UK
  • CPC AGA PSX
Odp: Tricki na Amstradzie
« Odpowiedź #1 dnia: 2013.02.06, 01:35:35 »
Propo mrugania na ekranie po wpisaniu CAT na dyskietce z grą R-Type 2012.
Mrugające kolory w Amstradzie to nie czary. Dopisując po wyświetleniu się tej listy rekordów INK 2,10,20 słowo Ranking zacznie mrugać tak samo. Bo dodając trzeci zbędny parametr przy definiowaniu koloru zaczyna mrugać. Podobnie BORDER 6,18 a normalnie wystarcza jeden parametr. Ciekawsze jest to że po wpisaniu komendy CAT zamiast wyświetlać listę plików i ilość wolnego miejsca tworzą się cuda. hehe :)

Zanim podpowiem jak coś takiego umieścić na dyskietce. Wyjaśnię że gdy wyświetlimy na ekranie komendą PRINT znaczki o kodach 1 do 31 można robić fajne rzeczy które normalnie robimy takimi rozkazami jak MODE, INK, BORDER, LOCATE, SYMBOL i parę innych. By uzyskać te znaczki wciskamy litery z Controlem.

Klawisz - co robi (parametry jeśli konieczne)
Ctrl+D - MODE - zmienia tryb graficzny (0, 1 lub 2)
Ctrl+] - BORDER - kolor ramki (2 znaczki jeśli nie ma mrugać to takie same)
Ctrl+\ - INK - definiuje kolor w palecie - (nr kol i 2 znaczki tak jak wyżej)
Ctrl+O - PEN (1 znak)
Ctrl+N - PAPER (1 znak)
Ctrl+X - przełącza kolory na invers
Ctrl+G - brzęczyk
Ctrl+0 - LOCATE - zmienia współrzędne kursora (2 znaki)
Ctrl+L - CLS
Ctrl+U - wyłącza wyświetlanie znaków
Ctrl+F - przywraca wyświetlanie
Ctrl+V - zmienia tryb nakładania się znaków na siebie (cyfra 1 pozwala nakładać na siebie np L i / dając literkę Ł)
Ctrl+Y - SYMBOL - definiuje wygląd znaku (1szy znak to nr ASCII a kolejne 8 to wygląd znaku)
Ctrl+(jeden z HIJK) - to strzałeczki które przesuwają kursor

Można się tym troszkę pobawić by sprawdzić jak to działa. Stosowanie takich tricków bardzo skracają lisingi w Basicu. Bo pozwala wcisnąć w komendę PRINT szereg rozkazów definiujących wygląd ekranu, albo upchać wygląd wszystkich polskich znaków w jednej linijce.
A teraz jak to zastosować na dyskietce. Będzie potrzebny jakiś edytor dyskowy. Na zerowej ścieżce 2KB czyli sektory od C1 do C4 zawierają katalog dyskietki. By zrobić coś takiego jak na wspomnianej R-Type trzeba przygotować sobie szereg znaczków jakie chcemy aby się wykonały lub wyświetliły po wpisaniu komendy CAT a potem podzielić je na 6 znakowe fragmenty i wykorzystując puste pozycje w katalogu wpisywać zamiast 8 znaków nazwy pliku, znaczek Ctrl+F potem 6 znaczków jakie chcemy i Ctrl+U by zapobiec wyświetleniu się kropeczki w nazwie pliku oraz ilości KB do tego pliku. Nie zapomnijcie zrobić kopi dyskietki na której grzebiecie i nie uszkodźcie nazwy prawdziwych plików jakie chcecie by działały z tej dyskietki. Miłej zabawy.
- Jeśli masz w domu światło i wodę, tzn. że masz światłowód. ;)

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Tricki na Amstradzie
« Odpowiedź #2 dnia: 2013.02.06, 10:09:54 »
A może zechciałbyś napisać taki wstępny artykuł - jak w ogóle Amstrad generuje obraz, jak jest zorganizowana pamięć obrazu, jak ustawia się tryby graficzne, zmienia paletę, jak wyświetlić sprajta ?

Żeby rozmawiać o trickach trzeba najpierw orientować się w podstawach ;)

ZbyniuR

  • *****
  • Wiadomości: 3333
  • Miejsce pobytu:
    Carlisle w UK
  • CPC AGA PSX
Odp: Tricki na Amstradzie
« Odpowiedź #3 dnia: 2013.02.06, 13:22:00 »
  To by pochłonęło masę czasu a z natury jestem leniwy. I obawiam się że mało kto by to chciał czytać i stosować. Nie za bardzo mi się chce uprawiać sztukę dla sztuki, wolałbym wiedzieć że konkretna osoba ma konkretne pytanie, to przynajmniej wiedział bym, że nie piszę do ściany.
  To co napisałem powyżej dla osoby która bawiła się kiedyś Basic-iem i to niekoniecznie na CPC, powinno być zrozumiałe. Jak komuś się bardzo zachce a umie używać Googla to sobie znajdzie dokładny opis komend Basica z parametrami, organizację pamięci, opis kernela (czyli wszystkich procedur maszynowych w ROMie), opis każdego pina na każdym złączu, czy też wspomniany wyżej opis rejestrów CRTC lub AY, Że o rozkazach Z80 nie wspomnę. Nawet jak materiał nie będzie w znanym mu języku Google przetłumaczy, a żyłka odkrywcy dopełni reszty. ;)
  Na sprajtach się nie znam, Basic standardowo komend do nich nie ma, a programy do ich tworzenia zwykle mają edytor i dodatkowe komendy by gotowych sobie w Basicu użyć, co dokładnie opisują w instrukcji. Sam jakoś nigdy się za żadne nie zabrałem. Gdy pisałem kiedyś coś a`la okienkowa nakładka na system, strzałeczkę nakładałem na tło w inversie tak by go nie naruszyć, a wyświetlałem jako zaprojektowane wcześniej znaki, wyświetlane w trybie graficznym by precyzję co do piksela umożliwić, a użyłem standardowych rozkazów Basica. Jeśli ktoś ma jakieś konkretne pytania a nie polegają na tym że znajdź mi to i to bo mi się nie chce Googla użyć. to mogę odpowiedzieć w tym wątku lub na gg. :)
  Zainteresowanym mogę udostępnić .dsk np z polskimi znakami w zaledwie 2óch linijkach Basica, albo wyjaśnienie jak używać wąskiej czcionki takiej o szerokości 4 pikseli tak aby mieć 40 znaków w wierszu w 16kolorowym trybie ekranu albo 80 znaków w tym 4kolorowym. To pierwsze pewnie nie raz w grach widzieliście nawet czcionki w paseczki, a to ostatnie to mój oryginalny pomysł. ;)

  Jeśli chodzi o artykuł wstępny to raczej by musiał wyjaśniać jak wogóle coś włączyć na Amstradzie z dyskietki lub taśmy. By chciało się komuś wyciągnąć maszynę z piwnicy kolegi albo pobawić się emulatorem. Nawet napisałem niedawno coś takiego na ppa.pl
To Amigowa stronka i jest tam także wątek o Amstradach ale martwy. Co mnie nie powstrzymało przed dodaniem swoich 3ech groszy.
http://www.ppa.pl/forum/hyde-park/13918/amstrad-cpc/2#m367884   <- tu i o jeden wpis powyżej też.
A także moje wynurzenia o retro kompach  http://www.ppa.pl/forum/hyde-park/24701/hej-byly-czasy-c64-i-atari/2#m350785

Jeśli ktoś tam zajrzy i chce skomentować to może tutaj, bo tam raczej nikt tego nie zauważy. ;)

PS.: Wiem że Overscan robi się podobnie jak pisałem w tym wątku wcześniej także na małym Atari 384x240, w ST 704x260 i w Amidze 704x576 OCS i 1440x580 AGA, a w Commodorku można wyświetlać duszki na ramce, ale czy można w nim robić Overscan to nie wiem. Podobnie nie wiem czy da się to w Spectrum zrobić. Nie śmiejcie się tylko mnie oświećcie. :)
- Jeśli masz w domu światło i wodę, tzn. że masz światłowód. ;)

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Tricki na Amstradzie
« Odpowiedź #4 dnia: 2013.02.06, 14:49:18 »
Rozumiem, też nie lubię pisać do ściany ;)

Więc mam konkretne pytanie:

W Spectrum mamy pamięć ekranu pod sztywnym adresem 16384 i żeby ten ekran wyświetlić nie trzeba robić nic, bo i tak 50 razy na sekundę zostanie on wysłany przez Ulę na telewizor, czy chcemy tego czy nie.

Jak jest w Amstradzie? Coś mi się kojarzy że tam trzeba napisać procedurę która wyśle grafikę na Spectrum za pomocą instrukcji OUT. Czy dobrze mi się kojarzy?

ZbyniuR

  • *****
  • Wiadomości: 3333
  • Miejsce pobytu:
    Carlisle w UK
  • CPC AGA PSX
Odp: Tricki na Amstradzie
« Odpowiedź #5 dnia: 2013.02.06, 17:16:17 »
W Amstradzie można wyświetlić dowolny obszar pamięci. Zmienia się go modyfikując w CRTC rejestr 12 (starszy bajt adresu nowej pamięci ekranu) a w rej.13 młodszy bajt, który zwykle zostawiamy na zero. Wtedy wyświetla 16 KB pamięci poczynając od podanego adresu. Domyślna pamięć ekranu zaczyna się od szesnastkowo &C000, a np polecenia OUT &BC00,12:OUT &BD00,&10 przełączy obszar pamięci wysyłanej na ekran na &4000. Natomiast OUT &BC00,12:OUT &BD00,&30 przywróci stan normalny. A 2gi parametr się nie pokrywa z adresem pamięci z punktu widzenia procesora bo CRTC widzi bloki pamięci w jakiejś innej kolejności, nie wiem czemu.  Jeśli przygotujesz sobie odpowiednio dwa obrazki i umieścisz pod tymi adresami i dopiszesz procedurkę w kodzie maszynowym (ot raptem kilkanaście bajtów) która nimi "miga" to powstaną kolorowsze obrazki tzn 10 kolorowy w trybie 4 kolorowym lub 136kol w trybie 16kol. Skoro "zmieszanie" np koloru 4 z 7 da taki sam kolor pośredni co zmieszanie kol 7 z 4 to więcej kombinacji się nie da. ;) Basic raczej nie będzie migał dość szybko, no chyba że na emulatorze przestawionym na kilkaset % prędkości. Zresztą trudniej przygotować takie obrazki niż sprawić by tak mrugały. hehe :D

A skoro już mowa o dwóch ekranach wpisując w 6128 - POKE &B7C6,&40  komputer zaczyna wszystkie polecenia do rysowania linii i wyświetlania tekstów wykonywać na pamięci ekranu od &4000, wpisując tam &C0 przywraca standardowy obszar pamięci. (W modelu 464 adresem tego POKE jest &B1CB) Ten POKE w kombinacji z tymi OUT-ami powyżej, daje możliwość przełączania dwóch ekranów tak by w chwili gdy wyświetla jeden z nich rysował sobie klatkę animki na drugim z nich, po czym wyświetla nowo narysowaną a na poprzednim ekranie w czasie gdy tworzy już kolejną klatkę na ekranie w danej chwili schowanej. Był o tym artykuł ANIMACJA w Bajtku 5/6-1986 niestety z błędami. Może pewnego pięknego dnia zechce mi się go poprawić i tu wstawić .dsk
A gdyby do tego jeszcze dodać bloki ramdysku - oczopląs. :D

PS.: Chyba jednak można to jakoś modyfikować w Spectrumie bo czytałem coś o programowych trybach graficznych które mrugają ekranami by tworzyć wrażenie dodatkowych kolorów.
- Jeśli masz w domu światło i wodę, tzn. że masz światłowód. ;)

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Tricki na Amstradzie
« Odpowiedź #6 dnia: 2013.02.06, 21:13:54 »
Dzięki :)

Cytuj
PS.: Chyba jednak można to jakoś modyfikować w Spectrumie bo czytałem coś o programowych trybach graficznych które mrugają ekranami by tworzyć wrażenie dodatkowych kolorów.

To trochę inaczej działa. Istotnie w opisanym efekcie co drugą klatkę wysyłamy np raz czerwony atrybut, a raz żółty w efekcie dostając kolor pomarańczowy, mniej lub bardziej migający.

Ale piksele i kolory te są czytane przez ULĘ zawsze spod tych samych adresów pamięci. Czyli nie możemy sobie wskazać na inny obszar pamięci tylko musimy podmienić wartości w sztywno ustalonym obszarze.

Na Spectrum 48 nie ma bata, trzeba przekopiować bajty jeden po drugim, na co między odświeżeniami ekranu jest niestety mało czasu i zrobić cały ekran jest praktycznie niemożliwe

Na modelach ze 128 kB jest myk w postaci stronicowania (paging). Ponieważ procesor Z80 jest w stanie obsłużyć tylko 64 kB adresów to aby móc korzystać z większej pamięci wprowadzono strony. Pisze się instrukcję OUT i całe 16 kB czyli jedna strona zostaje zamieniona przez inną stronę. W ten sposób  możemy łatwo i natychmiast przełączać dwa ekrany ale formalnie w chwili wyświetlania każdy z nich jest pod adresem 16384 :)

ZbyniuR

  • *****
  • Wiadomości: 3333
  • Miejsce pobytu:
    Carlisle w UK
  • CPC AGA PSX
Odp: Tricki na Amstradzie
« Odpowiedź #7 dnia: 2013.02.07, 07:13:53 »
Ahaaa :) Ciekawe jest to że 16KB bloki ramdysku w CPC 6128 a także w Atari 130XE. Przełączają się pod ten sam adres co w Spectrum. Może mają podobny scalaczek do zarządzania pamięcią? Nie wiem jak to jest w C128. Tylko że niestety w CPC tak przełączone bloki ramdysku widzi tylko procek a CRTC nie. :(  Możesz sobie tam przełączać co chcesz i Z80 widzi tam ten blok który przełączysz ale CRTC potrafi wyświetlać obraz tylko z podstawowych 64KB.

Ale nie płaczmy, tylko się bawmy. :) Komenda która przełącza blok pamięci 16KB zaczynający się od &4000 (lub 16384 jak ktoś woli), to OUT &7F00,192  <- ten ostatni numerek to standardowy blok. A ramdysk w 6128 to 4 bloki o numerach od 204 do 207. Ot i tyle. :)

Aha po podłączeniu standardowego rozszerzenia o 64KB (często kupowanego przez posiadaczy CPC464) dodatkowe bloki są pod numerami od 196 do 199, czyli innymi niż ramdysk w 6128, jednak 6128 też je będzie widział pod tymi samymi nr co w 464. Niestety na tak rozszerzonym 464 nie pójdzie większość programów które wymagają 128KB ramu właśnie z powodu tych innych nr bloków.

Są też rozszerzenia o 256KB które oba kompy (tzn 464 i 6128) widzą tak samo, bo w tym drugim wewnętrzny ramdysk jest wtedy niewidoczny. Można podłączyć takie dwa, co w sumie da 572KB RAMu. W takiej pamięci część dalszych bloków ma takie same nr jak te wewnętrzne w 6128 więc w 464 wraz ze stacją dysków, większość softu z 6128 powinna chodzić z wyjątkiem Basiców które używają którąś z nowych komend ze 6128. Większe rozszerzenia np o 4MB wymagają innego scalaczka do zarządzania RAMem. Może trudno je kupić ale w emulatorze się je ustawia suwaczkiem ot tak. ;)

Wszystkie powyższe uwagi o 464 prócz wersji Basica dotyczą tak samo modelu 664 oraz 464+, a te o 6128 dotyczą też 6128+. Standardowy blok przywraca OUT &7F00,192  A nr banku (w rozszerzeniu o 512KB) liczone od 0 do 31 oblicza wzór: OUT &7F00,196+(nrbanku AND 3)+(nrbanku AND 28)*2: Z czego standardowe wewnętrzne w 6128 to banki od 4 do 7.

PS.: Najszybszą znaną mi metodą przenoszenia bloku pamięci jest rozkaz ldir w asemblerze Z80. Jeśli nie kojarzysz to mogę wyjaśnić. :)
- Jeśli masz w domu światło i wodę, tzn. że masz światłowód. ;)

matofesi

  • *****
  • Wiadomości: 2048
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tricki na Amstradzie
« Odpowiedź #8 dnia: 2013.02.07, 07:22:08 »
LDIR nie jest w żadnym wypadku najszybszą metodą przenoszenia danych. Jest metodą najprostszą, ale ma na tyle duże narzuty, że choćby dobrze skonstruowana pętla z ciągiem kilkudziesięciu LDI będzie sporo szybsza.

Zresztą jak poprosisz to RafalM ci poopwiada więcej na ten temat ;)

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4537
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Tricki na Amstradzie
« Odpowiedź #9 dnia: 2013.02.07, 10:08:35 »
Jakbym bazował na LDI to Dziurak by nie powstał ;) Ale o tym, tzn o przenoszeniu blokow pamięci, będzie artykuł, tzn jest w moim TODO.

matofesi

  • *****
  • Wiadomości: 2048
  • Miejsce pobytu:
    Toruń/Poland
Odp: Tricki na Amstradzie
« Odpowiedź #10 dnia: 2013.02.07, 10:12:11 »
Wiem - dlatego napisałem choćby :P

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Tricki na Amstradzie
« Odpowiedź #11 dnia: 2013.02.07, 10:16:35 »
Cytuj
PS.: Najszybszą znaną mi metodą przenoszenia bloku pamięci jest rozkaz ldir w asemblerze Z80.

Jedna z wolniejszych :)

Kilka metod :

LD A,(DE)
LD (HL),A
INC HL
INC DE - 25 taktów na bajt

LDIR - 21 taktów na bajt

LDI - 16 taktów na bajt
LDI
LDI
LDI
...

kopiowanie przez stos - można zejść do jakichś 12,5 takta na bajt, ale  o wiele trudniejsze do zrozumienia i napisania niż poprzednie metody

No i pamiętajmy że w programowaniu mamy coś za coś - albo krótki kod kopiujący i mniejsza szybkość, albo dłuższy kod i większa szybkość.

W skrajnym najszybszym przypadku aby skopiować dajmy 5 kB danych potrzebny jest kod długości... jakieś 7 kB :)

Dobrym kompromisowym rozwiązaniem jest wspomniana pętla a w niej dajmy na to 16,32 itp. instrukcje LDI

ZbyniuR

  • *****
  • Wiadomości: 3333
  • Miejsce pobytu:
    Carlisle w UK
  • CPC AGA PSX
Odp: Tricki na Amstradzie
« Odpowiedź #12 dnia: 2013.02.07, 13:40:09 »
Ja pisywałem tylko w Basicu a

LD HL
LD DE
LD BC
LDIR
RET

to najbardziej zaawansowany kawałek kodu jaki zdarzało mi się używać świadomym znaczenia każdego bajta. :)
Czy potraficie tak zmodyfikować powyższą metodę bym mógł ją wywoływać w Basicu podając jednocześnie parametry?
czyli CALL adrprocedury,adrźródła,adrdocelowy,ileprzesłać 
a nie jak teraz, że muszę POKE-ami ją modyfikować i wywołać prostym CALL adrprocedury

I skoro trafiłem na takich speców to zapytam, ile by zajął kod do przeniesienia 16KB tą metodą LDI?
- Jeśli masz w domu światło i wodę, tzn. że masz światłowód. ;)

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4537
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Tricki na Amstradzie
« Odpowiedź #13 dnia: 2013.02.07, 13:53:11 »
to zależy od tego ile razy to LDI byłoby powtórzone:

LD HL,zrodlo ; 3b
LD DE,del ; 3b
LD A,0 ;2b <-- 256 powtorzen
petla:
rept 64 ; 64x powtorzone to co jest miedzy rept i endm
  LDI ; 64 * 2bajty
endm
DEC A ; 1b
jp NZ,petla ; 2b
ret

co da 13+128 = 141 bajtow
« Ostatnia zmiana: 2013.02.07, 14:26:14 wysłana przez Tygrys »

pear

  • *****
  • Wiadomości: 5509
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: Tricki na Amstradzie
« Odpowiedź #14 dnia: 2013.02.07, 13:59:13 »
Najszybsza metoda wymaga drobnej przeróbki http://velesoft.speccy.cz/data-gear/zxdma-interface2.jpg :)
Ile wtedy będzie bajtów/takt ? (Max. speed of data transfer on ZX128+ is 17.3 kB(17727 bytes) / frame = 865.6 kB(886350 bytes) / second) :)
ZX/Enterprise/CPC/Robotron/C128D