Autor Wątek: Z80 profiler  (Przeczytany 41159 razy)

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4537
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Z80 profiler
« Odpowiedź #15 dnia: 2016.01.19, 09:38:09 »
Odpaliłem profiler w następujący sposób:Z80Profiler.exe -c3.5 -la -ll -ld 48.ROM >48.lst
Wsadem jest ROM z ZX48.

Otrzymałem np takie wyniki:
Cytuj
.
.
.
.
l0d4d:
0d4d   xor a         ;         20T  AF
0d4e   ld hl,(05c8dh)      ;         80T  2A 8D 5C
0d51   bit 0,(iy+002h)      ;        100T  FD CB 02 46
0d55   jr z,0d5bh      ;         45T  28 04
0d57   ld h,a         ;         12T  67
0d58   ld l,(iy+00eh)      ;         57T  FD 6E 0E
l0d5b:
0d5b   ld (05c8fh),hl      ;         80T  22 8F 5C
0d5e   ld hl,05c91h      ;         50T  21 91 5C
0d61   jr nz,0d65h      ;         50T  20 02
0d63   ld a,(hl)      ;         14T  7E
0d64   rrca         ;          8T  0F
l0d65:
0d65   xor (hl)      ;         35T  AE
0d66   and 055h      ;         35T  E6 55
0d68   xor (hl)      ;         35T  AE
0d69   ld (hl),a      ;         35T  77
0d6a   ret         ;         50T  C9
l0d6b:

Ilość taktów dla xor, and i innych jest nieprawidłowa, przez co całość wyników zdaje się być mocno zawyżona.

Dr Piotr

  • ***
  • Wiadomości: 196
Odp: Z80 profiler
« Odpowiedź #16 dnia: 2016.01.19, 13:55:16 »
Odpaliłem profiler w następujący sposób:Z80Profiler.exe -c3.5 -la -ll -ld 48.ROM >48.lst
Wsadem jest ROM z ZX48.

Otrzymałem np takie wyniki:
Cytuj
.
.
.
.
l0d4d:
0d4d   xor a         ;         20T  AF
0d4e   ld hl,(05c8dh)      ;         80T  2A 8D 5C
0d51   bit 0,(iy+002h)      ;        100T  FD CB 02 46
0d55   jr z,0d5bh      ;         45T  28 04
0d57   ld h,a         ;         12T  67
0d58   ld l,(iy+00eh)      ;         57T  FD 6E 0E
l0d5b:
0d5b   ld (05c8fh),hl      ;         80T  22 8F 5C
0d5e   ld hl,05c91h      ;         50T  21 91 5C
0d61   jr nz,0d65h      ;         50T  20 02
0d63   ld a,(hl)      ;         14T  7E
0d64   rrca         ;          8T  0F
l0d65:
0d65   xor (hl)      ;         35T  AE
0d66   and 055h      ;         35T  E6 55
0d68   xor (hl)      ;         35T  AE
0d69   ld (hl),a      ;         35T  77
0d6a   ret         ;         50T  C9
l0d6b:

Ilość taktów dla xor, and i innych jest nieprawidłowa, przez co całość wyników zdaje się być mocno zawyżona.
Profiler usiluje wykonac kod, ktory mu wrzucasz, stad tez ilosc tstates czy ms moze byc wieksza jesli dana sekwencja rozkazow zostanie wykonana wiecej niz 1 raz. Tam, gdzie nie dotarl bedziesz mial czas 0.
Profiler w zasadzie nie ma opcji samej deasemblacji z podaniem liczby taktow na rozkaz. Jak chcesz tylko zobaczyc ile taktow zajmuje wykonanie danej instrukcji, sprobuj parametru -d (oraz -ax0d4d aby zaczal wykonywac od tego adresu) ew. tylko opcji -a.
W sumie moze dodam opcje takiej deasemblacji, moze sie przydac.

Dr Piotr

  • ***
  • Wiadomości: 196
Odp: Z80 profiler
« Odpowiedź #17 dnia: 2016.01.19, 15:21:58 »
Odpaliłem profiler w następujący sposób:Z80Profiler.exe -c3.5 -la -ll -ld 48.ROM >48.lst
Wsadem jest ROM z ZX48.
Aha, opcja -c3.5 bez opcji -lms nie ma sensu, bo wtedy wyniki sa wyswietlane w tstates, na co opcja -c nie ma wplywu.
« Ostatnia zmiana: 2016.01.19, 15:33:21 wysłana przez Dr Piotr »

