Jump to content

svenvandevelde

Members
  • Posts

    404
  • Joined

  • Last visited

  • Days Won

    16

Everything posted by svenvandevelde

  1. Wonderful! So this means that when writing to A000 at the first few hundreds of bytes, i get all kind of strange side effects (lol). So bank 1 is the start of things for A000... Thank you, it is a confirmation that I'm on the right path and help Jesper with some new CBM api that has been tested on the X16 loading a file from SD card :). Time to pull off a pull request ... @Jesper Gravgaard
  2. I found it ... I should not use bank 0 RAM A000. for some reason that interferes. bank 1 and beyond is ok. Note that the X16 by default uses bank 1 RAM!
  3. Can somebody help me? Please install kickc and complile the attached program load.c. I've also attached a TEXT file. TEXT load.c This C routine opens the TEXT file and reads it. But for some reason AFTER this process has been successfully executed, it seems that the character buffer ALSO contains the characters that were read from the file! And before I forget to mention, I read this from an sdcard file; I've also attached my X16.VHD image that you can load using -sdcard X16.vhd option of x16emu. //#pragma link("load.ld") #include <printf.h> #include <mos6522.h> // Address to load to banked memory. dword const loadtext = 0x00000000; char* const text = 0xA000; const word CBM_OPEN = 0xFFC0; const word CBM_CHKIN = 0xFFC6; const word CBM_READST = 0xFFB7; const word CBM_CHRIN = 0xFFCF; const word CBM_CLOSE = 0xFFC3; const word CBM_CLRCHN = 0xFFCC; // Kernal SETNAM function // SETNAM. Set file name parameters. void cbm_k_setnam(char* filename) { char filename_len = (char)strlen(filename); asm { // Kernal SETNAM function // SETNAM. Set file name parameters. // Input: A = File name length; X/Y = Pointer to file name. lda filename_len ldx filename ldy filename+1 jsr $ffbd } } // SETLFS. Set file parameters. void cbm_k_setlfs(char channel, char device, char secondary) { asm { // SETLFS. Set file parameters. // Input: A = Logical number; X = Device number; Y = Secondary address. ldx device lda channel ldy secondary jsr $ffba } } /* B-18. Function Name: OPEN Purpose: Open a logical file Call address: $FFC0 (hex) 65472 (decimal) Communication registers: None Preparatory routines: SETLFS, SETNAM Error returns: 1,2,4,5,6,240, READST Stack requirements: None Registers affected: A, X, Y Description: This routine is used to OPEN a logical file. Once the logical file is set up, it can be used for input/output operations. Most of the I/O KERNAL routines call on this routine to create the logical files to operate on. No arguments need to be set up to use this routine, but both the SETLFS and SETNAM KERNAL routines must be called before using this routine. How to Use: 0) Use the SETLFS routine. 1) Use the SETNAM routine. 2) Call this routine. */ char cbm_k_open() { char status; asm { //.byte $db jsr CBM_OPEN bcs error lda #$ff error: sta status } return status; } /* B-9. Function Name: CLOSE Purpose: Close a logical file Call address: $FFC3 (hex) 65475 (decimal) Communication registers: A Preparatory routines: None Error returns: 0,240 (See READST) Stack requirements: 2+ Registers affected: A, X, Y Description: This routine is used to close a logical file after all I/O operations have been completed on that file. This routine is called after the accumulator is loaded with the logical file number to be closed (the same number used when the file was opened using the OPEN routine). How to Use: 1) Load the accumulator with the number of the logical file to be closed. 2) Call this routine. */ char cbm_k_close(char channel) { char status; asm { //.byte $db lda channel jsr CBM_CLOSE bcs error lda #$ff error: sta status } return status; } /* B-2. Function Name: CHKIN Purpose: Open a channel for input Call address: $FFC6 (hex) 65478 (decimal) Communication registers: X Preparatory routines: (OPEN) Error returns: Stack requirements: None Registers affected: A, X Description: Any logical file that has already been opened by the KERNAL OPEN routine can be defined as an input channel by this routine. Naturally, the device on the channel must be an input device. Otherwise an error will occur, and the routine will abort. If you are getting data from anywhere other than the keyboard, this routine must be called before using either the CHRIN or the GETIN KERNAL routines for data input. If you want to use the input from the keyboard, and no other input channels are opened, then the calls to this routine, and to the OPEN routine are not needed. When this routine is used with a device on the serial bus, it auto- matically sends the talk address (and the secondary address if one was specified by the OPEN routine) over the bus. How to Use: 0) OPEN the logical file (if necessary; see description above). 1) Load the X register with number of the logical file to be used. 2) Call this routine (using a JSR command). Possible errors are: #3: File not open #5: Device not present #6: File not an input file */ char cbm_k_chkin(char channel) { char status; asm { ldx channel jsr CBM_CHKIN bcs error lda #$ff error: sta status } return status; } /* B-10. Function Name: CLRCHN Purpose: Clear I/O channels Call address: $FFCC (hex) 65484 (decimal) Communication registers: None Preparatory routines: None Error returns: Stack requirements: 9 Registers affected: A, X Description: This routine is called to clear all open channels and re- store the I/O channels to their original default values. It is usually called after opening other I/O channels (like a tape or disk drive) and using them for input/output operations. The default input device is 0 (keyboard). The default output device is 3 (the Commodore 64 screen). If one of the channels to be closed is to the serial port, an UNTALK signal is sent first to clear the input channel or an UNLISTEN is sent to clear the output channel. By not calling this routine (and leaving lis- tener(s) active on the serial bus) several devices can receive the same data from the Commodore 64 at the same time. One way to take advantage of this would be to command the printer to TALK and the disk to LISTEN. This would allow direct printing of a disk file. This routine is automatically called when the KERNAL CLALL routine is executed. How to Use: 1) Call this routine using the JSR instruction. */ void cbm_k_clrchn() { asm { jsr CBM_CLRCHN } } /* B-4. Function Name: CHRIN Purpose: Get a character from the input channel Call address: $FFCF (hex) 65487 (decimal) Communication registers: A Preparatory routines: (OPEN, CHKIN) Error returns: 0 (See READST) Stack requirements: 7+ Registers affected: A, X Description: This routine gets a byte of data from a channel already set up as the input channel by the KERNAL routine CHKIN. If the CHKIN has NOT been used to define another input channel, then all your data is expected from the keyboard. The data byte is returned in the accumulator. The channel remains open after the call. Input from the keyboard is handled in a special way. First, the cursor is turned on, and blinks until a carriage return is typed on the keyboard. All characters on the line (up to 88 characters) are stored in the BASIC input buffer. These characters can be retrieved one at a time by calling this routine once for each character. When the carriage return is retrieved, the entire line has been processed. The next time this routine is called, the whole process begins again, i.e., by flashing the cursor. How to Use: FROM THE KEYBOARD 1) Retrieve a byte of data by calling this routine. 2) Store the data byte. 3) Check if it is the last data byte (is it a CR?) 4) If not, go to step 1. FROM OTHER DEVICES 0) Use the KERNAL OPEN and CHKIN routines. 1) Call this routine (using a JSR instruction). 2) Store the data. */ char cbm_k_chrin() { char value; asm { //.byte $db jsr CBM_CHRIN sta value } return value; } /* B-22. Function Name: READST Purpose: Read status word Call address: $FFB7 (hex) 65463 (decimal) Communication registers: A Preparatory routines: None Error returns: None Stack requirements: 2 Registers affected: A Description: This routine returns the current status of the I/O devices in the accumulator. The routine is usually called after new communication to an I/O device. The routine gives you information about device status, or errors that have occurred during the I/O operation. The bits returned in the accumulator contain the following information: (see table below) +---------+------------+---------------+------------+-------------------+ | ST Bit | ST Numeric | Cassette | Serial | Tape Verify | | Position| Value | Read | Bus R/W | + Load | +---------+------------+---------------+------------+-------------------+ | 0 | 1 | | time out | | | | | | write | | +---------+------------+---------------+------------+-------------------+ | 1 | 2 | | time out | | | | | | read | | +---------+------------+---------------+------------+-------------------+ | 2 | 4 | short block | | short block | +---------+------------+---------------+------------+-------------------+ | 3 | 8 | long block | | long block | +---------+------------+---------------+------------+-------------------+ | 4 | 16 | unrecoverable | | any mismatch | | | | read error | | | +---------+------------+---------------+------------+-------------------+ | 5 | 32 | checksum | | checksum | | | | error | | error | +---------+------------+---------------+------------+-------------------+ | 6 | 64 | end of file | EOI line | | +---------+------------+---------------+------------+-------------------+ | 7 | -128 | end of tape | device not | end of tape | | | | | present | | +---------+------------+---------------+------------+-------------------+ How to Use: 1) Call this routine. 2) Decode the information in the A register as it refers to your pro- gram. */ char cbm_k_readst() { char status; asm { //.byte $db jsr CBM_READST sta status } return status; } // LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.) // - verify: 0 = Load, 1-255 = Verify // // Returns a status, 0xff: Success other: Kernal Error Code char cbm_k_load(char* address, char verify) { char status; asm { //LOAD. Load or verify file. (Must call SETLFS and SETNAM beforehands.) // Input: A: 0 = Load, 1-255 = Verify; X/Y = Load address (if secondary address = 0). // Output: Carry: 0 = No errors, 1 = Error; A = KERNAL error code (if Carry = 1); X/Y = Address of last byte loaded/verified (if Carry = 0). .byte $db ldx address ldy address+1 lda verify jsr $ffd5 bcs error lda #$ff error: sta status } return status; } // Configure the bank of the CX16 banked ram between A000 and BFFF. void cx16_Bank(char bank) { VIA1->PORT_A = bank; } // Load a file to memory // Returns a status: // - 0xff: Success // - other: Kernal Error Code (https://commodore.ca/manuals/pdfs/commodore_error_messages.pdf) char cx16_LoadFileBanked(char channel, char device, char secondary, char* filename, dword address) { cbm_k_setnam(filename); cbm_k_setlfs(channel, device, secondary); byte status = 0; char ch = 0; byte bank = (byte)(((((word)<(>address)<<8)|>(<address))>>5)+((word)<(>address)<<3)); byte* addr = ((<address)&0x1FFF); // stip off the top 3 bits, which are representing the bank of the word! addr += 0xA000; printf("%s/%lx/%hx/%x\n",filename,address, bank, addr); cx16_Bank(bank); status = cbm_k_open(); if(status!=$FF) return status; status = cbm_k_chkin(channel); if(status!=$FF) return status; ch = cbm_k_chrin(); status = cbm_k_readst(); while (!status) { //printf("%c",ch); *addr = ch; addr++; ch = cbm_k_chrin(); status = cbm_k_readst(); } status = cbm_k_close(channel); cbm_k_clrchn(); cx16_Bank(bank); return status; } void main() { // Load sprite file into memory char status = cx16_LoadFileBanked(1, 8, 0, "TEXT", loadtext); if(status!=0xff) printf("status = %x\n",status); printf("text = %s\n", text); } And those characters are then displayed. The X16 terminal locks up completely after that! It looks like the file buffer is filled when calling the above procedures! Does anybody have an idea why this happens? X16.vhd
  4. i meant this: 10 open5,8,5,"file1.txt,s,r" 20 open6,8,6,"file2.txt,s,r" 30 for i=1 to 15 40 get#5,a$:print a$; 50 get#6,b$:print b$; 60 next i 70 close5:close6
  5. Hello Frank. I have been making a short vera mode demo program for the x16 and I must say that I am really impressed with your card design. If the card you have created would be available in the 80s, that would have been a real differentiator from VGA. I can't wait to see your card at work in time real X16 machine. If you're interested, it's this program I'm talking about ...
  6. One should use this function with care, only when finishing all I/O operations. Imagine when you read simultaneously from 2 files or devices, calling this function for one device would also close the channel of the other! This is the description of CLRCHN: Description: This routine is called to clear all open channels and re- store the I/O channels to their original default values. It is usually called after opening other I/O channels (like a tape or disk drive) and using them for input/output operations. The default input device is 0 (keyboard). The default output device is 3 (the Commodore 64 screen). If one of the channels to be closed is to the serial port, an UNTALK signal is sent first to clear the input channel or an UNLISTEN is sent to clear the output channel. By not calling this routine (and leaving lis- tener(s) active on the serial bus) several devices can receive the same data from the Commodore 64 at the same time. One way to take advantage of this would be to command the printer to TALK and the disk to LISTEN. This would allow direct printing of a disk file. This routine is automatically called when the KERNAL CLALL routine is executed.
  7. Related to my other post regarding the load API, i've also been testing the .vhd virtual disks and using the -sdcard option in the x16emu. Unfortunately, the address indeed is ignored, and the files are loaded at another place in the memory than the place that you indicate using the X and Y registers of the FFD5 API, unfortunately. It would be good to get this bug fixed. I think the only option now is to write my own loader ... using open, close API and read byte by byte.
  8. Thank you. This is a great help. Such a simple solution. Is there a way to automatically start a prg from an sdcard when you load the emulator? Or is this not possible?
  9. When I was a teenager, this book was hard to get. Still, I could buy it. It was amazing how much technology you learned with the C64 in one single condensed manual. It has set the path to my later career in IT.
  10. I was 14 years old when I got my first home computer. A C64, earned through hard work with my father helping him with the construction of central heating systems. From that moment on, my life started to be around computers. Today, I'm an architect in the financial services industry, working with large firms helping them to transform into the digital era. The deep knowledge of computing that is required to do such a job, goes back to that same C64. The younger people working today in IT don't know what is a "byte", as they work with virtual machines. We do, the generation that grew up with 8-bit computers like many of us here, discovering the X16 Commander.

  11. Now with 3 background tiles ... PALETTES PLAYER Space.asm Space.c space.ld Space.prg SQUAREMETAL SQUARERASTER TILEMETAL TILES ENEMY2
  12. OK... Breakfast done and this is the result ... It all seems to work now. Note that I've now properly dealt with the 2 byte header in each file, maybe that was the root cause why the API returned with an error. Also, the load file (space.ld), I had accidentally commented the .file line of the program itself, so that could also have been the reason! It all works now ... This peace of code implements the smooth scroll reset. It's neat. Once a tile segment has been smoothly scrolled, move the remaining segments one row up, and reset the scroll. if(vscroll>(64)*2-1) { memcpy_in_vram(1, <VRAM_TILEMAP, VERA_INC_1, 1, (<VRAM_TILEMAP)+64*16, VERA_INC_1, 64*16*4); for(byte r=4;r<5;r+=1) { for(byte c=0;c<5;c+=1) { byte rnd = (byte)modr16u(rand(),2,0); vera_tile_element( 0, c, r, 3, TileDB[rnd]); } } vscroll=0; } Sven TILES ENEMY2 PALETTES PLAYER Space.asm Space.c space.ld Space.prg SQUAREMETAL TILEMETAL
  13. breakfast, i'll come back to this later today, ok?
  14. So, this is the working program ... Just copy all these files to a single folder, and run the program ... If you have all working, you should see the picture attached. I've removed all breakpoints from the program. When a bitmap file is not found however, it will display an error on the screen. char status = LoadFileBanked(8, FILE_SPRITES, (dword)BANK_PLAYER); if(status!=$ff) printf("status = %x\n",status); status = LoadFileBanked(8, FILE_ENEMY2, (dword)BANK_ENEMY2); if(status!=$ff) printf("status = %x\n",status); status = LoadFileBanked(8, "TILES", (dword)BANK_TILES_SMALL); if(status!=$ff) printf("status = %x\n",status); status = LoadFileBanked(8, "SQUAREMETAL", (dword)BANK_SQUAREMETAL); if(status!=$ff) printf("status = %x\n",status); status = LoadFileBanked(8, "TILEMETAL", (dword)BANK_TILEMETAL); if(status!=$ff) printf("status = %x\n",status); // Load the palette in main banked memory. status = LoadFileBanked(8, "PALETTES", (dword)BANK_PALETTE); if(status!=$ff) printf("status = %u",status); There should be no error ... ENEMY2 PALETTES PLAYER Space.asm Space.c space.ld Space.prg SQUAREMETAL TILEMETAL TILES
  15. Just note that I have my code working ... Shall we get into the real problem what I'm having and maybe we can find out what the error is? I'm able to load the graphics into my program correctly, but I have a strange error. "sometimes it loads, and sometimes not". The random factor is the "order of the routines" and "what routines are not commented out". Trust me, looking for weeks on this, and till today, cannot find the issue! What I'll do, if you're okay to help me searching for the real issue, is to post the programs that I have in this thread, together with all the files. I'll make a version that loads the files correctly, and one that does not load any file.
  16. So in summary, it is impossible to show the code at 00:D949?
  17. After a good sleep (I'm in Europe), I've also made an annotated video, showing you exactly what I'm doing, and what the issue is ... https://streamable.com/usd5wn Would you have any further thoughts why this is happening?
  18. Can you try this with my program pls? You'll see immediately what it does. Using F11, it does not jump into 00:d949. It seems to go over it, and shows the next statement back at
  19. Still having issue, i just cannot get this 00:d949 displayed, but you are showing it in your video ... What key are you using here at second 1:01 in your video, to do this jump to ?
  20. aha! now i see it! indeed! after a while it goes into 00:D949 ... I need to check myself. Could it be that what we see first is the routines they wrote for what we call a "far" jmp?
  21. I had a thorough look again at your video. Your video is not showing the code at 00:D949 ... Are you able to debug into that code fragment starting at 00:D949?
  22. ohh! didn't realize that! so you're saying that the debugger should be able to disassemble the 00:D949 ... well, I am unable and I really don't know what i'm doing wrong.
  23. This is what we should see when walking the code ... This is the routine in the rom of the load.s cbm code, modifed by michael steil to also support loading files into the vera etc. And this code is in bank 0! Because the kernal code is in bank 0. Bank 4 contains the Visual Basic code, and that is not what i meant here. The C procedure directly calls FFD5, and then it's impossible to see this code in the monitor. Try to go to bank 0 with d 0d949 ... And you'll see the above. This is the right code. When you type B ROM 0 (so BKO becomes 00, then when jumping to D949 nothing happens but the code seems to execute directly to the rts. But i remember something ... The monitor of the x16 seems to be derived from the monitor that was created in the final cardridge... I remember when I was like 16 years old or so, my friend had this cardridge (I envied that ...), that the ROM was not disassembled due to copyright restrictions. Could it be that this piece of restriction is still in the monitor? (That would be amazing).
  24. He hasn't been responding to me neither ... I guess he's putting his priorities.
  25. And before you consider, want to say thank you you're spending your time on this with me ... it may help other people later ...
×
×
  • Create New...

Important Information

Please review our Terms of Use