flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Qbasic like Macros

Author
Thread Post new topic Reply to topic
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
rCX
This has probably been done before (in a better way as well) but here are a few macro instructions based on QBASIC.

Code:
macro SCREEN mode
{
  push ax

  if mode = 0
    mov ah,0h               ;SCREEN 0; Default DOS screen mode
    mov al,3h
    int 10h
  else if mode = 13
    mov ah,0h               ;SCREEN 13; VGA
    mov al,13h
    int 10h
   end if

  pop ax
}

macro SLEEP
{
  ;Output:
  ;ah = BIOS scancode of key pressed
  ;al = ASCII character of key pressed
  ;Could have also used...
  ;       mov ah,8h
  ;       int 21h
  mov ah,0h
  int 16h
}

macro END
{
  mov ax,4Ch      ;\END
  int 21h         ;/
}

macro LOCATE row,col
{
  pusha
  mov ah,2                ;Function 2
  mov bh,0                ;Use page 0
  mov dh,row      ;row
  mov dl,col              ;col
  int 10h
  popa
}


    


So now my code looks like...

Code:
SCREEN 13
COLOR 33
LOCATE 5,5
PRINT "Hello World"
SLEEP
END
    


I have the code for the "PRINT" and "COLOR" functions if anyone wants them but I am still working on them. Smile

EDIT: To add attachment


Description:
Download
Filename: QBASIC.zip
Filesize: 2.65 KB
Downloaded: 184 Time(s)



Last edited by rCX on 17 Jan 2017, 03:38; edited 2 times in total
Post 16 Dec 2007, 01:03
View user's profile Send private message Reply with quote
KIRK



Joined: 05 Dec 2007
Posts: 17
Location: Russia
KIRK
good work!
rCX, do you know how to make INKEY$?
Post 16 Dec 2007, 06:46
View user's profile Send private message Reply with quote
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
rCX
I was just working on it. I'm planning to make a header file called "QBASIC" or something for these macros.

This program loops until you press escape. This INKEY$ is a little different from the one in QBASIC because it returns both an ASCII value and the bios scan code (which is good for using the arrow keys).

Code:
;Program waits until you press escape
org 100h
use16
format binary

macro END
{
  mov ax,4Ch      ;\END
  int 21h         ;/
}

macro INKEY$
{
  ;Output:
  ;       al = ASCII character
  ;       ah = BIOS scancode

  pushf
  mov ah,1                ;\Check if key was pressed.  If a key is pressed zf = 0
  int 16h                 ;/
  jz .KeyNotPressed       ;IF zf = 1 (IF a key was not pressed) THEN .KeyNotPressed.  Since a key was not pressed AX will be set to 0h
  mov ah,0        ;\ah = ASCII character, al = BIOS scancode. (INT 16h waits for a key to be pressed.  Because a key was pressed it gets the number of the key).
  int 16h         ;/
  jmp .KeyPressed

  .KeyNotPressed:
    mov ax,0        ;clears key press data

  .KeyPressed:
    popf
}


Start:    
  INKEY$
  cmp al,1Bh      ;The escape key
  jne Start
  END
    


Last edited by rCX on 17 Jan 2017, 03:41; edited 1 time in total
Post 16 Dec 2007, 14:07
View user's profile Send private message Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4240
Location: 2018
edfed
escuse me, but, is it possible and good to use an int9 for inkey$?

this int replace the bios IRQ1
no bios/dos keyboard available.
But... it returns:
the state for each key
the state of current key press
the buffer up to 4G keypress, mine is 2, current and old, thats all
the shift, ins, ctrl, alt, altgr, menu, lwin, rwin, numlock, shiftlock
scrollock, no pause, because of the 6 scancode combinaison, to be fixed

don't return any ascii character, but with a translation table, and the use of scancode equates, it's easy.

Code:
macro getkey $key$
{
         mov al,[key+key.$key$]
}
    

all this is automatic, the key map is updated by int9.

