6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 4:25 pm

All times are UTC




Post new topic Reply to topic  [ 46 posts ]  Go to page Previous  1, 2, 3, 4  Next
Author Message
 Post subject: Re: SDCC for 6502
PostPosted: Sat Feb 25, 2023 5:12 pm 
Offline

Joined: Sat Dec 12, 2015 7:48 pm
Posts: 122
Location: Lake Tahoe
barnacle wrote:
When I get to a more complete state of knowledge, I'll knock up a quick how-to. The main things I need to know are
  • How to compile anything! (done)
  • How to compile code to a given memory map (done)
  • How to handle interrupts and the BRK instruction
  • How to include assembly code directly

Neil


Here is how I included asm inline for my 8051 project using sdcc:
Code:
void neg_2udelay(word usecs) __naked     // Delay for multiples of 2 usecs
{
    __asm
        mov     a, dpl                  ; 2 cycles
        orl     a, dph                  ; 2 cycles
        jz      0002$                   ; 3 cycles
    0001$:
        inc     dptr                    ; 3 cycled
        mov     a, dpl                  ; 2 cycles
        orl     a, dph                  ; 2 cycles
        nop                             ; 1 cycle
        nop                             ; 1 cycle
        jnz     0001$                   ; 3 cycles
                                        ;---------
                                        ; 12 cycles * 4 cycles/clock / 24 MHZ clock = 2 usec
    0002$:
        ret                             ; 4 cycles
    __endasm;
    usecs = usecs;                      // Shut up warning message.
}


The __naked attribute skips the full function setup code


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Sat Feb 25, 2023 8:26 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Thank you. I found some similar hints in the documentation, but there is as yet nothing relating to the 6502 there.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Sun Feb 26, 2023 6:57 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
A bit more code: this is about as tight as it could be, with the sole exception of a couple of 'sec' before subtractions:
Code:
;   monitor.c: 202: signed char ctori (char ch, char radix)
;   -----------------------------------------
;    function ctori
;   -----------------------------------------
;   Register assignment is optimal.
;   Stack space usage: 0 bytes.
_ctori:
   stx   _ctori_radix_65536_106
;   monitor.c: 209: signed char ret = -1;
   ldx   #0xff
;   monitor.c: 211: if (ch >= '0')
   cmp   #0x30
   bcc   00108$
;   monitor.c: 213: ch -= '0';
   sec
   sbc   #0x30
;   monitor.c: 214: if (ch >= 10)
   cmp   #0x0a
   bcc   00104$
;   monitor.c: 216: ch -= 0x27;
   sec
   sbc   #0x27
;   monitor.c: 217: if (ch < 10)
   cmp   #0x0a
   bcs   00104$
;   monitor.c: 219: ch = 0xff;
   txa
00104$:
;   monitor.c: 222: if (ch < radix)
   cmp   _ctori_radix_65536_106
   bcs   00108$
;   monitor.c: 224: ret = ch;
   tax
00108$:
;   monitor.c: 227: return ret;
   txa
;   monitor.c: 228: }
   rts

In both cases the STC follows a BCC so it's already set, but hey, I'm not complaining.

