It is currently Sat Aug 18, 2018 7:13 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Sun Aug 05, 2018 7:43 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7471
Location: Chexbres, VD, Switzerland
So guys, those last years I've been always less and less into NESdev, and the probability that I ever release a full-featured game in my lifetime is getting smaller and smaller. In the last 2 years I have made pretty much zero (that is, 0) progress at all in my NESdev projects. Lack of time is not the only reason for that; lack of motivation and the start of other interest is the main reasons.

I don't know what I will do with my unfinished projects, but at least I'd like to share what I consider the more advanced and most "general purpose" thing I've developed. I developed this quite recently as I already started to slow down my progress on my main NESdev project, however I still think it is a great success.

The goal is to have a bytecode system that allows to waste less ROM memory to store programms as 6502 code, instead the 6502 interprets a byte-code having code in a more upper-level assembly language using 8 16-bit registers. This allows not only to save lots of ROM, but also to write some pieces of program more convieniently. The project is largely inspired by SWEET-16, however I found SWEET-16 was fairly lacking so I brought the following improvements over the concept :
  • Uses 32 instructions x 8 registers instead of 16 instructions x 16 registers
  • More instructions means a more complete instruction set, as such logical operations are added
  • Status registers are abandoned
  • Fully mergeable with native 6502 code (bytecode and native 6502 code routines can call eachother transparently)
  • Possibility to access to VRAM directly, as well as execute bytecode from CHR-ROM directly

The last point is what makes the project NES specific instead of 6502 specific. The idea is to code routines which are heavy in complex computations and VRAM access, such as loading routines, in bytecodes, and routines which needs to be fast and executed during normal gameplay in native 6502 assembly. Bytecode execution is around 10-20 times slower as native 6502 ASM, but can save PRG-ROM (up to 100%, since code can be stored in CHR-ROM and executed from there without using RAM).

I used WLA-DX marcos for coding, probably with some modifications it's easy to port this to other assembler's macros. To not confuse byte code with 6502 code, it uses 4-letter mnemonics. As a remainder it uses 8 registers, and most operations are operations are automatically operations between any register and R0 (just like the original SWEET-16). It does uses the same stack as 6502 code.

As an example code of what bytecode looks, here is an example from my game project that clears entiere name and attribute tables:
Code:
ClearVRAM
   LDIW R6, $2000
   LDZP M2000     ; Load previous $2000 value from M2000 in zeropage
   LDIB R1, $80
   LIOR R1
   STZP M2000   ; M2000 |= $80
   STMB R6      ; store it to actual $2000 registers
   CALL PaletteFadeOut    ; Call bytecode program that will fade out the palette over several frames

   DECR R6      ; R6 = $2000 (compensate auto-increment from previous STMB instruction !)

   CLER R0
   STMB R6      ; $2000 := 0
   STMB R6      ; $2001 := 0
   STZP M2000   ; M2000 := 0
   STZP M2001   ; M2001 := 0
   CALL ClrNamTbl

Clr2ndNamTbl
   LDIW R1, $2400      ; R1 points to second nametable
   BRNZ R1, SetNamAdress
ClrNamTbl
   LDIW R1, $2000      ; R1 points to first nametable
SetNamAdress
   LDIB R0, $ff   ; R3 (carry flag from 6502) nonzero -> Clear nametable with $ff
   BRNZ R3, _ff
   LDIB R0, $60   ; R3 (carry flag from 6502) zero -> Clear nametable with $60
_ff
   LDIW R2, $3c0   ; R2 counts bytes to write to nametable
   CALL _sub       ;Clear name table
   LDIB R2, $40
   CLER R0         ;Clear attribute table
_sub
   STVB R1        ; Store R0 to VRAM
   DJNZ R2, _sub   ; Loop until done
   RETN


Here is the code and documentation. Note that some aspects of the bytecodes were engineered for this game specifically (in particular it relies on CNROM mapper, and some instructions that went unused in the game were removed, but could be added back).


Attachments:
bytecode_doc.txt [13.52 KiB]
Downloaded 29 times
bytecode.asm [10.4 KiB]
Downloaded 19 times
Top
 Profile  
 
PostPosted: Sun Aug 05, 2018 8:24 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1747
Location: Fukuoka, Japan
It's great that you are releasing some part of the technology that you used for your game but if you have a chance, even if the project is not finished or never will be, it would be great to see up to what point you where able to make your game.

I still remember it, from 10 years ago and would love to see how much you where able to do. It's up to you, it would bring some closure as long as you explain what can be done or not with the current built ;)


Top
 Profile  
 
