forum speccy.pl

ZX Spectrum => PROGRAMOWANIE => Wątek zaczęty przez: Gelip w 2021.11.07, 10:21:24

Tytuł: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.07, 10:21:24
Potrzebuję program, który zamienia wartość HEX 8-bit na BIN, odwraca bity i oblicza znowu HEX:
HEX -> BIN -> REVBIN -> HEX
40 - 01000000 - 00000010 - 2
C0 - 11000000 - 00000011 - 3
78 - 01111000 - 00011110 - 1e

Znalazłem jakieś programy i próbuję zlepić ale coś chyba pomieszałem i nie wiem jak teraz zamienić znowu bin na dec i na hex:
HEXtoDEC (https://spectrumcomputing.co.uk/entry/25800/ZX-Spectrum/Hex_to_Dec_Conversion)
DECtoBIN (https://spectrumcomputing.co.uk/forums/viewtopic.php?p=52452#p52452)
Wyszło mi coś takiego.

DEC mi w sumie nie potrzebne tylko hex i bin
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: trojacek w 2021.11.07, 12:10:02
A jakie masz wymagania jeśli chodzi o wydajność? To jednorazowa konwersja, czy coś, co jest liczone na bieżąco?
Bo jeśli to ma być zrobione prosto i działać szybko, to ja bym to stablicował jako nibble (4 bity):

0 -> 0
1 -> 8
2 -> 4
3 -> C
4 -> 2
...
E -> 7
F -> F

Nie zapominając o zamianie miejscami młodszego nibble ze starszym.
Unika się jakiejkolwiek konwersji z/na format binarny*, przesuwania bitów itp. Masz znaki HEX na wejściu i znaki HEX na wyjściu.

* - z wyjątkiem policzenia indeksu do tablicy.
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.07, 12:43:36
Chodzi o jednorazowe przeliczenie:

Nie ukrywam iż chciałem gotowca  :P w przeciwnym razie będę musiał przysiąść do tego co mam bo już prawie uzyskałem rozwiąznie - trzeba by rozpisać na kartce blokowo co robią poszczególne części programu i gdzie mają być skoki goto.

Da się w BASIC'u bez zamiany na dec tylko od razy na bin?
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: trojacek w 2021.11.07, 12:49:18
To jakiś przykład dydaktyczny? Bo nie bardzo widzę w nim sens.
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.07, 14:35:22
To jakiś przykład dydaktyczny? Bo nie bardzo widzę w nim sens.
Konwerter kodu IR w formacie 32-bit unsigned integer na kod NEC ADDR=xx, CMD=xx np.
mam kod przycisku 807F28D7 gdzie adres 80 NOT=7F polecenie 28 NOT=D7 i z tego ma wyjść:

80h = 10000000b -> rev 00000001 = 01h ADDR
28h = 00101000b -> rev 00010100 = 14h CMD
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: steev w 2021.11.07, 16:18:10
A jak to się wiąże ze spectrum?
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.07, 17:03:44
Wejściowe i wyjściowe wartości do przeliczenia są 8-bitowe a poza tym w BASIC ZX coś tam potrafię w przeciwieństwie do C.
Z ciekawości - do ZX pewnie da się podłączyć nadajnik czy odbiornik IR np. przez RS-232 w ZX Interface 1 tylko pewnie jeszcze nikt nie próbował.
Chyba można wykorzystać ZX do różnych obliczeń nie związanych z samym komputerem - jeśli nie ten dział to proszę przenieść do odpowiedniego.
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: steev w 2021.11.07, 18:23:38
Pytałem, bo byłem ciekawy czy po prostu korzystasz z ZX jako kalkulatora, czy masz do niego podłączony odbiornik IR :)
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: steev w 2021.11.07, 20:00:39
Zła wiadomość - musisz najpierw załadować Beta Basic 3.0.
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.08, 01:27:32
Pomocy - zrobiłem nowe wersje podprogramów tak aby liniie w BASIC się nie pokrywały - ostatecznie połaczę wszystko w jeden program. Program hdclear.z80 to konwerter hex > dec (ma też konwersję w odwrotną stronę od linii numer 11)
Drugi program decbinv2.z80 konwertuje dec to bin gdzie mam wartość bin w b$. Myślałem iż zrobię z tego VAL b$ jako liczbę i wykorzystam polecenie BIN aby zamienić na dec a tu d..pa  :-\
Mam też drugą wersję dec na bin rev dbr.z80 - w tablicy DIM b() jest wartość bin przed odwróceniem a w tablicy DIM i() po odwróceniu.

Brakuje mi tylko przekształcenia na dec bo na hex to wykorzystam hdclear.z80 od linii 11
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Phonex w 2021.11.10, 09:08:26
Serio? Pomocy? Przecież konwersja liczby binarnej do dziesiętnej to zadanie dla pierwszej klasy informatyki.
Da się to napisać przy porannej kawie.
Algorytm bezpośrednio wynika z konstrukcji liczby binarnej.

Mamy liczbę binarną B: B7B6B5B4B3B2B1B0
DEC=B7*27+B6*26+B5*25+B4*24+B3*23+B2*22+B1*21+B0*20
A w Basic
LET dec=2^7*b(1)+2^6*b(2)+2^5*b(3)+2^4*b(4)+2^3*b(5)+2^2*b(6)+2^1*b(7)+2^0*b(8)
Dla liczby binarnej w zmiennej łańcuchowej b$:
LET dec=2^7*VAL b$(1)+2^6*VAL b$(2)+2^5*VAL b$(3)+2^4*VAL b$(4)+2^3*VAL b$(5)+2^2*VAL b$(6)+2^1*VAL b$(7)+2^0*VAL b$(8)

Albo elegancko w pętli
LET dec=0
FOR a=1 TO 8
LET dec=dec+2^(8-a)*VAL b$(a)
NEXT a
Można to zrobić na pierwotnej nie-odwróconej liczbie binarnej wystarczy odwrócić ją "w biegu", czyli zmieniać indeks od końca do początku.
LET dec=0
FOR a=1 TO 8
LET dec=dec+2^(8-a)*VAL b$(9-a)
NEXT a

Tylko po co zamieniać na dziesiętną? Można od razu na HEX.
To już poważniejsza sprawa, zajmuje aż 10 minut.
10 LET h$=""
20 LET start=1: GO SUB 1000
30 LET start=5: GO SUB 1000
40 STOP: REM wynik w h$

1000 LET h=0
1010 FOR a=0 TO 3
1020 LET h=h+2^(3-a)*VAL b$(a+start)
1030 NEXT a
1040 IF h>9 THEN LET h=h+(CODE "A"-CODE "9"-1)
1050 LET h$=h$+CHR$ (h+CODE "0")
1060 RETURN
Pętla oblicza wartość dziesiętną połówki bajta, dwie następne linie tworzą hex.
Oczywiście zamiast CODE "coś-tam" można wpisać stałe - będzie szybciej.

Także w tym przypadku można działać na nie-odwórconej liczbie binarnej:
10 LET h$=""
20 LET start=5: GO SUB 1000
30 LET start=1: GO SUB 1000
40 STOP: REM wynik w h$

1000 LET h=0
1010 FOR a=0 TO 3
1020 LET h=h+2^(3-a)*VAL b$(3-a+start)
1030 NEXT a
1040 IF h>9 THEN LET h=h+(CODE "A"-CODE "9"-1)
1050 LET h$=h$+CHR$ (h+CODE "0")
1060 RETURN
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.10, 17:15:03
Serio? Pomocy? Przecież konwersja liczby binarnej do dziesiętnej to zadanie dla pierwszej klasy informatyki.
Da się to napisać przy porannej kawie.
Wiem, wiem ale ostatnio jestem bardzo zmęczony i nic mi się nie chce. Mimo tego już rozwiązałem problem - wystarczy tylko połączyć wszystko w jeden program. Zrobiłem konwersję z bin na dec, odwrotność bin i znowu na dec tak jak w pliku decbinrevdec.z80

Ale oczywiście dzięki za Twój kod - sprawdzę tylko nie wiem kiedy.
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Phonex w 2021.11.10, 19:03:48
Luzik. W takim razie - "happy to help" cytując całkiem świeży film SF :)
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.11, 09:32:28
@Phonex
Sprawdziłem Twoje programy i ładnie konwertują BIN na HEX. A jak w odwrotną stronę czyli HEX na BIN?
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Phonex w 2021.11.11, 10:29:47
Trudne: 25 minut ;)
Albo to przez to, że dziś dzień wolny...
100 REM liczba HEX w x$, tylko duże litery
110 LET n$=""
120 LET s=CODE x$(1): GO SUB 2000
130 LET s=CODE x$(2): GO SUB 2000
140 STOP: REM wynik w n$
 
