Basic and machine codes

بواسطة Shinobi

Master (200)

صورة Shinobi

24-05-2023, 13:57

I learned the important stuff of z80 code with bios calls
I know msx basic
If i want to make a simple game, how do i incorporate basic and machine code..
I know about def usr and executing machine code..
But what I am asking is what parts of the program to write in assembly and what about jump addresses..should i calculate them in paper then adding them to the program..
Thanks

Login أوregister لوضع تعليقاتك

بواسطة theNestruo

Champion (430)

صورة theNestruo

24-05-2023, 15:47

Use a jump table as the entry points.
Let's say your machine code starts at &H9000:

  org $9000
  JP routine0
  JP routine1
  JP routine2
  JP routine3
routine0:
  ; ... your code here ...
  ret
routine1:
  ; ... etc ...

You will DEF USR at fixed addresses &H9000 for routine0, &H9003 for routine1, &H9006 for routine2, etc. regardless the actual length of your routines.

بواسطة shalafi

Master (171)

صورة shalafi

24-05-2023, 16:02

If you use MSX BASIC kun, you can embed assembly code with a preprocessor instrucción

بواسطة ericb59

Paragon (1126)

صورة ericb59

24-05-2023, 18:02

I like also the idea to call BIOS routine from Basic.
This is simple to do, and versatile.

Check from here : https://www.msx.org/forum/msx-talk/development/basic-program...

بواسطة Shinobi

Master (200)

صورة Shinobi

24-05-2023, 22:31

theNestruo wrote:

Use a jump table as the entry points.
Let's say your machine code starts at &H9000:

  org $9000
  JP routine0
  JP routine1
  JP routine2
  JP routine3
routine0:
  ; ... your code here ...
  ret
routine1:
  ; ... etc ...

You will DEF USR at fixed addresses &H9000 for routine0, &H9003 for routine1, &H9006 for routine2, etc. regardless the actual length of your routines.

So from what I understand, I will write the code in assembler then take the opcodes to basic DATA statements and poke them to memory and execute them...right??

بواسطة Sandy Brand

Champion (309)

صورة Sandy Brand

25-05-2023, 00:59

Manually poking the assembler into memory will definitely work. Smile

However, if your game is going to be bigger or more complex, maybe a simpler way would be to load the binary opcodes directly into memory using the BLOAD command.

Most assemblers can generate .bin files directly, and it will make your BASIC program significantly smaller (DATA statements are not the most efficient way to store large amounts of binary data), leaving more room for your assembly code.

Maybe as a general rule of thumb: use BASIC to handle the loading and initialization of memory+video memory and the high level states of your game application, and let the assembly do all the rest that requires the speed :)

بواسطة cjs

Master (143)

صورة cjs

25-05-2023, 05:09

It can be very educational to reverse-engineer other programs to see how they work.

For example, I've done a fair amount of RE work on the assembly language part of Slime World, an action RPG from the Frieve in MSX-FAN collection.

As described in the Theory of Operation I wrote up, that game uses machine language for two things. One is doing VRAM data copies to implement scrolling of the on-screen map, disassembled and reverse-engineered in src/scrollmc.asm. You'll note that there are several files full of data (the charset for the graphics and various maps for different levels) directly loaded into VRAM.

The other is for the background music. SLMOPNG.SLM, reverse-engineered in src/slimopng.slm, handles the setup for this by loading and running FMSLOTCK.SLM, reverse engineered in src/fmslotck.asm, to check for MSX-MUSIC and copy its BIOS to RAM page 1, if present. The BASIC code then lets the user pick between PSG and FM (if FM is present) and loads the appropriate file with the player and sound data, which copies the various routines it needs to BASIC-accessible RAM and page 1 RAM. Following the reverse-engineered code from src/bgm-psgv.asm through the files that it includes should give a good sense of how it works.

If you have particular questions about it,it's probably faster and easier to ask me in Discord on The MSX2 Channel server (link good for seven days only) or PM me there at cjs#6537.

بواسطة gdx

Enlighted (6439)

صورة gdx

