Jump to content
IGNORED

"Sierra Maestra", an Early WIP


vidak

Recommended Posts

I realised after making the map that I could randomly generate a maze, but I think I will stick with a static world because the bosses and overall game progression would not really change

 

I would recommend that. Having a really good map that plays well (and a large one at that!) is better than only random maps every time. And if you want to implement a "random" gamemode option later, you could still do that.

Link to comment
Share on other sites

  • 2 months later...

Would someone be able to explain F4 bank switching to me?

 

I think I will include some how-tos on my blog about how to set it up. From looking at Stay Frosty, I gather the following code is meant to use used:

====

    MAC JUMP_TABLE ; put this at the start of every bank
    RORG $F000

InitSystem
    cmp SelectBank8   ; inits system then goes to the menu
    jmp Label   ; jump to Main Menu
Kernel
    cmp SelectBank7
    jmp KernelCode
OverScan
    cmp SelectBank8
    jmp OverScanCode

=====

    MAC BANKS_AND_VECTORS ; put this at the end of every bank

    RORG $FFF4

SelectBank1 .byte $00
SelectBank2 .byte $00
SelectBank3 .byte $00
SelectBank4 .byte $00
SelectBank5 .byte $00
SelectBank6 .byte $00
SelectBank7 .byte $00
SelectBank8 .byte $00
    
    .word InitSystem ; NMI and 8 overlap NMI
    .word InitSystem ; RESET
    .word InitSystem ; IRQ
    
    ENDM


; Define a segment for code
    SEG CODE
	
; - bank 1

    ORG $E000
    JUMP_TABLE
    
; bank 2

    ORG $F000
    JUMP_TABLE

My question is - I want to use all eight 4K banks, and Stay Frosty only uses two.

 

I include BANKS_AND_VECTORS at the end of every bank.

 

I assume I must include a different ORG vector/statement that is not $E000 or $F000 for the other banks, but what locations do I give?

Thanks in advance!

Link to comment
Share on other sites

okay these are my efforts for today:

 

  • extending the random number generator to 32 bits, from 16 bits
    • I will be reducing the RNG to 24 bits, because I didn't understand the combinatorial choosing. I only need to choose 4 x 6 bits = 24 bits. 24 Choose 6 = 134596, and 134596 > 2^16 / 64k. 2^6 = 64, which means I can include 64 unique objects in the world.
  • Extending the random number generator to 32 is still possible while drawing a (synchronised) blank frame in order to make up time for calculation of an entire row of 256 cells.
  • So I should now be able to ensure a good degree of randomness in a 256 x 256 world. This is what I really wanted to do.
  • Started implementing bank switching. I will be using F4 bank switching. I may not need to use every bank.
    • Bank 1 = System Initialisation + Titlescreen + Menu
    • Bank 2 = Vertical Blank for Overworld (Processing Map Coordinates, Joystick + NPC movement, Frame skip logic, Overworld RNG logic)
    • Bank 3 = Overworld Kernel + Graphics (64 x 25 bytes graphics ~= 1.6k ROM)
    • Bank 4 = Overworld Overscan (Overflow for vertical blank)
    • Bank 5 = Vertical Blank for Battle Kernel (Processing Joystick, NPC movement within Battle mode)
    • Bank 6 = Battle Kernel + Graphics
    • Bank 7 = Battle Overscan (Overflow for vertical blank)
    • Bank 8 = Empty at the moment
Link to comment
Share on other sites

Glad you are back, long time no see!

 

That bank select table should look like this:

    ORG $1FF4
SelectBank1 .byte $00
SelectBank2 .byte $00
SelectBank3 .byte $00
SelectBank4 .byte $00
SelectBank5 .byte $00
SelectBank6 .byte $00
SelectBank7 .byte $00
SelectBank8 .byte $00
    
;   .word InitSystem ; NMI and 8 overlap NMI (SO THIS MUST BE COMMENTED OUT!)
    .word InitSystem ; RESET
    .word InitSystem ; IRQ

The data written to $1FF4 - $1FFB can be anything. You can't store anything important there, because accessing those addresses in any way (even with the program counter) will trigger a bankswitch. That's what the CMP instructions do, they trigger the bankswitch. However, it is better to use NOP instead of CMP, since it doesn't corrupt any of the CPU flags.