ssr86

  • *
  • Wiadomości: 37
  • Miejsce pobytu:
    Bydgoszcz
Odp: Z80 profiler
« Odpowiedź #18 dnia: 2016.01.22, 09:35:44 »
Dopiero dziś tu wszedłem. Bardzo przydatne narzędzie.
Jakiś czas temu sam zamierzałem się za coś podobnego zabrać, bo akurat było mi potrzebne, ale jak pomyślałem, że to w zasadzie wymaga napisania jakby kompilatora to się "wystraszyłem";P.
To czekam na release:)

A tak to piszę, bo chciałem zapytać, czy w miarę nieskomplikowane byłoby umożliwienie dodania opóźnień na dostępach (odczyt i zapis) do określonych obszarów pamięci (wideo)? 
"Kto zawsze tylko żył w pustyni..."

Dr Piotr

  • ***
  • Wiadomości: 196
Odp: Z80 profiler
« Odpowiedź #19 dnia: 2016.01.22, 09:57:44 »
A tak to piszę, bo chciałem zapytać, czy w miarę nieskomplikowane byłoby umożliwienie dodania opóźnień na dostępach (odczyt i zapis) do określonych obszarów pamięci (wideo)?
Na razie sa zaimplementowane dwie opcje tego rodzaju - dla amstrada cpc, rozciagajaca tstates do wartosci podzielnej przez 4 oraz dla msx dodatkowy tstate przy odczycie opcode. Mozliwe, ze zaimplementuje tez dla zx spectrum, ale to bardziej skomplikowane.
Do jakiego komputera to potrzebujesz?

ssr86

  • *
  • Wiadomości: 37
  • Miejsce pobytu:
    Bydgoszcz
Odp: Z80 profiler
« Odpowiedź #20 dnia: 2016.01.22, 10:05:30 »
Do Enterprise... Gdy jakiś czas temu pytałem autora emulatora jak można to sobie liczyć to otrzymałem poniższą informację:
Cytuj
Wait states generated by DAVE (if enabled on port BFh) are simple, they add 1 cycle to all memory accesses (00h) or only M1 reads (04h). The latter are the first byte of simple instructions with no prefix, or the first two bytes with CB/DD/ED/FDh prefix. Also, according to tests by Zozosoft, it seems that DAVE waits 2 cycles on turbo machines. But in programs where speed is important, wait states are disabled, so all the above does not matter.

Video memory and NICK I/O port timing are more complex: within each 889846 Hz "slot" (1 character), the Z80 is allowed access to one byte at a specific time, and it always needs to wait at least a certain amount of time (a few ns more than 5/16 of a character, and there is also few ns difference depending on the type of access - normal memory, M1 memory, and I/O). This is implemented by the NICK chip halting the Z80's clock, which it can do in 1/2 clock cycles (1/8000000 s on normal non-turbo machines). There is a test run on real machines here that measures the average time between video memory accesses at various intervals in Z80 cycles.

For the calculations in the sprite code, I used a simplified model: add 1.5 cycles to the time between the video memory accesses, and then round up the result to an integer multiple of 4.5 cycles, and that is the real amount of time, with the wait states (stopped Z80 clock) added. In other words, the best case is 1.5 cycles of wait, and the worst case is 5.5 cycles. This is not entirely accurate, but it gives a reasonable estimate.

When calculating video memory timing, it should also be taken into account exactly when the accesses occur within the instruction. This can be found in the Z80 documentation. For example, an LD (HL), A instruction is two memory accesses, an M1 read at 2 cycles, and a normal write at 6.5 cycles.
Chodziłoby o opóźnienia związane z dostępem do pamięci wideo.
"Kto zawsze tylko żył w pustyni..."

Dr Piotr

  • ***
  • Wiadomości: 196
Odp: Z80 profiler
« Odpowiedź #21 dnia: 2016.01.22, 11:15:24 »
Do Enterprise... Gdy jakiś czas temu pytałem autora emulatora jak można to sobie liczyć to otrzymałem poniższą informację:
Cytuj
Wait states generated by DAVE (if enabled on port BFh) are simple, they add 1 cycle to all memory accesses (00h) or only M1 reads (04h). The latter are the first byte of simple instructions with no prefix, or the first two bytes with CB/DD/ED/FDh prefix. Also, according to tests by Zozosoft, it seems that DAVE waits 2 cycles on turbo machines. But in programs where speed is important, wait states are disabled, so all the above does not matter.

