Autor Thema: Z80 - 16 Bit Pointer auf einen 16 Bit-Wert dereferenzieren  (Gelesen 194 mal)

0 Mitglieder und 1 Gast betrachten dieses Thema.

Offline LambdaMikel

Und mal wieder eine Frage an unsere Z80-Experten: da habe ich eine 16 Bit-Addresse im Speicher, die einen Pointer, also selbst eine 16 Bit-Addresse beinhaltet. Diese Addresse steht am label "pointer". Der Inhalt von "pointer" (= "(pointer)") ist also selbst eine 16 Bit-Addresse. Und nun möchte ich das 16-Bit Wort, auf das der Zeiger zeigt, in HL oder DE laden (oder IX oder IY).

Frage - gibt es was besseres als das?

pointer:  word &5678 ; example address

ld hl,(pointer)     
ld e,(hl)
inc hl
ld d,(hl)
...
jetzt habe ich in DE das Wort (Pointer+1)(Pointer), also den dereferenzierten Zeiger,
also D = RAM(&5678 + 1), E = RAM(&5678)

Idealerweise möchte ich also soetwas wie

LD DE,(HL)

haben, aber das gibt's nicht.  :motz:


« Letzte Änderung: 29. Juni 2021, 19:55:28 von LambdaMikel »

Offline HAL6128

Re: Z80 - 16 Bit Pointer auf einen 16 Bit-Wert dereferenzieren
« Antwort #1 am: 30. Juni 2021, 20:36:24 »
LD DE,(pointer)funktioniert, oder denke ich hier falsch?

Ne, quatsch, da bekommt DE ja auch nur die Adresse mit und nicht den Inhalt auf die referenzierte Speicherstelle.

Eventuell mit dem Stack arbeiten?
Irgendwie so, ohne dass dabei der Rechner NICHT abgeschossen wird (bin leider kein MC-Profi)?
ld hl,pointer
ex (sp),hl
pop de
ld a,(de)
« Letzte Änderung: 30. Juni 2021, 23:36:11 von HAL6128 »

Offline LambdaMikel

Re: Z80 - 16 Bit Pointer auf einen 16 Bit-Wert dereferenzieren
« Antwort #2 am: 30. Juni 2021, 21:55:35 »
LD DE,(pointer)funktioniert, oder denke ich hier falsch?

Ne, quatsch, da bekommt DE ja auch nur die Adresse mit und nicht den Inhalt auf die referenzierte Speicherstelle.

Eventuell mit dem Stack arbeiten?
Irgendwie so, ohne dass dabei der Rechner abgeschossen wird (bin leider kein MC-Profi)?
ld hl,pointer
ex (sp),hl
pop de
ld a,(de)

Hmm, das ist ja ne Bombe, muss ich mir mal genauer ansehen... besten Dank!

Na, ich mache das jetzt mal so - falls die Assembler-Profis Verbessrungsvorschläge haben, immer her damit. Ich mache Z80 nur alle 35 bis 40 Jahre  ;D

Hier also mein Testprogramm, das einen Speicherbereich mit <numbytes> (16 Bit) von 0 bis 255 füllt, über einen Pointer. Getestet mit Winape. Im BASIC dann call &4006. Im Debugger kann ich dann sehen, dass die Bytes richtig geschrieben wurden. Wäre nett wenn die Z80-Profis mal rübergucken könnten, ob man das besser / einfacher / schöner machen kann.


org &4000

; demonstrate how to fill a memory region based on a pointer

.counter defw 0
.numbytes defw &1000   

.pointer defb 0
.pointerh defb 0

; pointer contains is a memory address that points to a block of memory that
; we are writing to - starts at .memram

ld hl, pointer
ld (hl), memram mod 256
inc hl
ld (hl), memram / 256

; write numbytes from 0 to 255 starting at memram

ld a, 0

.loop

; compare 16 bit counter with 16 bit numbytes