In my example above, I am using an ORG point of $1FF4 for the bankswitch hotspots, but you can use any of the 8 mirrors (1Fxx, 3Fxx, 5Fxx, 7Fxx, 9Fxx, BFxx, DFxx, or FFxx). It isn't neccesary, but many people put each bank in its own "mirror" of ROM, so that every label is guaranteed to be unique. The important thing is to make sure that you are outputting the correct number of bytes for each 4K bank.

 

In my project, I am starting with an ORG of $0000 and an RORG of $1000. In the next bank, I use an ORG of $1000 and another RORG of $1000 (although you could use $3000 to keep all the labels unique). I don't know if the ORG's are really neccesary, but the RORG's are important.

 

Here are the macros I am using:

; <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
; Bankswitching Jump Table
;
; Define starting address of bank and include the bankswitch jump table
; Placed at the start of each bank
; <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>

	MAC START_BANK
	
	SEG BANK_{1}
	
	ORG [{1} - 1] * $1000
	RORG $1000
	
	SUBROUTINE

JmpSystemClear
	nop SelectBank1
	jmp SystemClear
JmpSomeOtherAddress
	nop SelectBank1
	jmp SomeOtherAddress
JmpEtCetera
	nop SelectBank2
	jmp EtCetera
	
	ENDM

; <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
; End of Bank
;
; Placed at the end of each bank to set the system vectors
; <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>

	MAC END_BANK

	ORG [{1} - 1] * $1000 + $0FFA
	
	.word JmpSystemClear	; NMI
	.word JmpSystemClear	; RESET
	.word JmpSystemClear	; IRQ
	
	ENDM

The way I add the banks is by having a main file that does nothing except include your project header files and each bank:

	PROCESSOR 6502
	
	include vcs.h
	include macro.h

; <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>
; Include 4K banks
; <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>

	START_BANK 1
	include Bank1.asm
	END_BANK 1
	
	START_BANK 2
	include Bank2.asm
	END_BANK 2
	
	START_BANK 3
	include Bank3.asm
	END_BANK 3
	
	START_BANK 4
	include Bank4.asm
	END_BANK 4

This makes it very easy rearrange banks if you need to, you can just change the include files for the banks.

 

As I said before, the data in the hotspot locations is not important, and if you include the hotspot labels in every bank, you will get errors from redefining existing labels. So instead, I like to define the hotspot labels like this:

SelectBank1 equ $1FF4
SelectBank2 equ $1FF5
SelectBank3 equ $1FF6
SelectBank4 equ $1FF7
SelectBank5 equ $1FF8
SelectBank6 equ $1FF9
SelectBank7 equ $1FFA
SelectBank8 equ $1FFB

I know this is probably overkill on the information, but what can I say, I have missed you!

Edited by JeremiahK
Link to comment
Share on other sites

far be it for me to prefer someone else's code over SpiceWare's... but i actually like yours better!

 

what's your new project on? you've obviously finished nyancat haven't you!

 

my email/XMPP is always open!!

Edited by vidak
Link to comment
Share on other sites

far be it for me to prefer someone else's code over SpiceWare's... but i actually like yours better!

 

Thanks, it's based off of SpiceWare's method posted here and Thomas Jentzsch's posted here.

 

what's your new project on? you've obviously finished nyancat haven't you!

 

 

I wish! No, I'm still working on Nyancat. I wrote a nice full-screen cat-and-rainbow kernel for the main menu, but I have since taken a bit of a break from that project to work on a 512 byte compo entry for the Nordlicht DemoParty.

Link to comment
Share on other sites

Okay hopefully I have understood this correctly:

 

ORG and RORG stand for the 'origin' in the address space for the 6502/6510 processor.

 

RORG stands for 'relocatable origin', and is more powerful than ORG. ORG just stands for 'origin'.

 

The way they work is like this:

 

- Every processor has a memory address space. The 6502 has a 16-bit address space, whereas the 6510 has a 12-bit address space (why is not important here).

- The processor loads instructions, or accesses RAM, or controls video cards by recieving or sending data to different address locations.

- Here are some address locations: $0000, the top of memory; $FFFF, the bottom of memory, also known as the top of the stack; $80, or $0080, the top of the RAM in the Atari 2600.

 