25-05-2023, 09:35

Shinobi wrote:

I know about def usr and executing machine code..
But what I am asking is what parts of the program to write in assembly and what about jump addresses..should i calculate them in paper then adding them to the program..

No need to calculate. Assemblers tell you the addresses of the labels, but a jumps table saves you from having to modify the addresses of the DEFUSR with each modification of the routines in machine.

بواسطة wilsonpilon

Champion (279)

صورة wilsonpilon

25-05-2023, 19:48

I like that approach. After the bload "prog.bin",r the program itself defines the DEFUSR 0..9, just call each one with USR, and can still use a parameter for each one

;***** Rotinas principais do programa *****************************************

include source/msxsys.asm
;***** Definicoes do Programa *************************************************
BUFA30 equ 0A000h

;***** Rotina de Entrada ******************************************************
ORG 0D500h
POSX: db 12
POSY: db 6
WIDT: db 39
HEIG: db 22
CHAR: db 20h

MAIN:
ld hl,CHOICE ;Prepara USR0(0) / Rotinas Gerais
ld (USRTAB),hl
ld hl,PTSTR ;Prepara USR1("") / Impressao
ld (USRTAB+2),hl
ld hl,IPTSTR ;Prepara USR2("") / Impressao Invertida
ld (USRTAB+4),hl
ld hl,BOOK ;Prepara USR3(0) / Rotinas do livro
ld (USRTAB+6),hl
ret

;***** Escolhe a rotina de acordo com parametro USR(x) ************************
CHOICE:
ld a,(FACLO)
cp 0
jp z,BLOCO
cp 1
jp z,SAVSCR
cp 2
jp z,LODSCR
ret

;***** Preenche uma sequencia de caracteres na VRAM ***************************
BLOCO:

بواسطة DamnedAngel

Champion (286)

صورة DamnedAngel

25-05-2023, 21:24

Tip/Autopromotion: if you use my BIN template, not only you can develop both in ASM and in C and compilation/assembly is a breeze and you'll get OpenMSX Debugger-compatible symbol files, but it will also help you with the integration with BASIC. You can enable the publishing the address of the routines in ASM to be accessed from BASIC, and the integration will not break even when the addresses of the routines change as consequence of new code being added.

You can just declare which symbols are to be published in a configuration file and with a simple BASIC routine you can safely determine your DEFUSR addresses and feel free to cade in ASM (or C) afterwards:

;----------------------------------------------------------
;	BASIC USR routines index
;
; NOT MANDATORY!
; Use this to have an address table to
; access from other routines - or from BASIC.
;
; BASIC usage example (for the standard app)
; 10 BLOAD "MSXAPP.BIN",R:REM Prints "Hello, MSX from !"
; 20 HM = PEEK(&HFC4A)+256*PEEK(&HFC4B)-2:REM Gets himem
; 30 FS = PEEK(HM)+256*PEEK(HM+1):REM Gets filestart (NEEDS TargetConfig|PUBLISH_FILESTART ON)
; 40 PRINT "Program starts at ";HEX$(FS);"."
; 50 AR = PEEK(FS)+256*PEEK(FS+1):REM Gets the first address in the index (_printFromBasic)
; 60 PRINT "_printFromBasic published at ";HEX$(AR);"."
; 70 DEFUSR = AR
; 80 M$="Hi MSX from a BASIC USR call!"+CHR$(13)+CHR$(10)+CHR$(0)
; 90 MA=VARPTR(M$):MS%=PEEK(MA+1)+256*PEEK(MA+2)-2^16
; 100 A=USR(MS%):REM Prints "Hi MSX from a BASIC USR call!"
;
SYMBOL			_printFromBasic			; USR/USR0
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR1
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR2
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR3
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR4
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR5
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR6
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR7
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR8
;SYMBOL/ADDRESS	_xxxxxxxxxxxxxx			; USR9

You can check my templates at https://github.com/DamnedAngel/MSX-Templates-for-VisualStudio/tree/master.

Note: despite its name ("for Visual Studio"), you can safely use any IDE or OS of your liking.