OldComp.cz

Komunitní diskuzní fórum pro fanoušky historických počítačů


Právě je 18.04.2024, 20:18

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]




Odeslat nové téma Odpovědět na téma  [ Příspěvků: 156 ]  Přejít na stránku Předchozí  1 ... 7, 8, 9, 10, 11  Další
Autor Zpráva
PříspěvekNapsal: 25.02.2020, 08:06 
Offline
Pan Štábní

Registrován: 23.06.2013, 23:49
Příspěvky: 1113
Has thanked: 100 times
Been thanked: 159 times
Tady jsem nasel emulaci programovaciho jazyka forth na Z80 a pouziva variantu pres emulaci druheho zasobniku pomoci HL. Protoze potrebuje rychle a kratce prepnout zasobnik a vratit se na puvodni. https://github.com/kenyapcomau/eforth/blob/master/z80efort/kernel.z80

_________________
Z80 Forth compiler (ZX Spectrum 48kb): https://codeberg.org/DW0RKiN/M4_FORTH


Nahoru
 Profil  
 
PříspěvekNapsal: 16.04.2020, 21:45 
Offline
Profík

Registrován: 06.02.2019, 11:47
Příspěvky: 901
Has thanked: 51 times
Been thanked: 230 times
Pisal som rutinu, kde na zaklade indexu, ulozeneho za instrukciou CALL, sa vyberie z tabulky adresa skoku a vykona skok bez toho, aby boli znehodnotene registre. Rutina je vsak relativne dlha. Ma niekto napad na skratenie (T)?
P.S. rutina bude v ROM, takze nemoze byt samomodifikacna.

Kód:
IJUMP:
EX      (SP), HL        ; vyber navratovu adresu        (19T)
PUSH    HL              ; duplikuj                      (11T)
INC     SP              ; posun stack pointer           (12T)
INC     SP
INC     HL              ; modifikuj navratovu adresu    ( 6T)
EX      (SP), HL        ; aby ukazovala o 1 bajt dalej  (19T)
DEC     SP              ; vrat stack pointer            (12T)
DEC     SP
EX      (SP), HL        ; uschovaj HL, vyber adresu     (19T)
PUSH    AF              ; na chvilu uloz A              (11T)
LD      L, (HL)         ; vyber index z kodu            ( 7T)
LD      H, 82h          ; adresa tabulky (horny bajt)   ( 7T)
LD      A, (HL)         ; vycitaj z tabulky adresu      ( 7T)
INC     HL              ; rutiny do HL                  ( 6T)
LD      H, (HL)         ;                               ( 7T)
LD      L, A            ;                               ( 4T)
POP     AF              ; obnov A                       (10T)
EX      (SP), HL        ; adresu na zasobnik, obnov HL  (19T)
RET                     ; skoc na adresu rutiny         (10T)
         ; 186T
;
; test
CALL    IJUMP
DB      00
; sem sa nakoniec vrati program




Nahoru
 Profil  
 
PříspěvekNapsal: 16.04.2020, 23:09 
Offline
Kecálek

Registrován: 10.07.2014, 01:57
Příspěvky: 169
Has thanked: 25 times
Been thanked: 225 times
Martin1 píše:
Kód:
LD      L, (HL)         ; vyber index z kodu            ( 7T)
LD      H, 82h          ; adresa tabulky (horny bajt)   ( 7T)

kedze za callom ma byt index do tabulky, ktorej prvky su dvojbajtove hodnoty, chyba ti tam nasobenie indexu dvomi. da sa pouzit toto:
Kód:
LD      L, (HL)
LD      H, 41h          ; polovica horneho bajtu adresy tabulky
ADD     HL,HL

ja osobne by som ale nepodmienoval zaciatok tabulky na vhodnu adresu a pouzil by som na vypocet adresy DE. samozrejme sa potom bude musiet push/pop-ovat DE, ale to sa nakoniec da spravit miesto push-popovania AF:
Kód:
PUSH    DE
LD      L,(HL)
LD      H,0
ADD     HL,HL
LD      DE,tabulka
ADD     HL,DE
LD      E,(HL)
INC     HL
LD      H,(HL)
LD      L,E
POP     DE

