Jump to content
IGNORED

Dmitry KickC Questions


Dmitry
 Share

Recommended Posts

The following code crashes my emulator:

 

#pragma target(atarixl)
#pragma emulator("/Users/rdupuy/kickc/atari800")
#include <atari-xl.h>

void main() {

    asm { 

  fontset:
	.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
	.byte $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$01,$15
	.byte $00,$00,$01,$05,$15,$55,$55,$55,$00,$10,$54,$54,$54,$54,$55,$55
	.byte $01,$05,$05,$15,$15,$55,$55,$55,$40,$50,$54,$55,$55,$55,$55,$55
  
  .byte $FE

      ldy #0
loop:
      lda fontset, y
      cmp #$FE
      bne cont
      jmp exit
cont: //sta $4800, y let's do absolutely nothing
      iny 
      jmp loop 
exit:
	    sei
    
    }
    
    // Loop forever 

    for(;;) {      

    };
}

 

3 Lines of .byte works.   4 Lines, crashes.

 

Could be my emulator, I don't know, but any ideas?  The code does absolutely nothing, I was just testing.

 

Also I have a question about the rasterbars.c example.

 

That example has some variables char TEXT[] and char DISPLAY_LIST[] and then it sets ANTIC display list pointer as follows :  ANTIC->DLIST = DISPLAY_LIST

 

It seems to me this example completely hides how it displays text on the screen.  How am I meant to find the answer to that.  I believe the website mentions several possibilities, such as read the manual, look through the source code, follow the open/closed features being developed and/or ask questions.   Would you recommend that I read through he source code or ask here?   The reference manual does not mention antic, and a search on open/closed features page, didn't turn up a result for keyword antic.


Thanks

 

edit: OK, maybe I have an inkling now on the DLI question.  You define then character array.  It exists somewhere.   And are passing the start and end address of that to the display list - hence why it gets displayed.  

 

I'd still like to know about the issue with the crashing, if anyone has an idea.

 

Edited by Dmitry
never mind on display list
Link to comment
Share on other sites

Thanks, the reason for the crash is that in the you embed table into the code of the main function, and the CPU is trying to execute this table as the code (from address 0x2000), which leads to crash. Move the table out of the code function.

 

    2000: 00                BRK
    2001: 00                BRK
    2002: 00                BRK
    2003: 00                BRK
    2004: 00                BRK
    2005: 00                BRK
    2006: 00                BRK
    2007: 00                BRK
    2008: 00                BRK
    2009: 00                BRK
    200A: 00                BRK
    200B: 00                BRK
    200C: 00                BRK
    200D: 00                BRK
    200E: 00                BRK
    200F: 01 00             ORA ($00,X)

Edited by ilmenit
Link to comment
Share on other sites

3 hours ago, Dmitry said:

I'd still like to know about the issue with the crashing, if anyone has an idea.

 

 

As @ilmenit points out, your program starts with the byte "00" which is BRK in 6502 and would cause an interrupt to happen and likely crash your emulator.

 

Here's an amended version of the application that works by assigning the bytes to an array (just as you would in C) which the asm block can then use.

Note that asm {} is clever enough to be able to work with variables declared outside of it, so has access to the fontset array.

 

#pragma target(atarixl)
#include <atari-xl.h>
#include <6502.h>

void main() {

	char fontset[] = kickasm {{
	.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
	.byte $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$01,$15
	.byte $00,$00,$01,$05,$15,$55,$55,$55,$00,$10,$54,$54,$54,$54,$55,$55
	.byte $01,$05,$05,$15,$15,$55,$55,$55,$40,$50,$54,$55,$55,$55,$55,$55
	.byte $FE
	}};

	BREAK();
    asm { 
      ldy #0
loop:
      lda fontset, y
      cmp #$FE
      bne cont
      jmp exit
cont: //sta $4800, y let's do absolutely nothing
      iny 
      jmp loop 
exit:
	    sei
    
    }
    
    // Loop forever 

    for(;;) {      

    };
}

I've add an include for 6502.h so I could put in a "BREAK();". Locally I've got my build creating an Altirra debug file converted from the kickc debug generated file, so I can use break points. It's just a bit of unix sed/awk to generate an atdbg file.

 

