Stumped (entry level ASM, gah)

Page 1/6
| 2 | 3 | 4 | 5 | 6

By Driehoogvoor

Resident (52)

Driehoogvoor's picture

10-08-2014, 11:35

After years of not writing any assembly, I thought it would be fun to see if I could still do it. So I set out to write a simple parallax star field. The very first thing I'm trying to write, though, is slowly driving me insane—a simple wait for space key press... I have no idea why, but it keeps crashing.

This should work, right? It crashes both my real MSX (an F700D) and openMSX. Please help, I'm losing my mind here. Crazy

ORG #C000

KEYS: EQU #FBE5

LOOP: LD A,(KEYS+8)
BIT 0,A
JP NZ,LOOP

RET
Login or register to post comments

By Sandy Brand

Champion (277)

Sandy Brand's picture

10-08-2014, 12:10

Try placing it lower in memory? (Like say, #9000).

From what I remember, on MSX 2 with diskdrive(s) quite a lot of memory is reserved by disk controllers and such in memory slot #C000 .. #FFFF. For MSX-DOS it goes down to something like #D000 so that should be safe; so I assuming here that you are running it from BASIC?

By kanima

Master (194)

kanima's picture

10-08-2014, 12:19

A couple of things I can think of that might be messing things up:

1) somehow the program starts executing with the interrutps disabled; the values in the KEYS array at $FBE5 are stored there by the interrupt handler which regularly scans all the key rows and then stores the results in that array. So, either read from the PPI directly yourself (if you ever replace the interrupt with your own you'll have to do that anyway) or enable the interrupts using EI at the start of your program.

2) you assemble this into a .com file; .com files start at $0100, not $c000. The JP NZ, loop translates to JP NZ,$c000, but with your program being at $0100 everything goes haywire.

3) you assemble this into a file for loading with BLOAD "file.bin",R in which case it's probably missing the 7 byte header; see http://www.msx.org/wiki/MSX-BASIC_file_formats#MSX-BASIC_binary_files This very probably is not the problem though, since your first byte is $3a, not $fe, so you should just get a warning from BASIC, not a crash

By Driehoogvoor

Resident (52)

Driehoogvoor's picture

10-08-2014, 12:17

I'm running it from Compass. That loads from MSX-DOS, so #C000 should be good, I think. I'll try #9000.

The weird thing is that if I do something like outputting a character to the screen before waiting for the space bar, it works just fine:

ORG #C000

KEYS: EQU #FBE5

LD A,65
CALL #00A2

LOOP: LD A,(KEYS+8)
BIT 0,A
JP NZ,LOOP

RET

By Driehoogvoor

Resident (52)

Driehoogvoor's picture

10-08-2014, 12:20

Kanima, I think it was the interrupts, like you said. If I replace the CHPUT call with simply EI, it works. Man, that's weird. Why would it start with interrupts disabled? :-/

By AxelF

Champion (395)

AxelF's picture

10-08-2014, 15:50

I think there are more elegant ways to detect the spacebar
For example Bios Calls #D8 GETTRIG or #9F CHGET... See the list of BIOS calls

OR if you dont want to use the BIOS see PPI controlls to read directly from the keyboardmatrix.

The MSX Assembly Page is a great recource for learning ASM

By Grauw

Ascended (10564)

Grauw's picture

10-08-2014, 16:36

Driehoogvoor: If you start directly from Compass, that’s just the way it does it I suppose. Loading from MSX-DOS or Basic, interrupts will always be enabled though.

When you want to read from the keys array for a game, keep in mind that it’s not updated every interrupt.

By Driehoogvoor

Resident (52)

Driehoogvoor's picture

10-08-2014, 17:06

Thanks, guys. You're right that it's better to read from the keyboard matrix directly. That'll be one of the things on my list when I'm going to clean up my code.

It's going pretty well. I've got a hook on H.TIMI that updates the screen. Rendering the stars and updating the x-coordinates works perfectly. I can't get CLS to work, though. I'm calling #00C3, but it doesn't do anything. If I use XOR A first, like Grauw suggests in the MSX BIOS document, it crashes my MSX.

Any tips? Calling #00C3 is the right way to clear the screen, right?

I'm having loads of fun writing assembly again, by the way. It's so different from what I normally code. Thinking in registers and addresses is so different than thinking in abstractions and models. Smile

By Grauw

Ascended (10564)

Grauw's picture

10-08-2014, 17:25

Actually BiFi wrote the MSX BIOS document Smile.

That said, xor a indeed sets the z flag, and the MSX2 technical handbook (linked from the MAP) also agrees that it must be set, so I don’t know what’s wrong. It’s a weird requirement though, what is it supposed to do if z is not set…

Glad you’re having fun! I completely agree.

By the way, Compass has a debugger, and openMSX does as well. It can be very helpful.

By Driehoogvoor

Resident (52)

Driehoogvoor's picture

10-08-2014, 17:36

Weird, I checked with the Compass debugger. Address #00C3 jumps to #0897 and that's a RET NZ instruction, after which it does the actual clear screen. It modifies pretty much every flag and register while actually clearing the screen, so I have no idea why it cares so much about the Z flag's initial state. It's designed to care, that's for sure, but why? Question Ah, well...

By AxelF

Champion (395)

AxelF's picture

10-08-2014, 18:34

As you said CALL #C3 allso changes the BC and DE registers.
If you still have some data in these regitsers, it wil be lost after the call.
to prevent this use PUSH and POP to save the registers to stack

...
push BC
Push DE
    Xor A
    call #c3
Pop DE
Pop BC

Call #C3 first has to find the width of te schreen, to see what earea that has to be cleaned

Page 1/6
| 2 | 3 | 4 | 5 | 6