Jump to content
Omegamatrix

Making use of the status register

Recommended Posts

I just had a thought of setting/clearing the interrupt flag to use the bit there. The idea is you are short on ram, and you need one bit. Presumably you know where the stack pointer is (pointed to some temp ram!), so:

 

   php              ; 3    put status register on the stack
   pla              ; 4    load accumulator with the status register, correct stack pointer
   and    #$04      ; 2    test the interrupt flag
   bne   .gotoThere
;code continues...

 

 

That's pretty straight forward. I do like it because PHP, PLA takes the same amount of bytes as loading from a regular register, and only 4 extra cycles.

 

 

The brings me to my questions. My understanding is the 2600 doesn't physically have an interrupt line, where a 7800 does. Presumably once the 7800 is locked into 2600 mode then the status of the interrupt flag won't matter, or will it?

 

Also some programmers skip SEI altogether to save a byte. Has anyone ever had problems on a 7800 with games that skip SEI, or does it generally get locked into 2600 mode quick enough that you're okay? I imagine you could use SEI at the top of your clear loop just to be safe, but once the clear loop is done you should be free to set/clear the interrupt flag.

 

Finally my last assumption was that the clear loop locks the 7800 in 2600 mode. But does it? Specifically would this do it (notice there is no TAY or TYA):

 

 

   sei
   cld
   ldx    #0
   txa
.loopClear:
   dex
   txs
   pha
   bne    .loopClear

Share this post


Link to post
Share on other sites

I went here once. The interrupt bit is fixed on that CPU. It's not a free bit. :(

 

Ran completely out of bits once, and was going to do this. Funny too. Since the RAM is so limited, it really is a case of "every bit matters".

Share this post


Link to post
Share on other sites

Well it might be a good news/bad news scenario. If I get you right, fixed in this case also means fixed to be always set?

 

 

This would be useful if you needed a flag to tell if you were on a 7800 on not (i.e. for Nukeys 7800/2600 pause switch routine). You could clear the interrupt flag if you detected a 2600, but leave it as is when it is a 7800 as it's always set.

 

 

It's too bad that bit can't be used otherwise.

Share this post


Link to post
Share on other sites

I also remember reading that, Spice. It was a long time ago and I forgot all about it. That definitely needs testing on real hardware! If no one takes it up I will in about a month or so when I get my Atari stuff back. Maybe though someone has already written something to try it, and has tested it. I'd like to know.

Share this post


Link to post
Share on other sites

I seem to recall reading about a a trick to get a few extra bits... <google>

 

Yep - 3 bits in SWCHB. I've not tried it though.

http://www.biglist.com/lists/stella/archives/200407/msg00042.html

Pretty nifty! I wonder if there are any other RIOT registers with bits we could use? For example, TIMINT has two bits-- 6 and 7-- which it uses for interrupt flags, but I think only bit 7 (the timer interrupt) has any significance on the 2600, so would it be possible to set or clear bit 6 for one more bit of storage?

 

Michael

Share this post


Link to post
Share on other sites

I never even knew that there was TIMINT register. :lol: I guess is would be a read only register? Switch A and B are controlled for I/O with DDR registers, so they do both. It would be cool if we could read/write to that bit 6 though.

 

 

I also have another ram location saver. I ran into a weird situation where I needed alot of temp ram for my kernal (I wrote a 7 digit display, good for any number 0 - 9,999,999). The situation was it was too tight to do a loop, so I had to draw the score scanline by scanline without looping. I ended up having to store one of the digit's gfx in ram.

 