2000 IF s>CODE "9" THEN LET s=s-(CODE "A"-CODE "9"-1)
2010 LET s=s-CODE "0"
2020 FOR a=3 TO 0 STEP -1
2030 LET s$="0"
2040 LET b=INT s/(2^a)
2050 IF b THEN LET s$="1": LET s=s-b*2^a
2060 LET n$=n$+s$
2070 NEXT a
2080 RETURN
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.11, 11:41:42
@Phonex
Posklejałem Twoje programy w jeden - dodałem odwrócenie BIN w tablicy DIM i$() ale coś jest nie tak bo źle oblicza. Możesz rzucić okiem na program conv.z80 bo coś źle działa.

P.S. Twój program zamiany HEX na BIN jednak źle działa. Jak podam mu HEX FF to źle oblicza BIN i zamiast samych 11111111 wyświetla 10001000
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.11, 13:07:51
Zrobiłem konwerter mynew.tap używając swoich początkowych plików. Program zamienia:
HEX -> DEC -> BIN -> REVBIN -> DEC -> HEX ale wyświetla wyniki tylko:
HEX -> BIN -> REVBIN -> HEX
Jeśli podamy Hex=0 to wychodzi z programu (polecenie STOP)

Power button: 20DF10EF (32-bit unsigned)

czyli 20 NOT 20=DF 10 NOT 10=EF