Additionally, it's worth looking at the generated asm file, as it's very readable with kickc (it's targetting "kick assembler"):

 

.segment Code
main: {
    // /home/markf/dev/personal/atari/kickc/bin/../lib/6502.c:20
    .break 
    // /home/markf/dev/personal/atari/projects/kickc-noodling/./src/crash.c:16
    ldy #0
  loop:
    lda fontset,y
    cmp #$fe
    bne cont
    jmp exit
  cont:
    iny
    jmp loop
  exit:
    sei
  __b1:
    jmp __b1
  .segment Data
  fontset:
.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
	.byte $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$01,$15
	.byte $00,$00,$01,$05,$15,$55,$55,$55,$00,$10,$54,$54,$54,$54,$55,$55
	.byte $01,$05,$05,$15,$15,$55,$55,$55,$40,$50,$54,$55,$55,$55,$55,$55
	.byte $FE
	
}

Here you can see the fontset has been moved into the "Data" segment, so isn't the first thing the application tries to "run", instead that's now correctly the "ldy" instruction.

 

Of course, you don't even have to resort to putting the bytes into an asm block, you can create the array in the standard C way too:

 

char fontset[] = {
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x15,
  0x00,0x00,0x01,0x05,0x15,0x55,0x55,0x55,0x00,0x10,0x54,0x54,0x54,0x54,0x55,0x55,
  0x01,0x05,0x05,0x15,0x15,0x55,0x55,0x55,0x40,0x50,0x54,0x55,0x55,0x55,0x55,0x55,
  0xFE
};

 

  • Like 2
Link to comment
Share on other sites

For a complete "C only" version of what you were doing, you can do this:

 

#pragma target(atarixl)
#include <atari-xl.h>
#include <6502.h>

void main() {
	char * OUT = 0x4800;

	char fontset[64] = {
	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,
	  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x15,
	  0x00,0x00,0x01,0x05,0x15,0x55,0x55,0x55,0x00,0x10,0x54,0x54,0x54,0x54,0x55,0x55,
	  0x01,0x05,0x05,0x15,0x15,0x55,0x55,0x55,0x40,0x50,0x54,0x55,0x55,0x55,0x55,0x55
	};

	for (char i = 0; i < 64; i++) {
		*(OUT + i) = fontset[i];
	}

	// Loop forever 
	while(1) ;
}

 

which produces:

 

.segment Code
main: {
    .label OUT = $4800
    ldx #0
  __b1:
    // /home/markf/dev/personal/atari/projects/kickc-noodling/./src/crash.c:16
    cpx #$40
    bcc __b2
  __b3:
  // Loop forever 
    jmp __b3
  __b2:
    // /home/markf/dev/personal/atari/projects/kickc-noodling/./src/crash.c:17
    lda fontset,x
    sta OUT,x
    // /home/markf/dev/personal/atari/projects/kickc-noodling/./src/crash.c:16
    inx
    jmp __b1
  .segment Data
    fontset: .byte 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, $40, 0, 0, 0, 0, 0, 0, 1, $15, 0, 0, 1, 5, $15, $55, $55, $55, 0, $10, $54, $54, $54, $54, $55, $55, 1, 5, 5, $15, $15, $55, $55, $55, $40, $50, $54, $55, $55, $55, $55, $55
}

 

Edited by fenrock
whitespace!
Link to comment
Share on other sites

Couple more questions, I'll check on this tomorrow.

 

On style.   I'm not sure I like the C-style better than the ASM style.

The main thing is, I need to have some tedium done by external programs, where possible.

 

Because I have a program that will produce byte lists in hex, I plan to just load it in asm with .byte directives.

 

But here, I didn't really have a handy way to lay out the tiles, so I used a C char string.   

 

On style  - OK, or what is a cleaner way?  I don't want to load from files, for now.

 

Secondly, why should I have to define a string and then copy the string contents to a memory location.  Shouldn't it be possible just to define the string at a certain location in the first place?

 

One other question - so, I expect that you cannot increment the y register past 255.  But, why does this actually hang if attempting more than 192?  If I had done the charset loading in C, would it handle a full 1024 without issue?

 

#pragma target(atarixl)
#pragma emulator("/Users/rdupuy/kickc/atari800")
#include <atari-xl.h>

void main() {


    asm { 

     lda #$48
		 sta $02F4 
     sta $D409

      ldy #0
loop:
      lda fontset, y
      cmp #$fe
      bne cont
      jmp exit
cont: sta $4800, y
      iny 
      jmp loop 
exit:
       ldy #0
loop2:
      lda fontset2, y
      cmp #$fe
      bne cont2
      jmp exit2
cont2: sta $48C0, y
      iny 
      jmp loop2
exit2:



	    sei
    
    }

 char * SCR = 0x6000;
 int i = 0;
char *p=TEXT;           // point to the start
while (*p++!=0) 
{ 
  *(SCR + i) = *p;
  i++;
}



    ANTIC->DMACTL = 0x21; 
    // Set ANTIC Display List Pointer
    ANTIC->DLIST  = DISPLAY_LIST;
    // Set colors
    GTIA->COLPF0 = 0xc8; 
    GTIA->COLPF1 = 0x11;
    GTIA->COLPF2 = 0x28; 
    GTIA->COLPF3 = 0xFF;

    for(;;) {      

      }


}



  char fontset[] = kickasm {{
	.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
	.byte $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$01,$15
	.byte $00,$00,$01,$05,$15,$55,$55,$55,$00,$10,$54,$54,$54,$54,$55,$55
	.byte $01,$05,$05,$15,$15,$55,$55,$55,$40,$50,$54,$55,$55,$55,$55,$55
	.byte $00,$00,$00,$00,$40,$41,$55,$55,$00,$00,$00,$00,$00,$50,$54,$55
	.byte $54,$45,$54,$15,$01,$00,$00,$00,$55,$15,$45,$54,$45,$05,$00,$00
	.byte $55,$55,$55,$11,$14,$05,$01,$00,$55,$55,$41,$15,$50,$01,$55,$00
	.byte $55,$15,$51,$15,$55,$54,$41,$00,$55,$55,$55,$11,$44,$50,$40,$00
	.byte $55,$55,$55,$54,$11,$45,$00,$00,$55,$51,$45,$14,$10,$00,$00,$00
	.byte $C0,$FF,$EA,$EA,$EA,$EA,$EA,$FF,$03,$FF,$AB,$AB,$AB,$AB,$AB,$FF
  .byte $FF,$55,$55,$55,$55,$55,$55,$55,$5A,$5A,$5A,$58,$58,$58,$58,$58
	.byte $A5,$A5,$A5,$05,$05,$F5,$F5,$F5,$58,$58,$5A,$5A,$58,$58,$5A,$5A
  .byte $FE
	}};

  char fontset2[] = kickasm {{
  .byte $F5,$F5,$A5,$A5,$F5,$F5,$A5,$A5,$55,$55,$55,$55,$55,$55,$55,$55
	.byte $AA,$AA,$A5,$A5,$AA,$AA,$A5,$A5,$AA,$AA,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$AA,$AA,$A5,$A5,$96,$96,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$A5,$A5,$A5,$AA,$96,$96,$96,$96,$96,$96,$96,$AA
  .byte $00,$00,$00,$00,$00,$00,$55,$00,$05,$05,$15,$15,$54,$54,$54,$00
	.byte $15,$15,$15,$15,$54,$54,$54,$00,$15,$15,$15,$15,$55,$55,$55,$00
	.byte $15,$15,$15,$15,$15,$15,$15,$00,$15,$15,$15,$15,$45,$45,$45,$00
	.byte $14,$14,$15,$15,$45,$45,$45,$00,$00,$00,$00,$00,$40,$40,$55,$00
	.byte $00,$00,$00,$00,$00,$2A,$15,$15,$00,$00,$00,$00,$00,$AA,$55,$55
	.byte $FE
	}};

char TEXT []= 
              "zzzzzz!\"zzzzzzzzzzzzzzzzzzzzzzzzz"
              "zz#$%&'()\"zzzzzzzzzzzzzzzzzzzzzzz"
              "z*+,-./01zzzzzzzzzzzzzzzzzzzzzz"
              "zzzzzzzzzzzzz232323232323zzzzzzz"
              "zzzzzzzzzzzzz444444444444zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz56569:;95656zzzzzzz"
              "zzzzzzzzzzzzz78789<=97878zzzzzzz"
              "zzzzzzzzzzzzz99999>?99999zzzzzzz"
              "@ABBBBBBBBBBBDDDDDDDDDDEEEEEEFG"
              "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
              "zzzzzzzHIJzHIJzHIJzHIJzHIJzHIJz"
              "zzzzzzzKLMzKLMzKLMzKLMzKLMzKLMz"
            ;

char DISPLAY_LIST[] = {
   BLANK8, BLANK8, BLANK8,    
   LMS|MODE4, 0x00, 0x60,            
   MODE4,                           
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,   
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4,    
   JVB, <DISPLAY_LIST, >DISPLAY_LIST    
};

 

Link to comment
Share on other sites

It seems that KickC support segments, take a look at the generated .asm file and later at the atarixl.* files in https://gitlab.com/camelot/kickc/-/tree/master/src/main/kc/target . It seems that with just a few modifications you could place data in dedicated segments at desired aligned locations, to avoid copying. I do not know if KickC support in-code selection of segments like CC65 does e.g. https://www.cc65.org/doc/cc65-7.html#ss7.6

Link to comment
Share on other sites

7 hours ago, Dmitry said:

Secondly, why should I have to define a string and then copy the string contents to a memory location.  Shouldn't it be possible just to define the string at a certain location in the first place?

 

One other question - so, I expect that you cannot increment the y register past 255.  But, why does this actually hang if attempting more than 192?  If I had done the charset loading in C, would it handle a full 1024 without issue?

 

Here are some notes about your code.

Please don't take any of this as criticism, I'm really trying to help, but sometimes questions may come across oddly as I don't know what your level of understanding is.

 

I'll be quoting mostly from the kickc manual at https://docs.google.com/document/d/1JE-Lt5apM-g4tZN3LS4TDbPKYgXuBz294enS9Oc4HXM/edit# which hopefully you've seen.

The kick assembler manual is at http://theweb.dk/KickAssembler/KickAssembler.pdf which is also a useful read, as kickc generates kick assembler code.

 

I'll come to a full solution to replace your asm code with C at the end.

 

Handling 1024 question

First, how well do you know C and do you understand that kickc is a C compiler, creating assembly from C programs?

Your question of "would it handle a full 1024 without issue" makes me think you may not have done much C before.

To answer this (the answer is yes) you have to understand C types. If you look at "Data Types" in the manual, you will find that "word" is a type that has a range of 0 to 65535 (or $0000 to $ffff in hex as it is 2 bytes).

What the C compiler does for you is find the appropriate code to match the types you are using. So if you're looping over a larger value than 255, you'd use a word (or similar) type and the compiler would generate the correct code.

 

 

Defining then copying

You don't have to do this, you can of course load strings directly into the address you want them.

There's a section on this in the manual using the "__address" modifier, e.g.

__address(0x2000) SPRITES[64*10];

There's also the ability to align bytes to a memory boundary, currently using the "align" modifier, but that is planned to change it to "__align" in the future, as all modifiers should be tagged with double underscore.

 

There is a downside to setting the address though, you have to understand that by default, kickc writes the Code segment to 0x2000.

So if you define an array at 0x4000 (say), then when you come to create the XEX program, there will be a lot of "zero" values between your code and the memory location you're writing to.

This can be solved by using XEX segment loading, which is something I've been helping @JesperGravgaard (the kickc author) to write, so that smaller binaries can be created, with different segments going into different addresses.

 

You can also change the default address from 0x2000 using the "#pragma pc(address)" command.

 

Overall, I would probably use a (long term) strategy of loading from a file, using the kickasm functions, as shown by Jesper here: 

 

but as you say, you want to do it directly at the moment.

 

There's other stuff you can do as I mentioned with XEX segment loading that would improve this, but some of that is in future releases.

 

Zero Page Variables

One other thing to note about kickc is that it aggressively tries to use ZP memory addresses for any generated code. This is great because in 6502 it's quicker to use, as you may well know.

However in the atari world, the OS uses memory addresses 0x00 to 0x7F, so you are best adding the following to the top of your C files:

#pragma zp_reserve(0x00..0x7f)

which will stop KickC from using that range of ZP addresses for itself.

This may stop some crashing you've seen, but I'll get to that in a moment.

 

The crashing above 192 problem.

I didn't see this happening, but I can see you've split your fontset up into 192 bytes and then created a fontset2, so assume it was around this.

 

I was able to change your code slightly to do up to 15 lines of 16 bytes, but had to remember to change the cont2 value up to $48F0 to compensate for the additional values.

You can't do 16 lines, because you're using $FE as a marker to the last byte, and that would be the 256th byte, which is out of the range of the the Y register which can only go from 0 to 255.

  ...
  cont2: sta $48F0, y
  ...

  char fontset[] = kickasm {{
	.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
	.byte $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$01,$15
	.byte $00,$00,$01,$05,$15,$55,$55,$55,$00,$10,$54,$54,$54,$54,$55,$55
	.byte $01,$05,$05,$15,$15,$55,$55,$55,$40,$50,$54,$55,$55,$55,$55,$55
	.byte $00,$00,$00,$00,$40,$41,$55,$55,$00,$00,$00,$00,$00,$50,$54,$55
	.byte $54,$45,$54,$15,$01,$00,$00,$00,$55,$15,$45,$54,$45,$05,$00,$00
	.byte $55,$55,$55,$11,$14,$05,$01,$00,$55,$55,$41,$15,$50,$01,$55,$00
	.byte $55,$15,$51,$15,$55,$54,$41,$00,$55,$55,$55,$11,$44,$50,$40,$00
	.byte $55,$55,$55,$54,$11,$45,$00,$00,$55,$51,$45,$14,$10,$00,$00,$00
	.byte $C0,$FF,$EA,$EA,$EA,$EA,$EA,$FF,$03,$FF,$AB,$AB,$AB,$AB,$AB,$FF
  .byte $FF,$55,$55,$55,$55,$55,$55,$55,$5A,$5A,$5A,$58,$58,$58,$58,$58
	.byte $A5,$A5,$A5,$05,$05,$F5,$F5,$F5,$58,$58,$5A,$5A,$58,$58,$5A,$5A
  .byte $F5,$F5,$A5,$A5,$F5,$F5,$A5,$A5,$55,$55,$55,$55,$55,$55,$55,$55
	.byte $AA,$AA,$A5,$A5,$AA,$AA,$A5,$A5,$AA,$AA,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$AA,$AA,$A5,$A5,$96,$96,$96,$96,$AA,$AA,$96,$96
  .byte $FE
	}};

  char fontset2[] = kickasm {{
	.byte $A5,$A5,$A5,$A5,$A5,$A5,$A5,$AA,$96,$96,$96,$96,$96,$96,$96,$AA
  .byte $00,$00,$00,$00,$00,$00,$55,$00,$05,$05,$15,$15,$54,$54,$54,$00
	.byte $15,$15,$15,$15,$54,$54,$54,$00,$15,$15,$15,$15,$55,$55,$55,$00
	.byte $15,$15,$15,$15,$15,$15,$15,$00,$15,$15,$15,$15,$45,$45,$45,$00
	.byte $14,$14,$15,$15,$45,$45,$45,$00,$00,$00,$00,$00,$40,$40,$55,$00
	.byte $00,$00,$00,$00,$00,$2A,$15,$15,$00,$00,$00,$00,$00,$AA,$55,$55
	.byte $FE
	}};

 

Doing the code fully in C

However, as you're in the world of C, you can do this entirely without asm blocks as follows.

This removes the need to worry about looping over >192 bytes, and worrying about Y register being 0-255, etc.

 

I've also used "memcpy" to move the TEXT array into the SCR address, rather than the loop you created, as it's much simpler. You could also use this to copy the fontset array too.

 

Note, there were a few alignment issues in your TEXT bytes, which I've rearranged to give exactly 32 bytes per line.

 

#pragma target(atarixl)
#pragma zp_reserve(0x00..0x7f)

#include <atari-xl.h>
#include <6502.h>
#include <string.h>

void main() {
	char * const NEW_CHBASE = 0x4800;
	void * const SCR = 0x6000;

	// here you can do the length of the data, rather than a tag value, there are 21 lines of 16 bytes
	// You could also use memcpy here too (see later) but this is for illustration of using > 256 bytes not erroring, or worrying about the Y register.
	for (word loop=0; loop < 21 * 16; loop++) {
		*(NEW_CHBASE + loop) = fontset[loop];
	}

	// Use C to set the values rather than ASM, use ">" to get the high byte of the NEW_CHBASE value
	*CHBAS = >NEW_CHBASE;
	ANTIC->CHBASE = >NEW_CHBASE;

	// we are using a narrow field (32 bytes per line) and there are 21 lines of text to display
	memcpy(SCR, TEXT, 32 * 21);

	// DMA Fetch + Narrow Field (32 bytes per line)
	ANTIC->DMACTL = 0x21; 
	// Set ANTIC Display List Pointer
	ANTIC->DLIST  = DISPLAY_LIST;
	// Set colors
	GTIA->COLPF0 = 0xc8; 
	GTIA->COLPF1 = 0x11;
	GTIA->COLPF2 = 0x28; 
	GTIA->COLPF3 = 0xFF;

	// this does same as "sei" in asm
	SEI();

	while(1) ;

}

char fontset[21 * 16] = kickasm {{
	.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
	.byte $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$01,$15
	.byte $00,$00,$01,$05,$15,$55,$55,$55,$00,$10,$54,$54,$54,$54,$55,$55
	.byte $01,$05,$05,$15,$15,$55,$55,$55,$40,$50,$54,$55,$55,$55,$55,$55
	.byte $00,$00,$00,$00,$40,$41,$55,$55,$00,$00,$00,$00,$00,$50,$54,$55
	.byte $54,$45,$54,$15,$01,$00,$00,$00,$55,$15,$45,$54,$45,$05,$00,$00
	.byte $55,$55,$55,$11,$14,$05,$01,$00,$55,$55,$41,$15,$50,$01,$55,$00
	.byte $55,$15,$51,$15,$55,$54,$41,$00,$55,$55,$55,$11,$44,$50,$40,$00
	.byte $55,$55,$55,$54,$11,$45,$00,$00,$55,$51,$45,$14,$10,$00,$00,$00
	.byte $C0,$FF,$EA,$EA,$EA,$EA,$EA,$FF,$03,$FF,$AB,$AB,$AB,$AB,$AB,$FF
	.byte $FF,$55,$55,$55,$55,$55,$55,$55,$5A,$5A,$5A,$58,$58,$58,$58,$58
	.byte $A5,$A5,$A5,$05,$05,$F5,$F5,$F5,$58,$58,$5A,$5A,$58,$58,$5A,$5A
	.byte $F5,$F5,$A5,$A5,$F5,$F5,$A5,$A5,$55,$55,$55,$55,$55,$55,$55,$55
	.byte $AA,$AA,$A5,$A5,$AA,$AA,$A5,$A5,$AA,$AA,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$AA,$AA,$A5,$A5,$96,$96,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$A5,$A5,$A5,$AA,$96,$96,$96,$96,$96,$96,$96,$AA
	.byte $00,$00,$00,$00,$00,$00,$55,$00,$05,$05,$15,$15,$54,$54,$54,$00
	.byte $15,$15,$15,$15,$54,$54,$54,$00,$15,$15,$15,$15,$55,$55,$55,$00
	.byte $15,$15,$15,$15,$15,$15,$15,$00,$15,$15,$15,$15,$45,$45,$45,$00
	.byte $14,$14,$15,$15,$45,$45,$45,$00,$00,$00,$00,$00,$40,$40,$55,$00
	.byte $00,$00,$00,$00,$00,$2A,$15,$15,$00,$00,$00,$00,$00,$AA,$55,$55
	}};

char TEXT[] = 
              "zzzzzz!\"zzzzzzzzzzzzzzzzzzzzzzzz"
              "zzz#$%&'()\"zzzzzzzzzzzzzzzzzzzzz"
              "zzz*+,-./01zzzzzzzzzzzzzzzzzzzzz"
              "zzzzzzzzzzzzz232323232323zzzzzzz"
              "zzzzzzzzzzzzz444444444444zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz56569:;95656zzzzzzz"
              "zzzzzzzzzzzzz78789<=97878zzzzzzz"
              "zzzzzzzzzzzzz99999>?99999zzzzzzz"
              "z@ABBBBBBBBBBBDDDDDDDDDDEEEEEEFG"
              "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
              "zzzzzzzHIJzHIJzHIJzHIJzHIJzHIJzz"
              "zzzzzzzKLMzKLMzKLMzKLMzKLMzKLMzz"
            ;

char DISPLAY_LIST[] = {
   BLANK8, BLANK8, BLANK8,    
   LMS|MODE4, 0x00, 0x60,            
   MODE4,                           
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,   
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4,    
   JVB, <DISPLAY_LIST, >DISPLAY_LIST    
};

There are other things you can do, e.g. aligning the DLIST just in case it crosses a 4k boundary, but for now the above is how I would move from ASM to C, given you're using kickc which is a C compiler which has the ability to embed ASM if you really really need it :)

 

Hope that helps!

 

 

 

Edited by fenrock
added some comments to the code, and some more on loading into memory
  • Like 2
Link to comment
Share on other sites

Quote

Please don't take any of this as criticism, I'm really trying to help, but sometimes questions may come across oddly as I don't know what your level of understanding is.

I'm not taking anything as criticism!   Probably it is true, I don't have the ability to craft my questions as a way of communicating my level of understanding.  They actually are intended to do the opposite, they are an expression of ignorance in order to facilitate a knowledge transfer.  This is how I view questions to work, at a fundamental level.  

 

But I sense maybe some explanation is needed - my questions will be on kickC implementation of C, and how to implement Atari related needs - only that.  I won't ask questions on C, even if I view it as 'yet another language'.   What attracts me to kickC, is that I find the most productive thing for me in creating an atari program is combining C and assembly.   Assembly, because of all the many examples out there.  And C, for doing the control flow of the game logic.    I've kind of let this question/answer thread go down the path of re-implementing assembly in the C language, which is not precisely what I meant to do - but at first I was getting hosed by my own mistakes, I see them now....

 

Anyway, this is good!  I may even have all my questions answered already...Now as far as having the non-used memory space ("lots of zeros") on the atari, partially between my code and my assigned memory areas for screen memory, character sets, and dli locations - guilty.  Its down on my list to move the non-used space to "after" since as long as I haven't run out of space and nothing conflicts - such choices don't impact usability.

 

OK, but I so much appreciate the answers!  Thanks, you are doing great.  It really expedites that accumulation of knowledge.

 

hmmm, time will tell, but I suspect this is already enough to get me going....thanks again all!!

 

 

 

 

 

Link to comment
Share on other sites

__address(0x2000) SPRITES[64*10];

Hey all, if anyone wants to help, I do appreciate it.

 

I cannot get this to work for anything.  But of course I do notice the example doesn't show it working.  The example doesn't load any data.  It just defines the address and does nothing else, that's why its so helpful to have full examples - because I want to load data directly to that address, and it just doesn't happen.

 

As an experiment, I still split the characters into fontset and fontset2. 

 

The snippet below shows how the global variables are defined. 

Fontset2 goes magically somewhere, and I copy it into the characters area in main().  That works.

Fontset, I use the address directive.  That does nothing.

 

Code snippet:

 


  __address(0x7000) char fontset[ 12 * 16] = kickasm {{
	.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
	.byte $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$01,$15
	.byte $00,$00,$01,$05,$15,$55,$55,$55,$00,$10,$54,$54,$54,$54,$55,$55
	.byte $01,$05,$05,$15,$15,$55,$55,$55,$40,$50,$54,$55,$55,$55,$55,$55
	.byte $00,$00,$00,$00,$40,$41,$55,$55,$00,$00,$00,$00,$00,$50,$54,$55
	.byte $54,$45,$54,$15,$01,$00,$00,$00,$55,$15,$45,$54,$45,$05,$00,$00
	.byte $55,$55,$55,$11,$14,$05,$01,$00,$55,$55,$41,$15,$50,$01,$55,$00
	.byte $55,$15,$51,$15,$55,$54,$41,$00,$55,$55,$55,$11,$44,$50,$40,$00
	.byte $55,$55,$55,$54,$11,$45,$00,$00,$55,$51,$45,$14,$10,$00,$00,$00
	.byte $C0,$FF,$EA,$EA,$EA,$EA,$EA,$FF,$03,$FF,$AB,$AB,$AB,$AB,$AB,$FF
  .byte $FF,$55,$55,$55,$55,$55,$55,$55,$5A,$5A,$5A,$58,$58,$58,$58,$58
	.byte $A5,$A5,$A5,$05,$05,$F5,$F5,$F5,$58,$58,$5A,$5A,$58,$58,$5A,$5A
	}};

  char fontset2[] = kickasm {{
  .byte $F5,$F5,$A5,$A5,$F5,$F5,$A5,$A5,$55,$55,$55,$55,$55,$55,$55,$55
	.byte $AA,$AA,$A5,$A5,$AA,$AA,$A5,$A5,$AA,$AA,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$AA,$AA,$A5,$A5,$96,$96,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$A5,$A5,$A5,$AA,$96,$96,$96,$96,$96,$96,$96,$AA
  .byte $00,$00,$00,$00,$00,$00,$55,$00,$05,$05,$15,$15,$54,$54,$54,$00
	.byte $15,$15,$15,$15,$54,$54,$54,$00,$15,$15,$15,$15,$55,$55,$55,$00
	.byte $15,$15,$15,$15,$15,$15,$15,$00,$15,$15,$15,$15,$45,$45,$45,$00
	.byte $14,$14,$15,$15,$45,$45,$45,$00,$00,$00,$00,$00,$40,$40,$55,$00
	.byte $00,$00,$00,$00,$00,$2A,$15,$15,$00,$00,$00,$00,$00,$AA,$55,$55
	.byte $FE
	}};

 

Link to comment
Share on other sites

I did figure out I must use the "export" keyword to keep the variable in the asm file, even if not used.

 

Which it does, and it appears to be OK, but something causes the program to crash.

 

The program works with the charset copy.  I comment that out, and then add the address directive and export keyword - it compiles, but the emulator crashes.

 

#pragma target(atarixl)
#pragma zp_reserve(0x00..0x7f)
#pragma link("atarixlseg.ld")
#pragma emulator("/Users/rdupuy/kickc/atari800")

#include <atari-xl.h>
#include <6502.h>
#include <string.h>


void main() {

//Memory Map
//Mode4 screeen does take 960 bytes (reserving 1k)
char * const SCR1 = 0x4000;
char * const SCR2 = 0x4400;
char * const SCR3 = 0x4800;
char * const SCR4 = 0x4C00;
char * const SCR5 = 0x5000;
char * const SCR6 = 0x5400;
char * const SCR7 = 0x5800;
char * const SCR8 = 0x5C00;

//DL cannot cross 4k boundary, reserving 1k for each
char * const DL1 = 0x6000;
char * const DL2 = 0x6400;
char * const DL3 = 0x6800;
char * const DL4 = 0x6C00;

//Characterset must be aligned along Page (256 bytes)
char * const CHARSET1 = 0x7000;
char * const CHBAS  = 0x02F4;
char * const CHBASE = 0xD409;

*CHBAS = >CHARSET1;
*CHBASE = >CHARSET1;

//memcpy(CHARSET1, fontset, 16 * 21);
SEI();
memcpy(SCR1, TEXT, 32 * 21);

    ANTIC->DMACTL = 0x21; 
    // Set ANTIC Display List Pointer
    ANTIC->DLIST  = DISPLAY_LIST;

    ANTIC->CHBASE = >CHARSET1;
    // Set colors
    GTIA->COLPF0 = 0xc8; 
    GTIA->COLPF1 = 0x11;
    GTIA->COLPF2 = 0x28; 
    GTIA->COLPF3 = 0xFF;

    for(;;) {      

      }


}

__address(0x7000) export char fontset[21 * 16] = kickasm {{
	.byte $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$01
	.byte $00,$00,$00,$00,$00,$00,$00,$40,$00,$00,$00,$00,$00,$00,$01,$15
	.byte $00,$00,$01,$05,$15,$55,$55,$55,$00,$10,$54,$54,$54,$54,$55,$55
	.byte $01,$05,$05,$15,$15,$55,$55,$55,$40,$50,$54,$55,$55,$55,$55,$55
	.byte $00,$00,$00,$00,$40,$41,$55,$55,$00,$00,$00,$00,$00,$50,$54,$55
	.byte $54,$45,$54,$15,$01,$00,$00,$00,$55,$15,$45,$54,$45,$05,$00,$00
	.byte $55,$55,$55,$11,$14,$05,$01,$00,$55,$55,$41,$15,$50,$01,$55,$00
	.byte $55,$15,$51,$15,$55,$54,$41,$00,$55,$55,$55,$11,$44,$50,$40,$00
	.byte $55,$55,$55,$54,$11,$45,$00,$00,$55,$51,$45,$14,$10,$00,$00,$00
	.byte $C0,$FF,$EA,$EA,$EA,$EA,$EA,$FF,$03,$FF,$AB,$AB,$AB,$AB,$AB,$FF
  .byte $FF,$55,$55,$55,$55,$55,$55,$55,$5A,$5A,$5A,$58,$58,$58,$58,$58
	.byte $A5,$A5,$A5,$05,$05,$F5,$F5,$F5,$58,$58,$5A,$5A,$58,$58,$5A,$5A
  .byte $F5,$F5,$A5,$A5,$F5,$F5,$A5,$A5,$55,$55,$55,$55,$55,$55,$55,$55
	.byte $AA,$AA,$A5,$A5,$AA,$AA,$A5,$A5,$AA,$AA,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$AA,$AA,$A5,$A5,$96,$96,$96,$96,$AA,$AA,$96,$96
	.byte $A5,$A5,$A5,$A5,$A5,$A5,$A5,$AA,$96,$96,$96,$96,$96,$96,$96,$AA
  .byte $00,$00,$00,$00,$00,$00,$55,$00,$05,$05,$15,$15,$54,$54,$54,$00
	.byte $15,$15,$15,$15,$54,$54,$54,$00,$15,$15,$15,$15,$55,$55,$55,$00
	.byte $15,$15,$15,$15,$15,$15,$15,$00,$15,$15,$15,$15,$45,$45,$45,$00
	.byte $14,$14,$15,$15,$45,$45,$45,$00,$00,$00,$00,$00,$40,$40,$55,$00
	.byte $00,$00,$00,$00,$00,$2A,$15,$15,$00,$00,$00,$00,$00,$AA,$55,$55
	}};

char TEXT[] = 
              "zzzzzz!\"zzzzzzzzzzzzzzzzzzzzzzzz"
              "zzz#$%&'()\"zzzzzzzzzzzzzzzzzzzzz"
              "zzz*+,-./01zzzzzzzzzzzzzzzzzzzzz"
              "zzzzzzzzzzzzz232323232323zzzzzzz"
              "zzzzzzzzzzzzz444444444444zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz565656565656zzzzzzz"
              "zzzzzzzzzzzzz787878787878zzzzzzz"
              "zzzzzzzzzzzzz999999999999zzzzzzz"
              "zzzzzzzzzzzzz56569:;95656zzzzzzz"
              "zzzzzzzzzzzzz78789<=97878zzzzzzz"
              "zzzzzzzzzzzzz99999>?99999zzzzzzz"
              "z@ABBBBBBBBBBBDDDDDDDDDDEEEEEEFG"
              "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
              "zzzzzzzHIJzHIJzHIJzHIJzHIJzHIJzz"
              "zzzzzzzKLMzKLMzKLMzKLMzKLMzKLMzz"
            ;

char DISPLAY_LIST[] = {
   BLANK8, BLANK8, BLANK8,    
   LMS|MODE4, 0x00, 0x40,            
   MODE4,                           
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,
   MODE4,   
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4, 
   MODE4,    
   JVB, <DISPLAY_LIST, >DISPLAY_LIST    
};

 

 

 

 

 

 

 

 

 

 

Edited by Dmitry
Link to comment
Share on other sites

This one seems like a bug.

 

If I memcpy 40 * 21 - the program won't display the screen.

But if I memcpy 40 * 19 - it will display but, it of course, is missing two lines I want to send.

 

If I change it to two memcpy, 40 * 19 and 40 * 2 - the program won't display the screen.

Even if there is some internal limit to memcpy, it is odd that it still doesn't work if split up.

 

It will work by 40 * 18 and 40 * 2, but I shouldn't have to do that.   Otherwise, I have at least set up the first screen, with DLI.

Using KickC.

result.png

test.c

Link to comment
Share on other sites

This isn't a memcpy issue, that works fine.

In the code you've posted, you skip copying into $42D0 to $42F8

 

SCR1 = $4000

SCR1 + 18 * 40 = $42D0

but, you're copying the last 2 lines into $42F8

 

However, this isn't the issue, but is kind of related as the extra data in the TEXT is messing with the next part...

The actual problem is that your DLIST is hanging off the end of some data, which is changing location as you add and remove lines.

This is sometimes crossing a boundary limit depending on the data before it, so as I mentioned in my previous message, you may need to align it to a page boundary, i.e.:

 

// Note, it's now 21 lines, I've add an extra line of "zzzzz..."
memcpy(SCR1, TEXT, 40 * 21);

// See the extra line in the data to make it 21 lines:
char TEXT[] = 
              "zzzzzz!\"zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
              "zzz#$%&'()\"zzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
              "zzz*+,-./01zzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz232323232323zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz444444444444zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz565656565656zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz787878787878zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz999999999999zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz565656565656zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz787878787878zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz999999999999zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz565656565656zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz787878787878zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz999999999999zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz56569:;95656zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz78789<=97878zzzzzzzzzzzzzz"
              "zzzzzzzzzzzzzz99999>?99999zzzzzzzzzzzzzz"
              "@ABBBBBBBBBBBBDDDDDDDDDDDDEEEEEEEEEEFGzz"
              "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz"
              "zzzzzzzHIJzHIJzHIJzHIJzHIJzHIJzzzzzzzzzz"
              "zzzzzzzKLMzKLMzKLMzKLMzKLMzKLMzzzzzzzzzz"
            ;

// Align the DLIST. Without this, the program may randomly crash because its location is after all the previous data,
// so its start position isn't fixed and may cross a memory boundary that stops it working. Ask atari why
char align(0x0100) DISPLAY_LIST[] = {
// ... as before

Note, as I say in the code, I add the extra line of "zzz" that was missing when you were jumping from 42D0 to 42F8.

 

The limitation on DLIST is explained in "Mapping the Atari" as:

Quote

The jump instructions are also used to skip across a 1K
boundary, since the DL itself cannot cross a 1K boundary without such
a jump. Also, DL data cannot cross a 4K boundary, so you must use an
LMS instruction before crossing one.

 

Edited by fenrock
added mapping the atari info, and link
Link to comment
Share on other sites

@Dmitry I had some time at lunch to have a play with this and setup your code into a project that uses XEX segment loading to load all the data into their respective memory blocks using kickc's new xex segment loader functionality.

 

This is in response to your post at:

 

 

I don't think the file you posted would work, so I went and created a project to get it working :D 

 

I've attached a tar.gz file which contains the src code split up into different files, there's a Makefile in there too of my own design that I use for kickc projects (it creates altirra debug file too).

 

There's some interesting things here.

 

1. I've used the latest build of kickc from https://gitlab.com/camelot/kickc with XeX segment support to compile the code.

2. I've split the data into separate files with a "#pragma data_seg(name)" to put it in its own segment, look in the "include" dir for "dlist.h", "fonts.h" for examples

3. I put the DLIST into its own memory segment so it doesn't have the bug I fixed earlier and is on a nice boundary.

4. I've create a custom link file (see target/custom.ld) to define the segment addresses and use the new XeX plugin for kickc to make things simpler. It's really nice :) Not that I'm biased because I helped make it.

5. Because this now splits the segments into small loadable sections, it no longer has lots of zeroes in the file - this means that your font table no longer sets the letter "z" to white space!

    So I've add an extra row of data to fontset (for the letter N) to be whitespace (I could have used \x00 instead, but then the TEXT string looked ugly :D )

6. I had to add a new "#pragma encoding(screencode_atari)" to the file. The new default in kickc is "atascii" which is entirely my fault as I think I convinced Jesper that this was more natural for atari use, but here you need the screencode values.

 

I haven't done anything with your Interrupt code which sets the code address to 0x6000, but that's automatically been put into its own segment because of the way the XeX plugin to kickc reads memory segments from the assembler, which I hadn't expected, but is a nice bonus.

It means any .pc settings in any block will automatically get created as separate segments in your output file!!

 

The final xex file now looks like this (I add the comment at the end of each line)

 

$ ataricom bin/main.xex 
ataricom 0.30-190808
(c) 2008-2019 Matthias Reichl <hias@horus.com>
block    1: 5000-501f (bytes:    32, offset:      6)   # DList
block    2: 6000-60a5 (bytes:   166, offset:     42)   # Interrupt code
block    3: 7000-74c0 (bytes:  1217, offset:    212)   # Fonts
block    4: 8000-808a (bytes:   139, offset:   1433)   # Application
block    5: 02e0-02e1 (bytes:     2, offset:   1576)   # Run address vector
       RUN: 8000

Anyway, I hope this helps. It was fun getting a real project to try out xex segments on and splitting them up into each chunks at their own addresses.

 

EDIT: I've add the XEX file for people to try out. It's only 1,578 bytes long, but covers memory addresses from 5000 to 808a

 

dmitry-kickc.tar.gz

main.xex

Edited by fenrock
  • Like 1
Link to comment
Share on other sites

On 11/26/2020 at 6:32 PM, fenrock said:

@Dmitry I had some time at lunch to have a play with this and setup your code into a project that uses XEX segment loading to load all the data into their respective memory blocks using kickc's new xex segment loader functionality.

 

I don't think the file you posted would work, so I went and created a project to get it working :D 

 

@fenrock That is a very nice demonstration of the new XEX format! 

The next release of KickC will include this linker plugin to make it easier to create better XEX files directly from KickC.

If anyone want to use it before it is released officially it is always possible to download the newest master build from https://gitlab.com/camelot/kickc

  • Like 1
Link to comment
Share on other sites

anyway, while I'm here I'll share a bit - I've primarily been working on the display list interrupts and vbi routine the last few days.

 

It's been interesting, I initially tried to cram far more into a display list interrupt than was in any way reasonable.   I mean like 2 to 3 times more than you can actually do, lol....

 

But the good news is, is that nevertheless, the code is coming together.  I'm getting too anxious, I want to be done already, ha!

 

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...