Jump to content
IGNORED

Assembly on the 99/4A


matthew180

Recommended Posts

25 minutes ago, retrodroid said:

Well that does complicate things.  I have a burning desire to not require 32KB expansion, probably some latent negative feelings towards it from when I was a kid and didn't have it then. ;)

I have nothing against GROM, however, just not sure how to configure my code to use it. The char patterns and map data could all live happily in GROMs. I'm fairly confident my game code can fit in a single 8K ROM.

 

Suggestions on where to find a tutorial or reference for configuring GROMs?   I'm using Classic99 for development, btw.

 

Look under:

GPL - Manuals/Tutorials

  • Like 2
Link to comment
Share on other sites

46 minutes ago, RXB said:

 

Look under:

GPL - Manuals/Tutorials

Okay, I found the GROM Header definition information.  So right now I'm using the following ROM? bank header for my main program:

 

* EXECUTABLE CART IMAGE

       IDT  'MSR'

       AORG >6000

       DATA >AA01
       DATA 0,0
       DATA MENU
       DATA 0,0,0,0

MENU   DATA 0
       DATA MAIN
       BYTE 13
       TEXT "PLATFORM GAME"

 

Based on the information in the GPL Manual, it sounds like I put the same header block into my GROM bank header, but minus the Program block, since it doesn't contain any executable code?

 

Link to comment
Share on other sites

1 hour ago, retrodroid said:

Okay, I found the GROM Header definition information.  So right now I'm using the following ROM? bank header for my main program:

 

* EXECUTABLE CART IMAGE

       IDT  'MSR'

       AORG >6000

       DATA >AA01
       DATA 0,0
       DATA MENU
       DATA 0,0,0,0

MENU   DATA 0
       DATA MAIN
       BYTE 13
       TEXT "PLATFORM GAME"

 

Based on the information in the GPL Manual, it sounds like I put the same header block into my GROM bank header, but minus the Program block, since it doesn't contain any executable code?

 

I have a whole series of videos and packages on that link of GPL demos called GPLHOW2 demos.

zip files and source all included along with the video that shows step by step how to do it.

Link to comment
Share on other sites

2 hours ago, apersson850 said:

If there's no code, you don't need any header either. Your assembly program running in the ROM would know how to read data from the GROM.

Okay, let's take a step back for a minute. I currently have some .asm files containing a bunch of BYTE and DATA definitions for my character patterns, sprite patterns, map definitions, etc. How do I assemble these so that the are accessible as GROMs from my cartridge build? From what I can glean there is some way to specify which GROM slot a particular file should fit into, for example. 

 

Looking through the xdt99 documentation, it clearly can assemble actual GPL programs, and you can specify 

$ xga99.py sample.gpl -g

Note that -g splits based on GROM directives, and not by size. Therefore, we must ensure ourselves that the size of each GROM does not exceed >2000 bytes.

However, I don't have GPL source files, I have .asm files containing data that I want to assemble into GROMs.

 

xdt99 also has the GROM directive:


The GROM directive sets the GROM base address for the code that follows. You can specify either the GROM number 0, ..., 7, or the absolute address >0000, ..., >e000, where bits 0-12 are ignored.

If more than one GROM directive is placed in one program, each GROM segment will be placed in a separate file, whose name is appended with the GROM address.

 

So I guess I'm looking for specific advice on how to get from where I am (.asm files) to one executable ROM (.bin) file, and several GROM files with my data?

 

EDIT> I also see that it should be possible to use ROM bank switching instead of GROMs. Would that be simpler to implement?  

EDIT2>  No, I see in http://www.stuartconner.me.uk/ti/ti.htm#bank_switching that it would require my executing code to be duplicated in each bank, which would defeat the purpose.

Edited by retrodroid
Link to comment
Share on other sites

7 hours ago, retrodroid said:

 

Quote

- cartridges that can be plugged directly into the console can provide up to 40K of GROM and up to 16K of ROM,

Is that a real restriction nowadays?

 

Depends on the hardware or emulator. My fbForth 2.x cartridge has 32 KiB (4 banks). The ROM-only boards that Jim Fetzner (@Ksarul) makes can have many more banks than that. In fact, I am toying with using a 64-KiB cartridge for my next fbForth go-round.

 

If you need GROM as well as ROM, you will need other boards (UberGROM, FinalGROM, ...), which have there own limitations, but can use far more than 16 KiB ROM (2 8KiB banks).

 

For emulators, the only one I know that limits a cartridge to 16 KiB ROM is the Win994A simulator, which I have never used because of this limitation and the fact that it is not currently maintained.

  • Like 3
Link to comment
Share on other sites

Myself I've never used GPL, so I've not used a GPL assembler. But don't they have a data directive as well? So you can specify the content of a GROM bank as data only?

 

System defined headers in ROM or GROM are there so the computer's operating system should be able to find and execute code in the different storage locations. But if you don't have code the system is supposed to execute there, then you don't need them. That doesn't say you couldn't have code there anyway, but then your program, which knows about the code without looking for headers, would have to execute it.

 