20 00100000 00000100 04
10 00010000 00001000 08

NEC ADDR=04, CMD=08
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Phonex w 2021.11.12, 08:25:08
Nawias w złym miejscu w linii 2040 >:(
Tak ma być:
100 REM liczba HEX w x$, tylko duże litery
110 LET n$=""
120 LET s=CODE x$(1): GO SUB 2000
130 LET s=CODE x$(2): GO SUB 2000
140 STOP: REM wynik w n$
 
2000 IF s>CODE "9" THEN LET s=s-(CODE "A"-CODE "9"-1)
2010 LET s=s-CODE "0"
2020 FOR a=3 TO 0 STEP -1
2030 LET s$="0"
2040 LET b=INT (s/2^a)
2050 IF b THEN LET s$="1": LET s=s-b*2^a
2060 LET n$=n$+s$
2070 NEXT a
2080 RETURN

Poprawiłem w pliku.
Drugi zamieszczony programik BIN -> HEX sam odwraca łańcuch w trakcie - nie potrzeba osobnej procedury, tak jest szybciej i krócej. Też poprawiłem. Teraz już działa dobrze. Można jeszcze trochę przyspieszyć i skrócić wpisując wartości zamiast CODE "xx".
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.12, 17:56:01
Pod jaką zmienną jest odwrócona wartość BIN bo chciałbym aby się wyświetlała jak w niepoprawionej wersji conv.z80 ?
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Phonex w 2021.11.13, 09:46:43
Sorry, nie ma.
Nie ma odwracania, program po prostu przetwarza łańcuch od końca.
Wiem, że wygląda teraz niesymetrycznie, ale tak naprawdę chyba nie jest do niczego potrzebne? ;)
Rozumiem, że przydawało się do testów, ale jak już działa...
Ewentualnie można wydrukować łańcuch od tyłu :P