To save on temp ram I aligned my digit pointers to the end of the ram table (making use of $FF, $FE, etc... as I wasn't jumping anywhere soon). I was also making use of the stackpointer to hold another value for a quick load.

 

The thing I did different though is I loaded one of the lines of gfx into TIM1T. This saved me a byte of ram I'd have to find elsewhere. My kernal used no branching so I just added the the number of cycles it took until INTIM was loaded, and voila! I had my old value back.

 

 

 

 

Here you can see the idea and usage:

   lda    NumberGfx+7,X         ;4  @16
   adc    #94                   ;2  @18    carry is clear, add 94 (cycles)
   sta    TIM1T                 ;4  @22    use timer 1 as a temp storage, and save 1 byte of ram
   tya                          ;2  @24
   tax                          ;2  @26
   txs                          ;2  @28    stack pointer now holds the missile index
   lda    #$01                  ;2  @30
   sta    PF2                   ;3  @33    1 piece only
   sta    VDELP0                ;3  @36    delay
   sta    VDELP1                ;3  @39    delay
   lda    #$FF                  ;2  @41
   sta    PF0                   ;3  @44    fill
   sta    PF1                   ;3  @47    fill
   lda    #NO_MO_74 | ENABLE    ;2  @49
   sta    HMBL                  ;3  @52
   sta    HMM1                  ;3  @55
   sta    HMP1                  ;3  @58    HMM0, ENABL not touched
   sta    HMP0                  ;3  @61
   sta    ENAM1                 ;3  @64    enable
   sta    ENAM0                 ;3  @67    enable
   lda    #$0E                  ;2  @69    white, 1 free cycle to load color from ram instead
   sta.w  COLUP0                ;4  @73
   sta    COLUP1                ;3  @76
;--------------------------------------
   ldy    #$07                  ;2  @2                          line #1
   lda    (digitPtrs),Y         ;5  @7     2nd
   sta    GRP0                  ;3  @10
   lda    (digitPtrs+2),Y       ;5  @15    3rd
   sta    GRP1                  ;3  @18
   lda    (digitPtrs+4),Y       ;5  @23    4th
   sta    GRP0                  ;3  @26
   lax    (digitPtrs+,Y       ;5  @31    7th
   lda    (digitPtrs+6),Y       ;5  @36    5th
   ldy    INTIM                 ;4  @40    6th   94 cycles has passed, timer now holds correct value
   sta    GRP1                  ;3  @43
   sty    GRP0                  ;3  @46
   stx    GRP1                  ;3  @49
   sta    GRP0                  ;3  @52
   tsx                          ;2  @54
   sta    HMCLR                 ;3  @57
   lda    NusizDigitTab+6,X     ;4  @61
   sta    NUSIZ0                ;3  @64
   lda    HmoveDigitTab+6,X     ;4  @68
   sta    HMM0                  ;3  @71
   sta    HMOVE                 ;3  @74
   ldy    #$06                  ;2  @76
;---------------------------------------
   sta    ENABL                 ;3  @3                          line #2
   lda    (digitPtrs),Y         ;5  @8     2nd
   sta    GRP0                  ;3  @11
   lda    (digitPtrs+2),Y       ;5  @16    3rd
   sta    GRP1                  ;3  @19
   lda    (digitPtrs+4),Y       ;5  @24    4th
   sta    GRP0                  ;3  @27
   lax    (digitPtrs+,Y       ;5  @32    7th
   lda    (digitPtrs+6),Y       ;5  @37    5th
   ldy    fifthDigitB           ;3  @40    6th   digit gfx stored in ram beforehand
   sta    GRP1                  ;3  @43
   sty    GRP0                  ;3  @46
   stx    GRP1                  ;3  @49
   sta    GRP0                  ;3  @52
   tsx                          ;2  @54
   sta    HMCLR                 ;3  @57
   lda    NusizDigitTab+5,X     ;4  @61
   sta    NUSIZ0                ;3  @64
   lda    HmoveDigitTab+5,X     ;4  @68
   sta    HMM0                  ;3  @71
   sta    HMOVE                 ;3  @74
   ldy    #$05                  ;2  @76
;---------------------------------------
   sta    ENABL                 ;3  @3                          line #3

Share this post


Link to post
Share on other sites

We used the "I" flag in Stella's Stocking when going back to the menu. I can't remember the details, but the I flag was used to tell the menu whether the menu was invoked by a cold or a warm start. I do not believe it is true that the flag is fixed on 7800s because otherwise Stella's Stocking would not return to the menu properly, and we tested this game on several 7800s.

 

It may be the case that the "B" flag is fixed but that is not what we are talking about here.

Share this post


Link to post
Share on other sites

We used the "I" flag in Stella's Stocking when going back to the menu. I can't remember the details, but the I flag was used to tell the menu whether the menu was invoked by a cold or a warm start. I do not believe it is true that the flag is fixed on 7800s because otherwise Stella's Stocking would not return to the menu properly, and we tested this game on several 7800s.

 

It may be the case that the "B" flag is fixed but that is not what we are talking about here.

This is really good news!! Thank you Batari!!! :D

Share this post


Link to post
Share on other sites

I also have another ram location saver. I ran into a weird situation where I needed alot of temp ram for my kernal (I wrote a 7 digit display, good for any number 0 - 9,999,999). The situation was it was too tight to do a loop, so I had to draw the score scanline by scanline without looping. I ended up having to store one of the digit's gfx in ram.

Slick! You'll be able to convert that to a loop soon w/no problem once we wrap up DPC+.

Share this post


Link to post
Share on other sites

I just wanted to say that I have sucessfully been able to use the interupt flag (as a bit) in the status register as well. I'm so happy it works! I did a hack of Starmaster to use the Genesis controllers, and RevEng tested the rom on a 7800 with his Harmony, and said it worked great.

 

 

So I commented out the SEI (first executed instruction) and did this instead:

 

START
;   sei             ; original code that is no longer used

  STA   NUSIZ0     ; dummy instruction, used to lock 2600 mode immediately
  CLI              ; interrupt won't trigger in 2600 mode

Note that a normal clear loop will set 2600 mode, and you could save a byte by using SEI before it, and CLI after it. Starmaster was doing some other stuff and jumping to a subroutine... so I just locked 2600 mode right away so that I could use CLI safely.

 

 

 

The situation in Starmaster was we wanted to make the second button (button C on the Genesis) bring up the mapscreen. The problem was it would only stay up as long as you held down button C. Ideally we wanted the map to come up with a press of the button C, and stay up until the button C was pressed again.

 

Starmaster only kept the state of the the player difficulty switches, and the color\bw switch. SWCHB was shifted to the right by 1, and then AND #$64.

 

In the new code below I check the button C, and then check to see if button C was pressed last frame (using the status register interrupt bit as my flag). If it wasn't set I would simply EOR the bit kept in $F9 that Starmaster used to hold the state of the color\b&w switch.

 

 

LF06C:
;    lda    SWCHB                 ; 4   original code that is no longer used
;    lsr                          ; 2
;    and    #$64                  ; 2



;new code uses INPT1 instead of Color\B&W switch
   BIT   INPT1
   BPL   .pressed1
   CLI
   BMI   .return1               ; always branch

.pressed1:
   PHP
   SEI
   PLA
   AND   #$04                   ; was interrupt set last frame?
   BNE   .return1               ; branch if interrupt was set last frame
   LDA   $F9                    ; this flipping happens only once per firebutton press...
   EOR   #$04                   ; flip the map screen switch
   STA   $F9
.return1:
   LDA    SWCHB
   LSR
   AND    #$60
   BIT    INPT1
   BMI    .notPressed1
   ORA    #$04
.notPressed1:


;original code continues...
   sta    $88                   ; 3
   eor    $F9                   ; 3
   and    #$64                  ; 2
   beq    LF08E                 ; 2³
   lda    $F9                   ; 3
   eor    #$80                  ; 2
   and    #$80                  ; 2
   ora    $88                   ; 3
   sta    $F9                   ; 3

Share this post


Link to post
Share on other sites

I seem to recall reading about a a trick to get a few extra bits... <google>

 

Yep - 3 bits in SWCHB. I've not tried it though.

http://www.biglist.com/lists/stella/archives/200407/msg00042.html

Okay, I've written a small test program. It updates SWBCNT to read & write to SWCHB.

 

On the screen it displays (in Hex) the values for bits D5, D4, and D2. We don't care about the other bits as they are all set/cleared by the console switches.

 

TestSWCHB.zip

 

 

 

Basically I found no matter what you write to SWCHB, you only read a high input back at these 3 bits. This was tested on both a 2600 and 7800.

 

 

-Jeff

Share this post


Link to post
Share on other sites

FYI, when it starts up a 2600 game, the 7800 has already locked out 7800 mode. This is both to ensure compatibility, and to enforce unsigned games from being able to use 7800 mode.

Share this post


Link to post
Share on other sites
It may be the case that the "B" flag is fixed but that is not what we are talking about here.

 

The so-called "B" flag isn't really a flag. When the 6502 stores the flag register in memory (either because of a BRK, an interrupt, or a PHP instruction) it stores the implemented flag bits along with a the state of a control line which indicates whether an interrupt is being taken. From what I've read, this usually but not always indicates whether the interrupt is being dispatched as a result of the IRQ line; a not-totally-safe assumption is that if the IRQ line isn't causing an interrupt, a BRK instruction is. If a BRK instruction occurs just as an IRQ arrives, the BRK flag will not be set (oops).

Share this post


Link to post
Share on other sites

Hi Forum Gamers, I just purchased a Micro SD Sandisk and adapter for the FB9 Console. It appears as this console is not as popular as the FBP version. I assume that the FBP was an improvement from the FB9 console and is more compatibile with game downloads. I attempted to load games using Game.zip and selecting games that I wanted for the FB9 and transfered these games to the Micro SD flash card and none of the games worked. I could not get any of the games to work so I removed the spacing and  ensured that .Bin extension was at the end of each file as well as captital letters for the first letter of the name, and tried again with no luck. I assume that the 32 GB SD adapter with micro SD card was incompatible with the FB9 console. The 32 GB micro SD was diffacult to insert into the FB9 console but I managed to insert it. My husband had to remove the adapper with a pair of pliers. 

 

My question is, What does the compatible Micro SD and adapter look like? Can anyone provide a visual? Can somone please provide a list of compatible games for the FB9? I do know that atleast a 16 GB Micro SD or lower should have been used instead of a 32 GB Micro SD. 

Share this post


Link to post
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...