Learning MSX assembler for games development, where to start?

By karloch

Prophet (2135)

karloch's picture

30-05-2021, 18:01

Hi *.*,

Although I have been on the MSX community for so long and currently I host the HispaMSX BBS, I would like to give a try to code a simple game for MSX. There are several things I am already familiar with:

  • I know how to code, at least at the foundational level. I am used to ANSI C language; so memory management, pointers, linked lists, dynamic arrays... are stuff I am quite familiar with.
  • I know the syntax and commands of Z80 assembler, mostly thanks to the awesome Easymbler from Nestor Soriano.
  • I know the hardware features and video modes of each generation of MSX and some of the limitations as the 5th sprite rule in the first generation.

But there are a lot of basics that I don't know and that's why I ask for guidance in this post:

  • The biggest of all my doubts: I don't know how to turn my assembler syntax knowledge into a program; not even something that sets a screen for painting sprites and graphics. I don't know anything about addressing, where to write values, how to read from keyboard, how to play music or sounds... Heck, I don't know even how to write a Hello World. I know nothing, like John Snow.
  • What support tool for drawing graphics or sprites are there? If I target MSX 1, SCREEN 2, then I guess that everything I paint on the screen is tileset based, is that correct? What are the differences vs using MSX 2 SCREEN 5 that is bitmap based?
  • ROM, BIN, COM, MSX-DOS... I don't know how to produce something executable in assembler and what is the difference between doing in one format or another. I guess ROM is the easiest, as everything is memory.
  • How to establish a game logic in assembler. Do I need a main loop that call routines to paint screen, check collisions, play the music, read keyboard...? How is that actually done? Some example would be very welcome.
  • I know there are several assemblers out there, is there any of them that would be recommended for a starter like me? What are the differences between one and other?
  • What is the best IDE environment for development? It would be great if I can use some combination of VisualStudio Code + openMSX for debugging, but maybe I am just dreaming
  • Is there a book, recommended read that you could tell me? I know the MSX 2 Technical Handbook is our bible, but is that a recommended one according to all the knowledge I lack of?

I am afraid I could have asked way too many questions, sorry for the long post.
Thanks!

Login or register to post comments

By santiontanon

Paragon (1470)

santiontanon's picture

30-05-2021, 18:56

Wow, lots of questions. Let me see if I can help a bit:

To get started, I'd recommend just starting with something simple!
- Take your favorite text editor (I am not a big fan of VisualStudio Code that you mention, but if that's your favorite, then by all means, use that one), and copy paste this into a new file (e.g. "example.asm"):

; BIOS functions / MSX constants----------------
WRTVDP: equ #0047
LDIRVM: equ #005c
CHGMOD: equ #005f
SPRTBL2: equ #3800   ; sprite pattern address          
SPRATR2: equ #1b00   ; sprite attribute address         

; ROM header -----------------------------------
    org #4000
    db "AB" ;   ROM signature
    dw Start  ; start address
    db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

Start:
    ld a, 2  ; Change screen mode (Screen 2)
    call CHGMOD
    ld bc, 0e201h  ; write e2h in VDP register 01h (activate sprites, generate interrupts, set 16x16 sprites)
    call WRTVDP

    ; Define sprite:
    ld de, SPRTBL2
    ld hl, shipsprite
    ld bc, 32
    call LDIRVM

    ; transfer sprite attributes to RAM:
    ld ix, spriteattributesRAM
    ld (ix), 64  ; y
    ld (ix+1), 64  ; x
    ld (ix+2), 0  ; sprite pattern
    ld (ix+3), 15  ; color

loop:
    halt  ; make the program run at 50/60 frames per second

    ld hl, spriteattributesRAM + 1
    inc (hl)  ; increase x

    ;; Update the sprite attributes in VRAM:
    ld hl, spriteattributesRAM
    ld de, SPRATR2
    ld bc, 4
    call LDIRVM

    jp loop

shipsprite:
    db 00h, 00h, 01h, 01h, 01h, 03h, 03h, 07h, 07h, 0fh, 1fh, 3fh, 3ch, 18h, 00h, 00h
    db 00h, 00h, 80h, 80h, 80h,0c0h,0c0h,0e0h,0e0h,0f0h,0f8h,0fch, 3ch, 18h, 00h, 00h

    ds 8000h - $  ; fill the rest of the ROM (up to 16KB with 0s)

    org 0c000h  ; RAM
spriteattributesRAM:
    ds virtual 4

- This is a complete example to create a ROM that moves a sprite, and should show you how to get started in creating a ROM, set up the video mode, how to create the main loop, etc.
- It's time to compile it! Choose an assembler. I like Glass http://www.grauw.nl/projects/glass/ because it's simple, cross platform and open source. But feel free to use another one. Other typical choices are tniasm (proprietary, I don't recommend it), pasmo, sjasm, sjasmplus, asmsx, etc. (or you can even use my own "MDL", but it's a more complex one to use, so, probably not for beginngers). Assuming you chose Glass, you can compile with:

java -jar Glass.jar example.asm example.rom

- And there you go! you should have a rom file compiled!
- You can now just run it in openMSX, or your favorite emulator
- For debugging, I recommend openMSXDebugger
- For drawing graphics: as you can see in the example, the sprite is defined directly in code. But there are many tools. Honestly, I recommend using a general-purpose tool like GIMP, and then just write your own scripts that convert the graphics you draw into whichever format you want it for your assembler code.
- For music, I guess that's a bit more involved. So, maybe next time around, but basically you have two choices: (1) you can do it your own (send commands to the PSG yourself, write your own playback code), or (2) use an existing tool like TriloTracker that have assembler libraries for reproducing music. If you are going to work on small MSX1 games, I recommend (1), since existing trackers/players are pretty large and would use a significant chunk of your cartridge. If you are thinking of a larger game (megaROM, MSX2, etc.), then definitively (2).

Anyway, I hope this helps and can get you started. You can take the example above, and start editing it, building from it (maybe you can try to take that example, and make the ship controllable with keyboard/joystick as a first next step :) )