Video memory and NICK I/O port timing are more complex: within each 889846 Hz "slot" (1 character), the Z80 is allowed access to one byte at a specific time, and it always needs to wait at least a certain amount of time (a few ns more than 5/16 of a character, and there is also few ns difference depending on the type of access - normal memory, M1 memory, and I/O). This is implemented by the NICK chip halting the Z80's clock, which it can do in 1/2 clock cycles (1/8000000 s on normal non-turbo machines). There is a test run on real machines here that measures the average time between video memory accesses at various intervals in Z80 cycles.

For the calculations in the sprite code, I used a simplified model: add 1.5 cycles to the time between the video memory accesses, and then round up the result to an integer multiple of 4.5 cycles, and that is the real amount of time, with the wait states (stopped Z80 clock) added. In other words, the best case is 1.5 cycles of wait, and the worst case is 5.5 cycles. This is not entirely accurate, but it gives a reasonable estimate.

When calculating video memory timing, it should also be taken into account exactly when the accesses occur within the instruction. This can be found in the Z80 documentation. For example, an LD (HL), A instruction is two memory accesses, an M1 read at 2 cycles, and a normal write at 6.5 cycles.
Chodziłoby o opóźnienia związane z dostępem do pamięci wideo.
Ten opis zawily troche jest, jakbys zorganizowal taka tabelke:
|start address|end address|M1 delay|read delay|write delay|io read delay|io write delay|

To moglbym sprobowac to podlaczyc.

Dr Piotr

  • ***
  • Wiadomości: 196
Odp: Z80 profiler
« Odpowiedź #22 dnia: 2016.01.25, 11:35:19 »
Zrobilem w weekend nowa wersje:
- laduje i wykorzystuje liste zmiennych, generowanych z assemblerow: maxam/winape, pasmo, sjasmplus
- opcja -d - tylko deasemblacja bez profilowania.
- opcja -t - wyswietlanie instrukcji w trakcie ich wykonywania
- opcja -ll - wyswietla liste wszystkich etykiet, zarowno tych wczytanych jak i automatycznie wygenerowanych w trakcie wykonywania

Nastepna wersja bedzie wczytywac pliki .cdb z kompilatora sdcc.
W kolejce czeka UI na windows, pluginy dla roznych procesorow, breakpointy itp :)

Dr Piotr

  • ***
  • Wiadomości: 196
Odp: Z80 profiler
« Odpowiedź #23 dnia: 2016.03.15, 10:38:44 »
Nowa wersja beta, teraz juz jako The Profiler :)

- wersja UI dla windows xp/7/8/10
- ladowanie plikow bin oraz .cdb (sdcc)
- ladowanie plikow z symbolami w formatach
  • maxam/winape
  • pasmo
  • sjasmplus
  • noGMB
- obsluga wielu procesorow (kazdy procesor jako osobny plugin)
  • profiler
  • symulator/debugger
  • disassembler
  • monitor pamieci
- wbudowany jezyk skryptowy
  • programowalne definiowanie urzadzen (procesor, pamiec ram/rom, porty wejscia) 
  • oprogramowanie obslugi np portow wejscia/wyjscia, ekranu, interpretacji pamieci itp.

pear

  • *****
  • Wiadomości: 5509
  • Miejsce pobytu:
    Będzin
  • Z80 only
Odp: Z80 profiler
« Odpowiedź #24 dnia: 2016.03.15, 10:44:21 »
Fajny kombajn  8)
ZX/Enterprise/CPC/Robotron/C128D

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4537
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Z80 profiler
« Odpowiedź #25 dnia: 2016.03.15, 11:13:21 »
Fajne, czy zatem jest szansa na moduł ZX dla profilera?

RafalM

  • *****
  • Wiadomości: 1133
  • Miejsce pobytu:
    Sulejówek
Odp: Z80 profiler
« Odpowiedź #26 dnia: 2016.03.15, 11:20:43 »
No widzę, że będzie z tego zaawansowane, profesjonalne narzędzie :)

Dr Piotr

  • ***
  • Wiadomości: 196
Odp: Z80 profiler
« Odpowiedź #27 dnia: 2016.03.15, 19:30:52 »
Fajne, czy zatem jest szansa na moduł ZX dla profilera?
Zrobilem podstawowa konfiguracje urzadzenia dla zx spectrum - obsluguje tylko io port drukarki, ale mozna w ten sposob wywietlac teksty na konsoli :)

Tygrys

  • Administrator
  • *****
  • Wiadomości: 4537
  • Miejsce pobytu:
    Warszawa
  • mistrz ceremonii