Przy okazji jak się przyglądałem, to wpadłem, że IF w linii 2050 nie jest do końca niezbędny. Odejmowanie od s sobie poradzi, tylko trzeba jakoś wybrać "0" czy "1". I wymyśliłem! Bezpośrednie indeksowanie łańcucha, które zawsze mnie rozbawia (w linii 2060) :D.
100 REM liczba HEX w x$, tylko duże litery
110 LET n$=""
120 LET s=CODE x$(1): GO SUB 2000
130 LET s=CODE x$(2): GO SUB 2000
140 STOP: REM wynik w n$
 
2000 IF s>CODE "9" THEN LET s=s-(CODE "A"-CODE "9"-1)
2010 LET s=s-CODE "0"
2020 FOR a=3 TO 0 STEP -1
2040 LET b=INT (s/2^a)
2050 LET s=s-b*2^a
2060 LET n$=n$+"01"(b+1)
2070 NEXT a
2080 RETURN
Jest krótsze.

Jak już miałem to w pamięci, to w ten sam sposób poprawiłem też BIN -> HEX:
10 LET h$=""
20 LET start=5: GO SUB 1000
30 LET start=1: GO SUB 1000
40 STOP: REM wynik w h$

1000 LET h=0
1010 FOR a=0 TO 3
1020 LET h=h+2^(3-a)*VAL b$(3-a+start)
1030 NEXT a
1050 LET h$=h$+"0123456789ABCDEF"(h+1)
1060 RETURN
I teraz jest szybsze!
I lepiej wygląda :D
I od razu widać co robi.

EDIT: poprawki w linii 1050. Zmiana załącznika
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.13, 10:00:31
Coś źle działa
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Phonex w 2021.11.13, 10:19:32
A no jasne! Zapomniałem o zerze w łańcuchu.
Przetestowałem za słabo, jak się okazuje.
Poprawiłem w poprzednim poście i zmieniłem załączony plik.
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Phonex w 2021.11.14, 12:47:29
Na zakończenie można by jeszcze sprawdzić, jak długi byłby konwerter korzystający z pomysłu trojacka z postu #2.
Skoro już jest działający poprawnie odwracacz HEX, można wygenerować sobie wszystkie wyniki i stablicować je.

Oto kompletny konwerter.
Dzięki "xxxxxxx" w tablicy, da się to zrobić w dwóch liniach tylko!
REM wejście x$, wyjście h$
LET a$="084C2A6E19xxxxxxx5D3B7F"
LET h$=a$(CODE x$(2)-47): LET h$=h$+a$(CODE x$(1)-47)

Dziękuję za uwagę :D
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.15, 13:40:41
Dzięki "xxxxxxx" w tablicy, da się to zrobić w dwóch liniach tylko!
Co mam wstawić za te xxxxxxx ?
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: matofesi w 2021.11.15, 13:50:00
Dokładnie to, co tam jest - iksy są po to, żeby przeskoczyć różnicę między kodem '9' i 'A' - '9' to 57, 'A' - 65 czyli między nimi masz 7 znaków, które się nigdy nie pojawią w wejściowym HEXie.
Tytuł: Odp: Konwerter HEX to BIN i odwrotność
Wiadomość wysłana przez: Gelip w 2021.11.15, 14:22:29
Faktycznie działa:
   5 POKE 23658,8
  10 INPUT "Hex ";x$
  20 LET a$="084C2A6E19xxxxxxx5D3B7F"
  30 LET h$=a$(CODE x$(2)-47): LET h$=h$+a$(CODE x$(1)-47)
  40 PRINT x$;" -> ";h$
  50 GO TO 10