By DamnedAngel

Master (227)

DamnedAngel's picture

30-05-2021, 21:00

There are several routes to choose from. Let me propose my suggestion:

I made a set of templates for C and ASM programs to MSX. Initially they were MS Visual Studio ony, but now, while the their foudation remais that IDE, they grew to allow other IDEs to be used. They even work on linux and Mac. Yes, you can use Visual Code and the build script generates symbol files to be used in OpenMSX Debugger. Seems a match.

There are three templates: ROM, MSX-DOS and BIN (to be BLOADable in MSXBASIC). Also seems a match for your expectations.

With them you can choose to have a pure ASM project, a pure C project or a MIX. If you know C, you could start with a C program and develop your ASM routines when performance is needed. Or you can go berserk and do everything in ASM.

The build script is pretty configurable to add more source files and libs, with some handy configurations to choose from.

The templates are compatible with Fusion-C, the C framework for MSX, which may get you started in a very short time.

All templates have two hello world examples: one for C and one for ASM. They are ready to be compiled (SDCC, python and Hex2Bin needed, but all free) and expanded into your program. Again, another match.

If you decide to give them a try, you can find them at https://github.com/DamnedAngel/MSX-Templates-for-VisualStudio.

I will be glad to give you any assistance you may need in order to get things on track.

By karloch

Prophet (2135)

karloch's picture

30-05-2021, 22:27

Thank you Santiago! The sample code gives me a place where to start, it is really useful. I can understand the code, except the very last line: ds virtual 4 What's "virtual" and why the "4" value?

@DamnedAngel: I want to go the full ASM way. Programming-wise, what is the difference between ROM, BIN and MSX-DOS executable?

By MsxKun

Paladin (1019)

MsxKun's picture

30-05-2021, 22:40

Programming wise... most of the times (not always), on a ROM code you will have it on a .. ROM, Yes, read only. So all the variables are going to go somewhere in the RAM. And most probably you're going to have the BIOS on page 0, available.
You can only count with 8kb of RAM for sure (and some of it is used by System variables), tho maybe there is more, you will have to check yourself.
A BIN will be loaded already in RAM so, if you wish, you can put variables between your code. Or not, you can do it like a ROM. Only the header changes, and the code starting address, as typically (not always) the ROM will start at $4000 and if you load a BIN from Basic the Interpreted is located there so you need to put code from $8000 above. BIOS is also available.
Still you can count with, for sure, a minimum of 8kb of RAM that will be even less being in Basic.
A COM will run under MSX-DOS. That means your code will be in RAM, like a BIN, but starting at $100 and you'll have a minimum of 64kb of RAM for sure. For your code and your data. BIOS is not directly available, but can be used.
Also on a COM, as you're under DOS, you can access some MSX-DOS routines, not only for disk access.
Sure, you can too on a ROM and BIN, but you can't be sure there is MSX-DOS available and you'll have to check and call BDOS with a bit more of hassle.
So, in the end, there's not much difference. Mostly if you use BIOS, under DOS you need some extra care to use it, but not a big deal.

