It is currently Tue Oct 17, 2017 10:03 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 17 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Sun Aug 20, 2017 10:30 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10046
Location: Rio de Janeiro - Brazil
One way to handle the fact that different fields have to be written to the same register is to have separate variables in RAM for each field, which in this case are the bank index and the name table, that you can change independently and call separate "WriteToMapper" function that combines the fields and writes the result to the mapper. Kinda like this:

Code:
  ;select bank 4
  lda #$04
  sta BankIndex
  jsr WriteToMapper

Code:
  ;select name table B
  lda #NAME_TABLE_B
  sta NameTable
  jsr WriteToMapper

Code:
WriteToMapper:
  lda BankIndex
  ora NameTable
  tax
  ;lda NoBusConflicts, x ;this is only needed if the values aren't sequential
  sta NoBusConflicts, x
  rts

A setup like this allows you to control the bank and the mirroring separately.

As for the complexity of coding for AxROM, I think it all comes from the fact that you don't have a fixed bank, so you need a workaround to "fake" a fixed bank, where all the interrupt handlers and bankswitch operations must be, and depending on the assembler, faking this fixed bank might not be the most straightforward thing to do.


Top
 Profile  
 
PostPosted: Sun Aug 20, 2017 11:59 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10046
Location: Rio de Janeiro - Brazil
OK, I did some tests and IFNDEF doesn't work 100% (if you reference the label before the IFNDEF block it apparently is considered defined!), so I tried a different method of creating a virtual fixed bank, using macros instead of includes and the type of label assignment I used in ASM6 (Label = *). Here's the basic template I made:

Code:
   .inesprg 4
   .ineschr 0
   .inesmap 7
   .inesmir 0

;----------------------------------------------------------------
; CONSTANTS
;----------------------------------------------------------------

NAME_TABLE_A = %00000000
NAME_TABLE_B = %00001000

;----------------------------------------------------------------
; VARIABLES
;----------------------------------------------------------------

   .rsset $000

NameTable .rs 1
FrameCounter .rs 1

;----------------------------------------------------------------
; MACRO: Selects a bank without affecting name table mirroring (A = bank index)
;----------------------------------------------------------------
SelectBank .macro

   ora <NameTable
   tax
   lda BankswitchTable, x
   sta BankswitchTable, x

   .endm

;----------------------------------------------------------------
; MACRO: Selects a name table without switching banks (A = name table)
;----------------------------------------------------------------
SelectNameTable .macro

   sta <NameTable
   ora CurrentBank
   tax
   lda BankswitchTable, x
   sta BankswitchTable, x

   .endm

;----------------------------------------------------------------
; MACRO: Generates an instance of the virtual fixed bank
;----------------------------------------------------------------
GenerateFixedBank .macro

FixedBankStart\@: ;global label to isolate local labels inside

   .org $ff00 ;this address should be adjusted according to the size of this repeated chunk

CallDoSomething = *

   ;remember the current bank
   lda CurrentBank
   pha

   ;select the function's bank and call it
   lda #BANK(DoSomething) / 4
   SelectBank
   jsr DoSomething

   ;restore the previous bank and return
   pla
   SelectBank
   rts

Reset = *

   ;initialize the name table
   lda #NAME_TABLE_A
   SelectNameTable

   ;switch to the bank that contains the initialization code and jump to it
   lda #BANK(Initialize) / 4
   SelectBank
   jmp Initialize

NMI = *

   ;indicate that an NMI happened
   inc <FrameCounter

   ;return
   rti

IRQ = *

   ;return
   rti

.CurrentBank:

   ;index of the current bank
   .db BANK(.CurrentBank) / 4

CurrentBank = .CurrentBank ;make this address visible from the outside

BankswitchTable = *

   ;values used to avoid bus conflicts
   .db $00, $01, $02, $03, $04, $05, $06, $07, $10, $11, $12, $13, $14, $15, $16, $17

   ;interrupt vectors
   .org $fffa
   .dw NMI
   .dw Reset
   .dw IRQ

FixedBankEnd\@: ;global label to isolate local labels inside

   .endm

;----------------------------------------------------------------
; PRG-ROM
;----------------------------------------------------------------

   .bank 0
   .org $8000

Initialize:

   sei
   cld

   ;(INITIALIZATION CODE GOES HERE)

Forever:

   ;call a function in another bank
   jsr CallDoSomething

   ;select name table B
   lda #NAME_TABLE_B
   SelectNameTable

   ;loop forever
   jmp Forever

   .bank 1
   .org $a000

   .bank 2
   .org $c000

   .bank 3
   .org $e000

   GenerateFixedBank

   .bank 4
   .org $8000

DoSomething:

   ;(THIS IS A FUNCTION IN ANOTHER BANK)

   ;return
   rts

   .bank 5
   .org $a000

   .bank 6
   .org $c000

   .bank 7
   .org $e000

   GenerateFixedBank

Note that while the mirroring can be changed from anywhere (since the bank doesn't change), changing banks can only be done from the fixed bank, so you need to create trampoline functions in the fixed bank for inter-bank calls, like the "CallDoSomething" I put in the template. You could also make a more complex, generic trampoline function that can call any address, as opposed to making individual trampolines for each function.

Another important detail about this template is that it uses the "all in main" approach to handling vblanks. The NMI simply changes a a variable, that you have to watch in the main loop in order to wait for vblank. This is a very newbie-friendly approach and I figured the template would look simpler with it, but you could also turn the NMI handler into a trampoline to a more specialized handler if you wanted to.

EDIT: Corrected a few mistakes in the code.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 17 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group