beispiel für ein rasterinterupt in cc65


  • ogd
  • 1084 Aufrufe 26 Antworten

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • beispiel für ein rasterinterupt in cc65

    C-Quellcode

    1. #include <6502.h>
    2. #include <c64.h>
    3. #include <stdint.h>
    4. #define FIRST (249)
    5. #define SECOND (FIRST + 2)
    6. #define CINV (*(uint16_t *) 0x0314)
    7. #define MEM (*(uint8_t *) 0x3fff)
    8. void newirq(void);
    9. int main(void)
    10. {
    11. SEI();
    12. CINV = newirq;
    13. VIC.rasterline = FIRST;
    14. VIC.ctrl1 = VIC.ctrl1 & ~(0x80);
    15. VIC.imr = 0x81;
    16. CLI();
    17. for (;;)
    18. {
    19. ++MEM;
    20. }
    21. }
    22. void newirq(void)
    23. {
    24. static uint8_t trash;
    25. if (!((VIC.irr = VIC.irr) & 0x80))
    26. {
    27. trash = CIA1.icr;
    28. CLI();
    29. __asm__("JMP $EA31");
    30. }
    31. else
    32. {
    33. if (VIC.rasterline < SECOND)
    34. {
    35. VIC.ctrl1 = 0x13;
    36. VIC.rasterline = SECOND;
    37. }
    38. else
    39. {
    40. VIC.ctrl1 = 0x1b;
    41. VIC.rasterline = FIRST;
    42. }
    43. __asm__("JMP $EA7E");
    44. }
    45. }
    Alles anzeigen
    Dateien
    • raster-irq.prg

      (444 Byte, 20 mal heruntergeladen, zuletzt: )

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ogd ()

  • sauhund schrieb:

    uh, vorsicht. die interrupt routine in C zu schreiben ist keine gute idee... damit bringst du zb den software stack durcheinander und es knallt recht schnell :)

    wie meinst du das genau? in der interrupt-routine wird ja nix "gestackt" laut assembler-listing:

    Brainfuck-Quellcode

    1. (...)
    2. ; ---------------------------------------------------------------
    3. ; void __near__ newirq (void)
    4. ; ---------------------------------------------------------------
    5. .segment "CODE"
    6. .proc _newirq: near
    7. .segment "BSS"
    8. L001B:
    9. .res 1,$00
    10. .segment "CODE"
    11. lda $D019
    12. sta $D019
    13. and #$80
    14. bne L001C
    15. lda $DC0D
    16. sta L001B
    17. cli
    18. jmp $EA31
    19. L001C: lda $D012
    20. cmp #$FB
    21. bcs L0029
    22. lda #$13
    23. sta $D011
    24. ldx #$00
    25. lda #$FB
    26. sta $D012
    27. jmp $EA7E
    28. L0029: lda #$1B
    29. sta $D011
    30. lda #$F9
    31. sta $D012
    32. jmp $EA7E
    33. .endproc
    34. (...)
    Alles anzeigen
  • ja, du hast natürlich recht, in diesem fall geht es ... man sollte aber genau wissen was man tut. wenn jetzt jemand auf die idee kommt zb eine c-funktion aus dem interrupt handler heraus aufzurufen dann sieht der fall schon ganz anders aus =)
  • eigentlich auf fast allen :) auch mit cc65 geht das prinzipiell, wenn man den interupthandler entsprechend aufbohrt (die von der runtime benutzten zeropage adressen retten und den pointer auf den softwarestack versetzen) - macht aber nicht viel sinn weil das dann so langsam wird das sich das mit dem interrupt schon garnicht mehr lohnt :) ich glaube der BRK handler vom "eingauten" debugger bzw monitor macht das.
  • #define CINV (*(uint16_t *) 0x0314)
    #define MEM (*(uint8_t *) 0x3fff)
    void newirq(void);

    unit8_t und uint16_t wird bei mir nicht erkannt, muss unsigned char und unsigned int einsetzen.
    Dieses wird auch nicht compiliert : void newirq(void);

    Was für ein ersatz gibt es dafür?


    mfg
  • schnucke schrieb:

    unit8_t und uint16_t wird bei mir nicht erkannt, muss unsigned char und unsigned int einsetzen.
    Dieses wird auch nicht compiliert : void newirq(void);

    ich habe es mit cc65 v2.12.0 erstellt. es erscheint zwar eine warnung, aber es klappt ...

    welche version von cc65 benutzt du denn?

    hier noch mal der source code:
    Dateien
    • raster-irq.zip

      (484 Byte, 12 mal heruntergeladen, zuletzt: )
  • Ich benutze V 2.12.9 vom November 2008.

    CINV = newirq wird bei mir nicht erkannt.
    Fehlermeldung: Incompatible types

    Bei dem anderen Werten hatte ich "stdint.h" nicht eingebunden.



    mfg

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von schnucke ()

  • schnucke schrieb:

    Ich benutze V 2.12.9 vom November 2008.

    CINV = newirq wird bei mir nicht erkannt.
    Fehlermeldung: Incompatible types

    schöne bescherung. mit der snapshot-version gehts tatsächlich nicht. wenn du aber

    Quellcode

    1. CINV = newirq;

    durch

    Quellcode

    1. CINV = (uint8_t *) newirq;

    ersetzt, klappts es ...

    weiss denn einer, wie ich die warnung "Converting pointer to integer without a cast" wegkriege?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ogd ()

  • weiss denn einer, wie ich die warnung "Converting pointer to integer without a cast" wegkriege?


    das sagt dir die warning doch schon ziemlich exakt - du musst explizit einen typecast machen... also zb

    char *p;

    p=0xc000; // hier gibts besagte warnung
    p=(char*)0xc000; // und hier nicht
  • sauhund schrieb:

    weiss denn einer, wie ich die warnung "Converting pointer to integer without a cast" wegkriege?

    das sagt dir die warning doch schon ziemlich exakt - du musst explizit einen typecast machen...

    danke, hatte falsch "gecastet". so verschwindet auch die warnung:

    Quellcode

    1. CINV = (uint8_t) newirq;

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von ogd ()

  • das ist ... interessant. es sollte aber eigentlich nicht funktionieren :) könnte ein compiler bug sein

    edit: grad mal kurz gecheckt, 2.12.9 macht aus

    Quellcode

    1. #include <stdint.h>
    2. #define CINV (*(uint16_t *) 0x0314)
    3. main()
    4. {
    5. CINV=0x1234;
    6. CINV=(uint8_t)0x1234;
    7. }


    richtigerweise folgendes:

    Quellcode

    1. ldx #$12
    2. lda #$34
    3. sta $0314
    4. stx $0314+1
    5. ldx #$00
    6. sta $0314
    7. stx $0314+1
    8. rts

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von sauhund ()