The importance of the commands ORG and RORG is to sort of 'virtually' control where the CPU thinks it is addressing. So you have the 'real' origin, then you have the 'controlled' origin which is determined by RORG and ORG.

 

Remember the address space of the 6510 in the 2600 is 12-bit, which means it can only access $0000 to $0FFF. But we have the ability of compiling code beyond these limits. What you can do to sort of 'simulate' address spaces bigger than 12 bits is use RORG to relocate the memory address location $0000 to a different place.

 

So when you write: RORG $1000 you are relocating the apparent location of $0000 to $1000 in the memory address of the ROM. So the processor thinks it is at $0000 but actually it is executing from $1000.

 

The same goes for RORG $1FF4, RORG $FFFB etc. All of these commands make the CPU actually execute from $1FF4 or $FFFB, but the processor will think it is executing from $0000.

 

Now what about ORG?

 

It would be irritating to have to be guessing where you were within a RORG 'jump'. You can shift within a 'virtual' RORG by using ORG. Here's an example:

 

RORG $0000 (or REND)
ORG $1000

Here we are executing from the REAL top of memory, so the origin is the REAL origin, and then we jump to $1000 in memory. So we are executing from $1000 in reality, and the processor THINKS it is executing from $1000.

 

Another example:

 

RORG $E000

ORG $0300

 

Here we relocate the virtual address $0000 to $E000, and then we jump to $0300 within $E000. So the processor is in reality executing from $E300, but the processor thinks it is executing from $0300.

 

==

 

Why is this useful?

When it comes to bank switching, you must use RORG to shift the apparent/virtual memory address because your overall code may be 16K, 8KB, or say 32KB. The 6510 can only address 4KB of memory because of the way it is manufactured (I predict there will be some arguments about it actually being able to address 8KB, but I am just going to wait for someone else to address that), so you need to make sure it thinks it is executing within addresses $0000 and $0FFF, otherwise you will be addressing memory it absolutely cannot access.

 

I have read 80% of the Stella Mailing List, and I never saw this come up, so hopefully this helps someone.

Link to comment
Share on other sites

Okay today I implemented the bank switching.

 

I think this makes my data structures much more parsimonious.

 

don't forget to check out where I keep my code: github.com/bootlicker/guerrilla-game

===

 

Things I still need to do in this phase are:

- write out the debug graphics into the kernel

- finish implementing the 24-bit Random Number Generator

- link the RNG and the Environment Graphics pointers

InitSystem.asm

OverworldVB.asm

che_main.asm

Link to comment
Share on other sites

  • 3 weeks later...

Alrighty.

 

I put a couple hours in today.

 

Today I:

  • Changed the random number generation to 24 bits
  • Linked the random number generator to the environmental graphics indexes (generator creates FOUR 6-bit numbers which are stored in memory as indexes)
  • Linked the indexes to the environmental graphics pointers (i.e. a 6-bit index will randomly select one graphical shape out of 64)
  • Created the pointer indexes for the environmental graphics (created a table of 64 pointers)
  • Created all the debugging symbols (Numbers 00 to 63) to use to check to see if the random number generation is working
  • Checked the timing on the random number generation (Seems OK)
  • Created the Overworld Kernel Bank

We are now very close to having a playable demo of the 256x256 overworld you can move around in.

 

A couple things I have to check are:

  • Which taps should I use for the random generation? (E.g. $B4, etc)
  • Is the Overworld Vertical Blank Bank too big and/or taking too long to execute (in which case I will move code into the Overworld Overscan Bank, which is empty [!!!])
  • Will the subroutine I created which increments map coordinates when you walk off the side of the screen work? (Will it be twitchy?)

I have not compiled and run my code, and I suspect it current DOES NOT work, but I am uploading it in any case.

che_main.asm

InitSystem.asm

OverworldKernel.asm

OverworldVB.asm

Edited by vidak
  • Like 1
Link to comment
Share on other sites

hey everyone.

 

i have started a patreon.

 

if you like this project and would like to see if completed, i invite you to donate $1 a month!

every tiny little bit counts.

https://www.patreon.com/dirtycommo

i am very sheepish about doing this, because i do see it as a bit selfish, but i am choosing to ignore that aspect of this request. i am very close to having the next phase of this game finished, and any little bit of change helps!!

sincerely, blair.

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   0 members

    • No registered users viewing this page.
×
×
  • Create New...