Avatar billede bizty Nybegynder
25. februar 2003 - 19:26 Der er 4 kommentarer og
1 løsning

Lidt hjælp til Z80 maskinkode

Jeg har lige et par spørgsmål:

Hvordan ganger jeg to 8-bit registre (f.eks. a og b)?
Er det nødvenig selv at lave et loop som lægger tallet a sammen med sig selv b-1 gange eller hvad?

Jeg er ved at lave et lille spil med en spilleplade med 81 felter, hvordan kan jeg bruge et register til at gemme brikkernes placeringer. hvert felt på pladen kan have tre tilstande 0,1 og 2. Hvordan laver, skriver og læser jeg til et sådan register) (P.S. Det må meget gerne være noget med OP1, da alle små registre er brugt (b-d))
Avatar billede jespernaur Nybegynder
25. februar 2003 - 21:55 #1
Halvt svar:
Du kommer til at gøre det med håndkraft på den ene eller anden måde, da der ikke er en multiplikations-instruktion. Du er også nødt til at tage stilling til, at i det generelle tilfælde, vil multiplikation af to 8-bit tal kunne resultere i et 16-bit resultat (255*255 =  65025). Det er selvfølgelig muligt, at du i dit aktuelle program kan overskue, at resultatet aldrig vil overstige 255, i så fald behøver du ikke tænke på 16-bit mellemregninger eller resultater.

Du har ret, en simpel måde er at lave en løkke som den du har skitseret. Hvis du ikke har specielle hastighedskrav (i mikrosekund-størrelsesorden), er det sikkert det nemmeste.

Det kan dog også løses med en løkke, der kun gennemløbes 8 gange, jeg skitserer den som C-kode, du kommer selv til at oversætte den til Z80-kode:

result = 0;  /* result er et 16-bit tal */
temp = b;    /* temp er et 16-bit tal */
mask = 1;

for (i = 0; i < 8; i++) {
  if ((a & mask) != 0) {
      result = result + temp;
  }
  temp = temp << 1;
  mask = mask << 1;
}

Mvh
Jesper Naur
Avatar billede bizty Nybegynder
25. februar 2003 - 22:08 #2
Ok, så må jeg bare lave en lille løkke, men hvordan er det lige at man selv laver en funktion som kan kaldes med call eller bcall sådan at man vender tilbage til der hvor man kaldte fra? det er nødvendigt da funktionen skal bruges mange steder.
Avatar billede jespernaur Nybegynder
25. februar 2003 - 22:54 #3
Du kan lave en subrutine:

MUL:    ...
    ...
    RET


som du fra andre steder kan kalde med:

    CALL MUL

Du er selvfølgelig selv nødt til at definere en konvention for, hvordan MUL får overført sine parametre, og hvordan resultatet returneres. Det betaler sig desuden, at MUL selv gemmer og retablerer alle registre, som den skal bruge til mellemregninger. Nemmeste metode: PUSH på stakken når man starter, POP fra stakken når man er færdig.
Avatar billede bizty Nybegynder
26. februar 2003 - 15:56 #4
Ok, bare bruge RET jeg troede bare det ville afslutte hele programmet, og tak for idéen med at bruge stakken. Men Jeg mangler stadig svar på mit vigtigste spørgsmål, og jeg skal nok afsætte nogle flere point hvis det er det... Kom nu, er der ikke nogen som kender en medtode? Heller ikke hvis i må bruge DE registret?
Avatar billede jespernaur Nybegynder
26. februar 2003 - 20:43 #5
Med hensyn til din spilleplade kunne du fx gøre følgende: Der er 81 felter så du afsætter 81 bytes i lageret til spillepladen, 1 byte pr. felt. Det kan gøres således (det er muligt, at den assembler du bruger, skal have det angivet lidt anderledes, men det må du slå op):

PLADE:  .blkb 81

Herved reserveres plads i lageret til de 81 bytes - BEMÆRK at der ikke er fyldt nogen værdier i. Det må du sørge for sker under programmets opstart, især hvis der er tale om en startopstilling af brikker.

Nu kan man adressere de enkelte felter direkte ved at bruge direkte adressering PLADE+<index> hvor <index> er et tal i intervallet [0..80]. Dette er dog nok ikke videre nyttigt, du er nok mere interesseret i at beregne indexet på et felt, og derefter læse eller skrive feltet.

Læsning: Register E indeholder <index>, læs felt <index>, aflever resultat i A

    LXI H,PLADE  ; Hent adressen på PLADE til HL
    MVI D,#0    ; Nulstil D
    DAD D        ; Adder <index> til HL
    LD  A,(HL)  ; Hent værdi i PLADE+<index> til A

Skrivning: Register E indeholder <index>, skriv værdien i A til feltet <index>

    LXI H,PLADE  ; Hent adressen på PLADE til HL
    MVI D,#0    ; Nulstil D
    DAD D        ; Adder <index> til HL
    LD  (HL),A  ; Skriv A til PLADE+<index>

Nu ved jeg ikke hvad det er for et spil du er ved at lave, men de 81 felter kunne antyde, at der er tale om en 9x9 felters spilleplade. Hvis du ønsker at adressere felterne med (række,søjle) hvor række og søjle begge kan gå fra 1 til 9, skal du regne <index> ud som følger:

  <index> = (række-1)*9 + søjle - 1

Dette vil medføre, at de første 9 bytes i PLADE hører til række 1, de næste 9 bytes til række 2 og så fremdeles.

Mvh
Jesper Naur

(PS: Intet af det ovenstående er testet!)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester