Jump to content
matthew180

F18A programming, info, and resources

Recommended Posts

@Rasmus: Nice work. It is nice to see exactly what the GPU is capable of, since I have absolutely no time to mess with my own creation. Remember you can also use the GPU to erase the VRAM, and you can do it 16-bits at a time. Note that V1.3 of the firmware has a serious bug with the GPU DIV instruction. The MPY instruction is very fast though, since it uses one of the FPGA's dedicated multipliers you get a multiply that is just as fast as any other simple instruction, i.e. INC, MOV, etc.

Share this post


Link to post
Share on other sites

I think CALL, RET, PUSH, POP are working in Classic99 - it's something else that goes wrong.

Share this post


Link to post
Share on other sites

Beautiful! Regarding the GPU emulation in Classic99, it runs the exact same code for the basic functionality, so, for instance, MOV R11,*R10+ should work fine, it's used in many places.

 

However, although I've implemented all of the modified GPU instructions /none/ of them have been tested. I have the information I need to make a proper spec for each of them, but no time. I'd have expected the stack instructions to work, but I took at guess at how they worked when I did the implementation and did not yet go back to verify them, so... if they are broken I'm not too surprised. F18A parts in Classic99 are all still in the "hack" phase, unfortunately, even the register unlock is not correct, it's just there as enough to be able to single-step through GPU code.

 

As far as I can tell from the debugger MOV instructions with post increment are not incrementing. If you run my demo and set a breakpoint at >2800 you only have to single step 8 times to get to a post incrementing instruction.

Since the GPU doesn't have a workspace pointer (I assume the registers are internal?) I would expect that the emulation has to be slightly different from the ordinary CPU.

Share this post


Link to post
Share on other sites

 

As far as I can tell from the debugger MOV instructions with post increment are not incrementing. If you run my demo and set a breakpoint at >2800 you only have to single step 8 times to get to a post incrementing instruction.

Since the GPU doesn't have a workspace pointer (I assume the registers are internal?) I would expect that the emulation has to be slightly different from the ordinary CPU.

 

The GPU registers are faked at the moment with a fake workspace pointer, since the core emulation expects there to be one. That's why I'm surprised you say that, the mov function is completely unchanged. But, I'll check that too. (You're giving me lots of work! ;) )

Share this post


Link to post
Share on other sites

Don't be silly, nothing to apologize for! You're actually trying to use things that nobody else has. :)

 

I can confirm your results, the autoincrement does not appear to work. The problem would appear to be that the post increment handler is incorrectly coded to directly access CPU memory rather than running through the virtual functions... so, that's an easy fix.

 

I'll see if I can round up a few of these fixes and get a new version out tonight.

Share this post


Link to post
Share on other sites

Looks like just another screen capture of Classic99 ...

 

 

... but wait, there's something strange going on. :P

  • Like 4

Share this post


Link to post
Share on other sites

Looks like just another screen capture of Classic99 ...

 

 

... but wait, there's something strange going on. :P

fantastic, so it's really perfect.

you are an amazing programmer.

congratulations

Share this post


Link to post
Share on other sites

Looks like just another screen capture of Classic99 ...

 

 

... but wait, there's something strange going on. :P

 

Come on then, let the cat out of the bag.

Share this post


Link to post
Share on other sites

Looks like just another screen capture of Classic99 ...

 

... but wait, there's something strange going on. :P

 

I'll say! The ship is MONOCHROME when I play it in Classic 99. Nice Job!

So where do we go for the new version?

Edited by Kevan

Share this post


Link to post
Share on other sites

Looks like just another screen capture of Classic99 ...

... but wait, there's something strange going on. :P

 

Looks pretty cool. Is this ECM for sprites only, or also for patterns? On one of the starting screens it looks like it could be patterns, but you might be using sprites for that as well... Have you talked to Tursi about this, what are the chances of your hack ending up in the main tree?

Share this post


Link to post
Share on other sites

Okay, I ran into this video on You Tube today...

http://www.youtube.com/watch?v=DSfj9s6cxGY

 

In the video, it appears one can get true 80 columns in Extended BASIC!

 

I have a couple of stupid questions:

 

1) Is this just some kind of display only trick that one can accomplish with MLC?

2) Or can I really write a program in XB, and have a functional 80 column interactive program?

 

3) Assuming this actually is possible, how would I map the input locations?

Share this post


Link to post
Share on other sites

Okay, I ran into this video on You Tube today...

http://www.youtube.com/watch?v=DSfj9s6cxGY

 

In the video, it appears one can get true 80 columns in Extended BASIC!

 

I have a couple of stupid questions:

 

1) Is this just some kind of display only trick that one can accomplish with MLC?

2) Or can I really write a program in XB, and have a functional 80 column interactive program?

 

3) Assuming this actually is possible, how would I map the input locations?

 

It's more like a new language embedded in DATA statements in XB. There's lots of information here: http://gtello.pagesperso-orange.fr/mlc_e.htm

  • Like 2

Share this post


Link to post
Share on other sites

 

It's more like a new language embedded in DATA statements in XB. There's lots of information here: http://gtello.pagesperso-orange.fr/mlc_e.htm

 

Thanks for the link! :)

 

I downloaded the program and the PDF file. I already printed it it out in book form, sliced the edges nice and neat, now I just have to bind it and make a suitable cover for it. Getting around to playing with it might have to wait until January, when work will slow down a tad and I'll have more time on my hands.

 

http://atariage.com/forums/gallery/album/1032-making-a-book/

Edited by Kevan

Share this post


Link to post
Share on other sites

Matthew, could you write a few lines about how the SPI_EN, SPI_DS, SPI_OUT and SPI_IN opcodes are working? Is it possible to brick the device if the GPU runs into random image data?

Share this post


Link to post
Share on other sites

You can definitely brick the F18A via GPU software if you write to the wrong part of the SPI Flash. The SPI Flash contains the bit stream for the FPGA and if you overwrite it then the FPGA will not have anything to load at power-on. Being able to write to the SPI Flash is key to me being able to write a software-based firmware update, as well as the file-system storage idea.

 

Having said that, you can safely *read* any part of the SPI Flash. It currently contains the FPGA bit stream and some font patterns. You also probably would not be able to accidentally write data to the SPI Flash, it takes a very specific sequence of commands and data.

 

The GPU-to-SPI interface is low level, so you will need to get the datasheet for the M25P80 SPI Flash chip. All serial flash is "command based", meaning to read data you have to send the "read data" command, followed by the 24-bit address, and finally read out the data. It is actually very similar to how the 9918A works, as well as the GROM.

 

I re-purposed four opcodes to interface with the SPI Flash:

 

CKON - clock on - Set the SPI chip enable low. The chip enable is active low.

CKOFF - clock off - Set the SPI chip enable high.

LDCR - load communication register - write a byte (always a byte) to the SPI Flash.

STCR - store communication register - read a byte from the SPI flash.

 

Did you see the "gpu_preload.asm" file I posted? It contains the pre-loaded GPU code that is part of the FPGA bit stream and has low level SPI functions.

 

Basically you would follow this sequence:

 

       CKON        Enable the SPI Flash
       . . .
       LDCR        Write to the SPI Flash
       STCR        Read from the SPI Flash
       . . . 
       CKOFF       Disable the SPI Flash
.

Here is a real example of reading some data from the SPI Flash:

 

CSON   EQU  >03A0             * SPI chip select enable
CSOFF  EQU  >03C0             * SPI chip select disable
.
.
.
* The name, address, length, and info byte
       EVEN
ENTNAM BYTE 32,32,32,32,32,32,32,32,32,32
ENTADR BYTE >00,>00,>00       * Catalog data 24-bit address
ENTLEN BYTE >00,>00           * Length of data
ENTINF BYTE >00               * Info, 1-byte
       EVEN

.
.
.

*      R1,R0 = Fast read command (1 byte) + 24-bit address of catalog entry to read

       LI   R3,ENTNAM         * Start of the catalog entry structure to load
       LI   R2,16             * Size of the catalog entry structure

       DATA CSON              * SPI !CE (CKON opcode)
       LDCR R1,8              * Send Fast-Read Command in MSB of R1
       SWPB R1
       LDCR R1,8              * Send MSB of 24-bit address
       LDCR R0,8              * Send 2nd byte
       SWPB R0
       LDCR R0,8              * Send LSB of 24-bit address
       STCR R0,8              * Consume (read) Fast-Read dummy byte
IDXG10 STCR *R3+,8            * Read 1-byte into the structure
       DEC  R2
       JNE  IDXG10
       DATA CSOFF             * SPI CE (CKOF opcode)
.

There are 16 "sectors" in the SPI Flash, each sector being 64K (>10000) each. The bit stream reserves the first 5 (0 to 4) sectors from >00000 to >4FFFF. The catalog reserves sector 5 from >50000 to >5FFFF. You can safely write data in any of the remaining 10 (6 to 15) sectors from >60000 to >FFFFF. It was this area that I was planning to use for the "disk" storage, but that idea is still vaporware.

Edited by matthew180

Share this post


Link to post
Share on other sites

Thank you, my concern was that I could accidentally brick the F18A if I my GPU code jumped to a random VPD RAM address, but it sounds like that's very unlikely.

Share this post


Link to post
Share on other sites

VRAM has nothing to do with the SPI Flash. To brick the F18A you would have to specifically issue the erase commands to the SPI Flash for sectors 0 to 4. There is no way to mess up the SPI Flash by reading or writing any VRAM (the original 16K or extra 2K). You can't "jump" to the SPI Flash, it is not in the memory map and does not work like that.

 

Unless you start messing with the CKON, CKOFF, and LDCR instructions, you can't hurt the F18A via software. But even a bricked F18A can be easily recovered with an external JTAG programmer.

Edited by matthew180

Share this post


Link to post
Share on other sites

What I mean is that a bug in your GPU code, e.g. a missing IDLE, could cause it to execute random instructions based on whatever you have in VDP RAM. Some instructions may be CKON, CKOFF, and LDCR, you have no control over that.

Share this post


Link to post
Share on other sites

He's talking about the GPU executing random instructions in a crash case, Matt, and accidentally executing SPI commands as a result. But because of the specific sequence required it's unlikely to accidentally corrupt the eeprom. (Which is why most flash devices have those sequences ;) ).

Share this post


Link to post
Share on other sites

I see. Yeah, that's not going to happen. The sequence is too specific and the random chance is too high. If that happens to someone, I'll swap their F18A.

  • Like 1

Share this post


Link to post
Share on other sites

Is there any way to use the PIX instruction on an off screen bitmap buffer? I know you can use it to calculate the address only, and you can then adjust the base address to point to your buffer, but that hardly saves any code (calculating the address is just two shifts and one add anyway). It would be really useful to be to be able to draw to a buffer that's not currently visible and then change the bitmap layer base address to point to your buffer once the drawing is done.

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.

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...