Page 3 of 3

Re: Bulkding banked code questions

Posted: Thu May 17, 2018 12:54 am
by Alcoholics Anonymous
--exclude-sections CODESWITCHING
Ok I've misunderstood what you were doing! You are making your own section "CODESWITCHING" and putting some c code there. You can do this but you have to make sure you add new sections to the memory map so that the linker knows where it's supposed to org to.

So we'll do something a little more advanced.

Add this to your zpragma.inc file:

Code: Select all

// append to the memory map from file "mmap.inc"

#pragma output CRT_APPEND_MMAP = 1
Next create a file "mmap.inc" to define your new sections:

mmap.inc

Code: Select all

SECTION CODESWITCHING
org 0xc000
Now the "--exclude-sections CODESWITCHING" where the sna/bin/tap/etc is built is what you want. Anything in this section will not be processed and will only be output as a raw binary. And this you can load as you were doing.

So that was a bit of detour and thinking outside the box on your part :) But the method of placing such data into the sections z88dk already defines to represent memory (BANK, PAGE) would allow z88dk to automatically process that data and check if stuff overlaps.
In the bankSwitchTest.map file there is a line for "_displayBank3Function = $C000 ; addr, public, , displayBank3Function_c, CODESWITCHING, displayBank3Function.c:4" so I assume it has the correct symbol.
By printing the address of the function it is indeed 0xC000 so my next dilema is why its crashing immediatly on calling this
This I think I know the answer to. When things don't make sense I always ask "where are the interrupts going" (z88dk's crts disable interrupts by default) and "where is my stack?". I have this list because I am frequently caught by it :) The answer to the last question is at address 65368 by default. That's in the top 16k so I am thinking you are paging out the stack and that's what's causing the crash. A "#pragma output REGISTER_SP = 0x8000" (or similar) will let you move the stack someplace out of harm's way.

Re: Bulkding banked code questions

Posted: Thu May 17, 2018 8:24 pm
by Bagpuss
All I can say is "woooo hoooooo"
Many thanks.
I think I was close but trying to sort out what was errors from my understanding was taking some time.
I was having a bit of a problem with the CODESWITCH and CRT_APPEND_MAP so I did the following:
#pragma output CRT_ORG_PAGE_30 = 0xC000
#pragma output CRT_ORG_PAGE_31 = 0xC000
#pragma output CRT_ORG_PAGE_32 = 0xC000
#pragma output CRT_ORG_PAGE_33 = 0xC000
#pragma output CRT_ORG_PAGE_34 = 0xC000

The --fullsize was sorted by the compilation, what I didn't realised was that the linking and create app phase understood the banking and wrote .bin files out accordingly.
All works great now. Just thinking of somewhere to put it as an example for future reference :)

Re: Bulkding banked code questions

Posted: Fri May 18, 2018 2:59 pm
by Alcoholics Anonymous
Great! Yes appmake understands zx next banking for BANK,PAGE,DIV and (not fully implemented) RES.

Re: Bulkding banked code questions

Posted: Fri May 18, 2018 6:50 pm
by Bagpuss
Cool. Thankfully I'm about an hour in restructuring now. Moved a lot of code as it was broken down into quite a lot of C files to start off with.
Many thanks for the help.

Re: Bulkding banked code questions

Posted: Sat Jun 02, 2018 4:42 pm
by EtchedPixels
For FUZIX I decided messing around with bank logic by hand was just too much hassle so I patched SDCC to do some of the work and wrote a rather nasty link tool to put the bits in the right places. It requires data is in common space (unless you insist on being clever) because otherwise you need 24bit pointers in C and that's just icky all round.

The compiler generates push af call func pop af, and the link tools magically turn interbank links into call __bank_a_b defw func. The extra push/pop leaves you space for the banking routines to work and the only other hard case is things like tables of function calls. For those the linker knows how to generate stubs so that the C sematics of if (func1 == func2) remain correct, and far calls work.

I've not taught the linker to do automatic layout although it woudn't in theory be too hard to do the job ok.

Re: Bulkding banked code questions

Posted: Sun Jun 03, 2018 4:46 pm
by Alcoholics Anonymous
At some point we'll be doing automatic linking of large programs, perhaps with some algorithm that can distribute code and data to minimize banking and make intelligent decisions about what code should be duplicated (or can be duplicated) to avoid banking. But the tools for manual banking have to be solid first.

The handling is quite good in z88dk now but there are still a couple of issues that need solving, one of the primary ones being we don't currently have a scalable method to define memory maps. The library code is separated into modules (heap allocation, block allocation, obstack, abstract data types, stdio, string, math, etc) and placed in independent sections so that the user can take control of placement of library code in memory if he wants it. That means there is a proliferation of SECTIONs in the memory map (SECTION being z80asm's equivalent of .AREA in sdasm) so making a completely custom memory map involves copying all these sections into a new memory map which can be intimidating (even if it's easy) and error-prone since new sections may appear for new modules added to the library. The proposed solution we have is simple - the memory map should accept wild-carded section names. So you can say put all "code_*" sections here unless there is a more specific match for the section name.

This also affects 3rd party library code. There is a 3rd party library code manager in z88dk ("z88dk-lib") that can install and uninstall 3rd party libraries. These libraries are compiled into sections and code from the library is placed in memory according to the user's memory map which says where those sections go. Ideally the 3rd party library names its sections uniquely as in "code_spritelib_XXXX" where XXX may be a signature, author name, whatever. Then the user can add that section to his memory map but right now this might entail making a complete memory map from scratch (it depends if the sections can be appended to the memory map rather than requiring insertion). 3rd party libraries are only recently being discovered by some people and what they've done is placed their code and data in standard user sections that are already in the "main binary" of the memory map. "code_user", "data_user", etc. But this means the code can't be moved into other memory banks. The current solution is to use another of z88dk's tools zobjcopy to change the section assignment of the 3rd party code to something else in the user's memory map, like another memory bank.

Anyway before the automatic placement is attempted, these other things should be solved. Then with automatic placement a couple of more things need to be defined like defining islands in memory that can't be placed into, and so on.

But for code that takes over the machine, I personally prefer having full control without automatic banking as it is now.

NextOS introduces another complication in that it has a page allocator built in. This means programs can be loaded and left running when they exit so that TSRs, drivers, etc can co-exist with the system and basic which is the primary interface to the system. To make use of this, the loader has to allocate pages the program gets loaded into and needs for workspace and it must write those pages into a table of logical to physical page mappings inside the loaded program. The loaded program must then use this table when it does any banking. This is within z88dk's capability now so we'll be doing that one too.


BTW, relevant to fuzix is how banked relocatable code can work. SymbOS does this for the z80 :- it generates multiple banks of code into a single binary ORGed at 0 that is segmented with pointers to the start of each segment. Then the linker can supply relocation data for the org 0 monolithic binary. As the SymbOS loader patches the binary and moves the pieces into available ram, it looks at the original (org 0) address, finds out what segment the patch applies to and adds a different offset depending on where that segment gets placed in ram. Anyway, in case you hadn't seen it. There are bugs in SymbOS's relocation that will cause it to fail but those bugs go away if everyone agrees that relocation only happens in steps of 256 bytes.

Re: Bulkding banked code questions

Posted: Mon Jun 10, 2019 10:40 am
by gskronn
Old thread, I know. Still: I'd like to take the opportunity to send a hearty THANK YOU to all contributors, especially to Alcoholics Anonymous. Just successfully converted my project to a paged memory model and the information found in this thread was absolutely key to getting it all to work. Thanks!

Cheers,
Gerhard