kazdopadne.. toto ale zavisi od toho ako casto sa ta rutina bude volat a ako kriticka je dlzka jej trvania, alebo velkost rutiny v romke. ono nakoniec.. jeden-dva bajty dlhsi kod moze byt efektivnejsi, ak by inak bolo treba dat tabulku na adresu o 10 bajtov vacsiu ako posledny bajt kodu (kvoli nutnosti zacinat na adrese so spodnym bajtom=00h), cim by tak zostalo 10 nevyuzitych bajtov.

[EDIT] jo, a ak teda nejde o dlzku kodu, ale ide o optimalizaciu na cas, vykasli sa na celu tabulku skokov a miesto indexu za CALL daj rovno adresu kam skocit. nieco ako
Kód:
call ijump
dw   rutina

usetris tak skoro tretinu T celej rutiny (136 oproti 197 [186+11 za pridane add hl,hl]):
Kód:
                    ;hl    de    (sp)         T
ijump               ;HL    DE    RET
      ex    (sp),hl ;RET   DE    HL          19
      push  de      ;RET   DE    HL,DE       11
      ld    e,(hl)  ;RET   Ddr   HL,DE        7
      inc   hl      ;RET+1 Ddr   HL,DE        6
      ld    d,(hl)  ;RET+1 addr  HL,DE        7
      inc   hl      ;RET+2 addr  HL,DE        6
      inc   sp      ;RET+2 addr  HL,D[E]      6
      inc   sp      ;RET+2 addr  HL[,DE]      6
      ex    (sp),hl ;HL    addr  RET+2[,DE]  19
      dec   sp      ;HL    addr  RET+2,D[E]   6
      dec   sp      ;HL    addr  RET+2,DE     6
      ex    hl,de   ;addr  HL    RET+2,DE     4
      ex    (sp),hl ;DE    HL    RET+2,addr  19
      ex    hl,de   ;HL    DE    RET+2,addr   4
      ret           ;HL    DE    RET+2       10

19+11+7+6+7+6+6+6+19+6+6+4+19+4+10 = 136


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 01:27 
Offline
Pan Generální