I've use GRAM as data repositories, but then it was data that was created by the program when it was running, so I didn't have to specify it with any DATA directives in any way.

  • Like 2
Link to comment
Share on other sites

Speaking of the FinalGROM 99, exclusively...

 

Using more than one type of HEADER(ROM\GROM), could confuse the menu system. That said, if you only specify a ROM HEADER, the GROM.BIN, wont even get loaded! So, if you want to use GROM/GRAM, along with ROM/RAM, best to use a GROM HEADER, and then jump to the program in ROM, if desired, by using an XML, instruction.

 

In ROM mode, FG99, can provide 128 pages, of 8K ROM.

 

In ROM\RAM mode, FG99, can provide 128 pages, of 4K ROM, and 128 pages, of 4K RAM. The ROM occupying address range >6000 - >6FFF. The RAM occupying >7000 - >7FFF. The upper/lower ranges are paged independently, so you can have code running from one page, while you switch the other page.

 

Total available memory is 1,048,576. So, in GROM/GRAM(40K, absolute) modes, ROM/RAM are restricted to 123 pages.

 

ROM/RAM data, can be loaded/preloaded easily(IMO), by using a HEX-EDITOR.

 

Want more options/restrictions/opinions?:evil:

 

FinalGROM 99, MANUAL(link)

  • Like 3
Link to comment
Share on other sites

18 hours ago, apersson850 said:

If there's no code, you don't need any header either. Your assembly program running in the ROM would know how to read data from the GROM.

Are you talking about RXB ROM 3?

XB ROM 1 and 2 are not changed much in RXB, but ROM 3 is not the same as ROM 1 and 2 as my ROM 3 is all built on subroutines not like these ROMs.

RXB ROM 3 just takes the values in Scratch Pad and uses them, it does not touch the GPL interpeter like XB ROM 1 and 2 do.

 

The advantage of this is a huge speed increase in RXB vs normal XB.

  • Like 1
Link to comment
Share on other sites

20 hours ago, retrodroid said:

EDIT2>  No, I see in http://www.stuartconner.me.uk/ti/ti.htm#bank_switching that it would require my executing code to be duplicated in each bank, which would defeat the purpose.

That may not be true, depending on what you're trying to do. I haven't been keeping up with this whole thread, but it looks like you're trying to run a multi-bank cartridge on a console with just the VDP RAM and scratchpad RAM? So let's say you have your main game loop in bank 0 and your character/sprite definitions in bank 1. What you would need, in the exact same position in each bank, is a small bit of code that handles the bank switching. So when the main game loop needs a new set of character definitions it calls the switching code which switches to bank 1 (where the processor continues executing at the next memory address in the new bank) and the code in that bank then copies the character definitions to VDP RAM then calls the switching code again to switch back to the main game loop in bank 0. You might want to use the same/similar switching code in each bank for convenience and use a pointer or similar in scratchpad RAM so the bank switching code knows where to return to. If you have map definitions in banks 2 onwards and all you needed to do was to copy the required map to VDP RAM for display then you could do that in a similar way. If however you have map data that needs to be read by the main game loop as it executes, you might be able to copy that to an unused area of VDP RAM from where the main game loop could read it, or you might be better duplicating the main game loop plus the map data for each level across a number of banks, and using scratchpad RAM to hold common data as you move between the main game loops for each level of the game.

 

You also need to handle that any bank might be active when you switch the machine on - so you need the cartridge header at the start of each bank, and your cartridge start code needs to make sure that bank 0 is selected.

  • Like 2
  • Thanks 1
Link to comment
Share on other sites

25 minutes ago, Stuart said:

That may not be true, depending on what you're trying to do. I haven't been keeping up with this whole thread, but it looks like you're trying to run a multi-bank cartridge on a console with just the VDP RAM and scratchpad RAM? So let's say you have your main game loop in bank 0 and your character/sprite definitions in bank 1. What you would need, in the exact same position in each bank, is a small bit of code that handles the bank switching. So when the main game loop needs a new set of character definitions it calls the switching code which switches to bank 1 (where the processor continues executing at the next memory address in the new bank) and the code in that bank then copies the character definitions to VDP RAM then calls the switching code again to switch back to the main game loop in bank 0. You might want to use the same/similar switching code in each bank for convenience and use a pointer or similar in scratchpad RAM so the bank switching code knows where to return to. If you have map definitions in banks 2 onwards and all you needed to do was to copy the required map to VDP RAM for display then you could do that in a similar way. If however you have map data that needs to be read by the main game loop as it executes, you might be able to copy that to an unused area of VDP RAM from where the main game loop could read it, or you might be better duplicating the main game loop plus the map data for each level across a number of banks, and using scratchpad RAM to hold common data as you move between the main game loops for each level of the game.

 

You also need to handle that any bank might be active when you switch the machine on - so you need the cartridge header at the start of each bank, and your cartridge start code needs to make sure that bank 0 is selected.

Thank-you!  That explains a lot.  I was starting to think the same thing might be possible, re: having the same small code in each bank to handle the bank switching. This makes more sense now. 

Edited by retrodroid
  • Like 2