This routine takes a character and a radix and converts the character into a value ('0'-'9', 'a'-'z' = 0-35, or -1 if the result is greater than the radix allows). There another routine which multiplies an integer by the radix and adds the new value, so I can input a value in any base (though in practical terms, that's likely to be only 2, 8, 10, or 16).

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Tue Feb 28, 2023 6:09 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Progress! Though still incomplete, this took me a day or so to knock up vs quite a lot longer to do the same in assembly... it's three or four times the size, too, but not as bad as I had feared.

Code:
Neolithic 6502 Monitor
>d 210
0210
0210 6d 34 12   adc $1234
0213 65 00      adc $00
0215 69 12      adc #$12
0217 7d 34 12   adc $1234,x
021a 79 34 12   adc $1234,y
021d 61 12      adc ($12,x)
021f 71 12      adc ($12),y
0221 75 00      adc $00,x
0223 2d 34 12   and $1234
0226 25 00      and $00
0228 29 12      and #$12
022a 3d 34 12   and $1234,x
022d 39 34 12   and $1234,y
0230 21 12      and ($12,x)
0232 31 12      and ($12),y
0234 35 00      and $00,x
0236 0a         asl a
0237 0e 34 12   asl $1234
023a 06 12      asl $12
023c 1e 34 12   asl $1234,x                                                                                 
023f 16 12      asl $12,x                                                                                   
0241 90 00      bcc $00                                                                                     
0243 b0 00      bcs $00                                                                                     
0245 f0 00      beq $00                                                                                     
0247 2c 34 12   bit $1234                                                                                   
024a 24 12      bit $12                                                                                     
024c 30 00      bmi $00                                                                                     
024e d0 00      bne $00                                                                                     
0250 10 00      bpl $00                                                                                     
0252 00         brk                                                                                         
0253 50 00      bvc $00                                                                                     
0255 70 00      bvs $00                                                                                     
0257 18         clc                                                                                         
0258 d8         cld                                                                                         
0259 58         cli                                                                                         
025a b8         clv                                                                                         
025b cd 34 12   cmp $1234                                                                                   
025e c5 00      cmp $00                                                                                     
0260 c9 12      cmp #$12                                                                                     
0262 dd 34 12   cmp $1234,x                                                                                 
0265 d9 34 12   cmp $1234,y                                                                                 
0268 c1 12      cmp ($12,x)                                                                                 
026a d1 12      cmp ($12),y                                                                                 
026c d5 00      cmp $00,x                                                                                   
026e ec 34 12   cpx $1234                                                                                   
0271 e4 12      cpx $12                                                                                     
0273 e0 00      cpx #$00                                                                                     
0275 cc 34 12   cpy $1234                                                                                   
0278 c4 12      cpy $12                                                                                     
027a c0 00      cpy #$00                                                                                     
027c ce 34 12   dec $1234                                                                                   
027f c6 12      dec $12                                                                                     
0281 de 34 12   dec $1234,x                                                                                 
0284 d6 12      dec $12,x                                                                                   
0286 ca         dex                                                                                         
0287 88         dey                                                                                         
0288 4d 34 12   eor $1234                                                                                   
028b 45 00      eor $00                                                                                     
028d 49 12      eor #$12                                                                                     
028f 5d 34 12   eor $1234,x                                                                                 
0292 59 34 12   eor $1234,y                                                                                 
0295 41 12      eor ($12,x)                                                                                 
0297 51 12      eor ($12),y                                                                                 
0299 55 00      eor $00,x                                                                                   
029b ee 34 12   inc $1234                                                                                   
029e e6 12      inc $12                                                                                     
02a0 fe 34 12   inc $1234,x                                                                                 
02a3 f6 12      inc $12,x                                                                                   
02a5 e8         inx                                                                                         
02a6 c8         iny                                                                                         
02a7 4c 34 12   jmp $1234                                                                                   
02aa 6c 34 12   jmp ($1234)                                                                                 
02ad 20 34 12   jsr $1234                                                                                   
02b0 ad 34 12   lda $1234                                                                                   
02b3 a5 00      lda $00                                                                                     
02b5 a9 12      lda #$12                                                                                     
02b7 bd 34 12   lda $1234,x                                                                                 
02ba b9 34 12   lda $1234,y                                                                                 
02bd a1 12      lda ($12,x)                                                                                 
02bf b1 12      lda ($12),y                                                                                 
02c1 b5 00      lda $00,x                                                                                   
02c3 ae 34 12   ldx $1234                                                                                   
02c6 a6 00      ldx $00                                                                                     
02c8 a2 12      ldx #$12                                                                                     
02ca be 34 12   ldx $1234,x                                                                                 
02cd b6 00      ldx $00,y                                                                                   
02cf ac 34 12   ldy $1234                                                                                   
02d2 a4 00      ldy $00                                                                                     
02d4 a0 12      ldy #$12                                                                                     
02d6 bc 34 12   ldy $1234,x                                                                                 
02d9 b4 00      ldy $00,x                                                                                   
02db 4a         lsr a                                                                                       
02dc 4e 34 12   lsr $1234                                                                                   
02df 46 00      lsr $00                                                                                     
02e1 5e 34 12   lsr $1234,x                                                                                 
02e4 56 00      lsr $00,x                                                                                   
02e6 ea         nop                                                                                         
02e7 0d 34 12   ora $1234                                                                                   
02ea 05 00      ora $00                                                                                     
02ec 09 12      ora #$12                                                                                     
02ee 1d 34 12   ora $1234,x                                                                                 
02f1 19 34 12   ora $1234,y                                                                                 
02f4 01 12      ora ($12,x)                                                                                 
02f6 11 12      ora ($12),y                                                                                 
02f8 15 00      ora $00,x                                                                                   
02fa 48         pha                                                                                         
02fb 08         php                                                                                         
02fc 68         pla                                                                                         
02fd 28         plp                                                                                         
02fe 2a         rol a                                                                                       
02ff 2e 34 12   rol $1234                                                                                   
0302 26 00      rol $00                                                                                     
0304 3e 34 12   rol $1234,x                                                                                 
0307 36 00      rol $00,x                                                                                   
0309 6a         ror a                                                                                       
030a 6e 34 12   ror $1234                                                                                   
030d 66 00      ror $00                                                                                     
030f 7e 34 12   ror $1234,x                                                                                 
0312 76 00      ror $00,x                                                                                   
0314 40         rti                                                                                         
0315 60         rts                                                                                         
0316 ed 34 12   sbc $1234                                                                                   
0319 e5 00      sbc $00                                                                                     
031b e9 12      sbc #$12                                                                                     
031d fd 34 12   sbc $1234,x                                                                                 
0320 f9 34 12   sbc $1234,y                                                                                 
0323 e1 12      sbc ($12,x)                                                                                 
0325 f1 12      sbc ($12),y                                                                                 
0327 f5 00      sbc $00,x                                                                                   
0329 38         sec                                                                                         
032a f8         sed                                                                                         
032b 78         sei                                                                                         
032c 8d 34 12   sta $1234                                                                                   
032f 85 00      sta $00                                                                                     
0331 9d 34 12   sta $1234,x                                                                                 
0334 99 34 12   sta $1234,y                                                                                 
0337 81 12      sta ($12,x)                                                                                 
0339 91 12      sta ($12),y                                                                                 
033b 95 00      sta $00,x                                                                                   
033d 8e 34 12   stx $1234                                                                                   
0340 86 00      stx $00                                                                                     
0342 96 00      stx $00,y                                                                                   
0344 8c 34 12   sty $1234                                                                                   
0347 84 00      sty $00                                                                                     
0349 94 00      sty $00,x                                                                                   
034b aa         tax                                                                                         
034c a8         tay                                                                                         
034d ba         tsx                                                                                         
034e 8a         txa                                                                                         
034f 9a         txa                                                                                         
0350 98         tya 

>


Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Tue Feb 28, 2023 3:09 pm 
Offline

Joined: Sun Nov 08, 2009 1:56 am
Posts: 387
Location: Minnesota
That makes no sense as code. Is it some sort of jump table?


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Tue Feb 28, 2023 4:48 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Oh, just a test group for the disassembler. I should have said :mrgreen:
Every NMOS 6502 legal opcode, using code written in C rather than assembly.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Tue Feb 28, 2023 5:02 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Here's the C code for the disassembler, minus a few helper functions which are pretty obvious:
Code:
// describes the mnemonic, base value, and permissible modes
// the base is the opcode to which the bbb values are added (or for
// opcodes with no bbb value, simply the opcode value)
typedef struct {
    char mnem [4];
    unsigned char base;
    unsigned int modes;   
} MNEMONIC;

// convert mode value (from instruction) to MODES
MODES val_to_mode [8] = {indx, zpg, imm, mabs, indy, zpx, absy, absx};

MNEMONIC const mnem[MAX_OPCODES] = {
   // mnem base  modes
    // 0
    {"ora", 0x01, mabs | zpg | imm | absx | absy | indx | indy | zpx},
    {"and", 0x21, mabs | zpg | imm | absx | absy | indx | indy | zpx},
    {"eor", 0x41, mabs | zpg | imm | absx | absy | indx | indy | zpx},
    {"adc", 0x61, mabs | zpg | imm | absx | absy | indx | indy | zpx},
    {"sta", 0x81, mabs | zpg |       absx | absy | indx | indy | zpx},
    {"lda", 0xa1, mabs | zpg | imm | absx | absy | indx | indy | zpx},
    {"cmp", 0xc1, mabs | zpg | imm | absx | absy | indx | indy | zpx},
    {"sbc", 0xe1, mabs | zpg | imm | absx | absy | indx | indy | zpx},
    // 8
    {"brk", 0x00, imp},
    {"jsr", 0x20, mabs},
    {"rti", 0x40, imp},
    {"rts", 0x60, imp},
    // 12
    {"???", 0x00, mabs},   // dummy entry to simplify the decode
    {"bit", 0x20, mabs | zpg},
    {"jmp", 0x40, mabs},
    {"jmp", 0x60, ind},      // jmp ind
    {"sty", 0x80, mabs | zpg |              zpx},
    {"ldy", 0xa0, mabs | zpg |        imm | absx | zpx},
    {"cpy", 0xc0, mabs | zpg |        imm},
    {"cpx", 0xe0, mabs | zpg |        imm},
    // 20
    {"asl", 0x02, acc | mabs | zpg |       absx | zpx},
    {"rol", 0x22, acc | mabs | zpg |       absx | zpx},
    {"lsr", 0x42, acc | mabs | zpg |       absx | zpx},
    {"ror", 0x62, acc | mabs | zpg |       absx | zpx},
    {"stx", 0x82,       mabs | zpg |              zpy},
    {"ldx", 0xa2,       mabs | zpg | imm | absy | zpy},
    {"dec", 0xc2,       mabs | zpg |       absx | zpx},
    {"inc", 0xe2,       mabs | zpg |       absx | zpx},
    // 28
    {"bpl", 0x10, rel},
    {"bmi", 0x30, rel},
    {"bvc", 0x50, rel},
    {"bvs", 0x70, rel},
    {"bcc", 0x90, rel},
    {"bcs", 0xb0, rel},
    {"bne", 0xd0, rel},
    {"beq", 0xf0, rel},
    // 36
    {"php", 0x08, imp},
    {"clc", 0x18, imp},
    {"plp", 0x28, imp},
    {"sec", 0x38, imp},
    {"pha", 0x48, imp},
    {"cli", 0x58, imp},
    {"pla", 0x68, imp},
    {"sei", 0x78, imp},
    {"dey", 0x88, imp},
    {"tya", 0x98, imp},
    {"tay", 0xa8, imp},
    {"clv", 0xb8, imp},
    {"iny", 0xc8, imp},
    {"cld", 0xd8, imp},
    {"inx", 0xe8, imp},
    {"sed", 0xf8, imp},
    // 52
    {"txa", 0x8a, imp},
    {"txa", 0x9a, imp},
    {"tax", 0xaa, imp},
    {"tsx", 0xba, imp},
    {"dex", 0xca, imp},
    {"???", 0x00, imp},     // dummy entry to simplify the decode
    {"nop", 0xea, imp},

};

////////////////////////////////////////////////////////////////////////
int opcode_to_text (int ptr)
{
// disassemble the code at ptr, print it nicely,
// and return the address of the next instruction
   MODES mode;
   int index;
   int size = 0;

   index = disassemble(*(char *)ptr, &mode);
   // print address and opcode
   hex4out(ptr);
   putchar(' ');
   hex2out(*(char *)(ptr));
   
   // print associated data if required
   if (mode > rel)
   {
      hex2out(*(char *)(ptr + 1));
      hex2out(*(char *)(ptr + 2));
   }
   else if (mode > acc)
   {
      hex2out(*(char *)(ptr + 1));
   }
   else
   {
      putchar(TAB);
   }

   putchar(TAB);
   put_s(mnem[index].mnem);
   putchar(' ');

   switch (mode)
   {
      case imp:   // opc
         // no further output
         size = 1;
         break;
      case acc:   // opc a
         putchar ('a');
         size = 1;
         break;
      case mabs:  // opc $hhll
         putchar('$');
         hex2out(*(char *)(ptr + 2));
         hex2out(*(char *)(ptr + 1));
         size = 3;
         break;
      case zpg:   // opc ll
         putchar('$');
         hex2out(*(char *)(ptr + 1));
         size = 2;
         break;
      case imm:   // opc #ll
         putchar('#');
         putchar('$');
         hex2out(*(char *)(ptr + 1));
         size = 2;
         break;
      case absx:  // opc $hhll,X
         putchar('$');
         hex2out(*(char *)(ptr + 2));
         hex2out(*(char *)(ptr + 1));
         put_s(",x");
         size = 3;
         break;
      case absy:  // opc $hhll,Y
         putchar('$');
         hex4out(*(int *)(ptr + 1));
         put_s(",y");
         size = 3;
         break;
      case indx:  // opc (ll,X)
         put_s("($");
         hex2out(*(char *)(ptr + 1));
         put_s(",x)");
         size = 2;
         break;
      case indy:  // opc (ll),Y
         put_s("($");
         hex2out(*(char *)(ptr + 1));
         put_s("),y");
         size = 2;
         break;
      case zpx:   // opc ll,x
         putchar('$');
         hex2out(*(char *)(ptr + 1));
         put_s(",x");
         size = 2;
         break;
      case zpy:   // opc ll,y
         putchar('$');
         hex2out(*(char *)(ptr + 1));
         put_s(",y");
         size = 2;
         break;
      case rel:   // opc bb
         putchar('$');
         hex2out(*(char *)(ptr + 1));
         size = 2;
         break;
      case ind:   // opc (hhll)
         put_s("($");
         hex4out(*(int *)(ptr + 1));
         putchar(')');
         size = 3;
         break;
   }
   crlf();

   return size;
}

////////////////////////////////////////////////////////////////////////

int disassemble (unsigned char opcode, MODES * mode)
{
    // decode an opcode to return an index into the opcode mnemonic table,
    // or -1 if nothing is found
    // does not check that the opcode represents a valid instruction (eg sta immediate)
    // but writes the discovered mode into modex
    // assumes 6502N basic instruction set

    unsigned char sliced;     // an opcode with bbb zeroed out
    unsigned char bbb;        // the mystery three bits, shifted right to 0-2
    unsigned char index;      // which entry in a group?


    int     ret = -1;   // -1 if nothing found

    bbb = (opcode & 0x1c) >> 2;
    sliced = opcode & 0xe3;
    index = (opcode & 0xe0) >> 5;

   // ora and eor adc sta lda cmp sbc
   if (mnem[index].base == sliced)
   {
      // we found one of eight
      ret = index;
      *mode = val_to_mode[bbb];
   }
   // get jsr brk rti rts out of the way to avoid a clash 0x00, 0x20, 0x40, 0x60
   else if (0x00 == (opcode & 0x9f))
   {
      index = opcode >> 5;
      if (mnem[index + 8].base == opcode)     // test against the whole opcode
      {
         // we found one of four
         ret = index + 8;
         *mode = (0x20 == opcode) ? mabs : imp;
      }
   }
   // php clc plp sec pha cli pla sei dey tya tay clv iny cld inx sed
   // 0x08 to 0xf8
   else if (0x08 == (opcode & 0x0f))
   {
      // one of sixteen, no alternate addressing modes
      ret = (opcode >> 4) + 36;
      *mode = imp;
   }
   // txa txa tax tsx dex ??? nop
   // 0x0a to 0xea
   else if (0x8a == (opcode & 0x8f))
   {
      // one of six, plus dummy for unused code
      ret = ((opcode - 0x80) >> 4) + 52;
      *mode = imp;
   }
    // bpl bmi bvc bvs bcc bcs bne beq
    // 0x10 to 0xf0
    else if (0x10 == (opcode & 0x1f))
    {
        // one of eight, no alternate addressing modes
        ret = (opcode >> 5) + 28;
        *mode = rel;
    }
   // bit jmp sty ldy cpy cpx (0x20 to 0xe0)
    else if (mnem[index + 12].base == sliced)
    {
        // found one of eight
        ret = index + 12;
        *mode =  (0x6c == opcode) ? *mode = ind : val_to_mode[bbb];
        if (indx == *mode) *mode = imm;   // this block is different!
   }
   // asl rol lsr ror stx ldx dec inc
   else if (mnem[index + 20].base == sliced)
   {
      // found one of eight
      ret = index + 20;
      *mode = val_to_mode[bbb];
      // uses acc instead of imm except for ldx
      if (imm == *mode) *mode = acc;
      // edge case: ldx uses imm instead of indx
      if (0xa2 == opcode) *mode = imm;
      // edge cases: ldx and stx use zpy instead of zpx
      if ((0xb6 == opcode) || (0x96 == opcode)) *mode = zpy;
   }
    return ret;
}

////////////////////////////////////////////////////////////////////////


Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Thu Mar 02, 2023 10:02 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
What an excellent error message, and shout-out to Frank Zappa :mrgreen:

Code:
monitor.c:1056: warning 110: conditional flow changed by optimizer: so said EVELYN the modified DOG


Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Sun Mar 05, 2023 9:57 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Things progress with the C-written simple monitor. It can
  • modify memory
  • list a block of memory
  • disassemble code line by line
  • assemble code line by line (no labels, and still being tested)
Still to do is to execute code in memory, and to import code (probably as a hex record on a line by line basis). I haven't thought a lot about single-stepping yet.
It obviously takes a lot more space than writing raw assembly; I'm currently generating about 5k of code (though there's a table of mnemonics and available modes that takes up 630 bytes, needed for both the assembly and the C version. There's also a couple of hundred bytes taken by the multiplication library routines.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Mon Mar 13, 2023 6:44 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
And now it can also execute a program written by the user. Which was an odd bit of code; I feel sure that there is a better way but my brain is looking forward to a holiday at present :D

Code:
typedef struct
   {
      char jump;
      int target;
   } JUMPER;
   
   JUMPER jumper;
   
void do_run (int ptr)
{
   // execute user assembly code at ptr
   // since we jsr to here, the assembly code can simply return, or
   // it can make a hard jump to the reset vector

   jumper.jump = 0x4c;      // jmp instruction
   jumper.target = ptr;
   
   __asm
   jsr _jumper;
   __endasm;
}   

compiles to
Code:
;------------------------------------------------------------
;Allocation info for local variables in function 'do_run'
;------------------------------------------------------------
;ptr                       Allocated to registers a x
;------------------------------------------------------------
;   monitor.c: 506: void do_run (int ptr)
;   -----------------------------------------
;    function do_run
;   -----------------------------------------
;   Register assignment is optimal.
;   Stack space usage: 0 bytes.
_do_run:
;   monitor.c: 512: jumper.jump = 0x4c;      // jmp instruction
   ldy   #0x4c
   sty   _jumper
;   monitor.c: 513: jumper.target = ptr;
   stx   ((_jumper + 0x0001) + 1)
   sta   (_jumper + 0x0001)
;   monitor.c: 517: __endasm;
    jsr   _jumper;
;   monitor.c: 518: }   
   rts