Registrován: 01.12.2017, 21:01
Příspěvky: 2089
Bydliště: BA-Petržalka :(
Has thanked: 18 times
Been thanked: 327 times
ub880d píše:
...miesto indexu za CALL daj rovno adresu kam skocit. nieco ako
Kód:
call ijump
dw   rutina

A nieje potom jednoduchšie s CALL skákať priamo na požadovanú rutinu?

_________________
Oznamy o novom príspevku mi na mail chodia iba sporadicky, takže keď sa nehlásim v diskusii, tak je to tým. V 80% nepríde mail vôbec.


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 07:41 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3661
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 795 times
Pozor, tato cast nemusi fungovat spravne:
Martin1 píše:
Kód:
INC     SP              ; posun stack pointer           (12T)
INC     SP
INC     HL              ; modifikuj navratovu adresu    ( 6T)
EX      (SP), HL        ; aby ukazovala o 1 bajt dalej  (19T)
DEC     SP              ; vrat stack pointer            (12T)
DEC     SP
EX      (SP), HL        ; uschovaj HL, vyber adresu     (19T)
Co myslis, co sa stane s vyberanou adresou, ak niekde tam uprostred dojde k preruseniu ?


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 08:16 
Offline
Profík

Registrován: 06.02.2019, 11:47
Příspěvky: 901
Has thanked: 51 times
Been thanked: 230 times
ub880d píše:
kedze za callom ma byt index do tabulky, ktorej prvky su dvojbajtove hodnoty, chyba ti tam nasobenie indexu dvomi

Nechyba, vynechal som to naschval, kedze pocet volani v tabulke bude cca 40, staci, ked bude index vzdy len parne cislo. Ale mozno to este zvazim.
ub880d píše:
kazdopadne.. toto ale zavisi od toho ako casto sa ta rutina bude volat a ako kriticka je dlzka jej trvania, alebo velkost rutiny v romke. ono nakoniec.. jeden-dva bajty dlhsi kod moze byt efektivnejsi,

Bude to hlavny bod vstupu uzivatelskych programov, teda sa bude volat dost casto. Vsetky volania systemovych rutin pojdu cez tento jediny bod.
Aj preto to musi byt cez "index", lebo adresa za volanim straca vyznam.
Busy píše:
Pozor, tato cast nemusi fungovat spravne:
Co myslis, co sa stane s vyberanou adresou, ak niekde tam uprostred dojde k preruseniu ?

Dobra pripomienka :like: , a mas v rukave nejaky napad na riesenie?


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 09:31 
Offline
Profík

Registrován: 06.02.2019, 11:47
Příspěvky: 901
Has thanked: 51 times
Been thanked: 230 times
Tak som to vyriesil bez upravy SP, este som aj par T usertril....
Kód:
START:          LD      HL, 1122h
                LD      DE, 3344h
                LD      BC, 5566h
                LD      A, 99h
                CALL    IJUMP
                DB      01h
                HALT
IJUMP:          PUSH    HL              ; uschovaj HL                   (11T)
                PUSH    DE              ; a DE                          (11T)
                LD      HL, 0004h       ; vytvor ukazatel na navr. ad.  (10T)
                ADD     HL, SP          ;                               (11T)
                LD      E, (HL)         ; nacitaj navratovu adresu      (20T)
                INC     HL
                LD      D, (HL)
                INC     DE              ; na nasledujuci bajt           ( 6T)
                LD      (HL), D         ; uloz naspat                   (20T)
                DEC     HL
                LD      (HL), E
                EX      DE, HL          ; zamen registre                ( 4T)
                DEC     HL              ; v HL je adresa indexu         ( 6T)
                LD      L, (HL)         ; nacitaj index                 ( 7T)
;               SLA     L               ; index * 2                     ( 8T)
                LD      H, 01h          ; adresa zaciatku tabulky       ( 7T)
                LD      E, (HL)         ; nacitaj vektor z tabulky      (20T)
                INC     HL
                LD      D, (HL)
                EX      DE, HL          ; vektor do HL                  ( 4T)
                POP     DE              ; obnov DE                      (10T)
                EX      (SP), HL        ; adresu na zasobnik, obnov HL  (19T)
                RET                     ; skoc na adresu rutiny         (10T)
                                        ; 176T  (184T)
TEST:           RET
TEST2:          RET
;
                ORG     0100h
TAB:            DW      TEST
                DW      TEST2


Naposledy upravil Martin1 dne 17.04.2020, 09:37, celkově upraveno 2

Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 09:36 
Offline
Pan Generální

Registrován: 01.12.2017, 21:01
Příspěvky: 2089
Bydliště: BA-Petržalka :(
Has thanked: 18 times
Been thanked: 327 times
Ja mám nápad. Keďže bude indexov iba 40, čo tak spraviť tabuľku priamo zo samých JP nn? Index by bol vždy deliteľný troma, iba by sa doplnil H a mohlo by sa skákať, nemusela by sa čítať adresa. Nevýhoda je +40 bytov naviac, a žiadna ochrana proti neplatnému indexu.

_________________
Oznamy o novom príspevku mi na mail chodia iba sporadicky, takže keď sa nehlásim v diskusii, tak je to tým. V 80% nepríde mail vôbec.


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 09:40 
Offline
Profík

Registrován: 06.02.2019, 11:47
Příspěvky: 901
Has thanked: 51 times
Been thanked: 230 times
PotPalo píše:
Ja mám nápad. Keďže bude indexov iba 40, čo tak spraviť tabuľku priamo zo samých JP nn? Index by bol vždy deliteľný troma, iba by sa doplnil H a mohlo by sa skákať, nemusela by sa čítať adresa. Nevýhoda je +40 bytov naviac, a žiadna ochrana proti neplatnému indexu.

To nič nerieši, a navyše prišiel by si o register HL.
Tak či tak by si musel vyčítať index a vytvoriť adresu na inštrukciu skoku.
M1


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 09:57 
Offline
Pan Generální

Registrován: 01.12.2017, 21:01
Příspěvky: 2089
Bydliště: BA-Petržalka :(
Has thanked: 18 times
Been thanked: 327 times
Niečo takéto. Akurát HL treba niekde odložiť, ale tie 2 byty v RAM sa hádam nájdu.
Kód:
ld (odkl.),hl
pop hl
inc hl
push hl
dec hl
ld l,(hl)
ld h,htab.
push hl
ld hl,(odkl.)
ret

tab:
jp prog1
jp prog2
jp prog3

_________________
Oznamy o novom príspevku mi na mail chodia iba sporadicky, takže keď sa nehlásim v diskusii, tak je to tým. V 80% nepríde mail vôbec.


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 11:30 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3661
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 795 times
A co tak uplne sa vykaslat na cely IJUMP a nechat len tabulku "vektorov" ?
Kód:
          org #0100
polozka1: jp prog1
polozka2: jp prog2
polozka3: jp prog3
A v aplikacii by namiesto definicii sluzieb jednobajtovymi indexami boli sluzby definovane adresou "polozkaX" v tabulke.

T.j. namiesto
Kód:
nazov_sluzby = polozka2 - #100
call ICALL
db nazov_sluzby
by bolo
Kód:
nazov_sluzby = polozka2
call nazov_sluzby
Btw. tento sposobom volania sluzieb pouziva aj romka v Spektre 128k :)


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 12:42 
Offline
Profík

Registrován: 06.02.2019, 11:47
Příspěvky: 901
Has thanked: 51 times
Been thanked: 230 times
Busy píše:
A co tak uplne sa vykaslat na cely IJUMP a nechat len tabulku "vektorov" ?
Kód:
nazov_sluzby = polozka2
call nazov_sluzby
Btw. tento sposobom volania sluzieb pouziva aj romka v Spektre 128k :)

Ak to dobre chapem, tak mas na mysli tabulku skokov ako zacina napriklad BIOS v CP/M?
Potom musis mat stale a verziami nemenne umiestnenie tabulky skokov. Tak som to mal doteraz ale prave to chcem nahradit niecim univerzalnejsim, t. j. staci Ti poznat jednu adresu a cislo sluzby.
Inak pozeral som, ako to ma Z88, a je to velmi podobne, ako pise PotPalo, naozaj je tam tabulka skokov s prikazmi JUMP nnnn, teda cislo sluzby musi byt nasobkom troch.


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 12:58 
Offline
Óm Nejvyšší

Registrován: 22.05.2013, 21:14
Příspěvky: 3661
Bydliště: Bratislava
Has thanked: 373 times
Been thanked: 795 times
Martin1 píše:
Busy píše:
A co tak uplne sa vykaslat na cely IJUMP a nechat len tabulku "vektorov" ?
Potom musis mat stale a verziami nemenne umiestnenie tabulky skokov. Tak som to mal doteraz ale prave to chcem nahradit niecim univerzalnejsim, t. j. staci Ti poznat jednu adresu a cislo sluzby.
Tak ale od tej adresy musi byt rutinka IJUMP co podla cisla skace, alebo aspon skok na tu rutinku, v kazdom pripade je to pevna adresa, a v tom pripade by som tam rovno dal celu tabulku. A usetri to zopar bajtov rutinky IJUMP a jeden dalsi bajt pre kazde volanie sluzieb v uzivatelskych programoch.


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 18:56 
Offline
Kecálek

Registrován: 10.07.2014, 01:57
Příspěvky: 169
Has thanked: 25 times
Been thanked: 225 times
PotPalo píše:
ub880d píše:
...miesto indexu za CALL daj rovno adresu kam skocit. nieco ako
Kód:
call ijump
dw   rutina

A nieje potom jednoduchšie s CALL skákať priamo na požadovanú rutinu?
je ;] nejak mi to vobec nenapadlo, ze v tom pripade je vlastne cele vyratavanie adresy zbytocne ;]


