Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by SerErris

  1. LOL another # issue (LDA #<address is different then LDA <address (which works btw) but obviously not with the right content.
  2. Yep, still getting used to it ... not as comfy as my old sofa ... but I am getting there
  3. I still cannot figure out, why LD does not put the load address to the beginning of the output file. From verbose output it looks like cl65 is allways linking the cx16.lib to it (which most likely contains the startup routines ... ) ld65 -v -o LOADER.PRG -C cx16-bank.cfg loader.o ship.o cx16.lib ... but again figuring out in the cx16.lib source code how it is done ... not possible for me. /EDIT: But for now I am sticking to cl65 I am coming more and more to the conclusion that cc65 is great for C and simply completely overshoot for assembler and does not add anything to ACME other you can have multiple files ... The later is somehow great as you can simply collect some functional stuff in individual files, however also risks to overshoot with to many files and the complete code becomes unreadable. The only thing that is great is that you do not think about placing of stuff anywhere in the memory as that is automatically done and you do not waste a single byte...
  4. Okay I played around with it a little bit more. I stripped down my .cfg to that (please find attached) x16-asm.cfg I have setup the following code, that should from my understanding give me the right output: .export __LOADADDR__ = $0801 .segment "LOADADDR" ; .word $0801 ;this has been uncommented and was not there in the original file .. this is the workaround .segment "EXEHDR" ;put BASIC start into program file (SYS 2061) $80E .byte $0b,$08,$0a,$00,$9e,$32,$30,$36,$31,$00,$00,$00 .segment "CODE" ldx #$00 ;initialize index loop: lda hellostring,x ;Load character from string I compiled it with: ca65 -t cx16 hello.asm ld65 -C x16-asm.cfg -o HELLO.PRG hello.o However it does not .. (at least I found a way to set a Symbol that LD does not complain anymore). The output looks like that (please see the first two bytes, that should read 01,08 ... however that is actually my first basic byte loader ($0b,$08...). The result is obviously, that the LOAD" command in X16 loads the code to $080b and not to $0801. The __LOADADDR__ is never used anywhere in the .cfg file - but needs to be there otherwise the ld complains about a missing symbol and the two bytes required in the header of the PRG file are simply not getting inserted. I found this workaround which is putting the word $0801 simply in the code (uncommenting it). That will create the correct load address .. So what is going wrong? Should the __LOADADDR__ not have instructed the linker to add the two bytes to the file? It looks like the linker does not add the loading address (or Startaddress) to the PRG file at all.. IT links the code to the correct STARTADDRESS however. Here for convenience the relevant sections of the x16-asm.cfg again (removed the banks for simplicity here): FEATURES { STARTADDRESS: default = $0801; } SYMBOLS { __LOADADDR__: type = import; __BANKRAMSTART__: type = export, value = $A000; __BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM } MEMORY { ZP: file = "", start = $0002, size = $FF-$02, define = yes; LOADADDR: file = %O, start = %S - 2, size = $0002; MAIN: file = %O, start = %S, size = $D000 - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = rw; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; BSS: load = MAIN, type = bss, optional = yes, define = yes; } Last point: If we look here again, you can see my "HELLO WOLRD!" String that starts from $1F. As you can see it is totally garbled and not PETSCII code. I tried .asciiz and .byte ... both lead to the same result. I used the -t cx16, which should lead to PETSCII code instead ... any Idea? /EDIT: Same issue with the RAM bank (e.g. my models) It is missing the two bytes of the loader address (should be $A000) to my understanding... But it is simply missing.
  5. A hardware reset (that is actually pulling the resetline up) will also reset the banking to default (like you power on). Reset not working was a software reset. And that might be the same issue. If you call the reset routine and you do not see the KERNAL rom, then you will be out of luck ... The procedure you created is the save method of calling a reset, yes.
  6. Hi all, thanks for all your input. A lot of stuff to digest. Sorry for that very long post. I really try to work my way into cc65 environment as it has been said to be the go to solution for development on X16. I have to admit that I do not understand a lot based on the documentation. It seems like none of the documentation is actually written with pure assembly in mind. I have now invested a lot of hours trying to learn how it works and even with your input here I cannot figure it out yet. So please forgive me for those questions and the long wordings around it. I do not have any better way to ask them or to find my way through. If you have a better way to get this asked and answered or have a tutorial for CC65 specifically focussing on pure assembler (does not have to be X16 related) then please let me know. So now on to my questions Regarding Question 1: the ZP assignment of the two segments we have in there: I understood - there is no automatic way to let the linker assign the variables to addresses if you grow out of one of the two ZP areas. Doing it manual is obviously a way, but I thought there would be a automation. So then I can just setup the ZP as the full segment (e.g. $02-$FF) to define ZP addresses and manually do the split at the point when it runs out of the 1st ZP range. I am will put in a debug output to help to find that specific point in my source code ( .out sprintf("Symbol Name %04X",SYMBOL) ). Regarding Question 2: I will check again if it creates a file .. but as I have it in a source file on its own, I believe it would need to create at least an object file, otherwise the exporting of symbols would not work? The other question was, how I can define the Symbols in a way that the assembler/linker calculates corresponding addresses. I stumbled accross the include file for the KERNAL roms where it is managed by setting the first address (e.g.$02) and from there let the assembler calculate the variables - so no .res statement, but SymbolY=SymbolX+2. I would then just include that file into every source file to have those symbols available. This method would also remove the need to export all the variables. However I will continue to try the .res x method with labels to understand if that works (or maybe works better). Regarding Question 3-5: Got those points. I still quite do not understand all the stuff in the .cfg files esp the __SOMETHING__ directives or keywords ... Things I do not understand: First: Where do I get __LOADADDR__ from? I do not have any C in there and also do not use cc65 and want to be able to use ca65 and ld65 instead of cl65 ... so how or what do i need to put into my .asm files to get __LOADADDR__ populated and avoid that the linker complains about this unset symbol? I tried .org $A000 .export LOADADDR = * But that did not remove the error from ld65 ... Second: How to use the .segment statements in the .asm files? I have seen the Hello-World.asm from Matt. .org $080D .segment "STARTUP" .segment "INIT" .segment "ONCE" .segment "CODE" Questions: 1. Why do we have the .org instruction in there? Should the linker not automatically place it? 2. All that .segment statements ... What are they for? I simply cannot get my head around what the logic behind it. To my understanding the first three do nothing as the .segment control command just switches the segment. Correct? So the first three .segment statements just can go away? and the only relevant .segment is "CODE" ? Third: @Greg Kingreading your cx16-bank.cfg I still see a lot of C stuff in there. And for some of the parameters I have no idea how to produce them: Looking at this section from SYMBOLS { __LOADADDR__: type = import; __EXEHDR__: type = import; __BANKRAMADDR__: type = import; __STACKSIZE__: type = weak, value = $0800; # 2K stack __HIMEM__: type = weak, value = $9F00; __BANKRAMSTART__: type = export, value = $A000; __BANKRAMSIZE__: type = weak, value = $2000; # 8K banked RAM } Similar to __LOADADDR__ how do I define __BANKRAMADDR__ and what is it used for? It is never referenced anywhere later on. Only __BANKRAMSTART__ and __BANKRAMSIZE__ are getting used later on. Also __EXEHDR__ What is it? Do I need it for assembler? The next section is giving me questionmarks: MEMORY { ZP: file = "", define = yes, start = $0022, size = $0080 - $0022; LOADADDR: file = %O, start = %S - 2, size = $0002; HEADER: file = %O, define = yes, start = %S, size = $000D; MAIN: file = %O, define = yes, start = __HEADER_LAST__, size = __HIMEM__ - __HEADER_LAST__; BSS: file = "", start = __ONCE_RUN__, size = __HIMEM__ - __ONCE_RUN__ - __STACKSIZE__; So MAIN is depending on __HEADER_LAST__ which is again not defined anywhere. BSS what is that? And another symbol in here with no definition (not getting imported or anywhere else from) __ONCE_RUN__ . And then the segments ... I do not even know where to start: SEGMENTS { ZEROPAGE: load = ZP, type = zp; EXTZP: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = HEADER, type = ro; STARTUP: load = MAIN, type = ro; LOWCODE: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = ro; RODATA: load = MAIN, type = ro; DATA: load = MAIN, type = rw; INIT: load = MAIN, type = rw; ONCE: load = MAIN, type = ro, define = yes; BSS: load = BSS, type = bss, define = yes; I understand ZP and CODE, I understand DATA - it is just there to differentiate CODE from DATA in Memory blocks (not BANKs). I do not understand all the rest. Is it at all relevant for programming in Assembler, or can it get simply removed? This is from x16-asm.cfg: FEATURES { STARTADDRESS: default = $0801; } SYMBOLS { __LOADADDR__: type = import; } MEMORY { ZP: file = "", start = $0002, size = $00FE, define = yes; LOADADDR: file = %O, start = %S - 2, size = $0002; MAIN: file = %O, start = %S, size = $D000 - %S; } SEGMENTS { ZEROPAGE: load = ZP, type = zp, optional = yes; LOADADDR: load = LOADADDR, type = ro; EXEHDR: load = MAIN, type = ro, optional = yes; CODE: load = MAIN, type = rw; RODATA: load = MAIN, type = ro, optional = yes; DATA: load = MAIN, type = rw, optional = yes; BSS: load = MAIN, type = bss, optional = yes, define = yes; } That looks much more assembler to me and I would assume I just need to add the Bank information there, correct? Bank switching is anyhow something I need to handle myself in my code. Still I have BSS which I do not understand what it is - but I could ignore it as it is optional. So I just would need to place segments into banks and let the linker create multiple files (one for the CODE) and one for each Bank. Is that a correct understanding?
  7. It is just the extension .. it does not really live anymore .. (the github page does not exist anymore) and is pretty much outdated. You even need to download a very old .net integration to get it running at all. And you cannot change the name of the .prg file - it needs to be named as TEST.PRG. So I will now switch as well to Atom as I hope that it is better customizable (e.g. more open or at least easier).
  8. Hi, I am working on a larger project and need to understand better how the structuring in files and the placing in memory works. The project will be a pure assembler project and also will not use any BASIC operation. Question 1: I will need to define a lot of variables inside ZP. As far as I understood I can use $02-$7F and $A9-$AF. How do I need to setup the cx16.cfg ZP directive, that it does automatically assign the bytes to the allowed windows? This does work (e.g compiles) to enable more ZP bytes then the normal $20-$7F ... but it obviously would just overwrite $80- $A8, which is unsave for the Kernal and might crash the machine (makes kernel functions unusable). Question 2: Maybe related to the first one: As I do not know how many variables I will have and may want to change them during the development process and they all have different length, I want to use the .res statement to define the length of each variable and using labels to get the symbols for the addresses of each ZP. I did something like that: As my ZP segement starts @$02 ZP will point to $02 as well as RAND and TRPTB will point to $06. My issue with that is, that the compiler will actually create code and place it into memory after loading. Is there any other way of automatically (in opossition to calculate everything manually) define some symbols (e.g. memory addresses) but not get it actually compiled into the source code? I can see the EXTZP segment in the cx16-asm.cfg ... but what does it mean? It has not been defined. Also I do not understand how to load things like LOADADR correctly. It is getting imported... from where? That brings me to my question 3: I like to have a main PRG file (e.g. loader) and some .bin files that keep individual parts of the real program, such as models or math library or main loop etc. From the file structure I do understand how to create multiple source files and exporting symbols I want to use from outside. However how do I instruct the assembler/linker to create a .bin file out of a given object file? Lets assume I want to have the following three files out of the input files: Loader.s => LOADER.PRG math.s => GAME1.BIN models.s => GAME2.BIN mainloop.s => GAME3.BIN Question 4: Also I want to instruct the linker to put the GAME2.BIN @$A000 to be able to use it in a BANK. How can I use multiple BIN files using the same address space, as they are all sitting in BANKS (so all starting with $A000?) Question 5: How do I get all this together, that all the parts can be loaded to the corresponding RAM areas? (I am not talking about the Loader here, but how does the linker get the correct addresses to math.s and how do I get those addresses to get my loader right (e.g. prepare the right bank before loading it). I would be interested in a good documentation, that goes into those details to understand much better the building process. I see you heavily using it for the KERNAL but even there I do not even understand were it starts and how it works. The official documentation does not go into any detail on that - it is a good reference, but not very good to learn.
  9. Using vs code the first time in my life. I agree the make process will most likely work. The run portion also need something that I can call an external program and using a parameter (e.g. what is the PRG file from the makefile? I can potentially create a small ps script and populate it, as it will contain always the same prg file and I always could call it run.ps1 or something. That should do this trick. What do you use for atom syntax highlighting of the ca65 assembler in Atom? As VS Code is anyhow just another Atom clone I might want to go the opensource route...
  10. I am looking into that option now but have issues to get it to work. I have cc65 running, I have Visual Studio Code and I use "cc65 for 6502/65816 machines" by SharpNinja as an expansion. However I cannot get VS Code to build anything. It never understands that it shall use cc65. Instead it asks me to tell VS Code what compiler to use. Is there anything I need to configure in the workspace for it to work?
  11. Yes, you just need to setup CYGWIN in your Windows PATH variable. For me that is D:\Development\cygwin\bin ... after that you can run anything that has been compiled under cygwin just from cmd window. As I said - developing inside Linux would be the last option. It is simply to much back and forth for me. Also I am not looking for running it manually, I am looking to get it fully integrated into VS Code. There is a plugin for CC65 and also a integration into vice (it just runs the emulator with some commands), so that should work with x16emu as well. However it does not work like that - I could not get VS Code to compile it with CC65 it is looking for a compiler/assembler to do the work and does not understand the CC65 plugin stuff or does not link it to the workspace
  12. I have found out, that you are actually not using VS Code and also do not have any build run integration. You have a manual build and run process (e.g. create a Makefile and than run make command in cygwin). That works - no doubt. But I am looking for the integrated solution.
  13. Hi, what editor do you use? I am trying to integrate it now in Visual Studio Code. I am working on Windows - I potentially could switch for the complete development to Ubuntu in a VM, but would like to keep everything in the same place. For now all the stuff is sitting in Files on my Windows part. So worked through your instructions and setup the cygwin and the cc65 inside cygwin. I also created a link from my home directory to the working directory. All great. I have installed Visual Studio Code and were able to create a link to the cygwin shell (works great). I downloaded the CC65 integration (cc65 for 6502/65816 machines from SharpNinja) from the marketplace. But where I now struggle is to link the cc65 compiled under cygwin to Visual Studio Code. Main reason: I need to call CC65 within the cygwin environment because of the cygwin libraries required. I cannot just run the ca65.exe for instance as it will not find the cygwin libraries if I am not in the cygwin environment. Any idea how to get this integrated? /Edit: got one step further - it is important for the CYGWIN environment that you setup the Windows PATH environment variable .. Then the cygwin.dlls could be found and you can run ca65 from a windows cmd window ... Cracking on with the integration into CS Code
  14. I am really considering now to port it to X16 ... It is still a huge endeavour ... but it is getting possible now.
  15. This is what Ian Bell and David Braben created (explained by Mark) This is just the summary, In the source is following long and long discussion on the details of that.
  16. Actually there was some recent and monumental work on documenting the original assembler of the BBC ELITE. The great stuff is, the BBC computer had a 6502 as well and all the MATH code and all the graphics code could be reused simply. Obviously the draw routines need rework (e.g. the screen setup and output) and the sound as well. But if you ignore sound for now, and adapt the draw routines for the Vera, it should be possible to get the start screen working - e.g. your spinning ship with line removal This is two masterpieces .. the longer I look at the Elite Source code ... wow ... and those guys were still in school or university at that time. And the comments is another masterpiece. I never have seen a better commented source code with actual explanations on how the engine worked. That includes all the math routines, how the backface culling works and alot of that stuff. It also completely explains the main game loop, how it works and so you can learn a lot by reading this. The commenting has been done by Mark Moxon (of cause with a lot of help by others). https://raw.githubusercontent.com/markmoxon/elite-beebasm/master/sources/elite-source.asm This is the original definition of a MK3 btw:
  17. You can switch the charset to one, that has upper and lower cases in a single set. And then you can do that. Regarding the amount of text ... we have 512k of memory for that ... quite a huge amount of text. Paired with loading from disk you can have even more text. .. But in reality ... look at what Elite did ... They generated the text from some phrases and put it together to look unique for each Planet etc. pp. so that is then generated text with pseudo random generators.
  18. Actually it is both... I have described it in another thread here. the screenram layout should change .... move the charrom to the End $1F000 and move layer 0 to $04000 ... I I’ll suggest it as a Pullrequest for the kernel
  19. And with very little change, you can get 00 terminated strings. This gives you a string routine that can print strings of any length between 0 and 255 bytes. org $1000 LDX #$00 ;set string position to 0 .loop LDA $1500,X ;read byte from string @position BEQ end ;if Value is 00 end JSR $FFD2 ;else ... print char INX ;next character in the string BNE loop ;jump back as long as X is not 0 again ... (means max string length is 256 bytes including the termination string). .end RTS org $1500 !byte $48,$45,$4C,$4C,$4F,$0D,$00 ; "HELLO<CR><STRTERM>" If you put it directly into the monitor, you need to first assemble the stuff with some placeholder addresses and then check for the correct addresses of loop and end to insert the correct address in the BEQ and BNE commands. Or you use ca65 ... or any other assembler, it does it for you.
  20. No it is actually two parameters, and they can work idependently. So you can set hscale to 64 and get 320 and vscale to 52 (as far as I remember from my old brain) and that gives you 200... So you have a resolution of 320x200. So you can scale to any value. I have not tried myself what happens if you scale to anything between 64 and 52 ... Regarding the number of characters per Row... that is also affected by vscale and hscale.. 128 for hscale equals 80 characters. Where 64 equals 40 characters and so on... 16 would equal 10 characters AFAIK (not 100% sure) you can only scale the whole VERA. That means, you cannot scale the two layers with differenet scaling parameters.
  21. Line 20 is the VERA reset. In my case that was the only way to reset the Palette and all pointers to where they belong (I moved the tilebase etc.). You can try without the VERA reset. Maybe it is enought in your case. The above resets the screen to the original setup after startup.
  22. lol .. @Fnord42 is right .. max is by all means 640x480. but other than that you are pretty free to play around with the scalings ..
  23. @Greg King answered that in this thread: Where I had pretty much the same issue: Here is the answer. My issue was even a little bit bigger (reset the palette and stuff), but if you just want to get back to a blank text mode screen that is what works. 10 SCREEN $80 20 POKE $9F25, $80 30 SYS $FF81
  • Create New...

Important Information

Please review our Terms of Use