GOTO there Very Happy
Post 17 Dec 2007, 21:24
View user's profile Send private message Visit poster's website Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo
Perhaps BASM286 will help you? (Oh, and BTW, I guess you know that FreeBASIC is pretty good, heh.)
Post 18 Dec 2007, 00:46
View user's profile Send private message Visit poster's website Reply with quote
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
rCX
Quote:
escuse me, but, is it possible and good to use an int9 for inkey$?

I did not know I could do that. I'll Try it Smile

Here's the Print function I've been working on. A little bulky but it works. Is there a way to make it smaller?

Code:

macro PRINT Variable*,Type
{
;Input:
;        es = Segment
;       Variable = Pointer or "Quoted String"
;    Type = i indicates that variable is not a string.

       local .AfterString
  local .BeforeString

     pusha

   if Variable eqtype ""                 ;If Variable is quoted string
               mov bp,.BeforeString                    ;bp = Pointer to Variable
           mov cx,.AfterString - .BeforeString     ;cx = Length of string at .BeforeString
             jmp .AfterString

                .BeforeString:      
                    db Variable
         .AfterString:
   else                            ;If Variable is a quoted pointer or integer
         push word Variable      ;Save Variable in case it is a register

         if Type eq i                    ;If Variable is an integer
                  pop ax                          ;ax = Variable
                      mov di,TempInteger$             ;di = TempInteger$
                  call WordToInteger$             ;Convert ax to an interger string at offset di
              else                            ;If Variable is a pointer
                   pop di                          ;di = Variable
              end if

          call LEN                        ;cx = Length of string at di
                mov bp,di                       ;bp = di = Pointer to Variable
      end if

  mov bh,0                ;Use Page 0

     ;Get cursor position.
       push cx
     mov ah,3                ;Function 3h
        int 10h                 ;dh = row, dl = col; Also changes ax and cx.
        pop cx

  mov ah,13h              ;Function 13h
       mov al,00000001b        ;Update cursor after printing
       mov bl,[PRINT_COLOR]    ;bl = PRINT_COLOR
   int 10h                 ;LOCATE dh,dl: PRINT bp

     popa
}
    


Code:
PRINT String$
PRINT "I am a quoted String"
PRINT [num],i                   ;"i" tells PRINT macro to convert the integer stored...
                           ;...at num to an integer string before printing

num dw 12345
String$ db "Hello, World!$"
    


I also have LEN and WordToInteger$ in the above macro.
EDIT: updated PRINT macro


Last edited by rCX on 27 Dec 2007, 19:24; edited 3 times in total
Post 18 Dec 2007, 16:10
View user's profile Send private message Reply with quote
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
rCX
rugxulo wrote:
Perhaps BASM286 will help you? (Oh, and BTW, I guess you know that FreeBASIC is pretty good, heh.)


FB is very cool. Sadly it's not an optimizing compiler...
Post 18 Dec 2007, 16:14
View user's profile Send private message Reply with quote
rugxulo



Joined: 09 Aug 2005
Posts: 2341
Location: Usono (aka, USA)
rugxulo
rCX wrote:
FB is very cool. Sadly it's not an optimizing compiler...


In the future, they hope to have (more) OOP features, a C outputter, and maybe even be an official GCC backend. (Work has begun on all of these.) See their forum for more info. And BTW, I've read that it does "some" optimizations, so it's much better than "nothing", at least. Wink
Post 25 Jan 2008, 07:49
View user's profile Send private message Visit poster's website Reply with quote
tonyMac



Joined: 29 Oct 2004
Posts: 10
Location: Flint Michigan
tonyMac
Hey guys,

I'm working on a similar thing for DexOS, if you would like to compare ideas let me know.

_________________
Press any key to continue
Post 14 Mar 2008, 18:37
View user's profile Send private message Reply with quote
Rahsennor



Joined: 07 Jul 2007
Posts: 61
Rahsennor
Very nice. Cool
I started on something like this once, but I gave up and made this instead:

Code:
include 'rc.inc'

