-
Írtam a múltkor egy BMP fájl kiolvasó programot BASIC-ben.
Most elkészítettem egy másik programot, és próbáltam a kiolvasó rutint átvenni.
Első csatolmány szerint a föprogramból (nincs ciklus) a 735 sorban elugrok 1120 sorba, hogy ott megnyissam a file-t. Kiolvassak belöle dolgokat.
Ott müködik is minden beolvassa az elejét szépen ahogy kell (csatolmány 2) majd a 1390-sorban visszaugrok a föprogramhoz. A fájl nagy, csak az első néhány byte-ot olvasom ki.
A 1390 elötti a sorokban leellenörzöm, hogy valóban a fájlból olvas-e. Minden rendben.
A visszaugrás után (1. csatolmány) 740. sortól a GET nem müködik, mindig csak decimális 66-ot olvas és sosem fogy el a puffer. Nincs hibaüzenet sem. (3. csatolmány)
Mi lehet a baj?
System:
Basic 2.1 + BRD
I wrote last time a BMP file reader program in BASIC.
I made an another program, and I tried to take the file read routine from the BMP reader.
According to the 1. attachment from the main part (no nested cycle) in the line 735 it jumps to the 1120, it opens the file, to read things.
At this point everything works fine, it reads the header (attachment 2) and then if it is ready, it jumps back to the main code. I read only the first some bytes of the big file.
In the line 1390 i check the reading everything is fine.
After the jump (1. attachm) from the line 740 the GET is not working, it gives back always decimal "66" and the buffer will be never empty, no error message. (3. Attachment)
What could be the problem?
-
Nem csoda, ezt irtad: ORD("B$") ... Ez ugye a B$-t constant string-nek tekinti, tehat megnezi a B ascii kodjat ... Gondolom ezt akartad volna irni: ORD(B$)
-
Ahh! Ezer köszönet!
Fáradt vagyok már nem látom meg.
-
Úgy emlékszem meg kellene adni az y,x pozíciót is és utána kiolvasni mert így a 0,0 pozíciót olvasod állandóan.
-
Amúgy arra a sok randa gotora mi szükség van? Ez nem C64 BASIC :oops:
-
GOSUB RETURN volt bent eredetileg, de azt hittem az átír valamit emiatt nem megy ezért GOTO-ra cseréltem
Néhány kérdés merült fel a BASIC használatakor
- Hogy lehet csak az 1000 sor utáni részt újszámozni, hogy 10-es lépésekben sorszámozzon.
- Hogy tudok EDIT 0-án lévő programból részleteket az EDIT 1-ben lévő programba átmásolni?
- Ha elkészül egy program hogyan tudom kimásolni szövegfájlkét adathordozóra?
-
- Hogy lehet csak az 1000 sor utáni részt újszámozni, hogy 10-es lépésekben sorszámozzon.
RENUMBER 1000 to 1500 at 1000 step 10
Bár problémák adódhatnak .
- Hogy tudok EDIT 0-án lévő programból részleteket az EDIT 1-ben lévő programba átmásolni?
Ezt én úgy oldom meg hogy, edit 0 list kb. 30-40 sor ami a bufferbe befér
edit 1
kurzor vissza a lista elejére és enter,enter....
- Ha elkészül egy program hogyan tudom kimásolni szövegfájlkét adathordozóra?
Jó pár helyen megtalálható
Én
open #1:"filename" access output
ok
list #1
ok
close #1
használom
-
GOSUB RETURN volt bent eredetileg, de azt hittem az átír valamit emiatt nem megy ezért GOTO-ra cseréltem
És miért nem DEF blokk?
-
Hogyal lehet az editor text puffer méretét megnövelni? Ha jól emlékszem valamelyik csatornát le kell zárni, átírni egy rendszerváltozót és újranyitni, de már nem emlékszem.
Esetleg az is érdekelne mennyi a default, és mennyi a max?
Ugye amikor az ember már 512+ MB géppel dolgozik, akkor szívesen adna több memóriát a szeretett gépének.
-
editor buffer (http://www.ep128.hu/Ep_Konyv/Reference.htm#3)
-
- Hogy tudok EDIT 0-án lévő programból részleteket az EDIT 1-ben lévő programba átmásolni?
Én kiírnám txt fájlba az edit 0-ás programot, ott módosítanám a PC-n, majd a módosított verziót betölteném az edit 1-re.
I would save the "edit 0 program" into a txt file, I would modify that (using the PC), then I would load the modified version into "edit 1 program".
-
Én kiírnám txt fájlba az edit 0-ás programot, ott módosítanám a PC-n, majd a módosított verziót betölteném az edit 1-re.
I would save the "edit 0 program" into a txt file, I would modify that (using the PC), then I would load the modified version into "edit 1 program".
Persze csak akkor ha nem több 16k-nál a BASIC program.
-
Ferro ezt hogy érted?
Már 5 sort sincs kedvem pc-re átmásolni.
-
Már 5 sort sincs kedvem pc-re átmásolni.
Hogyhogy átmásolni? Legfeljebb a copy-paste módszerrel kell másolni. Vagy nem az emulátorral dolgozol?
-
Mesélj, hogy működik a copy-paste? Melyik emulátoron van ez és hogyan kell kérni?
-
Mesélj, hogy működik a copy-paste? Melyik emulátoron van ez és hogyan kell kérni?
Kiírod txt fájlba a programjaidat (Ferro írta lejjebb, hogyan kell), aztán ott úgy másolgatsz és módosítasz bennük, ahogy akarsz. Utána betöltheted load-dal.
You save your programs into txt files (Ferro wrote below how to do it) then you can copy and modify within them as you wish. Then you can load them with typing load.
-
Dolgozhat egy ASCII fájlon, majd betöltheti azt az emulátorba a PC-n található könyvtárból.
Ez az emulátor (https://github.com/istvan-v/ep128emu/releases/tag/2.0.11.2).
Válassza ki a PC-n azt a könyvtárat, ahová a TXT fájlt tette, a menü segítségével: Opciók/Munkakönyvtár beállítása(ALT+F). Általában ...\ep128emu2\files\
Ezután válassza ki a File/Configuration/Load from ASCII file(ALT+Q) menüpontot az Enterprise konfiguráció kiválasztásához. Az összes IO végződésű fájl lehetővé teszi, hogy MENTENI vagy TÖLTENI tudjon egy fájlt a számítógépes könyvtárból.
[attachimg=1]
Mostantól kezdve minden fájlparancs a meghatározott könyvtárat fogja használni. Természetesen továbbra is elérheti a többi adathordozót, mint ezen a példán: LOAD "TAPE:név".
És ha nem adsz meg nevet a LOAD "" vagy a SAVE "" parancsokkal, akkor az emulátor megnyit egy fájlválasztó ablakot.
----
You can work on an ASCII file and then load it on the emulator from a directory on the PC.
This Emulator (https://github.com/istvan-v/ep128emu/releases/tag/2.0.11.2).
Select the directory on the PC where you have put the TXT file, with the menu: Options/Set working directory(ALT+F). Usually ...\ep128emu2\files\
Then go to File/Configuration/Load from ASCII file(ALT+Q) to select an Enterprise configuration. All the ones that end with IO will let you SAVE or LOAD a file from a PC drectory.
From now on all your file commands will use the defined directory. Of course you still can access the other storage media, like on this example: LOAD "TAPE:name".
And if you don't specify a name with LOAD "" or SAVE "" the emulator will open you a file selector window.
-
Mindezek az IO konfigurációk az IstvanV által létrehozott epfileio.rom-ot használják a gazdaszámítógépen lévő könyvtárban lévő fájlok kezelésére.
Ön is engedélyezheti vagy letilthatja a funkciót a kívánt konfiguráción.
Először is ellenőrizze, hogy az epfileio.rom telepítve van-e a 10-es szegmensben, a Machine/Configure/Memory menüpontban.
Ehhez jelölje be vagy vegye ki a jelölést a Machine/Configure/General/Enable virtual file IO opcióból. Ez a következő hard reseteléskor lesz hatályos, Machine/Reset/Force reset(Ctrl+F11).
-------
All these IO configurations use the epfileio.rom, created by IstvanV to manage files on a directory on the host computer.
You also can enable or disable the function on your preferred configuration.
First, check that you have the epfileio.rom installed on segment 10, on Machine/Configure/Memory.
To do it, tick or untick the option Machine/Configure/General/Enable virtual file IO. It will be effective on the next hard reset, Machine/Reset/Force reset(Ctrl+F11).
-
Thank you gflorez! Now I understand.
A question, what you describing is from file into EP. But my question, how can I get the basic source code from the EP to the PC?
As I correctly remember if EP basic saves a file it is not plain text. It is coded.
-
But my question, how can I get the basic source code from the EP to the PC?
As I correctly remember if EP basic saves a file it is not plain text. It is coded.
open #1:"prg.txt" access output
list #1
close #1
-
Wow, ez újdonság. Köszönöm!
-
Thank you gflorez! Now I understand.
A question, what you describing is from file into EP. But my question, how can I get the basic source code from the EP to the PC?
As I correctly remember if EP basic saves a file it is not plain text. It is coded.
open #1:"filename" access output
ok
list #1
ok
close #1
-
A probléma, számomra nagyszerű tulajdonság, hogy amikor egy Basic ASCII fájlt betöltesz az EP-re, az értelmező az egész listát ellenőrzi a szintaktikai helyesség szempontjából. Más Basic dialektusok ezt nem teszik meg (például a CPC vagy az MSX), a fájlt úgy töltik be, ahogy van, nem kódolják a parancsokat a következő SAVE-ig.
Ez azt jelenti, hogy az értelmező MINDEN talált hiba esetén leállítja az ellenőrzést, így ki kell javítanod a hibát, és újra és újra próbálkoznod kell, amíg az egész fájl helyes nem lesz..... De ez biztosítja, hogy a betöltött Basic lista "legális". Ez nem jelenti azt, hogy tökéletesen fog RUN... sok más hiba is van, ami csak a végrehajtáskor derül ki.
Ne feledje, ha minden hibát kijavított, azonnal SAVE a fájlt normál .BAS fájlként, különben hard reset esetén meg kell ismételni az eljárást.
Az utolsó ASCII sor ellenőrzésével is van egy probléma, ami sok általam látott Basic értelmezőnél gyakori. Még sikeres betöltés esetén is ellenőrizni kell, hogy az utolsó sor is elemezve lett-e, mert néha eltűnik..... Gondolom, ez akkor történik, amikor a "end -of-file" a "carriage-return" előtt található.
The problem, for me a great feature, is that, when you load a Basic ASCII file on the EP, the interpreter will check the whole listing for syntactic correctness. Other Basic dialects don't do that(for example CPC or MSX), they LOAD the file as is, they don't encode the commands until the next SAVE.
This means that the interpreter will stop the checking at ANY error found, so you will need to fix the error and try it again and again until all the file is correct.... But this assures you that the loaded Basic listing is "legal". It doesn't means that it will RUN perfectly... there are a lot of other errors that only are found on execution.
Remember, once all errors fixed, SAVE immediately the file as a normal .BAS file or you will need to repeat the procedure in case of a hard reset.
Also, there is a problem with the checking of the last ASCII line, common on a lot of Basic interpreters I have seen. Even on a successful loading you must check if the very last line has been parsed, because some times it disappears.... I imagine that it happens when the end-of-file is found before a carriage-return.
-
Az utolsó ASCII sor ellenőrzésével is van egy probléma, ami sok általam látott Basic értelmezőnél gyakori. Még sikeres betöltés esetén is ellenőrizni kell, hogy az utolsó sor is elemezve lett-e, mert néha eltűnik..... Gondolom, ez akkor történik, amikor a "end -of-file" a "carriage-return" előtt található.
Ez EXOS hiba ha jól emlékszem.
Én is bele futottam ebbe a hibába.
EXOS csere és máris jó.
-
Utolsó sor problémám (https://enterpriseforever.com/ep128emu/ep128emu-146/msg85656/#msg85656) volt
-
Ugyanez történik néha akkor is, amikor egy szöveges fájlt tölt be a CPC BASIC. Az ASCII fájloknak nincs fejléce, ezért idegenek egy operációs rendszer számára.
The same also happens sometimes when loading a text file on the CPC BASIC. ASCII files have no header, so they are alien for an operating system.
-
Úgy emlékszem meg kellene adni az y,x pozíciót is és utána kiolvasni mert így a 0,0 pozíciót olvasod állandóan.
Ezt az idézetet Ferro arra írtad, hogy amikor a fájlt olvassuk pl. a következő kóddal:
OPEN #1:"file.bin"
DO
GET #1:A$
LOOP
Nem igaz amit írsz, de a pozícionálás megérdemelne pár szót:
Most kíváncsi vagyok, hogy BASIC-ben a fájlkiolvasáskor az EXOS hogyan kezeli. Mert szerintem nem lehet pozicionálni az adatfolyamot. Azért sem, mert szerintem az EXOS két PAUSE közti adatot tárol be, és ha azt mind kiolvastam, akkor megint beolvas és felülírja a buffert. Emiatt nem lehetséges pozicionálni, mert vissza kell kézzel tekerni a szalagot.
Mivel az EP kazettán alapult, a lemezkezelés is hasonló kell legyen.
Erősítsen meg vagy cáfoljon meg valaki!
-
Ezt az idézetet Ferro arra írtad, hogy amikor a fájlt olvassuk pl. a következő kóddal:
Ferro szerintem ott félre értette a dolgokat, és arra gondolt, hogy a grafikus képernyőt olvasod.
Mivel az EP kazettán alapult, a lemezkezelés is hasonló kell legyen.
Ekkora marhaságot leírni! :oops: Az EP nem Spectrum!
Ajánlott olvasmány: EXOS könyv, azon belül 3-as EXOS változó és az EXOS 10-es funkcióhívás.
Az viszont igaz, hogy az alap IS-BASIC-ben nincs fájlmutató állítására utasítás, Plus bővítéssel már van (FILE PTR). Plus nélkül némi CODE blokkal oldható meg.
Megjegyzés: az ep128emu FILEIO-ja is fájlkezelő egység, így működik a pozicionálás. (Ez kellett pl a HEASS fileio-s működéséhez.)
-
Ferro szerintem ott félre értette a dolgokat, és arra gondolt, hogy a grafikus képernyőt olvasod.
Mivel a képen nem utal semmi a #150 minek lett megnyitva.
Ezért gondolta úgy.
-
Hogyan lehet a gépi kódú betétnek, amit CALL USR()-rel hívunk egynél több változót megadni?
És visszatérési értéknek több változót fogadni?
Bármilyen dirty megoldás jó.
-
Mondjuk csinálhatnám, hogy nem értéket, hanem címet adok át és poke-kal kiolvasom. De hol van szabad hely?
-
De hol van szabad hely?
A kódod mögött a foglaláskor megadott extra memóriaterületen?
-
A kódod mögött a foglaláskor megadott extra memóriaterületen?
Mi a kezdőcím?
-
Mi a kezdőcím?
A Tippek és trükkök ENTERPRISE (http://ep.homeserver.hu/PDF/TippekEsTrukkokEnterprise.pdf) könyv 10-11. oldalán található memóriatérkép és IS-BASIC példaprogram alapján meg lehet határozni. Szerintem.
-
Megvan.
Csak nem beszél az allocate kulcsszóról.
-
Azt talaltam ki, hogy írok egy kamukódot helyfoglalónak, ami a "variables" lesz.
100 Allocate 100
110 code variables=hex$("00","00","00","00")
120 code a1=hex$(".... ! Ide jön a gépi kódom
130 poke variables+0=12
140 poke variables+1=55
150 poke variables+0=43
160 poke variables+1=44
170 call usr(a1,variables) ! Átadom a variables címét, hogy tudja a gépi kód hol keresse, tárolja a változókat
Visszatérési értéket pedig a peek(variables+x) függvénnyel olvashatom ki.
-
Azt talaltam ki, hogy írok egy kamukódot helyfoglalónak, ami a "variables" lesz.
100 Allocate 100
110 code variables=hex$("00","00","00","00")
120 code a1=hex$(".... ! Ide jön a gépi kódom
130 poke variables+0=12
140 poke variables+1=55
150 poke variables+0=43
160 poke variables+1=44
170 call usr(a1,variables) ! Átadom a variables címét, hogy tudja a gépi kód hol keresse, tárolja a változókat
Visszatérési értéket pedig a peek(variables+x) függvénnyel olvashatom ki.
130 poke variables+0,12
140 poke variables+1,55
150 poke variables+0,43
160 poke variables+1,44
Így valahogy.
Ha jól emlékszem call usr(a1,variables) ~ ->ld hl,variables -> call a1
-
Ez a POKE VARIABLES+0=12 forma nekem meglehetősen szokatlan. De az még inkább, hogy kétszer van +0 és +1. Így nem lesz az adatok fele felülírva?
-
Azt talaltam ki, hogy írok egy kamukódot helyfoglalónak, ami a "variables" lesz.
170 call usr(a1,variables) ! Átadom a variables címét, hogy tudja a gépi kód hol keresse, tárolja a változókat
Ügyes, pont ezt akartam javasolni!
Ha aztán a kódban átrakod a variables-t az IX vagy IY-ba, akkor könnyedén tudsz hivatkozni ott is (IX), (IX+1), stb módon rájuk.
-
Már csak arra kellene rájönni, hogy egy kétbájtos integert hogyan hozok és viszek át gépi kódból basic-be. Mármint hogy nem 1 byte-ként kezelem, hanem 2 byte módon.
Ha a fenti megoldást használom több adat áthozására és átvitelére, akkor a 8 bites (1 byteos) számokkal kell dolgoznom, amiket aztán át kell alakítani 2 byte integerré.
let a=peek(variables+0) tartalmazza az alsó byte-ot
let b=peek(variables+1) tartalmazza a felső byte-ot
csinálhatnám, hogy
let c=a+(256*b), de attól félek, hogy a basic tényleg elvégzi a szorzást, és sokáig tart, nem pedig csak 8 bittel eltol.
A másik dolog visszafelé BASIC->ASSEMBLY még nagyobb a probléma, mert 256-tal kell osztanom, és maradékos osztás kell. Ha csupa drága idő elmegy feleslegesen.
Nem úszom meg, deklarálni kell egy-két globális basic változót, amik integer számok, és dirketben férek hozzájuk:
100 ALLOCATE 100
110 LET A=256 ! azért 256. hogy a basic 2byte integerként kezelje
120 LET B=256
130 LET C=256
140 CODE P1=HEX$("....... kódom
150 = itt kiszámolom A címét valahogy =
160 CALL USR(p1,A-címe)
170 PRINT A
-
Megtaláltam. Hát nagyon nem egyszerű a dolog.
Forrás Tippek és Trükkök könyv.
A program által lefoglalt tárterület után a változókat tárolja a számítógép. Ez a terület változó nagyságú, és kezdete is függ a program hosszától. Azt, hogy egy adott esetben ennek a területnek mik a határai, azt a rendszerváltozó terület megfelelő címeiről olvashatjuk ki (17. program).
1 PROGRAM "Var_TBL.bas"
100 ! valtozo tabla mamoriabeli helye, merete
110 LET A=2 ! kiserletezz ertekadasokkal
120 ! vizsgald a hatasat: DIM,DEF,A$
130 LET ELEJE=PEEK(566)+256*PEEK(567)
140 LET VEGE=PEEK(564)+256*PEEK(565)
150 PRINT "Valtozo tabla eleje: ";ELEJE
160 PRINT "Valtozo tabla vege: ";VEGE
170 PRINT "valtozo tabla altal foglalt:";VEGE-ELEJE
Ezen a területen a gyanútlan szemlélőnek kusza összevisszaságban helyezkednek el a bejegyzések, pedig logikája nyomon követhető. Nézzünk bele a változóterület tárolására szolgáló memóriaterületbe a 18. program segítségével.
1 PROGRAM "Szam.bas"
100 ! szamabrazolas
110 LET SAMU=1.2345678 ! ezt valtoztasd
120 LET M=PEEK(566)+256*PEEK(567)
130 ! M az elsonek bejegyzett valtozo tarolasi helye
140 LET H=PEEK(M+3) ! valtozonev hossza
150 PRINT M+2;PEEK(M+2),"adattipus jelzo"
160 PRINT M+3;H,"valtozonev hossza"
170 FOR V=M+4 TO M+H+3 ! nev kiiras
180 PRINT V;PEEK(V);CHR$(PEEK(V))
190 NEXT
200 FOR V=M+H+4 TO M+H+8
210 LET T=PEEK(V) ! tarolt ertek
220 LET E=INT(T/16) !BCD elso tag
230 LET M=MOD(T,16) ! BCD masodik tag
240 PRINT V;T,E;M
250 NEXT
260 PRINT V;PEEK(V),"hatvanykitevo"
A numerikus változók értékét változó táblában 5+1 byte-on tárolja a gép. Egész típusú - 10 0000x10 00 nagyságú számokat két byte-on hexadecimális alakban találhatjuk a memóriában és a hatványkitevő tárolására szolgáló 6 byte tartalma 127. A 9999-nél nagyobb egészeket és a törtszámokat a gép BCD alakban ábrázolja.
Hogyan néz ki egy decimális szám BCD alakban? A tízes számrendszerű szám egy helyi értékének ábrázolásához négy bit bőven elegendő, így lehetőség van arra, hogy nyolc biten (egy byte-on) két decimális számjegyet ábrázoljunk úgy, hogy az egyik (alacsonyabb helyi értékű) számjegyet binárisan a 0-3. biten, a másik a magasabb helyi értékű számjegyet pedig a 4-7. biten tároljuk.
Azaz 29DEC=0010 1001 BCD, igaz ez a szám a szokványos módon kiolvasva (hiszen PEEK-kel kiolvashatjuk) egészen más értéket reprezentál. Ezért kell tudni, hogy a kiolvasott érték BCD-ben van! Ez a számábrázolás-tárolás kissé pazarló, hiszen öt byte-on tízjegyű decimális szám ábrázolható, míg tisztán bináris (vagy hexadecimális) formában ugyanezen az 5 byte-on 2 * 749 *10^14 értékű a maximálisan ábrázolható szám. Ez a pazarlás a műveletek elvégzése során időben megtérül. A binárisan kódolt decimális rendszerben (BCD) a 10-es alapot megtartjuk, azaz a szomszédos számok egymásnak tízszeresei, de a számokat binárisan fejezzük ki.
Az elmondottak jobb megvilágítására, ill. a szerzett ismeret hasznosítására futtassuk le a 19. programot.
100 ! PEEK-el kiolvasott ertek visszaalakitasa
110 LET PROBA=1988.12 ! csak tort szamot
120 LET M=PEEK(566)+256*PEEK(567)
130 LET H=PEEK(M+3)
140 IF PEEK(M+H+9)=127 THEN 330
150 LET SZORZO=.0000000001
160 LET SUMMA=0
170 FOR V=M+H+4 TO M+H+8
180 LET T=PEEK(V)
190 LET E=MOD(T,16) ! BCD elso tag
200 LET SUMMA=SUMMA+E*SZORZO:LET SZORZO=SZORZO*10
210 LET M=INT(T/16) ! BCD masodik taz
220 LET SUMMA=SUMMA+M*SZORZO:LET SZORZO=SZORZO*10
230 PRINT T,M;E
240 NEXT
250 LET KI=PEEK(V)
260 LET S=(KI BAND 128)/128
270 LET KI=KI-64-128*S
280 IF S=1 THEN LET ELOJEL=-1
290 IF S=0 THEN LET ELOJEL=1
300 PRINT KI,"hatvanykiyevo"
310 PRINT ELOJEL*SUMMA*10^(KI+1)
320 END
330 PRINT "Ez egesz szam, erre mas szabaly igaz!"
A 9999-nél nagyobb egészeket [...] a gép (IS-BASIC) BCD alakban ábrázolja.
Ezen nagyon elszomorodtam. Es sokat bonyolít mindenen. :(
-
Esetleg használod a Plus-t (http://ep128.hu/Ep_Konyv/Ep_Plus.htm), és abban van DOKE/DEEK (16 bites POKE/PEEK).
-
Esetleg használod a Plus-t (http://ep128.hu/Ep_Konyv/Ep_Plus.htm), és abban van DOKE/DEEK (16 bites POKE/PEEK).
Akkor bele kellene építeni a BASIC program elejébe egy ellenőrzőt ami nézi telepítve van a 'plus'.
Mert nem mindenki telepíti alapból.
-
Már csak arra kellene rájönni, hogy egy kétbájtos integert hogyan hozok és viszek át gépi kódból basic-be. Mármint hogy nem 1 byte-ként kezelem, hanem 2 byte módon.
Ha jól emlékszem BASIC
call usr(a1,65535)
ld hl,65535
call a1
ret
a1 kódod
...
-
csinálhatnám, hogy
let c=a+(256*b), de attól félek, hogy a basic tényleg elvégzi a szorzást, és sokáig tart, nem pedig csak 8 bittel eltol.
100 ALLOCATE 100
110 LET A=256 ! azért 256. hogy a basic 2byte integerként kezelje
120 LET B=256
130 LET C=256
140 CODE P1=HEX$("....... kódom
150 = itt kiszámolom A címét valahogy =
160 CALL USR(p1,A-címe)
170 PRINT A
Miért kell ?
100 ALLOCATE 100
110 CODE RAM00=HEX$("0000")
120 CODE RAM02=HEX$("0000")
...
540 CODE P1=HEX$("....... kódom
550 LET CIM_RAM00=RAM00
555 LET CIM_RAM02=RAM02
660 CALL USR(p1,CIM_RAM00)
170 A=USR(RD_RAM,RAM00)
Annyi hogy A= -327xx és 32767 között lesz.
De szerintem van BASIC változó ami AA=xxx(a) -327xx-32767 -> 0-65535 csinál.
-
Annyi hogy A= -327xx és 32767 között lesz.
De szerintem van BASIC változó ami AA=xxx(a) -327xx-32767 -> 0-65535 csinál.
Nem találtam de ha:
xxxx VALTOZO=USR(RD_RAM,RAM00)
xxxx IF VALTOZO<0 THEN VALTOZO=VALTOZO+65536
Már jó is.
-
IS-BASIC does the 32768 "trick" itself internally. Source code for PEEK():
;-----------------------------------------------------------------------------;
; FNPEEK = PEEK function. ;
; ;
;-----------------------------------------------------------------------------;
FNPEEK:: CALL @P_NUM ; Get address
CALL GET16ADR
LD L,(HL) ; Get value at this address
LDL:
PEEKRES: LD H,0 ; Set MSB to zero
RST OP
DEFB $LOADINT## ; Put result on stack, and return.
DEFB $END##
RET
GET16ADR: LD HL,32768
PUSH HL
RST OP
DEFB $LOADINT## ; Put 32768 on dtack
DEFB $FSUB## ; Subtract from address, and then FIX
DEFB $FIX## ; to return value between -32768 and
DEFB $END## ; +32767
POP DE ; DE = 32768
ADD HL,DE ; Adjust to get proper address
RET
-
Hello Bruce!
I try to describe it english maybe you did not get from the translation.
My problem is i would like to use assembly code in IS-Basic by using the Call USR function.
I would like to pass more then one 16 bit value, and maybe receive also more than one.
I need an advice how to do it without too much calculation.
The problem is, if I use poke to send a 16 bit value, i have to do a division with 256 and use the result to sent the hibyte, and take the remainder to send the lobyte. This division in is basic probably very expensive, because of the division.
On the way back, from assembl to basic (by using more than one return variable), i have to multiply the hibyte with 256 and add to lobyte. I assume the multiplicatiom with 256 and adding is more expensive than put the high and lowbyte together.
My idea was, that the assembly code takes the variable from the memory directly where the e.g LET a=23675 stores the value, instead of passing somewhere else. But later i read that is-basic stores only integer from 0-9999, and if we exceed it it will be converted to bcd format (where a 8bit memory stores 2 decimals.
It would be handy, if CALL(USR) would take 2 possible or maybe more values: call usr(routine1,x,y)
I could accept that it returns only 1 value, because in that case i would call it twice (with different routines), to get more results.
Maybe you have an idea about this topic.
-
Végül is mennyi adatot szeretnél egyszerre egy USR(PR1,v1,v2,...)-nél ?
-
Kettőt biztosan. Harmadik már opcionális.
-
Csak ennyi kell:
3840 DEF PEEK16(M)
3850 LET PEEK16=PEEK(M)+PEEK(M+1)*256
3860 END DEF
4010 DEF POKE16(M,N)
4020 NUMERIC X
4030 LET X=MOD(N,256)
4040 POKE M,X
4050 LET N=(N-X)/256
4060 POKE M+1,N
4070 END DEF
(Az FDISK-emből. Ott van 32 bites variáció is.)
-
nem emlékszem pontosan de volt BASIC ban a CODE HEX$ kódban olyasmi
CODE P1=HEX$("...,C9")
CODE P2=HEX$("...,CD"& xxx(P1) &("...,C9")
Egy változó ami a P1 NNNN címet beilleszti a gépi kódba.
-
Megtaláltam WORD$() a változó.
Olyasmit kipróbáltam, hogy
CODE RAM00... bc
CODE RAM02... de
CODE RAM04... hl
CALL USR(WR0,nnnn) ~ LD (RAM00),nnnn
CALL USR(WR2,nnnn) ~ LD (RAM02),nnnn
CALL USR(WR4,nnnn) ~ LD (RAM04),nnnn
A=USR(RD16,RAM00) ~ LD nnnn,(RAM00)
A=USR(RD16,RAM02) ~ LD nnnn,(RAM02)
A=USR(RD16,RAM04) ~ LD nnnn,(RAM04)
igaz A=-3276x-3276x
-
Sorry, only in English:
This has been discussed several times. For example this one (https://enterpriseforever.com/programming/where-am-i/msg38070/#msg38070).
One of the beauties and also a handicap of Machine Code on IS-Basic is that the resulting routine is relocatable: the start address depends on the extras you have installed on your Enterprise.
Zozo gave me long ago the clue to manage it: CALL USR(MC,MC)
I am not a real programmer, but I like to do little routines, almost by writing them on a note of paper....
This is how I would do what you want:
Send the start address of the routine as the second operand with the CALL USR(MC,MC) Basic command. Then place an immediate relative jump at the start of your code, leaving all the data bytes you need. Save HL value for later. Like on this example:
MC:
JR Start ; A JR instruction has a length of 2 bytes: 18h+two's complement of the displacement.
Value1: DEFB 0
Value2: DEFB 255
etc...
Start:
PUSH HL
etc...
You can know on every moment the address of Start, adding JR displacement + MC( in HL), and also Value1 address=MC+2, Value2 address=MC+3, etc. Then you can do the same easily on Basic: Value1=peek(mc+2): Value2=peek(mc+3)
-
Megtaláltam WORD$() a változó.
Olyasmit kipróbáltam, hogy
CODE RAM00... bc
CODE RAM02... de
CODE RAM04... hl
CALL USR(WR0,nnnn) ~ LD (RAM00),nnnn
CALL USR(WR2,nnnn) ~ LD (RAM02),nnnn
CALL USR(WR4,nnnn) ~ LD (RAM04),nnnn
A=USR(RD16,RAM00) ~ LD nnnn,(RAM00)
A=USR(RD16,RAM02) ~ LD nnnn,(RAM02)
A=USR(RD16,RAM04) ~ LD nnnn,(RAM04)
igaz A=-3276x-3276x
A WORD$ függvény arra való (Gépi kódú programozás könyv szerit), hogy ha vann egy CODE-dal deklarált string a basic kódban:
CODE A=CHR$(17)&"THIS IS A STRING." ! itt CHR utáni "17" a string hosszát adja meg
Akkor ennek a CODE-dal készített "String füzérnek" a kezdőcímét be tudjuk tenni a gépi kódba:
CODE ROUTINE1=HEX$("00",... assembly code...,WORD$(A), ... assembly code....)
Mert ugye alapvetően a CODE egyébként is azt mondja meg, hogy hol tárolta el a HEX után deklarált kódot a memóriában (2Byte-os integer).
Mivel a basic dinamukusan fordít, arra is jó lehet, hogy egy vagy több integer számot szétbontson két byte-ra, és elhelyezze a CODE-ban, viszont többszöri meghívásra ez nem alkalmas mert a CODE csak egyszer helyez el memórában adatot.
Amit még el tudok képzelni, hogy van egy integer, amit WORD-del szétbontuk, majd ORD-vel leszedjük az elemeket.
100 ALLOCATE 100
110 CODE MEMO=HEX$("00","00","00","00") ! Helyfoglaló
120 A=12345
130 B=3425
140 D$=WORD$(A) ! A értéke szétbontva D$-ba kerül
150 E$=WORD$(B)
160 POKE (MEMO+0),ORD(D$(1:1)) ! copy lo-BYTE to MEMORY
170 POKE (MEMO+1),ORD(D$(2:2)) ! hi-BYTE
180 POKE (MEMO+2),ORD(E$(1:1)) ! lo-BYTE
190 POKE (MEMO+3),ORD(E$(2:2)) ! hi-BYTE
Már csak Benchmarkot kell lefuttatni, hogy a fenti kód gyorsabb-e, vagy a lenti osztás.
POKE (MEMO+0)=MOD(A,256)
POKE (MEMO+1)=A/256
-
Közben elvégeztem egy gyors tesztet:
127 db futás 6 poke,
- WORD és ORD-dal - 13 sec
- Osztással és MOD-dal - 38 sec
Tehat a WORD/ORD 3-szor gyorsabb kódot ad.
Még egy lehetőség van, hogy a CALL USR() rutint többször egymás után hívom meg, hogy adatokat átadjak:
100 CODE MEMO("00,00,00,00,00,00")
110 CODE PASS_A=HEX$("...,WORD$(MEMO)... ,C9") ! LD IX,MEMO ; LD (IX+0),L ; LD (IX+1),H ; RET ;
120 CODE PASS_B=HEX$("...,WORD$(MEMO)... ,C9") ! LD IX,MEMO ; LD (IX+2),L ; LD (IX+3),H ; RET ;
130 CODE CALC_RES1=HEX$("...WORD$(MEMO)....,C9")
140 CODE GET_RES2=HEX$("........,C9") ! LD IX,MEMO ; PUSH HL, POP IX (a változatosság kedvéért); LD L,(IX+2) ; LD H,(IX+3) ; RET ;
150 LET A=23456
160 LET B=1234
170 CALL USR(PASS_A,A) ! A value goes into HL, then stored to MEMO
180 CALL USR(PASS_B,B) ! B value goes into HL, then stored to MEMO
190 LET RESULT1=CALL USR(CALC_RES1)
200 LET RESULT2=CALL USR(MEMO)
Itt még talán a 120 és 130 sorokat össze lehetne vonni, hogy amikor a CALC kódot hívom, akkor egyúttal átadok egy értéket, így nem kell kétszer hívni.
Lassan megoldódik a kérdésem.
-
Ha ennyire kritikus a sebesség, akkor nem lenne esetleg megfontolandó más nyelvre áttérni? Pl. Pascal.
-
Beépített interpreteres nyelvre van szükségem. Csak az IS-Basic adja magát.
Itt most a sebesség azért fontos mert sokféle megoldás van, és nem akarom a leglassabbat választani.
-
Közben elvégeztem egy gyors tesztet:
127 db futás 6 poke,
- WORD és ORD-dal - 13 sec
- Osztással és MOD-dal - 38 sec
Tehat a WORD/ORD 3-szor gyorsabb kódot ad.
Beszállhatok egy 3. lehetőséggel ?
1000x
- WORD és ORD-dal - 55 sec
- Osztással és MOD-dal - 201 sec
- USR osztó - 46 sec
-
Beszállhatok egy 3. lehetőséggel ?
1000x
- WORD és ORD-dal - 55 sec
- Osztással és MOD-dal - 201 sec
- USR osztó - 46 sec
Hogy néz ki az USR osztó?
-
Hogy néz ki az USR osztó?
Mellékletben ott van a teszt mellet.
-
Én hibám, nem láttam. De mostmár látom.
Olvasgattam a Gépi Kódú programozás könyvet a 254.oldalon, és azt láttam, hogy van megoldás az ALLOCATE elkerülésére. Amivel az a baj, hogy a függvény vagy kód nem hajtható végre, ha a program éppen valamilyen hibaüzenettel leállt, és debuggolni szeretnénk úgy, hogy végre kell hajtani egy USR kódot.
Allocate elkerüléséhez CODE előtt ki kell adani a
POKE 540, address lobyte
POKE 541, address hibyte
parancsokat, amiknek hatására a CODE utáni részt fixen oda teszi ahova akarjuk. Sajnos csak belapozott helyen működik. A 3.lapon ROM-van, oda nem lehet. A 2. Lapon a 255-ös szegmens van, de ugya a video: kezeli. A 1. Lapon nem tudom mi van, de a 0.lap az fix. A könyv a 3000h címet ajánlja, amennyiben a basic program nem túl hosszú.
Vajon rövid kódot lehet-e elhelyeznii a 0000 címtől valamedig?
-
Vajon rövid kódot lehet-e elhelyeznii a 0000 címtől valamedig?
Szerintem nem 0000h minimum ~0066h NMI ig nem érdemes módosítani a RAM-ot.
-
Szerintem nem 0000h minimum ~0066h NMI ig nem érdemes módosítani a RAM-ot.
0x0000-0x002f-ig nyugodtan tehetsz bármit
meg Zozó meg tudja mondani, hogy 0x38 fölött hol
mármint ha mindezt nem BASIC-ben akarod használni (közben rájöttem, h te BASIC-ben akarod)
mert az használ rst rutinokat
edit: ahogy nézem, egyedül az első 8 bájt szabad BASIC-ben (0x0000-0x0007)
-
Miért kell fix memória, és kb. mennyi?