Jump to content

CurtisP

Members
  • Content Count

    259
  • Joined

  • Last visited

Everything posted by CurtisP

  1. That's exactly what I was saying. A, S, and R did not work. The only combination I could find that did was all six round buttons.
  2. To get the self-test mode on my Flashback Portable 2017, I had to hold down all six round keys (A, R, S,P, L, and T) while powering on.
  3. I was at my local Rite-As this morning and they had one each of the ATGames consoles at 50% off. There was an Atari Flashback Portable 2017, so I snatched it up.
  4. Do you plan to do the NTSC port yourself?
  5. If you still have this code, I'd like to see it.
  6. I'm using 3.9.3 since that's what's in the Linux Mint 17.3 Rosa repository.
  7. What kind of television did you test it on? I used a 1990's GE CRT television with a digital tuner and the flicker was terrible. Oddly enough, this same television had a rock stable display when I accidentally ran a PAL game on it (the display just ran off the bottom of the screen). I have at least two more CRT televisions at home that I can test it on, including a color set from the 1960's (if it still works). I'm interested to see how these turn out.
  8. I had been wanting to run this on my unmodified Supercharger which requires not accessing ROM locations $FFF8 and $FFF9, but as is the code uses every single byte of the 4K cartridge. Today, I took a look at the source code, and by making a small optimization I was able to trim 5 bytes from the code so that it ends at $FFF5. I changed the end of SetRespx from STA 0,X ; RESPx RTS to STA 0,X ; RESPx STA $10,X ; HMPx RTS then I changed the calls to SetRespx from JSR SetRespx STA HMM1 RTS JSR SetRespx STA HMP0 JSR SetRespx STA HMBL RTS to JMP SetRespx JSR SetRespx JMP SetRespx Edit: After setting NTSC mode in the source and re-assembling, the game runs flawlessly on my 6-switcher using the Supercharger. Thanks for releasing the code, Ed.
  9. On more suggestion, if you can spare the 8 bytes, is to change if mode = atari echo "Free bytes section 2: ",$fffc-* org $fffc .word START ; RESET .word START ; BRK endif to if mode = atari echo "Free bytes section 2: ",$fff4-* org $fff4 .ds 8 ; Bank Switching Hotspots .word START ; RESET .word START ; BRK endif This will keep your code from accessing any of the bank switch areas, any problems on unmodified Superchargers or Flash Carts. Of course, this assumes you can keep the entire ROM below 4k.
  10. Stella refuses to use OpenGL so it's stuck in software rendering mode. I'll try to grab a photo and/or video from my TV tonight.
  11. Also, 1K is not always recognized as a valid ROM size. Stella doesn't mind it, but MAKEWAV choked on it, so I had to change the source from org $fc00 to org $f800 and reassemble to make a 2k ROM before I could convert.
  12. This flicker is rather noticeable in Stella, even with phosphor mode on (at least on Linux Mint). I'll load it up on my Supercharger tonight and see how it looks on my television.
  13. I'm making a lot of design compromises. Originally, the compiler didn't even recognize registers. I added them in because I thought it might be useful. Now compiling X=3 into LDX #3 is easy enough, but what about X=TEMP+3 That would have to be LDA TEMP CLC ADC #3 TXA So my choices are to use the expression parser (which uses the Accumulator) followed by a TAX, not allow expressions when assigning values to X or Y, or write some extra complicated code to figure out what is after the equals sign. At this point, I've decided that I want all assignments to work the same way and have predictable side effects. In general, user programs won't be using the registers anyway, because they can be overwritten by the generated code.
  14. Sorry about that. I'm getting names all mixed up, especially late at night. By the way. I've found it quite useful.
  15. I've been working on a 2-line kernel library based on Random Terrain's Spiceware's Collect Tutorial. Here's a simple program that uses the kernel to display both players: #pragma origin $F800 //4k Cartridge #include <vcshead.h02> //TIA and RIOT Registers #include <vcsstub.h02> //Initialize VCS #include <vcslib.h02> //VCS Library Routines #include <k2line.h02> //Two Line Game Kernel #define KNLLNS = 96 //Kernal Lines (Scanlines/2) #define P0HGHT = 10 //Player 0 Height #define P1HGHT = 10 //Player 1 Height //Color Table char colors = {$86, $C6, $46, $00, $0E, $06, $0A, $00}; //Human Shaped Player Graphics char human = {%00011100, %00011000, %00011000, %00011000, %01011010, %01011010, %00111100, %00000000, %00011000, %00011000}; /* Setup Code */ void setup() { setclr(&colors); //Set Color Table } /* Vertical Blank Code */ void vrtblk() { posobj(0,0); //Set P0 X-Position p0prep(96, &human); //Set P0 Y-Position & Graphics Pointer posobj(8,1); //Set P1 X-Position p1prep(96, &human); //Set P1 Y-Position & Graphics Pointer } /* Execute Kernel Code */ void kernel() { dsplns(); //Display Playfield and Objects } /* Execute Overscan Code */ void ovrscn() { } #include <digits.h02> //Digit Graphics #include <vcsfoot.h02> //Finalization Code
  16. Tiny C uses the non-standard directives #asm and #asmend. I should probably do something similar, where it takes the inline assembly and converts is to the form expected by the target assembler. This would allow me to embed the assembly language right in the header files instead of having a separate assembly file.
  17. Already implemented. You can use either #include "filename.asm" which simply inserts the contents of the specified file, or asm("label", "opcode", "operand"); which generates a single line of assembly language. The latter is used in my example program in the second comment.
  18. There are other 6502 based systems that use strobe registers so, I modified the compiler to allow implicit assignments. IMPLICIT ASSIGNMENTS A statement consisting of only a simple variable is treated as an implicit assignment of the A register to the variable in question. This is useful on systems that use memory locations as strobe registers. Examples: HMOVE; //Move Objects (Atari VCS) S80VID; //Enable 80-Column Video (Apple II) Note: An implicit assignment generates an STA opcode with the variable as the operand. Thanks for the idea.
  19. Do you have a link to Atac-c. When I Googled it, I got too many unrelated hits.
  20. Registers are already abstracted. So the code VSYNC=2; Compiles to LDA #2 STA VSYNC I allowed the use of a register as a variable as an advanced feature so redundant LDA's can be avoided.
  21. A variable by itself as statement doesn't have any meaning in C-like languages. If I implemented C-like macros then I could possibly do something like this. #define WSYNC = WSYNC = A WSYNC; However, almost all code that uses strobe registers is going to be in a function that's coded in assembly language anyway, so it should not be necessary.
  22. This is handled through function calls that are coded in pure assembly language. I started to type in an example, then hit backspace at the wrong time and lost it. I'll post it shortly.
  23. The compiler is efficient enough that I can write most VCS code directly in C02. Here is an example: //Atari VCS Color Bars Program #pragma origin $F800 //2k Cartridge #include <vcshead.h02> //TIA and RIOT Registers /* Generate Vertical Sync Signal */ void vtsync() { A=2; //Set Bit 2 (D1) WSYNC=A; //Wait for end of Scanline VSYNC=A; //Turn On Vertical Sync WSYNC=A; //Wait 2 More Scanlines WSYNC=A; A=0; //Clear Bit 2 (D1) WSYNC=A; //Wait for End of 3rd Scanline VSYNC=A; //Turn On Vertical Sync return; } /* Execute Vertical Blank Code */ void vtblnk() { X=37; //Delay 37 Scanlines do { WSYNC=A; //Wait for end of Scanline X--; } while (X); return; } /* Execute Kernel Code */ void kernel() { A=0; //Clear All Bits WSYNC=A; //Wait for end of Scanline VBLANK=A; //Turn Off Vertical Blank X=0; //Draw 192 Scanlines (256-64) do { if (X & 3) { WSYNC = A; //Wait for end of Scanline COLUBK = X; //Set Background Color } X--; } while (X); return; } /* Execute Overscan Code */ void ovrscn() { WSYNC=A; //Wait for end of Scanline A=2; //Set Bit 2 (D1) VBLANK=A; //Turn On Vertical Blank X=27; //Delay 27 Scanlines do { WSYNC=X; //Wait for end of Scanline X--; } while(X); return; } start: asm("","SEI",""); asm("","CLD",""); A = 0; X = A; Y = A; do { X--; asm("","TXS",""); push 0; } while (X); irqbrk: //Code to Execute when BRK Instruction is Encountered main: //Start of Program Code vtsync(); //Generate Vertical Sync Signal vtblnk(); //Generate Vertical Blank Signal kernel(); //Execute Kernal Code ovrscn(); //Execute Overscan Code goto main; #include <vcsfoot.h02> //Finalization Code And here is the Assembly Language that's created: PROCESSOR 6502 ORG $F800 ; ======== Assembler File include/vcshead.a02 ======= VSYNC EQU $00 ;0000 00x0 Vertical Sync Set-Clear VBLANK EQU $01 ;xx00 00x0 Vertical Blank Set-Clear WSYNC EQU $02 ;---- ---- Wait for Horizontal Blank COLUBK EQU $09 ;xxxx xxx0 Color-Luminance Background ; ========================================== VTSYNC: ;VOID VTSYNC() { LDA #2 ; A = 2 STA WSYNC ; WSYNC = A; STA VSYNC ; VSYNC = A; STA WSYNC ; WSYNC = A; STA WSYNC ; WSYNC = A; LDA #0 ; A = 0; STA WSYNC ; WSYNC = A; STA VSYNC ; VSYNC = A; RTS ; RETURN; } VTBLNK: ;VOID VTBLNK() { LDA #37 ; X = 37; TAX ; L_0001: ; DO { STA WSYNC ; WSYNC = A; DEX ; X--; TXA ; } WHILE(X); BEQ L_0000 JMP L_0001 ; L_0000: RTS ; RETURN; } KERNEL: ;VOID KERNEL() { LDA #0 ; A = 0; STA WSYNC ; WSYNC = A; STA VBLANK ; VBLANK = A; LDA #0 ; X = 0 ; TAX ; L_0003: TXA ; DO { AND #3 ; IF ( X & 3 ) { BEQ L_0004 ; STA WSYNC ; WSYNC= A TXA ; COLUBK = X; STA COLUBK ; } L_0004: DEX ; X--; TXA ; } WHILE (X); BEQ L_0002 ; JMP L_0003 ; L_0002: RTS ; RETURN; } OVRSCN: ;VOID OVRSCN() { STA WSYNC ; WSYNC= A; LDA #2 ; A = 2; STA VBLANK ; VBLANK= A; LDA #27 ; X = 27; TAX ; L_0006: TXA ; DO { STA WSYNC ; WSYNC= X; DEX ; X--; TXA ; } WHILE (X); BEQ L_0005 ; JMP L_0006 ; L_0005: RTS ; RETURN; } START: ;START: SEI ; ASM("","SEI",""); CLD ; ASM("","CLD",""); LDA #0 ; A = 0; TAX ; X = A; TAY ; Y = A; L_0008: ; DO { DEX ; X--; TXS ; ASM("","TXS",""); LDA #0 ; PUSH 0; PHA ; TXA ; } WHILE (X); BEQ L_0007 ; JMP L_0008 ; L_0007: ; IRQBRK: ;IRQBRK: MAIN: ;MAIN: JSR VTSYNC ; VTSYNC(); JSR VTBLNK ; VTBLNK(); JSR KERNEL ; KERNEL( JSR OVRSCN ; OVRSCN( JMP MAIN ; GOTO MAIN; ; ======== Assembler File include/vcsfoot.a02 ======= ORG $FFF8 ;Control and Interrupt Registers SCCTL DC.B $00 ;$FFF8 Supercharger Control Register SCAUD DC.B $00 ;$FFF9 Supercharger Audio Data DC.W $0000 ;$FFFA Non-Maskable Interrupt Vector (Unused) DC.W START ;$FFFC Reset Vector DC.W IRQBRK ;$FFFE Interrupt Vector ; ==========================================
  24. This is something that had been bouncing around in my head for at least ten years. I originally started it about five years ago, but then got distracted and finally picked it up again a couple months ago. The language and compiler are still in the alpha stage of development. The code is currently a bit of a mess, and I'm still wrestling with design decisions. Here is some explanation from the beginning of the documentation that I have written: INTRODUCTION C02 is a simple C-syntax language designed to generate highly optimized code for the 6502 microprocessor. The C02 specification is a highly specific subset of the C standard with some modifications and extensions PURPOSE Why create a whole new language, particularly one with severe restrictions, when there are already full-featured C compilers available? It can be argued that standard C is a poor fit for processors like the 6502. The C was language designed to translate directly to machine language instructions whenever possible. This works well on 32-bit processors, but requires either a byte-code interpreter or the generation of complex code on a typical 8-bit processor. C02, on the other hand, has been designed to translate directly to 6502 machine language instructions. The C02 language and compiler were designed with two goals in mind. The first goal is the ability to target machines with low memory: a few kilobytes of RAM (assuming the generated object code is to be loaded into and ran from RAM), or as little as 128 bytes of RAM and 2 kilobytes of ROM (assuming the object code is to be run from a ROM or PROM). The compiler is agnostic with regard to system calls and library functions. Calculations and comparisons are done with 8 bit precision. Intermediate results, array indexing, and function calls use the 6502 internal registers. While this results in compiled code with virtually no overhead, it severely restricts the syntax of the language. The second goal is to port the compiler to C02 code so that it may be compiled by itself and run on any 6502 based machine with sufficient memory and appropriate peripherals. This slightly restricts the implementation of code structures.
  25. Droid Sans Mono is easier on the eyes, especially if you have eye problems. Bah on Trutype fonts, I want my pixels!
×
×
  • Create New...