function ax putc(a)
function ax sum(a,b)
function ax retone()

org 100h
        putc(sum('a',retone()))
        mov ah,4Ch
        int 21h

sum:
        mov ax,[esp+2]
        add ax,[esp+4]
        ret 4

putc:
        mov dl,[esp+2]
        mov ah,02h
        int 21h
        ret 2

retone:
        mov ax,1
        ret
    

Very Happy
Post 18 Mar 2008, 05:22
View user's profile Send private message Reply with quote
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
rCX
I attached, QBASIC.inc in the first post, which has some these functions. It's not perfect and it would be great to have others input. I also have functions, for PSET, GET, and PUT written but they are not ready yet.

Code:
format binary
use16
org 100h
include "QBASIC.inc"

CLS
SCREEN 13

COLOR 11
LOCATE 10,15
PRINT "Hello, World!"

mov ax,12345
COLOR 44
LOCATE 11,15
PRINT ax 

COLOR 47
LOCATE 12,15
PRINT 5678

LOCATE 13,15
LEN String$       ;cx = length of String$
PRINT cx

COLOR 15
LOCATE 14,15
PRINT String$,$

SLEEP
SCREEN 0

END

String$ db "Press any key to quit.",0
    


tonyMac wrote:

Hey guys,

I'm working on a similar thing for DexOS, if you would like to compare ideas let me know.

That would be fine. You can use any of my functions if you want to. Smile

rCX
Post 15 May 2008, 22:59
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Thanks rCX , tonyMac is still working on this cool project, which i think is a great idea.
Post 18 May 2008, 00:49
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid
Just for fun, can you post sample of resulting code?
Post 18 May 2008, 01:11
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
rCX
For some reason the attachment is not showing up so here is what was in it

Code:
;QBASIC.inc
jmp SkipQBASIC

;___________CLS (SCREEN 13)____________
macro CLS
{
     pushf
       pusha
       push es
     cld                             ;df = 0; direction is up for the stosb functions
    push word SCREEN_13_Segment     ;\es = A000h
       pop es                          ;/
  xor di,di                       ;di = 0
     xor ax,ax                       ;ax = 0         ;color = black
      mov cx,32000                    ;\64000 bytes = 32000 dwords on SCREEN 13
  rep stosw                       ;/store string word ax at es:di, di = di + 2.
   pop es
      popa
        popf
}

;________________COLOR_________________
macro COLOR NewColor
{
     mov word [TextColor],NewColor
}

;_________________END___________________
macro END
{
      mov ax,4C00h            ;\END
      int 21h                 ;/
}

;__________________LEN_________________
macro LEN Variable*
{
        local .AfterString
  local .BeforeString

     push di
     if Variable eqtype ""         ;If Variable is quoted string
               mov di,.BeforeString                    ;bp = Pointer to Variable
           jmp .AfterString
            .BeforeString:
                  db Variable
         .AfterString:
   else
                mov di,Variable
             call _LEN
   end if

  pop di
}

_LEN:               ;Input: es:di = Pointer to string; Output: cx = String length
   pushf
       push ax
     push di

 cld                             ;df = 0; direction is up 
   mov al,[StringTerminator]       ;al = byte to look for
      mov cx,-1                       ;cx = count

     .NextByte:
              inc cx                  ;count = count + 1
          scasb                   ;di = di + 1, IF [di] = al THEN zf = 1
              jne .NextByte           ;NextByte

       pop di
      pop ax
      popf
        ret

;_______________LOCATE_________________
macro LOCATE row,col
{
        pusha
       mov ah,2                ;Function 2
 mov bh,0                ;Use page 0
 mov dh,row              ;row
        mov dl,col              ;col
        int 10h                 ;LOCATE y,x
 popa
}