By MsxKun

Paladin (1019)

MsxKun's picture

30-05-2021, 22:54

karloch wrote:

@DamnedAngel: I want to go the full ASM way.

That's a wise choice. Easier and more clear. You really only need any text editor (the simpler you can get is perfectly good for the job. But one with fancy colors and stuff sometimes saves you some work) and an Assembler. And some doc, sure Smile
All you need to know is your machine, Z80, VDP and PSG (mostly, for a start). And, for a start, the BIOS is your friend.

By santiontanon

Paragon (1470)

santiontanon's picture

30-05-2021, 23:07

karloch wrote:

Thank you Santiago! The sample code gives me a place where to start, it is really useful. I can understand the code, except the very last line: ds virtual 4 What's "virtual" and why the "4" value?

Oh, sorry for the lack of comment there! that is "Glass" syntax, other assemblers would define that differently. Basically what that line does is to define a block of RAM of 4 bytes (for "spriteattributesRAM"), to store the sprite attributes in RAM (y, x, pattern index, color).

Let us know how is your learning experience! I think there's a few other users in the forum also starting to learn assembler, so, maybe their threads are useful too:
- This one where Pbk71 is reporting his progress in learning to code his first assembler game: https://msx.org/forum/msx-talk/development/writing-my-first-...
- And this one where Pbk71 (and I just realized both threads are by the same user, didn't realize until now haha) is reporting progress in writing a blog about learning to code in assembler: https://learningmsxmachinecode.blogspot.com/

Best of luck with your coding! :)

By DamnedAngel

Master (227)

DamnedAngel's picture

31-05-2021, 02:23

karloch wrote:

@DamnedAngel: I want to go the full ASM way. Programming-wise, what is the difference between ROM, BIN and MSX-DOS executable?

That's an option too. The templates do support that and have the hello world ready for you, with a build script to automate the compilation/assembly processes in a neat manner and generate the symbol file for openMSX debugger.

Of course, other assemblers/tools can help you as well and you may find similar features.

ROM is a image suited for cartridges, but nowadays can be easily run fom MSX-DOS using tools like SofaRUN/SofaROM or ExecROM.
MSX-DOS is a program to be run form the S.O. natively. Your program is located on RAM and has *almost* the full 64kb space to deal with, and probably more with a memory mapper.
BIN are programs you run from MSX-BASIC with the command BLOAD.

From the programming perspective they are very similar.

Normally games are made in ROM format, which opens the possibility of a physical cartridge version. I personally like the MSX-DOS format, with games that can be called from the S.O. *AND* eventually return to it without booting the machine. But unfortunatelly these are quite rare.

By ~mk~

Champion (301)

~mk~'s picture

31-05-2021, 21:44

I have also been wondering why some of the recent 64k games that have been released (Stupid Martians, Mutants from the Deep) are not released in different formats, eg. MSX-DOS com format.
I guess the answer is because it would take a lot of work and requires many parts of the code to be programmed differently (e.g. to load data from disk, because MSX-DOS and command interpreter uses some of the 64k of ram), and apart from that, nowadays most MSX users have a flashrom cartridge.
But IMO, it would be nice if game developers consider releasing games in other formats other than rom.
Might not be straightforward, but would open up the possibilities a bit more... I think.
I would love to hear the opinion from some of the experienced game developers.

For now, I am starting to get the hang of the MSX-C compiler, and I am having lots of fun.
I am not coding a full game (which might be a different story) but I am willing to go in that direction, and it gives a nice feeling to do all the development within MSX, and test the results inmediately without any cross development or external tools. Of course, I am using an emulator to speed up compile time, but if I only had my MSX I could still do the same and it would just take longer.
But I think cross compiling can also output binary format, so here I am talking about two different things.
I hope I can progress with my little project soon and have something to show Smile

By thegeps

Paladin (855)

thegeps's picture

31-05-2021, 22:08

Yep, cross compilers can output binary format too.
Developing cartridge games (roms) allow to avoid loading times. And problems like drives' malfunctions (they happen often, in 30-40 years old machines...

By karloch

Prophet (2135)

karloch's picture

05-06-2021, 20:36

Thank you so much for all the answers. I have now a place where to start Smile