PostPosted: Sun Aug 05, 2018 9:27 am 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7471
Location: Chexbres, VD, Switzerland
Banshaku wrote:
It's great that you are releasing some part of the technology that you used for your game but if you have a chance, even if the project is not finished or never will be, it would be great to see up to what point you where able to make your game.

I still remember it, from 10 years ago and would love to see how much you where able to do. It's up to you, it would bring some closure as long as you explain what can be done or not with the current built ;)

Doing so would mean officially abandoning the project. I'm not here yet, but if I ever officially abandon the project then yeah, I'll release everything I guess.


Top
 Profile  
 
PostPosted: Sun Aug 05, 2018 11:24 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6599
Location: Canada
I've been working on a thing with its own bytecode myself lately, always good to see someone else's ideas and implementation. :)


Top
 Profile  
 
PostPosted: Sun Aug 05, 2018 12:36 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 10714
Location: Rio de Janeiro - Brazil
This is pretty interesting, but I don't know if I'd ever trade performance for ROM space, considering that mappers can easily provide us with tons of PRG-ROM space, while performance will always be limited by the 1.79 MHz CPU, unless you use much more complex/expensive/questionable expansions.

I also don't consider 6502 assembly a chore to code, I actually find it pretty fun, so I don't really feel the need to "raise the level" in order to get things done. I mean, not that I can easily get things done, I just don't feel that the language is what's holding me back.


Top
 Profile  
 
PostPosted: Sun Aug 05, 2018 12:58 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7471
Location: Chexbres, VD, Switzerland
tokumaru wrote:
This is pretty interesting, but I don't know if I'd ever trade performance for ROM space, considering that mappers can easily provide us with tons of PRG-ROM space, while performance will always be limited by the 1.79 MHz CPU, unless you use much more complex/expensive/questionable expansions.

I think we already had this debate countless times. Basically I limited myself to mapper #3, 32kb PRG + 32kb CHR and did not want to develop for a more advanced mapper (yet). The goal was originally then to make further games using more complex mappers as I progressed.

Quote:
I also don't consider 6502 assembly a chore to code, I actually find it pretty fun, so I don't really feel the need to "raise the level" in order to get things done. I mean, not that I can easily get things done, I just don't feel that the language is what's holding me back.

To be honest it entirely depends on what you want to do. Sometimes, in most cases 6502 code will come naturally and do the job just fine. In some rare cases though, especially when dealing with a lot of 16-bit stuff, having just 3 registers is a complete hassle, and coding things becomes a nightmare. Of course if you don't care about code size then it becomes less a problem as you can afford having all your variables in RAM and doing worthless LDA / STA all the time, but if you want something more optimal it's not easy.


Top
 Profile  
 
PostPosted: Sun Aug 05, 2018 5:54 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 1747
Location: Fukuoka, Japan
Ok, no problem then! I hope that you make some kind of demo someday, even 1 level, would love to see it. Sorry for derailing a little bit.

As for the current post, I'm not knowledgable enough about bytecode system so I will abstain from commenting on it. I will keep a copy and browse the code for educational purpose.


Top
 Profile  
 
PostPosted: Sun Aug 05, 2018 8:17 pm 
Offline
User avatar

Joined: Thu Mar 31, 2016 11:15 am
Posts: 335
tokumaru wrote:
This is pretty interesting, but I don't know if I'd ever trade performance for ROM space, considering that mappers can easily provide us with tons of PRG-ROM space, while performance will always be limited by the 1.79 MHz CPU, unless you use much more complex/expensive/questionable expansions.

I suppose the byte code instructions can be implemented in a way that's faster but less space efficient. It's kinda cool to have that choice without having to rewrite the entire program.


Top
 Profile  
 
PostPosted: Sun Aug 05, 2018 11:32 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7471
Location: Chexbres, VD, Switzerland
pubby wrote:
I suppose the byte code instructions can be implemented in a way that's faster but less space efficient. It's kinda cool to have that choice without having to rewrite the entire program.

No, no, no. The whole point of the bytecode system is to reduce ROM consumption to the bare minimum possible to store a program/algorithm, and speed of execution is sacrified for that. If you need real-time execution, then the program should be written in native 6502. And most of the game is written in native 6502, only key parts of particularly complex initializing and loading are written in byte code; every piece of code which is executed regularly on a frame-basis is always written in native 6502.


Top
 Profile  
 
PostPosted: Mon Aug 06, 2018 2:30 am 
Offline
User avatar

Joined: Fri Feb 27, 2009 2:35 pm
Posts: 287
Location: Fort Wayne, Indiana
I found it very interesting that math instructions are swapped around, where the "special" register is the only source instead of the only destination.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 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