Link to home
Start Free TrialLog in
Avatar of kordova
kordova

asked on

Passing parameters and references in 16bit TASM

I'm presently converting a simple 16bit TASM video mode 13h program to use the stack instead of globals and register passing to functions. I'm learning from a MASM book which may be the reason for some confusion on my behalf.

At present I have the following three functions in a file that is assembled separately and then linked with my main file:
.model small
.386

PUBLIC _DrawPixel
PUBLIC _ResetVideoMode
PUBLIC _SaveVideoMode
.data
BackBuffer db 64000 dup(?)
.code
_SaveVideoMode PROC near
ARG VideoMode:PTR BYTE
    push bp
      mov bp,sp

    mov ah,0Fh                       ; function 0Fh - get current mode
    int 10h                       ; Bios video service call
    mov BYTE PTR [VideoMode],al ; save current mode

    pop bp
    ret
_SaveVideoMode ENDP

_ResetVideoMode PROC near
ARG VideoMode:BYTE
; Resets the prior video mode (as stored in VideoMode) ; Originally a global
    push bp
      mov bp,sp

    mov al,VideoMode         ; set video mode 3, text
    xor ah,ah                   ; clear ah - set mode
    int 10h                   ; call bios service

    pop bp
    ret
_ResetVideoMode ENDP

_DrawPixel  proc near
ARG X:WORD,Y:WORD,Color:BYTE
LOCAL DT:BYTE    ; UNUSED AT PRESENT, WILL BE USED
; Plot Color at (X,Y)
    push bp
      mov bp,sp

    mov ax,320
    mul Y
    add ax,X
    mov di, OFFSET BackBuffer
    add di,ax
    mov al,Color
    mov [di],al

    popbp
    ret
_DrawPixel  endp
end

The pertinent sections of main:
.model small
.stack 100h
.386

EXTRN _SaveVideoMode:near
EXTRN _ResetVideoMode:near
EXTRN _DrawPixel:near
.data
VideoMode  db ?
.code
    ;... in main proc
    Call _SaveVideoMode C, offset VideoMode
    ; Set up timer etc

    Call _DrawPixel C, 160, 100, RED_INDEX   ; Draw red pixel in center of screen
    Call _FlipBuffer C  ; Show the change...

    Call _ResetVideoMode C,VideoMode
    ... etc


Now, I've used all of these functions successfully with globals and register passing, so I'm relatively sure that the logic is sound. However, it is evident from the results that none of the parameters passed are as expected...

What exactly am I doing wrong?

Thanks in advance for any help.

UPDATE:
I've found in using the functions that if I use:
    mov ax,170
    mov bx,110
    Call _DrawPixel C, ax, bx, RED_INDEX

It works fine, though with:
    Call _DrawPixel C, WORD 170, WORD 110, RED_INDEX
it does not work as expected...

Isn't specifying an arg as a word the same as using a word register in the argument list?

Also, I seem to be getting functional behavior from the set/reset function when I set it as a word instead of a ptr byte in the argument list. (And I can't get it to pass as a byte at all, I'm getting the feeling that working with words works better...)

I'm still unsure as to what is wrong with the DrawPixel when I include the local variable (which I will need).
ASKER CERTIFIED SOLUTION
Avatar of grg99
grg99

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of kordova
kordova

ASKER

Ok, I looked through the .lst file (a first time for me, though it is quite helpful!) and I came upon the following:
    256      0088  B0 03                   mov al,3
    257                               Call _ResetVideoMode C,al
1   258      008A  50                       PUSH    AL
**Error** main.ASM(239)      CALLPROC(1) Argument to      operation or instruction has illegal size

I had been testing it with registers/immediates etc.

I'm getting the impression that the extended call is actually just a macro of some sort. Since it pushes all parameters on the stack, and evidently only words can be pushed onto the stack, are only parameters of word size allowed?

I must be missing something as that would force you to use your own macro to translate bytes into words when passing values, do that manually for every function call or limit yourself to words...

Thanks again
it's a x86 CPU restriction, there's no way to push just a byte.  It's a hardware thing.