;________________PRINT_________________
macro PRINT Variable*,Type
{
;Input:
;       es = Segment
;       Variable = "Quoted String", register, number or pointer to string
;        Type = use "$" to if variable is a pointer to a string. Otherwise leave this parameter off.

   local .AfterString
  local .BeforeString

     pusha

   if Variable eqtype ""         ;If Variable is quoted string
               mov bp,.BeforeString                    ;bp = Pointer to Variable
           mov cx,.AfterString - .BeforeString     ;cx = Length of string at .BeforeString
             jmp .AfterString

                .BeforeString:
                  db Variable
         .AfterString:
   else                            ;If Variable is an integer or pointer to string
             push word Variable      ;Save Variable in case it is a register

         if Type eq $                    ;If Variable is a pointer to string
                 pop di                          ;di = Variable
              else
                        pop ax                          ;ax = Variable
                      mov di,TempInteger$             ;di = TempInteger$
                  call WordToInteger$             ;Convert ax to an interger string at offset di
              end if

          call _LEN                       ;cx = Length of string at di
                mov bp,di                       ;bp = di = Pointer to Variable
      end if

  mov bx,[TextColor]      ;\bl = TextColor
   mov bh,0                ;/Use Page 0
        

        ;Get cursor position.
       push cx
     mov ah,3                ;Function 3h
        int 10h                 ;dh = row, dl = col; Also changes ax and cx.
        pop cx

  mov ah,13h              ;Function 13h
       mov al,00000001b        ;Update cursor after printing
       int 10h                 ;LOCATE dh,dl: PRINT bp

     popa
}

WordToInteger$:       ;Input: ax = number to convert, es:di = segment:offset of string ;Output: es:di = decimal string
                ;Based on EXDEC.ASM by MAD
  pushf
       pusha

   cmp ax,0                        ;\IF ax >= 0 THEN .Positive
     jge .Positive                   ;/
          neg ax                  ;ax = -ax
           mov byte [di],"-"     ;Put a "-" in front of the number.
                inc di                  ;di = di + 1

    .Positive:
      xor cx,cx                       ;cx = 0; will be used as digit counter
      mov bx,10                       ;divide by 10

   .GetDigit:
              xor dx,dx               ;dx = 0
             div bx                  ;dx:ax/bx; ax = answer dx = remainder, the decimal digit
                inc cx                  ;increase digit counter
             add dx,48               ;48 - 57 are the ASCII numbers
              push dx                 ;Put digit on stack.
                cmp ax,0                ;\IF there are more digits left THEN .GetDigit
             jne .GetDigit           ;/

      .PopLoop:
               pop ax                  ;Get diget off stack.
               stosb                   ;mov [di], al, inc di
               loop .PopLoop           ;loop cx times. cx = cx - 1

     mov al,[StringTerminator]
   stosb

   popa
        popf
        ret

;_______________SCREEN_________________
macro SCREEN mode
{
   push ax
     mov ah,0h                       ;Function 0h

    if mode = 0
         mov al,3h               ;SCREEN 0; 40x25 Text; 8x8 Characters; The default DOS screen mode
          int 10h
     else if mode = 13
           mov al,13h              ;SCREEN 13; 300x200 Pixels, 40x25 Text; 8x8 Characters; VGA
         int 10h
     end if

  pop ax
}

;________________SLEEP_________________
macro SLEEP
{
;Output:
;   ah = BIOS scancode of key pressed
;  al = ASCII character of key pressed

     mov ah,0h
   int 16h

;Could have also used...
;    mov ah,8h
;  int 21h
}

;_________________Data_________________
TextColor           dw 15
TempInteger$           db "-12345",0
StringTerminator     db 0

SCREEN_13_Segment = 0xA000

;------Colors------
Black = 0
DarkBlue = 1
 Blue = 1
DarkGreen = 2
 Green = 2
DaryCyan = 3
DarkRed   = 4
 Red = 4
LightBlue = 9
LightGreen = 10
LightCyan = 11
LightRed = 12
White = 15
Transparent = 255

;-------Keys-------
UpKey   = 72
RightKey = 77
DownKey = 80
LeftKey = 75
TabKey = 9
EnterKey = 13
EscKey = 27