ld hl,(counter)
ld de,(numbytes)

sbc hl,de

jr z,done

call inccounter

; dereference the pointer - store the accumulator to (*pointer) and (*pointer+1)

ld hl,(pointer)
ld (hl), a
inc hl

; now, update the pointer

push hl
pop de

ld hl,pointer
ld (hl), e
inc hl
ld (hl), d

; next round with incremented accu

inc a
jr loop

; done, wait for keypress

.done

ld a, '!'
call &bb5d
call &bb18

ret

; subroutine - increment the counter at a fixed address:

.inccounter

ld hl,(counter)
inc hl
push hl
pop de
ld hl, counter
ld (hl), e
inc hl
ld (hl), d

ret

; memory block to which we are writing:

.memram defb 0
 

Online TFM

  • Administrator
  • CPC 6128+
  • *****
  • Beiträge: 3.535
  • Likes gesamt: 22
  • Karma: +54/-0
  • Geschlecht: Männlich
  • FutureSoft und CPC - Ein starkes Team!
    • FutureOS
Re: Z80 - 16 Bit Pointer auf einen 16 Bit-Wert dereferenzieren
« Antwort #3 am: 01. Juli 2021, 11:40:22 »
Michael, da hast Du schon die ideale Programmierung gefunden. So etwas wie LD rr,(rr) gibt es leider nicht. Nur LD rr,(addr).

Helfen könnten hier IX und IY (anstatt RAM nutzen), aber die sind nicht gerade schnell.


Anstatt LD A,0 bitte XOR A,A verwenden, ist doppelt so schnell und halb so lang.
« Letzte Änderung: 01. Juli 2021, 11:44:21 von TFM »
TFM of FutureSoft
http://www.FutureOS.de --> Das Betriebssystem FutureOS (Update: 24.01.2021)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> RSX ROM für LambdaSpeak (Update: 15.7.2021)

Offline LambdaMikel

Re: Z80 - 16 Bit Pointer auf einen 16 Bit-Wert dereferenzieren
« Antwort #4 am: 01. Juli 2021, 19:09:42 »
Michael, da hast Du schon die ideale Programmierung gefunden. So etwas wie LD rr,(rr) gibt es leider nicht. Nur LD rr,(addr).

Helfen könnten hier IX und IY (anstatt RAM nutzen), aber die sind nicht gerade schnell.


Anstatt LD A,0 bitte XOR A,A verwenden, ist doppelt so schnell und halb so lang.

Danke! Ja, das vergesse ich immer... allerdings muss ich sagen, dass mir die "direkte Lesbarkeit" (0 wird geladen) im Code meist wichtiger ist als 2 oder 3 Cycles zu sparen. Aber ja, für eine Optimierung sollte man das machen.  :smiley027:

Das Problem mit IX, IY + offset ist dass ich dann nur 256 Bytes addressieren kann, und IX, IY Tabellenbasis dann immer umladen muss alles 256 Bytes, aber das wäre noch einmal einen Versuch wert. Es scheint so aber auch schnell genug zu sein, insofern ist meine Motivation gering.

Online TFM

  • Administrator
  • CPC 6128+
  • *****
  • Beiträge: 3.535
  • Likes gesamt: 22
  • Karma: +54/-0
  • Geschlecht: Männlich
  • FutureSoft und CPC - Ein starkes Team!
    • FutureOS
Re: Z80 - 16 Bit Pointer auf einen 16 Bit-Wert dereferenzieren
« Antwort #5 am: 04. Juli 2021, 15:17:24 »
Also ich mach's immer mit HL, ist schön schnell und gut zu handhaben.
TFM of FutureSoft
http://www.FutureOS.de --> Das Betriebssystem FutureOS (Update: 24.01.2021)
http://futureos.cpc-live.com/files/LambdaSpeak_RSX_by_TFM.zip --> RSX ROM für LambdaSpeak (Update: 15.7.2021)