*Very* new to ASM. Where to start?

Página 2/5
1 | | 3 | 4 | 5

Por Mirg

Expert (88)

Imagen del Mirg

16-09-2005, 23:03

Ok, I've done a lot of reading, I've gotten familiar with WBASS2, I even understand the simple demo-program used in its manual and I've started reading "How to program the Z80 (3rd edition)" from cover to cover (on PDF, as my physical copy is in the mail (I hope)). Big smile

Let's see if the information that's my slowly beginning to form in my head makes any sense so far.

With an assembler, you basically put opcodes (assembler codes translated to their bytecode equivalent) in the MSX's memory. When executed, the code is pretty much interpreted like BASIC (a pointer runs through the code, executing command after command until the code finished with a final RET).

That's correct, right? Tongue

I've noticed that some commands, like DEFB, aren't described in the "Z80 instruction set" bit of "How to program the Z80". Are those MSX-specific, or maybe WBASS2 specific even?

Also, I've searched for an easy to understand schematic / list of the MSX's memory layout, but I can't seem to find one that I understand. What I mean is some sort of diagram that says "From here to here is BIOS, from here to here is yours" or something like that. So, anyone got any tips for an easy to comprehend explanation of the memory model? Smile

Again, sorry for all the questions. Slowly but surely, I'm getting there. Tongue

Por Edwin

Paragon (1182)

Imagen del Edwin

16-09-2005, 23:27

DEFB/DB, DEFW/DW are just direct data lines for bytes and words that the assembler puts into memory directly.

MSX memory layout is a bit tricky. Memory is separated into 4 pages (starting at $0000, $4000, $8000, $C000) of 16K. Each of those pages is set into one of four slots (0 usually being ROM, 1,2 usually the external slots and 3 usually ram). Some slots may have up to four subslots as well. Memory slots can have a mapper with up to 256 pages. And all of that stuff can be changed around when needed. There should be plenty of docs around describing the slot/mapper structure. When in basic, the first two pages ($0000-$7FFF) are in rom and the last two are in ram ($8000-$FFFF). So you should initially start using the ram area for your code until you figure out how to deal with the memory. You may want to remember that basic programs are stored starting at $8000 and that ram above $D500 is often already in use by disk basic and other stuff.

Some more detail info here.

Por ARTRAG

Enlighted (6845)

Imagen del ARTRAG

17-09-2005, 00:13

Hi Mirg
There are many "op code" like DEFB that actually are command for the assembler. They can have many purposes,
you can use tham in order to fill a memory position with a data, leave free some memory position, assemble the source
like it where at a given address, etc. etc.
All those commands are for the assembler, NOT for the z80, and their meaning and sintax depend on the assembler
you have chosen.
One very nice thing to understand and use are MACROS. A macro is a short segment of code that has a
proper name.
The assembler, each time that finds the macro's name, substitutes that name with the corresponding segment of code.
Macros can have paramates and can easily substitute function calls in many cases, but their
implementation depends on the assembler you have chosen.

Por Mirg

Expert (88)

Imagen del Mirg

17-09-2005, 00:15

Thanks! That was exactly what I was looking for! Smile

My first "program" just echoed keypresses. Now, I'll try to put a pixel on screen, but I guess I'll need the VDP for that. If it proves a bit too difficult, I'll try some more screen 0 stuff I think. Smile

At least the memory bit is way more clear now. Big smile

Por norakomi

Paragon (1123)

Imagen del norakomi

17-09-2005, 09:36

putting a pixel on screen 5 for instance:

ld a,5
call $5f ;screen 5

call vdpwrt
....
....
....
....
ret

VDPWRT: ;set vdp to write page 0
LD C,$99
LD A,H
AND $C0
RLCA
RLCA
DI
OUT (C),A
LD A,14+128
OUT (C),A
LD A,H
NOP
OUT (C),L
OR 64
EI
OUT (C),A
RET

This is what you need to do...
so you SET the vdp to write....
in this case you write to page 0.
Set in HL the address where you want to write...

For instance if HL=5 then you write at top line of the screen
the 10th pixel.
if HL=100 then you write top line 200th pixel.
if HL=200 then you write the 400th pixel, which is 2nd line, 144th (144+256=500) pixel.

To actually write I guess you have to send a color value to port 98, something like.

ld a,16 ;color 16, usaully white
out ($98),a