Nahoru
 Profil  
 
PříspěvekNapsal: 17.04.2020, 20:22 
Offline
Profík

Registrován: 06.02.2019, 11:47
Příspěvky: 901
Has thanked: 51 times
Been thanked: 230 times
Busy píše:
A usetri to zopar bajtov rutinky IJUMP a jeden dalsi bajt pre kazde volanie sluzieb v uzivatelskych programoch.

Pokial sa na volanie nepouzije RST xx namiesto CALL. A vtedy sa uz pomer zasadne obracia


Nahoru
 Profil  
 
Zobrazit příspěvky za předchozí:  Seřadit podle  
Odeslat nové téma Odpovědět na téma  [ Příspěvků: 156 ]  Přejít na stránku Předchozí  1 ... 7, 8, 9, 10, 11  Další

Všechny časy jsou v UTC + 1 hodina [ Letní čas ]


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 2 návštevníků


Nemůžete zakládat nová témata v tomto fóru
Nemůžete odpovídat v tomto fóru
Nemůžete upravovat své příspěvky v tomto fóru
Nemůžete mazat své příspěvky v tomto fóru
Nemůžete přikládat soubory v tomto fóru

Hledat:
Přejít na:  
Založeno na phpBB® Forum Software © phpBB Group
Český překlad – phpBB.cz