Still looking at interrupts...

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Mon Mar 13, 2023 9:13 pm 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Yeah, the interrupts are a bit worrying.
  • The code that's generated doesn't look particularly safe:
    Code:
    void irq_int (void) __interrupt (1)
    {
       static int temp = 0;
       
       temp++;
       return;
    }

    produces
    Code:
    ;------------------------------------------------------------
    ;Allocation info for local variables in function 'irq_int'
    ;------------------------------------------------------------
    ;temp                      Allocated with name '_irq_int_temp_65536_208'
    ;------------------------------------------------------------
    ;   monitor.c: 1031: void irq_int (void) __interrupt (1)
    ;   -----------------------------------------
    ;    function irq_int
    ;   -----------------------------------------
    ;   Register assignment is optimal.
    ;   Stack space usage: 0 bytes.
    _irq_int:
       tya
       pha
    ;   monitor.c: 1035: temp++;
       inc   _irq_int_temp_65536_208
       bne   00103$
       inc   (_irq_int_temp_65536_208 + 1)
    00103$:
    ;   monitor.c: 1036: return;
    ;   monitor.c: 1037: }
       pla
       tay
       rti

    which doesn't preserve either X, A, or the status register.
  • There doesn't seem to be a way to assign an interrupt service routine to either of NMI or IRQ. Irrespective of the interrupt number used (I was trying anything!) the code is generated, but no interrupt vector is assigned (they remain pointing to the start of the C program at - in this case - 0xe000) and the address of the interrupt routine is not to be found anywhere in the hex file.
    Code:
    :06FFFA0000E000E000E061

