hex2dec converter, line (rows) Data generator
Tak tu mám ďalší program prevodník HEX-DEC_HEX - zvláda konverziu v rozsahu 0÷FFFFh a teda aj 0÷65535d. Pretože je napísaný v jazyku MicrosoftBasic, tak by mal fungovať naprieč 8bitovými platformami bez nejakých problémov. Pochádza tak isto z časopisu Popular Electronics, len akurát odložené pdf akosi neobsahuje čitateľne uložené číslo a rok. Tento časopis je zaujímavý mimo svojho obsahu ešte jednou vecou - počas svojej existencie zmenil svoje meno - až sa nakoniec vrátil k pôvodnému. Celkom zaujímavý spôsob ako si skoro "zabiť" zavedený časopis. (Bola tam vtedy "nová metla" vo vedení ? ...)
Program:
Hex_dec_hex_converter2.pdf (349,79 kb)
Je to iné riešenie ako program, ktorý bol uverejnený v pokračovaní č.17 o SBC6502.
___________________________________________________________
No a nasleduje aj niečo z vlastnej tvorby:
Príklad - ak je hexadecimálne číslo = 1A, tak vlastne prebieha tento výpočet, ale dá sa to tiež previesť na viacero spôsobov:
dec = 1*(16^1) + 10*(16^0) = 26
_______________
(Úprava tejto časti - 06.11.2021)
Prevodník Hex to dec v rozsahu 0÷FFh → 0÷255d:
Je riešený inak - a funguje jedným smerom. Je úsporný, výsledné riešenie je dané tým že som bol na chalupe (bez SBC6502 a vlastne som ho napísal v Notepade (najčastejšie píšem programy v Basicu práve v Notepade). Nakoniec pri práci na programovom vybavení pre programátor PROM 74188 som prišiel na podstatne kratšie a úspornejšie riešenie, akurát to vyžaduje použiť o niečo viac premenných (označenie prenných klasika - LO, HI a použité sú stringy H$ a L$). No a dúfal som že to po nahratí do SBC doma bude fungovať, nakoniec som ním nahradil pôvodný podprogram ktorý bol dlhší a napísaný tak aby fungoval - a to aj bez znalosti použitia stringovej funkcie VAL. Program je myslím si prehľadný a je jasné akým spôsobom prichádza k prekladu. Tu sa kontroluje iba či je správne zadaný počet vložených znakov (2), inak je to bez ďalšej kontroly:
4200 REM Converter HEX (0-FFh) to dec (0-255d)
4201 REM Igi(c)10/2021, ver.1.0
4203 PRINT "Adress: data:":PRINT "(hex) (dec)"
4207 PRINT:INPUT A$
4209 IF LEN (A$)<>2 THEN PRINT "Problem":STOP
4210 H$=LEFT$(A$,1):L$=RIGHT$(A$,1)
4215 IF H$="F" THEN HI=15:GOTO 4244
4216 IF H$="E" THEN HI=14:GOTO 4244
4217 IF H$="D" THEN HI=13:GOTO 4244
4218 IF H$="C" THEN HI=12:GOTO 4244
4219 IF H$="B" THEN HI=11:GOTO 4244
4220 IF H$="A" THEN HI=10:GOTO 4244
4221 HI=VAL(H$)
4244 IF L$="F" THEN LO=15:GOTO 4270
4245 IF L$="E" THEN LO=14:GOTO 4270
4246 IF L$="D" THEN LO=13:GOTO 4270
4247 IF L$="C" THEN LO=12:GOTO 4270
4248 IF L$="B" THEN LO=11:GOTO 4270
4249 IF L$="A" THEN LO=10:GOTO 4270
4250 LO=VAL(L$)
4270 S=HI*16+LO:? " ";A$;" ";S
4280 GOTO 4207
(dĺžka programu: 804 byte)
Verzia, kde je už plná kontrola použitého rozsahu použitých znakov - kotroluje sa tu tak isto ako v predchádzajúcom programe správny počet zadaých znakov (2) a tiež sa kontroluje povolený rozsah znakov (0÷Fh), program vďaka tomu mierne nabobtná, ale aj napriek tomu je stále o 727 byte kratší ako pôvodný program (uvedený v ďalšom odstavci):
4200 REM Converter HEX (0-FFh) to dec (0-255d)
4201 REM Igi(c)11/2021, ver.1.1
4202 B$="0123456789ABCDEF"
4203 PRINT "Adress: data:":PRINT "(hex) (dec)"
4207 PRINT:INPUT A$
4209 IF LEN (A$)<>2 THEN GOSUB 5000
4210 H$=LEFT$(A$,1):L$=RIGHT$(A$,1)
4211 QQ=1
4212 IF MID$(B$,QQ,1)=H$ THEN 4215
4213 IF QQ=17 THEN GOSUB 5000:GOTO 4207
4214 QQ=QQ+1:GOTO 4212
4215 QQ=1
4216 IF MID$(B$,QQ,1)=L$ THEN 4225
4217 IF QQ=17 THEN GOSUB 5000:GOTO 4207
4218 QQ=QQ+1:GOTO 4216
4225 IF H$="F" THEN HI=15:GOTO 4244
4226 IF H$="E" THEN HI=14:GOTO 4244
4227 IF H$="D" THEN HI=13:GOTO 4244
4228 IF H$="C" THEN HI=12:GOTO 4244
4229 IF H$="B" THEN HI=11:GOTO 4244
4230 IF H$="A" THEN HI=10:GOTO 4244
4231 HI=VAL(H$)
4244 IF L$="F" THEN LO=15:GOTO 4270
4245 IF L$="E" THEN LO=14:GOTO 4270
4246 IF L$="D" THEN LO=13:GOTO 4270
4247 IF L$="C" THEN LO=12:GOTO 4270
4248 IF L$="B" THEN LO=11:GOTO 4270
4249 IF L$="A" THEN LO=10:GOTO 4270
4250 LO=VAL(L$)
4270 S=HI*16+LO:? " ";A$;" ";S
4280 GOTO 4207
5000 PRINT "Error !":RETURN
(dĺžka programu : 1083 byte)
______________
A takto vyzerá pôvodný program - ten má výhodu v tom že sa dá ľahko ošetriť pre chybné zadanie dát (čo u prechádzajúceho programu bolo treba riešiť inou cestou, ale zadarilo sa úspešne to doriešiť):
4200 REM Converter HEX (0-FFh) to dec (0-255d)
4201 REM Igi(c)10/2019
4203 PRINT "data:"
4207 S=0:PRINT"(hex)";:INPUT A$
4208 IF LEN (A$)<>2 THEN GOSUB 5000:GOTO 4207
4227 IF LEFT$ (A$,1)="F" THEN S=240:GOTO 4244
4228 IF LEFT$ (A$,1)="E" THEN S=224:GOTO 4244
4229 IF LEFT$ (A$,1)="D" THEN S=208:GOTO 4244
4230 IF LEFT$ (A$,1)="C" THEN S=192:GOTO 4244
4231 IF LEFT$ (A$,1)="B" THEN S=176:GOTO 4244
4232 IF LEFT$ (A$,1)="A" THEN S=160:GOTO 4244
4233 IF LEFT$ (A$,1)="9" THEN S=144:GOTO 4244
4234 IF LEFT$ (A$,1)="8" THEN S=128:GOTO 4244
4235 IF LEFT$ (A$,1)="7" THEN S=112:GOTO 4244
4236 IF LEFT$ (A$,1)="6" THEN S=96:GOTO 4244
4237 IF LEFT$ (A$,1)="5" THEN S=80:GOTO 4244
4238 IF LEFT$ (A$,1)="4" THEN S=64:GOTO 4244
4239 IF LEFT$ (A$,1)="3" THEN S=48:GOTO 4244
4240 IF LEFT$ (A$,1)="2" THEN S=32:GOTO 4244
4241 IF LEFT$ (A$,1)="1" THEN S=16:GOTO 4244
4242 IF LEFT$ (A$,1)="0" THEN S=0:GOTO 4244
4243 GOSUB 5000:GOTO 4207
4244 IF RIGHT$ (A$,1)="F" THEN S=S+15:GOTO 42
4246 IF RIGHT$ (A$,1)="D" THEN S=S+13:GOTO 4270
4247 IF RIGHT$ (A$,1)="C" THEN S=S+12:GOTO 4270
4248 IF RIGHT$ (A$,1)="B" THEN S=S+11:GOTO 4270
4249 IF RIGHT$ (A$,1)="A" THEN S=S+10:GOTO 4270
4250 IF RIGHT$ (A$,1)="9" THEN S=S+9:GOTO 4270
4251 IF RIGHT$ (A$,1)="8" THEN S=S+8:GOTO 4270
4252 IF RIGHT$ (A$,1)="7" THEN S=S+7:GOTO 4270
4253 IF RIGHT$ (A$,1)="6" THEN S=S+6:GOTO 4270
4254 IF RIGHT$ (A$,1)="5" THEN S=S+5:GOTO 4270
4255 IF RIGHT$ (A$,1)="4" THEN S=S+4:GOTO 4270
4256 IF RIGHT$ (A$,1)="3" THEN S=S+3:GOTO 4270
4257 IF RIGHT$ (A$,1)="2" THEN S=S+2:GOTO 4270
4258 IF RIGHT$ (A$,1)="1" THEN S=S+1:GOTO 4270
4259 IF RIGHT$ (A$,1)="0" THEN S=S+0:GOTO 4270
4260 GOSUB 5000:GOTO 4207
4270 PRINT "(dec)";S:GOTO 4203
5000 PRINT "Error !":RETURN
(dĺžka programu: 1810 byte)
___________________________________________________________
Doplnené 06.11.2021:
Veľmi šikovný programček - výpis všetkých premenných použitých v programe:
9800 PRINT "Variables:"
9802 FOR W=(PEEK(124)*256+PEEK(123))TO(PEEK(126)*256+PEEK(125)-1)STEP 6
9804 PRINT CHR$(PEEK(W));CHR$(PEEK(W+1)),:NEXT W
Stačí ho priložiť k pôvodnému programu, po jeho spustení (a prejdení všetkými možnosťami) stačí stopnúť program pomocou CTRL+C a napísať GOTO 9800, tým zostanú použité premenné neporušené. Program by mal byť umiestnený vždy na konci pôvodného programu, t.j. ak použité čísla riadkov nevyhovujú tak ich prepíšte na hodnotu ktorá už v programe nie je použitá. Samozrejme si treba uvedomiť že do zoznamu použitých premenných bude patriť aj použitá samotná premenná na výpis - jedná sa o W.
Vypíšu sa všetky použité premenné v programe, stringové premenné sa vypíšu namiesto napríklad A$ v tvare A€. Je to výborná pomôcka ak si chceme overiť koľko premenných je reálne v programe použitých.
___________________________________________________________
Ďalšou vecou je basicový program - Line Data generator, je to u mňa používané aj po názvom Rows Data generator:
Pretože SBC6502 nemá dostupné príkazy SAVE a LOAD a ani nepracujeme pomocou otvorenia kanálov (≠1 a pod. ako na niektorých 8bitoch) je tu naozaj dosť problematické ak máme nejakú oblasť pamäte a chceme jej obsah z akýchkoľvek dôvodov odložiť na opätovné použitie. Tak som si urobil Line Data generator, ktorý "zosníma" danú oblasť pamäte a vytvorí potom z toho nám potrebné Data riadky. Tie potom v programe na svoje miesto načítame pomocou príkazov Restore a Read. Funguje to dobre, akurát musíme mať zapnutý záznam (Capture Text) v Hypertermináli aby sme potom vedeli nakopírovať riadky naspäť do programu.
Ukážka č.2 - výber Capture
Zvolíme Capture Text, názov súboru, po spustení záznamu SBC6502 vygeneruje riadky a uložíme text, potom si z uloženého textu "vytiahneme" nám potrebné Data riadky. Samozrejme je to o niečo zložitejšie, ale pritom stále použiteľné, pretože neviem o tom ako inak uložiť Data riadky do vytvoreného Basic programu. Následne už potom Data riadky môžu byť súčasťou vytvoreného programu.
Program pre jednoduchosť načítava vždy celé násobky čísla 8, t.j. ak chceme uložiť nejakú oblasť pamäte voľte vždy dĺžku záznamu ktorý je násobkom čísla 8, čiže napríklad uloženie obsahu 256 byte RAM je naprosto v poriadku, teda 32x8=256 - je to číslo deliteľné :8 bezo zvyšku, teda no problem. Ako vždy je to daň za jednoduchosť takto vytvoreného programu. Najväčším problémom bolo "nasekať" výstup po 8 byte, hlavne aby na konci riadku nebola navyše čiarka. Ak na dodržanie správnej dĺžky pamätáme tak pri používaní nevzniká pri generovaní Data riadkov žiaden problém. Mne vyhovovalo pre použitie ak je v jednom riadku uložený obsah 8byte (pre dané použitie mi to prišlo omnoho prehľadnejšie ako napríklad ukladanie 10 byte v riadku), dá sa to zvýšiť, ale stále platí:
Celková dĺžka vygenerovaného DATA riadku nesmie presiahnuť 72 znakov !
(Obmedzenie je dané verziou použitého jazyku Basic pre SBC6502).
Program nie je určený na ukladanie obsahu desiatok kB (na to naozaj nie je dosť pamäte), ale nejaký ten kByte (a určite aj viac) s ním určite uložíte. Spotreba pamäte je pri tomto spôsobe ukladania o hodne väčšia, čo sa týka veľkosti datových riadkov - nie je to úsporné (majitelia ZX Spectrum by mohli rozprávať - tam ale zase môžu mať riadok dlhší), ale konečne viem ukladať potrebné údaje (u mňa sa jedná iba o uloženie pár desiatok byte, takže problém s obsadením RAM a veľkosťou na to potrebnej RAM je vcelku nezaujímavý - ale funguje to a to je najdôležitejšie. Nakoniec - ako ďalšiu možnosť môžeme najprv nahrať Data, preniesť ich do potrebnej oblasti RAM a až následne spustiť vlastný program. Síce je to potom o niečo zložitejšie, ale omnoho úspornejšie na obsadenie RAM. Dodatočným riešením je zväčšiť RAM, trebárs na už spomínaných 40kB.
Pre zatiaľ najdlhší úsek čo som kedy na SBC6502 potreboval boli 2kB obsahu v DATA riadkoch, to sa naozaj s prehľadom do 32kB RAM priamo zmestí a ešte je stále miesta dosť aj na ďalšie programové vybavenie.
Program generuje Data riadky od čísla 32000 smerom nahor (tam je pre istotu na začiatku v riadku 32000 vlastný poked - kto si po čase pamätá, že ? - uložená štartovacia adresa a dĺžka záznamu v bytoch (dec)), ukladá sa s krokom nasledujúceho ďalšieho riadku +1 (je to možné zmeniť). Tu len pripomínam že SBC6502 nemá obmedzenie čísla riadkov na maximálne číslo riadku =32767, teda riadky kľudne môžu mať aj vyššie číslovanie (SBC6502 povoľuje číslovanie riadkov aj niekde okolo hodnoty = 63000 !), čo je hodne zaujímavé a málokde sa niečo také vidí.
Program Line Data generator:
(Rows Data generator)
31500 REM ___/Rows or Line/ Data generator V.1.1 ___
31501 REM Igi (c) 2020
31502 ?:?:H=32001:REM H=Data line start number
31503 ? "Start adress 0 - 65528 (dec):";:INPUT X
31504 ? "Record lenght max 65536 (dec):";:INPUT Y
31505 IF Y>65536 THEN ? "max.65536 !":GOTO 31502
31507 ?:? " 32000 REM Start adress=";X;", Record lenght=";Y
31508 FOR Q=0 TO 3000:NEXT Q
31510 FOR F=X TO X+Y-8 STEP 8:? H;:? "DATA";:
31520 FOR G=F TO F+6:? PEEK(G);",";:NEXT G:? PEEK(F+7)
31530 H=H+1:NEXT F
31550 END
(Riadok 31508 je možné vynechať, len spomaľuje výpis aby sme stíhali sledovať čo sa to deje.)
Program:
8x data in 1 line generator.txt (498,00 bytes)
Ukážka (obrázok č.3) - Data na ukážku sú naplnené týmto programovým riadkom:
10 A=0: FOR F=31000 TO 31255: POKE F,A: A=A+1: NEXT F
Príde k vygenerovania riadkov s Data údajmi (konkrétne tu snímam adresu 31000d =0 a vyššie adresy, skúšobne je to naplnené údajom zvýšeným vždy o 1 na ďalšej adrese až do rozsahu 310255d kde je obsah =255), najprv zosnímaných iba prvých 32 byte, následne potom celých 256byte.
Ukážka č.3
Ukážka č.4:
Celý rozsah naplnených 256 byte, každá bunka - obsah zvýšený postupne o 1.
Je vidieť nastavenie zvyšovania čísla DATA riadkov o 1.
Dosť mi možnosť ukladania obsahu pamäte v SBC6502 chýbala, ale teraz som už s takouto dostupnou alternatívou celkom spokojný (zatiaľ som na nič lepšieho neprišiel). Ak sa niekedy stretnete s týmto problémom tak mi určite porozumiete čo som tým sledoval. Mňa to bez tejto veci naozaj doteraz v niektorých veciach na SBC6502 citeľne obmedzovalo.
Možno Vás to inšpiruje tiež vytvoriť nejaké tie pomocné Basic programy - a možno ich napíšete o poznanie lepšie a aj kompaktnejšie.
Držím palce !
___________________________________________________________
07.12.2023
Veľmi jednoduché riešenie ako zobraziť vkladané vstupné data v rozsahu 0÷511d ako hexa adresu na výstupe. Konvertor fungoval pôvodne v rozsahu 0÷255d, potreboval som ale 2x väčší rozsah ako poskytoval pôvodný program - nemal som chuť hľadať ako inak na to, takže bolo to vyriešené "homemade" najľahším spôsobom :
2000 ? CHR$(12):A$="0123456789ABCDEF"
2010 ? "(dec)";:INPUT N:IF N>511 THEN 2010
2015 IF N>255 AND N<512 THEN N=N-256:Q=1:GOTO 2020
2016 Q=0
2020 L=N AND 15:H=(N-L)/16
2030 ?"(hex):"Q;CHR$(8);MID$(A$,H+1,1)MID$(A$,L+1,1)
2040 GOTO 2010
Výpis v terminálovom okne.
Pôvodný program pre vstupný rozsah 0÷255d:
2000 ? CHR$(12):A$="0123456789ABCDEF"
2010 ? "(dec)";:INPUT N
2020 L=N AND 15:H=(N-L)/16
2030 ?"(hex): ";:? MID$(A$,H+1,1)MID$(A$,L+1,1)
2040 GOTO 2010
___________________________________________________________
Návrat do všetkých pokračovaní o SBC6502:
http://blog.3b2.sk/igi/post/Directory-SBC6502.aspx
____________________________________________________________
Vaše hodnotenie, Rate post: