Jump to content

bsteux

+AtariAge Subscriber
  • Posts

    84
  • Joined

  • Last visited

Everything posted by bsteux

  1. The next step. Support for DLIs (Display List Interrupts). This allows to execute a (short) function on the fly while Maria is displaying the screen. In the following example, I just change the background color to red on Display List 7 (out of 14), i.e. in the middle of the screen. Note that using DLI (which uses 6502 NMI : Non Maskable Iterrupt), it's necessary to declare an "interrupt" function. This is a new keyword that was added to cc7800 in the new v0.2.4. An example of use (this is examples/test_nmi.c from the cc7800 github repository) : #include "prosystem.h" #include "multisprite.h" char i, xpos, ypos; #define NB_SPRITES 64 ramchip short sp_xpos[NB_SPRITES], sp_ypos[NB_SPRITES]; ramchip char sp_direction[NB_SPRITES]; const signed short dx[24] = {300, 289, 259, 212, 149, 77, 0, -77, -150, -212, -259, -289, -300, -289, -259, -212, -149, -77, 0, 77, 149, 212, 259, 289}; const signed short dy[24] = {0, 124, 240, 339, 415, 463, 480, 463, 415, 339, 240, 124, 0, -124, -239, -339, -415, -463, -480, -463, -415, -339, -240, -124}; const char horizontal_pingpong[24] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13 }; const char vertical_pingpong[24] = { 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; holeydma reversed scattered(16,2) char bb_char1[32] = { 0x01, 0x00, 0x01, 0x40, 0x0a, 0x94, 0x2a, 0x90, 0x3b, 0xa0, 0xc8, 0xe5, 0xc8, 0xe4, 0xc8, 0xd0, 0xc8, 0xe5, 0xbb, 0x84, 0x0c, 0x20, 0x2a, 0x90, 0x0e, 0x50, 0x3f, 0x94, 0x3d, 0x68, 0x5d, 0x6a }; void interrupt dli() { *BACKGRND = 0x32; } void main() { multisprite_init(); multisprite_enable_dli(7); *P0C1 = multisprite_color(0x1c); // Setup Palette 0 *P0C2 = multisprite_color(0xc5); // Green *P0C3 = multisprite_color(0x0f); // White // Initialize sprites for (ypos = 0, xpos = 0, i = 0, X = 0; X != NB_SPRITES; xpos++, ypos++, X++) { sp_xpos[X] = xpos << 8; sp_ypos[X] = ypos << 8; sp_direction[X] = i++; if (i == 24) i = 0; } // Main loop do { multisprite_flip(); *BACKGRND = 0; // Back to black background for (i = 0; i != NB_SPRITES; i++) { Y = sp_direction[X = i]; sp_xpos[X] += dx[Y]; sp_ypos[X] += dy[Y]; xpos = sp_xpos[X] >> 8; ypos = sp_ypos[X] >> 8; if ((xpos < 5 && (dx[Y] >> 8) < 0) || (xpos >= 150 && (dx[Y] >> 8) >= 0)) { sp_direction[X] = horizontal_pingpong[Y]; } if ((ypos < 5 && (dy[Y] >> 8) < 0) || (ypos >= MS_YMAX - 20 && (dy[Y] >> 8) >= 0)) { sp_direction[X] = vertical_pingpong[Y]; } multisprite_display_sprite(xpos, ypos, bb_char1, 2, 0); } } while(1); } To compile the example, just type : (Make sure DASM is in the current path) cc7800 -Iheaders examples/test_nmi.c In attachment, a picture of the result, and the new version of cc7800 installer for Windows. cc7800-0.2.4-x86_64.msi
  2. The cc7800 project is going on... Let's now introduce conio.h, a console I/O (well, only O) to display text. It's not complete, but it supports putch, puts, gotoxy, textcolor, clrscr and delline. The included font is the lowercase C64 font. 128 characters are defined, so there is room for another 128 custom characters. Technically, my design of conio favors 3 goals : KISS (Keep it stupid simple), minimizing the CPU load (i.e. minimizing the number of Display List Headers - 0 when nothing is displayed), and maximizing the possibility to use colors. It's possible to use 8 colors on a line, with some limitations (the algorithm tries to use one DL header per color, and due to Maria design, this results in color priorities (the last color used has display priority over the first used)). Here is an example of use (a test indeed). The result is the picture in attachment. The "hearth" character is a custom character that is appended automatically by cc7800 to the C64 font (using the scattered keyword, indicating this is a MARIA graphics). Note the use of assert from assert.h, which turns background to red if the assertion is not correct (in my example, I check the the length of Display Lists) : #include "conio.h" #include "assert.h" char i; reversed scattered(8,1) char special_char[8] = { 0x66, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x00 }; void main() { clrscr(); // Draw a square gotoxy(0, 0); textcolor(7); putch(CONIO_TL_CORNER); for (i = 0; i != 20; i++) { putch(CONIO_HBAR); } putch(CONIO_TR_CORNER); for (i = 0; i != 8; i++) { gotoxy(0, i + 1); putch(CONIO_VBAR); gotoxy(21, i + 1); putch(CONIO_VBAR); } gotoxy(0, 9); putch(CONIO_BL_CORNER); for (i = 0; i != 20; i++) { putch(CONIO_HBAR); } putch(CONIO_BR_CORNER); // Write some text for (i = 0; i != 8; i++) { textcolor(i); gotoxy(i + 1, i + 1); cputs("Hello World!"); } // Long text test gotoxy(0, 10); cputs("This is a long text that fits in a line."); gotoxy(10, 11); cputs("World!"); gotoxy(4, 11); cputs("Hello"); gotoxy(10, 12); cputs("World!"); gotoxy(4, 12); textcolor(4); cputs("Hello"); gotoxy(0, 13); for (i = 0; i != 8; i++) { textcolor(i); putch('!'); } gotoxy(0, 14); for (i = 0; i != 8; i++) { textcolor(7 - i); putch(128); // Special character } // Unit tests (Display lines length check) : assert(_ms_dlend[X = 0] == 5); assert(_ms_dlend[X = 1] == 10); assert(_ms_dlend[X = 7] == 10); assert(_ms_dlend[X = 8] == 5); assert(_ms_dlend[X = 9] == 5); assert(_ms_dlend[X = 10] == 10); assert(_ms_dlend[X = 11] == 5); assert(_ms_dlend[X = 12] == 10); assert(_ms_dlend[X = 13] == 40); assert(_ms_dlend[X = 14] == 40); while(1); } cc7800-0.2.3-x86_64.msi
  3. Hi, I think I've found the issue with PlusROM high scores. Gameover function was possibly called 3 times instead of only once, sending PlusROM data 3 times, and likely overwriting previous buffers, causing incorrect behaviour. I've replaced : if ((*CXP0FB & 0x80) != 0) gameover(); if ((*CXP1FB & 0x80) != 0) gameover(); if ((*CXBLPF & 0x80) != 0) gameover(); with if ((*CXP0FB & 0x80) != 0) gameover(); else if ((*CXP1FB & 0x80) != 0) gameover(); else if ((*CXBLPF & 0x80) != 0) gameover(); Should be better now. I've attached PAL and NTSC corrected binaries (now v1.07 FINAL version). Still no ghost in the machine this time... Sorry for all the people who could be the highscore but were not registered. Official high score today in Pro mode is 111 by Zeropage Homebrew (in direct live!) ! Time to beat it. happybird-v1.07-NTSC-PLUSROM.bin happybird-v1.07-PAL-PLUSROM.bin
  4. Yes, you're right. I can't see how a page crossing could "ghost" trigger the hotspot at the end of the ROM. It's likely a real (),Y which goes too far into the rainbow table, because it's next to the hotspot I think... What I wonder is why I don't see any glitch or anything else unexpected... As soon as I have a little time ahead, I'll make this search with traps and a thorough examination of the source code to sort out the issue...
  5. In order to avoid these side effects, wouldn't it make sense to wait a little (a few hundred milliseconds should be enough no ?), or better to wait for a feedback from CartPlus (just a flag that would tell that's ok) ? It's very likely that there are many page crossings in my code. As it's written in C, It uses a lot of use of (),Y indexing with page crossing, and the tables located are at the end of each bank (especially the rainbow table... which could be involved in our case). I'll try to have a look in order to find where this happens...
  6. Thank you very much for your video, which was particularly appreciated by Paul, my 9 year-old son. Sorry I couldn't see it in direct (I live in France). AtariVox retransmlssion + a high-score in direct live! Wow! Great show.
  7. Here is the source code that sends the high score... Looks simple... Is it possible to check from the program that the comm is OK ? Is my ROM the only one in troubles ? plusrom_send_score SUBROUTINE ;{ ; *WriteToBuffer = game_mode; LDA game_mode ; 3 STA WriteToBuffer ; 3 ; i = score_high; LDA score_high ; 3 STA i ; 3 ; dec_to_bcd(); JSR dec_to_bcd ; 6 ; *WriteToBuffer = j; LDA j ; 3 STA WriteToBuffer ; 3 ; i = score_low; LDA score_low ; 3 STA i ; 3 ; dec_to_bcd(); JSR dec_to_bcd ; 6 ; *WriteToBuffer = j; LDA j ; 3 STA WriteToBuffer ; 3 ; *WriteSendBuffer = 60; LDA #60 ; 2 STA WriteSendBuffer ; 3 RTS
  8. Along with the example source code, here are : - The bitmap file for the graphics (including a 3 colors bitmap font) - The YAML file for the graphics description (so that sprites7800 tool can generate the C code) - A new windows installer for cc7800 v0.2.2 cc7800-0.2.2-x86_64.msi Bubble Bobble.yaml
  9. Hi, I've made some progress on the Multisprite library for cc7800. I've added vertical scrolling. Here is a working example : #include "prosystem.h" #include "gfx.h" #define VERTICAL_SCROLLING #define _MS_DL_SIZE 64 #define _MS_DL_MALLOC(y) ((y == 6 || y == 7 || y == 8)?_MS_DL_SIZE * 2:_MS_DL_SIZE) #include "multisprite.h" char i, counter, xpos, ypos; char *ptr; char xchest; #define NB_SPRITES 32 ramchip short sp_xpos[NB_SPRITES], sp_ypos[NB_SPRITES]; ramchip char sp_direction[NB_SPRITES]; const signed short dx[24] = {300, 289, 259, 212, 149, 77, 0, -77, -150, -212, -259, -289, -300, -289, -259, -212, -149, -77, 0, 77, 149, 212, 259, 289}; const signed short dy[24] = {0, 124, 240, 339, 415, 463, 480, 463, 415, 339, 240, 124, 0, -124, -239, -339, -415, -463, -480, -463, -415, -339, -240, -124}; const char horizontal_pingpong[24] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13 }; const char vertical_pingpong[24] = { 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; const char background[22] = { 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 }; #define LTR(x) (((x) - ' ') * 2) const char hello_world[] = { LTR('H'), LTR('E'), LTR('L'), LTR('L'), LTR('O'), LTR(' '), LTR('W'), LTR('O'), LTR('R'), LTR('L'), LTR('D') }; void main() { counter = 0; multisprite_init(); multisprite_set_charbase(tiles); // Set up a full background for (counter = 0; counter < _MS_DLL_ARRAY_SIZE; counter++) { if (counter & 2) { ptr = background + 2; } else { ptr = background; } multisprite_display_tiles(0, _MS_DLL_ARRAY_SIZE - 1 - counter, ptr, 20, 1); } multisprite_save(); *P0C1 = multisprite_color(0x1c); // Setup Palette 0: Yellow *P0C2 = multisprite_color(0xc5); // Green *P0C3 = 0x0f; // White *P1C1 = multisprite_color(0x55); // Dark pink *P1C2 = multisprite_color(0x5B); // Light pink *P2C1 = multisprite_color(0x32); *P2C2 = multisprite_color(0x3D); *P2C3 = multisprite_color(0x37); *P3C1 = multisprite_color(0x92); *P3C2 = multisprite_color(0x97); *P3C3 = multisprite_color(0x9D); // Initialize sprites for (ypos = 0, xpos = 0, i = 0, X = 0; X != NB_SPRITES; xpos++, ypos++, X++) { sp_xpos[X] = xpos << 8; sp_ypos[X] = ypos << 8; sp_direction[X] = i++; if (i == 24) i = 0; } // Main loop do { // Prepare scrolling data if (multisprite_vscroll_buffer_empty()) { if (counter & 2) { ptr = background + 2; } else { ptr = background; } multisprite_vscroll_buffer_tiles(0, ptr, 20, 1); multisprite_vscroll_buffer_sprite(xchest, chest, 2, 3); xchest += 45; counter++; } multisprite_flip(); multisprite_vertical_scrolling(1); multisprite_reserve_dma(104, sizeof(hello_world), 2); for (i = 0; i != NB_SPRITES; i++) { X = i; Y = sp_direction[X]; sp_xpos[X] += dx[Y]; sp_ypos[X] += dy[Y]; xpos = sp_xpos[X] >> 8; ypos = sp_ypos[X] >> 8; if ((xpos < 5 && (dx[Y] >> 8) < 0) || (xpos >= 150 && (dx[Y] >> 8) >= 0)) { sp_direction[X] = horizontal_pingpong[Y]; } if ((ypos < 5 && (dy[Y] >> 8) < 0) || (ypos >= MS_YMAX - 20 && (dy[Y] >> 8) >= 0)) { sp_direction[X] = vertical_pingpong[Y]; } multisprite_display_sprite(xpos, ypos, bb_char1, 2, 0); } for (xpos = 40, i = 0; i != sizeof(hello_world); xpos += 8, i++) { ptr = chars0 + hello_world[X = i]; multisprite_display_sprite_fast(xpos, 104, ptr, 2, 2); } } while(1); } The result ? See the video. I think it's getting close to what is needed to implement a shm'up. I'm still working on conio.h for console output. It's starting to work, but it is still not usable in a real program (at the moment it generates a display list for every print). The next steps are adding horizontal scrolling, support for joystick and sound (TIA and hopefully POKEY), writing some docs, and cc7800 will be ready for making good Atari 7800 games that eat the NES alive. a7800_vertical_scrolling.mp4
  10. Hi, I've updated cc7800 to v0.2. It now directly produces .a78 files with the included header., making things way simpler for users. It's now running DASM internally as a second stage compiler (this requires DASM to be present in the current directory or found in the system's path). This release also includes a bug fix which prevented cc7800 to run correctly under Windows (due to CRLF issues). Here is the new installer for windows. I'm working now on a conio.h header to add console-like facilities... cc7800-0.2.0-x86_64.msi
  11. This is an excellent suggestion! I was wondering how to cope with PAL and NTSC versions. Yes, using a 16x14 zones to have a "standard" 224 lines picture seems a good way to go, with an added autodetection of TV model. I've implemented your get_tv function and included it in the header : void multisprite_get_tv() { while (!(*MSTAT & 0x80)); // Wait for VBLANK while (*MSTAT & 0x80); // Wait for end of VBLANK X = 0; do { strobe(WSYNC); strobe(WSYNC); X++; } while (!(*MSTAT & 0x80)); if (X >= 135) _ms_pal_detected = 0xff; } This is called by multisprite_init() now, and it seems to work perfectly (tested on a7800) I've added a macro to process the colors (adding +1 phase shift for NTSC to PAL conversion) : // Macro to convert NTSC colors to PAL colors // To be used outside of grayscale ($0x) and NTSC $Fx #define multisprite_color(color) (color + (_ms_pal_detected & 0x10)) which doesn't cost much CPU... The difference in pixel ratio is partially compensated by the availability of wide screen displays. If we use a 4:3 PAL display and a 16:9 NTSC display, the result is looking similar... Adopted. Thank you !
  12. Hi, Yes, let's see if C can get a little room in between Basic and Assembler on the Atari 7800... I've made some progress in terms of usability... - v0.1.2 of cc7800 now correctly handles memory mapping, bankswitching, etc. It's rather complete now. - I've added a multisprite.h header, with all the necessary functions to ease, well, multisprite display... At the moment, it's quite basic, but at least it's working... Tested on real hardware and a7800 (see the video attached). It doesn't handle scrolling, but includes memory protection and DMA time computation so that glitches can be detected and handled if necessary. It also supports double buffering. At the moment, only 160A mode is supported. - I've made a program to read and process images in order to generate C sprite code: sprites7800. It's located in my new tools7800 repository (https://github.com/steux/tools7800), and is written in Rust (and thus can run on any platform). - And I've managed to make an installer for cc7800 for Windows... Here it is in attachment. Please tell me if it's working. I'm only using linux... Here is an example that displays 48 sprites at 50Hz (on my PAL system), with a full tiled background. Quite straightforward to understand for anyone who knows C and has a little bit of MARIA knowledge (the video attached shows the result on my PAL system) : #include "prosystem.h" #include "multisprite.h" char i, xpos, ypos; #define NB_SPRITES 48 ramchip short sp_xpos[NB_SPRITES], sp_ypos[NB_SPRITES]; ramchip char sp_direction[NB_SPRITES]; #ifdef PAL #define YMAX 240 #else #define YMAX 192 #endif const signed short dx[24] = {300, 289, 259, 212, 149, 77, 0, -77, -150, -212, -259, -289, -300, -289, -259, -212, -149, -77, 0, 77, 149, 212, 259, 289}; const signed short dy[24] = {0, 124, 240, 339, 415, 463, 480, 463, 415, 339, 240, 124, 0, -124, -239, -339, -415, -463, -480, -463, -415, -339, -240, -124}; const char horizontal_pingpong[24] = { 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13 }; const char vertical_pingpong[24] = { 0, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 }; holeydma reversed scattered(16,2) char bb_char1[32] = { 0x01, 0x00, 0x01, 0x40, 0x0a, 0x94, 0x2a, 0x90, 0x3b, 0xa0, 0xc8, 0xe5, 0xc8, 0xe4, 0xc8, 0xd0, 0xc8, 0xe5, 0xbb, 0x84, 0x0c, 0x20, 0x2a, 0x90, 0x0e, 0x50, 0x3f, 0x94, 0x3d, 0x68, 0x5d, 0x6a }; reversed scattered(16,2) char tiles[32] = { 0x5a, 0x5a, 0x69, 0x69, 0x69, 0x69, 0xa5, 0xa5, 0xa5, 0xa5, 0x96, 0x96, 0x96, 0x96, 0x5a, 0x5a, 0x5a, 0x5a, 0x69, 0x69, 0x69, 0x69, 0xa5, 0xa5, 0xa5, 0xa5, 0x96, 0x96, 0x96, 0x96, 0x5a, 0x5a }; const char background[20] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; void main() { multisprite_init(); multisprite_set_charbase(tiles); for (i = 0; i != _MS_DLL_ARRAY_SIZE; i++) { // 20 characters (8 pixels wide) on each line, using palette 1 (pink) multisprite_display_chars(0, i, background, 20, 1); } multisprite_save(); *P0C1 = 0x1c; // Setup Palette 0 *P0C2 = 0xd5; // Green *P0C3 = 0x0f; // White *P1C1 = 0x65; // Dark pink *P1C2 = 0x6B; // Light pink // Initialize sprites for (ypos = 0, xpos = 0, i = 0, X = 0; X != NB_SPRITES; xpos++, ypos++, X++) { sp_xpos[X] = xpos << 8; sp_ypos[X] = ypos << 8; sp_direction[X] = i++; if (i == 24) i = 0; } // Main loop do { while (!(*MSTAT & 0x80)); // Wait for VBLANK multisprite_flip(); for (i = 0; i != NB_SPRITES; i++) { X = i; Y = sp_direction[X]; sp_xpos[X] += dx[Y]; sp_ypos[X] += dy[Y]; xpos = sp_xpos[X] >> 8; ypos = sp_ypos[X] >> 8; if ((xpos < 5 && (dx[Y] >> 8) < 0) || (xpos >= 150 && (dx[Y] >> 8) >= 0)) { sp_direction[X] = horizontal_pingpong[Y]; } if ((ypos < 5 && (dy[Y] >> 8) < 0) || (ypos >= YMAX - 20 && (dy[Y] >> 8) >= 0)) { sp_direction[X] = vertical_pingpong[Y]; } multisprite_display_sprite(xpos, ypos, bb_char1, 2, 0); } } while(1); } The sprites are generated using sprites7800, with the following YAML file as input : sprite_sheets: - image: Bubble Bobble.png sprites: - name: bb_char1 top: 0 left: 0 width: 16 holeydma: true - name: tiles top: 16 left: 0 width: 16 holeydma: false I hope this will give an idea of the possibilities C coding is offering to Atari7800 game developers... I'll go on making new headers for vertical scrolling, horizontal scrolling, text display and split screen. See you ! cc7800_example_sprites.mp4 cc7800-0.1.2-x86_64.msi
  13. Hi, I'm pleased to announce the availability of cc7800, a C compiler (subset of C indeed) dedicated to the Atari 7800, available right now at https://github.com/steux/cc7800. It's a preliminary release (v0.1), but it's functional. I could compile a few examples and run them on my old PAL Atari 7800 (on a Concerto cart). The main limitation today is the poor support of the silly memory map of the 7800 (I still need to manage the shadowing of the zeropage and the stack in the middle of the RAM). What's nice is the "automatic" support of memory scattering and holey DMA (yet another quirk of the 7800). Another limitation is the lack of examples and support libraries (well, at the moment, you have to work your Maria display lines yourself...). I'm working on it, so stay tuned ! In the mean time, here is a sprite display example (you can move it with the joystick and it's PAL and NTSC compatilble) : #include "prosystem.h" char i; unsigned char X, Y; unsigned char xpos, ypos; char *dlpnt; holeydma scattered(16, 1) char sprite[16] = { 0x3c, 0x3c, 0x42, 0x42, 0x99, 0x99, 0xa5, 0xa5, 0x81, 0x81, 0xa5, 0xa5, 0x42, 0x42, 0x3c, 0x3c }; ramchip char dl0[64], dl1[64], dl2[64], dl3[64], dl4[64], dl5[64], dl6[64], dl7[64], dl8[64], dl9[64], dl10[64], dl11[64]; #ifdef PAL #define DLL_ARRAY_SIZE 15 #define YMAX (240 - 16) ramchip char dl12[64], dl13[64], dl14[64]; const char *dls[DLL_ARRAY_SIZE] = { dl0, dl1, dl2, dl3, dl4, dl5, dl6, dl7, dl8, dl9, dl10, dl11, dl12, dl13, dl14 }; #else #define DLL_ARRAY_SIZE 12 #define YMAX (192 - 16) const char *dls[DLL_ARRAY_SIZE] = { dl0, dl1, dl2, dl3, dl4, dl5, dl6, dl7, dl8, dl9, dl10, dl11 }; #endif ramchip char dll[(DLL_ARRAY_SIZE + 4) * 3]; char dlend[DLL_ARRAY_SIZE]; void main() { // Build DLL // 25 blank lines dll[X = 0] = 0x4f; // 16 lines dll[++X] = 0x21; // 0x2100 = Blank DL dll[++X] = 0x00; dll[++X] = 0x48; // 9 lines dll[++X] = 0x21; // 0x2100 = Blank DL dll[++X] = 0x00; // 192 lines divided into 12 regions for (Y = 0; Y != DLL_ARRAY_SIZE; Y++) { dll[++X] = 0x4f; // 16 lines dll[++X] = dls[Y] >> 8; // High address dll[++X] = dls[Y]; // Low address } // 26 blank lines dll[++X] = 0x4f; // 16 lines dll[++X] = 0x21; // 0x2100 = Blank DL dll[++X] = 0x00; dll[++X] = 0x49; // 10 lines dll[++X] = 0x21; // 0x2100 = Blank DL dll[++X] = 0x00; // Setup Maria registers *DPPH = dll >> 8; *DPPL = dll; *P0C1 = 0x18; // Setup Palette 0 *P0C2 = 0x38; *P0C3 = 0x58; *CTRL = 0x43; // Enable DMA *CTLSWA = 0; // Setup ports to read mode *CTLSWB = 0; xpos = 64; ypos = 64; // Main loop do { while (!(*MSTAT & 0x80)); // Wait for VBLANK if (!(*SWCHA & 0x80)) { // Pushed right ? xpos++; // Move right } if (!(*SWCHA & 0x40)) { // Pushed left ? xpos--; } if (!(*SWCHA & 0x20)) { // Pushed down ? if (ypos != YMAX) ypos++; } if (!(*SWCHA & 0x10)) { // Pushed up ? if (ypos != 0) ypos--; } // Reset DL ends for (X = DLL_ARRAY_SIZE - 1; X >= 0; X--) { dlend[X] = 0; } // Build DL entries X = ypos >> 4; dlpnt = dls[X]; // Create DL entry for upper part of sprite Y = dlend[X]; dlpnt[Y++] = sprite; // Low byte of data address dlpnt[Y++] = 0x40; // Mode 320x1 i = ypos & 0x0f; dlpnt[Y++] = (sprite >> 8) | i; dlpnt[Y++] = 0x1f; // Palette 0, 1 byte wide dlpnt[Y++] = xpos; // Horizontal position dlend[X] = Y; if (ypos & 0x0f) { // Is the sprite lying on another region ? X++; dlpnt = dls[X]; // Point to the next region Y = dlend[X]; dlpnt[Y++] = sprite; // Low byte of data address dlpnt[Y++] = 0x40; // Mode 320x1 dlpnt[Y++] = ((sprite - 0x1000) >> 8) | i; dlpnt[Y++] = 0x1f; // Palette 0, 1 byte wide dlpnt[Y++] = xpos; // Horizontal position dlend[X] = Y; } // Add DL end entry on each DL for (X = DLL_ARRAY_SIZE - 1; X >= 0; X--) { dlpnt = dls[X]; Y = dlend[X]; dlpnt[++Y] = 0; } // Wait for VBLANK to end while (*MSTAT & 0x80); } while(1); } What is interesting is the generated code. Very very close to pure assembly with little to no overhead (which was the primary goal). Well, have fun and please contribute if you find this exciting ! Regards.
  14. Very nice looking, colorful, and funny to play.
  15. Yes. To me, it is very similar to cc65. It's a very complete and capable C compiler targeting "bigger" 6502 platforms like C64 or NES. But unlikely suited to writing 2600 kernels, and lacking support for Atari 2600 specific bankswitching schemes like 3E or DPC/DPC+. cc2600 is designed as a complement to DASM, not as a full C compiler like cc65 or kickc.
  16. Hi, Here is the latest installer for windows (generated by Cargo Wix), which is also published on Github (releases). Best regards cc2600-0.1.7-x86_64.msi
  17. Hi M. Prizrak,

    Just a small message to tell you that there is an upgraded version of Paul's Happybird available to put on the PlusStore. The most important change is the support for AtariVox speech, and the lower difficulty. Ah, and the PAL version is 50Hz, not 60Hz as specified in the PlusStore file name.

    Have a nice day !

    happybird-v1.06-NTSC-PLUSROM.bin happybird-v1.06-PAL-PLUSROM.bin

  18. Hi, I've received my AtariVox ! So here is a new version of Paul's HappyBird with Atarivox support (20 different exclamations while playing, one exclamation every 8 points), with reset debouncing. Tested on PlusCart (PAL version). Have fun ! happybird-v1.06-PAL-PLUSROM.bin happybird-v1.06-NTSC-PLUSROM.bin
  19. Thanks! This is what I was looking for.
  20. Hi, The link to atarimuseum to get the schematics is not working anymore. Would anyone still have its own copy of the Maria schematics ? I'm a former teacher of VHDL and I was wondering if I could be of any help working on a Maria ASIC remake. Best regards.
  21. You're right, I'll debounce the reset and yes, apparently nobody cares about 50Hz anymore (probably not many CRTs left...). This is what I figured out myself when I saw other people homebrews... In the future, I'll only make 60fps games...
  22. Regarding HDTV connection, in case you wouldn't know (and only for European atarians I'm afraid), Philips HDTVs still have analogue tuners that work perfectly with unmodified PAL or SECAM Atari 2600. I've just bought a Philips 32PHS5507/12 at 179€, and it works perfectly (tested with PAL and SECAM).
  23. Hi, Here is an updated version (v1.05). I've removed the issue with the paddle detection pattern in Stella (by adding a pixel in a sprite), and I've made the game easier thanks to your feedback. The challenge should be in endurance. I've reached 206 on high score club, and I'm very bad at games. Should be easy to reach 1000+. Have you played Atari today ? Regards. happybird-v1.05-NTSC-PLUSROM.bin happybird-v1.05-PAL-PLUSROM.bin
  24. 1. Q-Bert 2. Combat 3. Moon Patrol 4. Super Breakout 5. Ms Pacman 6. Berzerk 7. Space Invaders 8. Pengo 9. Mario Bros 10. Video Olympics
  25. Bruce Lee really ? I have to see that. That was one of my favourite games. Indeed, I haven't had too much look into stack management, since stack size is so small on 2600 that clash with variables in zeropage is not easy to avoid. But the idea of stack frames is nice, and I definitely need a way to add function arguments, as least through shadowing registers... Designing cc2600 was hard work, but I did it during a flu week when I was stuck to bed. Intensive programming with fever. I love Rust and Pest, so programming it was very funny indeed.
×
×
  • Create New...