Perhaps they haven't finished that bit yet.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Mon Mar 13, 2023 9:43 pm 
Offline
User avatar

Joined: Tue Feb 28, 2023 11:39 pm
Posts: 133
Location: Texas
barnacle wrote:
...
which doesn't preserve either X, A, or the status register.


The status register gets preserved by the CPU itself when it receives an IRQ request so there's no need for them to save that one. The fact that it isn't saving the A or X registers is concerning.

At the very least it looks like it was smart enough to optimize the postfix ++ operator to be the same as if it was doing infix given how the function was written.
Infix is (or used to be) slightly faster because you don't have to preserve the value before incrementing and returning to whatever uses the value.

barnacle wrote:
[*] There doesn't seem to be a way to assign an interrupt service routine to either of NMI or IRQ. Irrespective of the interrupt number used (I was trying anything!) the code is generated, but no interrupt vector is assigned (they remain pointing to the start of the C program at - in this case - 0xe000) and the address of the interrupt routine is not to be found anywhere in the hex file.
Code:
:06FFFA0000E000E000E061
[/list]

Perhaps they haven't finished that bit yet.
...


:/


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Tue Mar 14, 2023 6:58 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Ah yes, I forgot that the flags are pushed automatically. Still thinking 8080 :D
But as you say, the A and X are worrying. Even an empty interrupt routine demolishes A to save Y and ignores X.