Link to comment
Share on other sites

22 hours ago, retrodroid said:

EDIT> I also see that it should be possible to use ROM bank switching instead of GROMs. Would that be simpler to implement?  

EDIT2>  No, I see in http://www.stuartconner.me.uk/ti/ti.htm#bank_switching that it would require my executing code to be duplicated in each bank, which would defeat the purpose.

I personally would go for bank switching instead of GROM data.  With no GROM, it would then work on both FlashROM99 and FinalGROM99 carts.  Not all the executing code needs to be duplicated in each bank: only the cart header, and some bank switching trampoline functions, and any useful functions you might want to call from any bank.  I'm attaching a simple 2-bank switching example code for you to use as a reference.  The main game loop code goes in bank 0 and the graphics data and loading function go in bank 1.

 

EDIT: I read Stuart's post and realized I forgot to handle the case where it could start up in bank 1 (most emulators and FinalGROM start in bank 0 always, but other hardware may not be the case)  Now the START routine is in all banks, and uses BANK0 to switch before going the INIT routine.  Please download again.

 

 

banksw.zip

Edited by PeteE
  • Like 3
  • Thanks 1
Link to comment
Share on other sites

Just now, PeteE said:

I personally would go for bank switching instead of GROM data.  With no GROM, it would then work on both FlashROM99 and FinalGROM99 carts.  Not all the executing code needs to be duplicated in each bank: only the cart header, and some bank switching trampoline functions, and any useful functions you might want to call from any bank.  I'm attaching a simple 2-bank switching example code for you to use as a reference.

 

 

 

banksw.zip 7.09 kB · 0 downloads

Thank you!

  • Like 2
Link to comment
Share on other sites

17 minutes ago, retrodroid said:

Thank you!

I read Stuart's post and realized I forgot to handle the case where it could start up in bank 1 (most emulators and FinalGROM start in bank 0 always, but other hardware may not be the case.)  Now the START routine is in all banks, and uses BANK0 to switch before going to the INIT routine.  Please download again.

  • Like 3
Link to comment
Share on other sites

  • 4 weeks later...
56 minutes ago, Vorticon said:

Hi. Can anyone tell me what these statements do? I suspect that they relocate the start of an XB program in memory but I'm not certain...

CALL LOAD(-31890,56,24)::CALL LOAD(-31964,56,24)

 

This doesn't answer your question, but just a plug for this list (shared by @atrax27407) in another forum could be a useful reference to be added to the Development sticky and updated as other CALL LOADs are defined.

CALL LOADS.pdf

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

1 hour ago, HOME AUTOMATION said:

 

Ha! I was exactly looking at that bitmap program for XB in the French publication 99 Magazine (https://www.abandonware-magazines.org/affiche_mag.php?mag=87) issue 11 by Alexandre Amortilla! I am actually in the process of typing it in to test it out and dissect it.  I have to say that this magazine is a treasure trove of high quality articles and programs.

I'm still not clear though as to the exact function of these statements... Anybody able to explain them in a little more detail?

  • Like 2
Link to comment
Share on other sites

1 hour ago, Vorticon said:

Hi. Can anyone tell me what these statements do? I suspect that they relocate the start of an XB program in memory but I'm not certain...

CALL LOAD(-31890,56,24)::CALL LOAD(-31964,56,24)

 

-31890 = >836E is the XB GPL VDP Stack pointer

56 = >38 AND 24 = >18 so loading >3818 into >836E thus changed the location of the XB GPL VDP Stack pointer

 

-31964 = >8324 is a temporary Scratch Pad address sometimes used as a backup for the XB GPL VDP Stack pointer

56 = >38 AND 24 = >18 so loading >3818 into >836E thus changed the location of the XB GPL VDP Stack pointer

 

 

  • Like 4
Link to comment
Share on other sites

43 minutes ago, RXB said:

-31890 = >836E is the XB GPL VDP Stack pointer

56 = >38 AND 24 = >18 so loading >3818 into >836E thus changed the location of the XB GPL VDP Stack pointer

 

-31964 = >8324 is a temporary Scratch Pad address sometimes used as a backup for the XB GPL VDP Stack pointer

56 = >38 AND 24 = >18 so loading >3818 into >836E thus changed the location of the XB GPL VDP Stack pointer

 

 

Thank you Rich! So what is the usual default value of that stack pointer and what is its function?

Link to comment
Share on other sites

1 hour ago, Vorticon said:

Thank you Rich! So what is the usual default value of that stack pointer and what is its function?

XB normal stack address is 2392 or >0958 

 

RXB has a command CALL VDPSTACK(address) so you can move that stack where you want.

I did this so you can run support like TML without having to run a LOAD program to do this.

Link to comment
Share on other sites

3 minutes ago, RXB said:

XB normal stack address is 2392 or >0958 

 

RXB has a command CALL VDPSTACK(address) so you can move that stack where you want.

I did this so you can run support like TML without having to run a LOAD program to do this.

So basically those CALL LOADs are moving the VDP stack to the low expansion memory?

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   1 member

×
×
  • Create New...