I could have made some mistakes here,
lemme know if it worked.

Bart

Por ARTRAG

Enlighted (6845)

Imagen del ARTRAG

17-09-2005, 11:23

Ok let me recollect.
The VDP has a separate memory space (128KB of VRAM) that cannot be accessed directly by the Z80.

This memory is used to by the VDP to display the current screen and sprites. The VDP has also a set of write only registers whose values indicate the screen mode (scr0- 40 columns, scr0-80 columns, scr1,2,3,4,5, etc. etc.)

In order to change video mode (e.g. to go to screen 5) you need to change the VDP registers, (look the VDP manual at http://map.tni.nl/resources/v9938.html for register’s meaning) or to use a BIOS call passing the right parameters.

Once you are in the correct video mode, reading the VDP manual you need to understand (look at the VDP manual http://map.tni.nl/resources/v9938.html) how the memory is used in that video mode in order to display the current screen. In screen 5, each byte means two pixels of 16 colors (it is a bitmap mode, look also the use of the memory in scr5 on the VDP manual in order to understand how pages work and where they start in VRAM).

In order to modify the VRAM you need to use the I/O ports of the z80 98H and 99H that are connected to the VDP (also other ports are used by the VDP, but not for VRAM access). This architecture is slower than having VRAM directly mapped in RAM, but gives us much more room for RAM and VRAM.

First you specify the address from where you want to start to write (port 99H is used for this), then you write the bytes you want to write at port 98H (the address increments automatically).

Actually, as the VRAM address space is 128Kbyte, setting a generic VRAM address involves also the change of a VDP register (R# 14).

The best thing I can do is to link to this good tutorial on the use of the VDP
http://map.tni.nl/articles/vdp_tut.php

Going back to norakomi’s example, let say you want to draw a dotted (black and white) line of 128 pixels form (0,0) to (128,0)

ld a,5
call $5f ;screen 5

ld hl,0 ; address 0 in VRAM
call vdpwrt

ld b,64 ; 64 bytes = 128 pixels
ld a,#F1 ; left pixel white (#F), right pixel black (#1)
loop:
out (#98),a
djnz loop

Por Mirg

Expert (88)

Imagen del Mirg

18-09-2005, 12:00

Thanks! I'm going to try that out right now. I was wondering how that whole VDP-thing worked, heh. Thanks for clearing that up. Smile

One more tiny lil' thing, though. In BASIC, you could easily define variables to hold all kinds of information, like the X and Y coordinates of a cursos for example. How does something like that work in ASM?

My guess is to store the values at some address and then use LD HL,$xxxx to retrieve them and LD (HL),$xxxx to modify them? Or shouldn't I be using HL for that?

Por Mirg

Expert (88)

Imagen del Mirg

18-09-2005, 12:22

Oh, one more question, or two actually, about speed-issues.

In norakomi's VDPWRT-code, there's this construct:

LD C,$99
OUT (C),A ; This is used four times

Isn't it faster to use OUT ($90),A instead, as it would save the one LD C,$99 command? It's just nutpicking probably, but I'm trying to understand the whole optimized code thingy as I'll ultimately attempt to make a game in the far, far future.

Also, there's this:

LD A,14+128

The +128 is to make clear that bit 7 is set, right? But where is the "14+128" calculated? Does the assembler calculate, or the program you end up with? If it's the assembler calculating it to 142 before building the program in memory, no worries, no speed gained by just writing 142. Smile

Por AuroraMSX

Paragon (1902)

Imagen del AuroraMSX

18-09-2005, 13:23

Isn't it faster to use OUT ($90),A instead,
OUT ($99),A Smile, but yes. You're right
LD A,14+128

The +128 is to make clear that bit 7 is set, right? But where is the "14+128" calculated? Does the assembler calculate, or the program you end up with? If it's the assembler calculating it to 142 before building the program in memory, no worries, no speed gained by just writing 142. Smile
The assembler does this, you'll find no trace of the addition in the assembled code. Alternatively, one could have written "$8E", which - to me - is just as clear as "128+14", but at least clearer than plain "142" Smile

Por Mirg

Expert (88)

Imagen del Mirg

18-09-2005, 13:24

Whoops, typo, heh. Well, at least the typo is in here instead of in my code, making me wonder why my code's not working. Tongue

And thanks for clearing that up. Big smile

Página 2/5
1 | | 3 | 4 | 5