SkipQBASIC:

    
Post 18 May 2008, 16:59
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
A quick example of code to run on DexOS is
QBASIC.inc
Code:
;QBASIC.inc was written by rCX (converted to run on DexOS, by Dex)use32     ORG   0x400000                                 ; where our program is loaded to       jmp   start                                    ; jump to the start of program.        db    'DEX2'                                 ; We check for this, to make shore it a valid Dex4u file. ;-- --------------------------------------------------; ; Start of program.                                  ; ;----------------------------------------------------;start:    mov   ax,18h  mov   ds,ax   mov   es,ax ;----------------------------------------------------; ; Get calltable address.                             ; ;----------------------------------------------------;        mov   edi,Functions                           ; this is the interrupt mov   al,0                                    ; we use to load the DexFunction.inc    mov   ah,0x0a                                 ; with the address to dex4u functions.  int   40h   jmp   SkipQBASIC;___________CLS (SCREEN 3)____________CLS equ   call [Clstext];________________COLOR_________________macro COLOR NewColor{ mov   al,NewColor     call  [TextColor]};_________________END___________________macro END{      call  [SetDex4uFonts] ret};_______________LOCATE_________________macro LOCATE row,col{  pushad        mov   ah,row  mov   al,col  call  [SetCursorPos]  popad};_______________PRINT_________________macro PRINT String{     local .Done   local .a            mov esi, .a           call [PrintString]            jmp .Done   .a db String,13,0   .Done:};_______________SCREEN_________________macro SCREEN mode{      push eax      mov ah,0h   if mode = 0           mov al,3h             call  [RealModeInt10h]        else if mode = 13             mov al,13h            call  [RealModeInt10h]        end if      pop eax};________________SLEEP_________________macro SLEEP{;Output:;       ah = BIOS scancode of key pressed;       al = ASCII character of key pressed call  [WaitForKeyPress]}SkipQBASIC:    

And Hello.asm
Code:
include "QBASIC.inc"CLSSCREEN 0COLOR 11LOCATE 10,4PRINT "Hello, World!1"COLOR 12LOCATE 12,4PRINT "Hello, World!2"COLOR 15LOCATE 14,4PRINT "Press any key to quit."SLEEPENDinclude 'Dex.inc'                                     ; Dex inc file    


The full code is included in the zip, to assemble just type:
c:\fasm hello.asm hello.dex <enter>


Description:
Download
Filename: Qbasic.zip
Filesize: 6.52 KB
Downloaded: 140 Time(s)

Post 18 May 2008, 18:49
View user's profile Send private message Reply with quote
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
rCX
I'll have to get DexOS to try it. Cool
Post 19 May 2008, 13:12
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u
Cool, the more user's the better Smile
Post 19 May 2008, 15:00
View user's profile Send private message Reply with quote
rCX



Joined: 29 Jul 2007
Posts: 166
Location: Maryland, USA
rCX
Hey, Rahsennor

Do you have rc.inc or where can I find it?

Thanks!
Post 06 Jul 2008, 23:55
View user's profile Send private message Reply with quote
roboman



Joined: 03 Dec 2006
Posts: 122
Location: USA
roboman
Been playing with the macro basic started by rCX here, decided FASM Basic was a better name to use with my ver. Not a huge amount so far:
Beep
cls
color
end_program
gosub
GoTo
input
locate
peek
poke
print
return
reboot
In_Port
Out_Port
Sleep
Screen
Sound
def
cursoron
cursoroff
pause
All work to some degree, let is still to disfunctional and to much a mess. It all needs clean up, but what the heck post what I have and maybe some one can find it usefull or point out a major stupidity... all coments welcome


Description: Macro basic for DexOS, need to clean it up a bit more, do a Dos / Win ver, and then start adding more functions
Download
Filename: MacroDex.zip
Filesize: 6.88 KB
Downloaded: 146 Time(s)

Post 12 Oct 2009, 00:44
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2020, Tomasz Grysztar. Also on GitHub, YouTube, Twitter.

Website powered by rwasa.