Using
Code:
void irq (void) __critical __interrupt
...

results in it saving the flags and immediately disabling interrupts, which is as described.

Code:
void irq (void) __interrupt __naked
...

produces just the body of the code; no prologue or epilogue. So I suppose the way it could be used is to code it that way; save the registers by hand and dropping the routine address into the hex file directly. Clumsy, but vaguely usable.

Neil


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Thu Mar 23, 2023 2:54 am 
Offline
User avatar

Joined: Tue Feb 28, 2023 11:39 pm
Posts: 133
Location: Texas
Erf, got it working myself, does some wild and crazy stuff alright.

Code:
char * const VIA_PORT_B = 0x8000;

int main(void)
{
    *VIA_PORT_B = 0;
    return 0;
}


Result:
Code:
;   main.c: 3: int main(void)
;   -----------------------------------------
;    function main
;   -----------------------------------------
;   Register assignment is optimal.
;   Stack space usage: 0 bytes.
_main:
;   main.c: 5: *VIA_PORT_B = 0;
   lda   _VIA_PORT_B
   ldx   (_VIA_PORT_B + 1)
   sta   *(__DPTR+0)
   stx   *(__DPTR+1)
   lda   #0x00
   tay
   sta   [__DPTR],y
;   main.c: 8: return 0;
   tax