Odp: Z80 profiler
« Odpowiedź #28 dnia: 2016.03.15, 19:51:40 »
A jak mi/nam zdradzisz jak się robi taką konfigurację, to w pewnej nieodległej przyszłości mógłbym ja lub ktoś to ma akurat więcej czasu, taki konfig wykonać.

Dr Piotr

  • ***
  • Wiadomości: 196
Odp: Z80 profiler
« Odpowiedź #29 dnia: 2016.03.15, 21:28:29 »
A jak mi/nam zdradzisz jak się robi taką konfigurację, to w pewnej nieodległej przyszłości mógłbym ja lub ktoś to ma akurat więcej czasu, taki konfig wykonać.
Jasne, konfiguracja jak i cala emulacja portow io jest robiona za pomoca kompilowanego skryptu, ktory mozna samemu napisac. W tej chwili kod do konfigu spectrum wyglada mniej wiecej tak:
#include "TheProfiler"

forward public ULAWrite(Address, Data);
forward public ULARead(Address, Data);
forward public PrinterWrite(Address, Data);

public InitScript()
{
SetDeviceName("ZX Spectrum 48k","1.0","Union Systems","Copyright 2016 Union Systems");
SetDeviceCPU("Z80", 3500000, DEVICE_GENERIC);
AddMemoryBlock("KERNEL ROM", 0x0000,0x4000, MEMORY_READONLY, 0, "", "Sinclair/48.rom");
AddMemoryBlock("Video RAM", 0x4000,0x1800, MEMORY_READWRITE, 0, "", "");
AddMemoryBlock("Video Attributes RAM", 0x5800,0x300, MEMORY_READWRITE, 0, "", "");
AddMemoryBlock("Base RAM", 0x5b00,0xa500, MEMORY_READWRITE, 0, "", "");
AddMemoryBlock("IO Ports", 0x00,0x100, IOMEMORY_READWRITE, 0, "", "");

AddIODriver(0x00fe,0x00fe, "ULARead", "ULAWrite");
AddIODriver(0x00fb,0x00fb, "", "PrinterWrite");
}

public FinishScript()
{

}

public AboutScript()
{
printf("ZX Spectrum 48k device configuration v 1.0. Copyright 2016 Union Systems.");
printf("Developed by Piotr Drapich.");
}


// ULA emulation
public ULAWrite(Address, Data)
{
//TODO
}

public ULARead(Address, Data)
{
//TODO
return Data;
}

// printer emulation
public PrinterWrite(Address, Data)
{
static textbuf[255];
static textbufptr=0;

if (Data==13)
{
textbuf[textbufptr]=0;
printf(textbuf);
textbufptr=0;
return;
}
textbuf[textbufptr]=Data;
textbufptr++;
}

Przy ladowaniu urzadzenia jest wywolywany InitScript, potem AboutScript, przy zamknieciu FinishScript.
Inne funkcje skryptu sa callbackami, podawanymi jako parametry np przy definiowaniu bloku pamieci czy portow io i wywolywanymi przy zapisie/odczycie do danego obszaru pamieci.
Np dodanie obslugi portu drukarki jest zdefiniowane w   AddIODriver(0x00fb,0x00fb, "", "PrinterWrite");
Prototyp tej funkcji to AddIODriver(StartIOAddress,EndIOAddress, IOReadCallBack[], IOWriteCallBack[]);
Dodaje ona read albo write callback dla zakresu portow, zdefiniowanych przez StartIOAddress I EndIOAddress.
Przy profilowaniu programu, w momencie wykonania np out (#fb),a zostanie wywolany callback PrinterWrite z zawartoscia rejestru a jako Data,  adresem #fb jako Address.
PrinterWrite jest prosta funkcja buforujaca znaki az do otrzymania LineFeed, wtedy zebrany tekst jest wyswietlany za pomoca printf w oknie konsoli programu (to na dole po lewej stronie na screenshocie :)
Analogiczne callbacki mozna dodac do kazdego bloku pamieci. Np. dodajac taki callback do bloku pamieci video ramu mozna za pomoca udostepnianego interfeju wyswietlac interpretacje zawartosci tej pamieci w oknie user view monitora pamieci. Dodajac obsluge pozostalych portow i pare innych rzeczy mozna stworzyc prosty emulator wybranego urzadzenia.
btw: W programie powyzszy kod jest dostepny tylko skompilowany w formie binarnej, ale jest mozliwosc pisania i kompilowania wlasnych skryptow.