BBC BASIC
Programming >> Assembly Language >> Interrupts
http://bbcbasic.conforums.com/index.cgi?board=assembly&action=display&num=1466323816

Interrupts
Post by Ric on Jun 19th, 2016, 08:10am

I have spoken to RTR already, so to get you up to speed :-

I posed the question - "Why does the int operand not seem to work?"

And Richards reply -

The explanation is quite simple really. INT is a 'privileged'
instruction which can only be used by the Operating System Kernel. If
you attempt to execute it from a user-mode program, such as a Windows
application, it will immediately fault with a protection violation.

As such it's in the same category as the port input/output instructions
IN and OUT (and the related INSx and OUTSx instructions), which will
also cause a fault if you attempt to execute them in user mode.

You may well ask why the BB4W assembler includes instructions that you
can't use! The reason is twofold. Firstly since the instructions could
be used (and were useful) in MS-DOS, and of course the 32-bit assembler
in BB4W was derived from the 16-bit assembler in 'BBC BASIC for MS-DOS',
they were already there. Secondly in Windows 9x (95/98/Me) user-mode
programs *could* successfully execute some of these privileged
instructions. Conceivably you might even use the BB4W assembler to
write code destined to run on a system which does allow those
instructions to be used.

But as far as 'modern' Windows is concerned those instructions are 'off
limits'. As you're programming in assembler code you may find it
helpful to install a 'post mortem debugger' because that will give you
much more information when a crash occurs, and in this case would
probably have made the cause more obvious.

Re: Interrupts
Post by Ric on Jun 19th, 2016, 08:23am

Thanks Richard

This then leads to a few more questions.

How do I generate the equivalent asm routine for INKEY(-n), is there a way of coding CALL "oskey"? Ihave tried putting a negative number in to the eax register in hope, but this is not the answer.

I have stumbled across GetKeyboardState, but don't know if this is the answer.

I would also like to imitate int 33,3 and read the mouse inputs?

Ric
Re: Interrupts
Post by Richard Russell on Jun 19th, 2016, 09:43am

on Jun 19th, 2016, 08:23am, Ric wrote:
How do I generate the equivalent asm routine for INKEY(-n), is there a way of coding CALL "oskey"? Ihave tried putting a negative number in to the eax register in hope, but this is not the answer.

The thing you probably didn't realise is that the information is returned in the carry flag. Here is a working program to demonstrate:

Code:
      DIM P% 16      [      .spacebar      mov eax,-99      call "oskey"      cmc      sbb eax,eax      ret      ]      REPEAT        WAIT 10        IF USR(spacebar) THEN          PRINT "Space bar pressed"        ELSE          PRINT "Space bar NOT pressed"        ENDIF      UNTIL FALSE 

Quote:
I would also like to imitate int 33,3 and read the mouse inputs?

INT &33 is an MS-DOS interrupt so not relevant to Windows at all. If you want information about the mouse call the relevant Windows APIs: GetCursorPos for the mouse coordinates, in screen units, and GetAsyncKeyState for the state of the buttons.

However there is almost certainly an easier way of going about this. It is rare, and in many respects undesirable, for assembler code to run continuously for long periods. For example no event interrupts will be processed (such as ON CLOSE) and not even the ESCape key will be monitored, unless you do so in the assembler code.

Almost always it will be easier and more satisfactory for the assembler code to return periodically to BASIC. For example if the assembler code is drawing graphics, it will probably want to return to BASIC every 'frame' in order to update the display. The time taken to do this will be negligible, and it's much easier than doing everything in assembler.

So if you are in any case regularly returning to BASIC, test the keyboard and mouse there! You can easily communicate the information to the assembler code, for example in shared variables. Check out the supplied example program MANDEL.BBC for an example of this.

BBC BASIC is not an ideal platform on which to write 'pure' assembler code, that is code which does everything in assembler and runs continuously without returning to BASIC. That kind of code is better written using a conventional assembler like NASM or FASM.

The power of the BBC BASIC assembler is in mixing BASIC code and assembler code so that each does what it does best. Time-critical things can be done in assembler whereas non-time-critical things like user input can be done in BASIC. This 'division of labour' can be a very powerful technique.

Richard.
Re: Interrupts
Post by Ric on Jun 19th, 2016, 1:34pm

Thanks Richard,

Again for the detailed answer. You are right, I was checking eax directly on return, hence the failure.

The reason I want to access the keyboard in assembler is just to test my 3d software without dropping fps. When I have sorted it to a standard which I am happy with ,i will put a proper user interface in, in Basic.

Ric

PS. It is all just for a personal challenge. And why not, it's fun.
Re: Interrupts
Post by Richard Russell on Jun 19th, 2016, 3:16pm

on Jun 19th, 2016, 1:34pm, Ric wrote:
The reason I want to access the keyboard in assembler is just to test my 3d software without dropping fps.

Remember that there is virtually no benefit in the frame rate exceeding about 60 fps, because the eye/brain system cannot perceive the difference. The only effect is to waste CPU time and flatten batteries prematurely! Having spent much of my career in the business of generating high-quality video I am not impressed by meaningless FPS values. tongue

The thing to aim for is a fixed frame rate (ideally synchronised with the display refresh) and then to take full advantage of those 16 milliseconds or so per frame to make your graphics look as nice as possible. When looked at from that viewpoint there's no need for your assembler code to test the keyboard or the mouse, just return to BASIC at the end of each frame. The effect on the overall execution time will be tiny, and the effect on the frame rate zero (so long as you are locked to the vsync).

I wonder if you've checked the CPU time used by the WORLD.BBC example program supplied with BB4W. That renders a 3D rotating sphere, texture-mapped with an image from NASA, and illuminated by a virtual sun. It runs at approaching 100 fps, is written in 100% BASIC code (even D3DLIB is all BASIC) and uses less than 1% CPU on my laptop!

Richard.

Re: Interrupts
Post by Ric on Jun 22nd, 2016, 09:46am

Cheers, I'll have a look.