;   main.c: 9: }
   rts
   .area CODE
   .area RODATA
_VIA_PORT_B:
   .dw #0x8000
   .area XINIT
   .area CABS    (ABS)


I can trim it down with the following:
Code:
int main(void)
{
    *((char *)0x8000) = 0;
    return 0;
}


Result:
Code:
;   main.c: 3: int main(void)
;   -----------------------------------------
;    function main
;   -----------------------------------------
;   Register assignment is optimal.
;   Stack space usage: 0 bytes.
_main:
;   main.c: 6: *((char *)0x8000) = 0;
   ldx   #0x00
   stx   0x8000
;   main.c: 8: return 0;
   txa
   tax
;   main.c: 9: }
   rts
   .area CODE
   .area RODATA
   .area XINIT
   .area CABS    (ABS)


Which you could put this behind a #define to get the same effect, but I prefer to not use #defines if I can help it.


Top
 Profile  
Reply with quote  
 Post subject: Re: SDCC for 6502
PostPosted: Sun Mar 26, 2023 9:15 am 
Offline

Joined: Mon Jan 19, 2004 12:49 pm
Posts: 660
Location: Potsdam, DE
Yes, I'm writing the same basic monitor that took 5k in C in assembly using the same general algorithms, to see how much smaller it gets.
But I'm on holiday at the moment, so not quite yet.

Neil


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 46 posts ]  Go to page Previous  1, 2, 3, 4  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 23 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: