Author Topic: BxbAsm  (Read 178874 times)

SteveA

  • Guest
Re: BxbAsm
« Reply #180 on: April 24, 2012, 01:03:16 PM »
James,
I've been testing wlib.exe, that come with jwasm and I seems to work quite well.
I think I like it.
It has a whole list of commands and options, unlike lcclib.
It's quite easy to use.
Does the Linux version of jwasm come with wlib ?
Steve

jcfuller

  • Guest
Re: BxbAsm
« Reply #181 on: April 24, 2012, 01:37:40 PM »
Steve,
  No. ar is the library maker on linux as is using gcc/ld as the linker.

James

jcfuller

  • Guest
Re: BxbAsm
« Reply #182 on: April 24, 2012, 01:46:23 PM »
Steve,
  Where did you find wlib.exe. It's not in the download from jwasm site.

James

SteveA

  • Guest
Re: BxbAsm
« Reply #183 on: April 24, 2012, 02:02:34 PM »
James,
its in jwasm-206\JWlinkbw.zip


SteveA

  • Guest
Re: BxbAsm
« Reply #184 on: April 24, 2012, 02:14:37 PM »
It looks like, with wlib, I only have to use lcclib on those C functions that I create in Wedit, (C functions).
Then, combine the C-Objs and the ASM-Objs using wlib into the final .Lib.
Since, I think, most of the Objs will be from assembled code rather than compiled C code, I will be using wlib more.

jcfuller

  • Guest
Re: BxbAsm
« Reply #185 on: April 25, 2012, 07:21:15 AM »
Steve,
  I found RadAsm3 is the best for creating libraries with jwasm.
Just toggle each source as a module, select Assemble Modules then build. All done.
I used polib from pellesc.
James

jcfuller

  • Guest
Re: BxbAsm
« Reply #186 on: April 26, 2012, 08:24:25 AM »
Steve,
  FWIW I ported the IUP headers to jwasm.
James

Code: [Select]
   .486
    .model flat, c
    option casemap :none
    
    include \jwasm\include\crt\crt.inc
    include \jwasm\iup\include\iup.inc
    includelib \jwasm\wininc\Lib\msvcrt.lib
    includelib \iup_dll6\iup.lib
;==============================================================================
CStr macro pszText:VARARG
local szText
    .const
szText    db pszText,0
    .code
    exitm <offset szText>
endm
;==============================================================================    
    .code
start:
    call main
    invoke exit,0
;==============================================================================
quit_cb proc
    mov eax,IUP_CLOSE
    ret
quit_cb endp
;==============================================================================
AddChild proc parent:PTR Ihandle,child:PTR Ihandle
    invoke IupAppend,parent,child
    invoke IupRefresh,parent
    ret
AddChild endp
;==============================================================================
Create proc Value:PTR BYTE,Attr:PTR BYTE,parent:PTR Ihandle
    LOCAL ihWnd:PTR Ihandle
    mov ihWnd,0
    invoke IupCreate,Value
    .IF eax
        mov ihWnd,eax
        invoke strlen,Attr
        .IF eax
            invoke IupSetAttributes,ihWnd,Attr
        .endif
        .IF parent
            invoke AddChild,parent,ihWnd
        .endif
        mov eax,ihWnd
    .endif
    ret
Create endp
;==============================================================================
main proc
    LOCAL \
    win:PTR Ihandle,\
    vbox:PTR Ihandle,\
    topBox:PTR Ihandle,\
    serverFrame:PTR Ihandle,\
    serverBox:PTR Ihandle,\
    serverCombo:PTR Ihandle,\
    btnFetch:PTR Ihandle,\
    controlFrame:PTR Ihandle,\
    controlBox:PTR Ihandle,\
    btnAbout:PTR Ihandle,\
    btnClear:PTR Ihandle,\
    btnExit:PTR Ihandle,\
    dictFrame:PTR Ihandle,\
    serverList:PTR Ihandle,\
    transFrame:PTR Ihandle,\
    text:PTR Ihandle,\
    bottomBox:PTR Ihandle,\
    lbl:PTR Ihandle,\
    entry:PTR Ihandle,\
    btnSearch:PTR Ihandle,\
    chkAll:PTR Ihandle,\
    chkUTF:PTR Ihandle
          
    invoke IupOpen,0,0
    invoke Create,CStr("dialog"),CStr("TITLE=Thesaurus, SIZE=500x300"),NULL
    mov win,eax
    invoke Create,CStr("vbox"),CStr("MARGIN=10x10"), NULL
    mov vbox,eax
    invoke Create,CStr("hbox"),CStr(" GAP=10"), vbox
    mov topBox,eax
    invoke Create,CStr("frame"),CStr("TITLE=Servers, EXPAND=YES"), topBox
    mov serverFrame,eax
    invoke Create,CStr("hbox"),CStr("GAP=5"), serverFrame
    mov serverBox,eax
    invoke Create,CStr("list"),CStr("DROPDOWN=YES, SIZE=120x, EXPAND=HORIZONTAL, VALUE=1"), serverBox
    mov serverCombo,eax
    invoke Create,CStr("button"),CStr("TITLE=Fetch, SIZE = 50x"), serverBox
    mov btnFetch,eax
    invoke Create,CStr("frame"),CStr("TITLE=Controls"), topBox
    mov controlFrame,eax
    invoke Create,CStr("hbox"),CStr("Margin=6x6, GAP=5"), controlFrame
    mov controlBox,eax
    invoke Create,CStr("button"),CStr("TITLE=About, SIZE = 50x"), controlBox
    mov btnAbout,eax
    invoke Create,CStr("button"),CStr("TITLE=Clear, SIZE = 50x"), controlBox
    mov btnClear,eax
    invoke Create,CStr("button"),CStr("TITLE=Exit, SIZE = 50x"), controlBox
    mov btnExit,eax
    invoke IupSetCallback,btnExit,CStr("ACTION"),OFFSET quit_cb
    invoke Create,CStr("frame"),CStr("TITLE=Dictionaries"), vbox
    mov dictFrame,eax
    invoke Create,CStr("list"),CStr("EXPAND=YES, VISIBLELINES=1"), dictFrame
    mov serverList,eax
    invoke Create,CStr("frame"),CStr("TITLE=Translation"), vbox
    mov transFrame,eax
    invoke Create,CStr("text"),CStr("MULTILINE=YES, EXPAND=YES"), transFrame
    mov text,eax
    invoke Create,CStr("hbox"),CStr("GAP=10"), vbox
    mov bottomBox,eax
    invoke Create,CStr("label"),CStr("TITLE=Enter Word to Search For:,SIZE=x12"), bottomBox
    mov lbl,eax
    invoke Create,CStr("text"),CStr(" EXPAND=HORIZONTAL"), bottomBox
    mov entry,eax
    invoke  Create,CStr("button"),CStr("TITLE=Search, SIZE=50x"), bottomBox
    mov btnSearch,eax
    invoke Create,CStr("toggle"),CStr("TITLE=ALL, VALUE=ON,SIZE=x12"), bottomBox
    mov chkAll,eax
    invoke Create,CStr("toggle"),CStr("TITLE=UTF-8, SIZE=x12"), bottomBox
    invoke AddChild,win,vbox
    invoke IupShow,win
    invoke IupSetFocus,btnFetch
    invoke IupMainLoop
    invoke IupClose
    mov eax,0
    ret
main endp
end start

« Last Edit: April 29, 2012, 05:52:39 AM by jcfuller »

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Re: BxbAsm
« Reply #187 on: April 26, 2012, 08:56:13 AM »
Nice job James!

I'm glad to see you becoming comfortable with IUP.


SteveA

  • Guest
Re: BxbAsm
« Reply #188 on: April 26, 2012, 10:29:31 AM »
Nice job James!
I'm glad to see you becoming comfortable with IUP.

Yes, nice.

James,
I've been incrementally converting the funct.c functions over to individual .obj files and adding them to bxblib.lib.
I'm doing it one at a time, because I want to test each one, to make sure it's working correctly.
In some cases I have to make a few modifications so that everything works correctly, like: proto's, externdef's and includes.
The functions themselves work, I just need to let the assembler and linker know what's going on.
Over-all, it's going well.

I did discover another function that may not work correctly under Linux, due to the fact that it uses win32 API calls.
That's the INPUT statement.

Such as:   INPUT ;"First: "; first$; " Initial: "; init$; " Last: "; last$:

The INPUT statement controls the cursor positioning on the screen.

Steve

jcfuller

  • Guest
Re: BxbAsm
« Reply #189 on: April 26, 2012, 05:07:15 PM »
Steve,
  The INPUT statements I'm familiar with (Bcx,ubx/mbc,Bacon) use fgets I believe.

James

jcfuller

  • Guest
Re: BxbAsm
« Reply #190 on: April 27, 2012, 05:58:31 AM »
Steve,
  Food for thought re INPUT.
Here is the "c" output of ubx from this basic code.
James

ubx basic code:
Code: [Select]
Dim A, B$

Input "Enter A Number ", A


Select Case A

  Case   >1 And <10
  Print ">1 And <10 "

  Case   >10 And <20
  Print ">10 And <20"

  Case   31,32,33
  Print "31,32,33"

  Case Else
  Print "No special case found"

End Select


PRINT

input "Type one, two, qwerty, or other ", B$

select case B$

  case  "one","two"
  Print "one, two"

  case  "qwerty"
  Print "qwerty"

  case else
    Print "else"
end select

produces this "c" code. I don't see any WinApi?
Code: [Select]
// *********************************************************************
//   Created with Ubx 311.46 (2012/01/14)by James C. Fuller
//   Based on OSX port by Armando Rivera
//   Ported from BCX32 BASIC To C/C++ Translator (V) 5.12
//   BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//   Translated for compiling with the g++ Compiler
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <commdlg.h>
#include <mmsystem.h>
#include <shellapi.h>
#include <shlobj.h>
#include <richedit.h>
#include <wchar.h>
#include <objbase.h>
#include <ocidl.h>
#include <winuser.h>
#include <olectl.h>
#include <oaidl.h>
#include <ole2.h>
#include <oleauto.h>
#include <conio.h>
#include <direct.h>
#include <ctype.h>
#include <io.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <setjmp.h>
#include <time.h>
#include <stdarg.h>
#include <process.h>
#include <stdbool.h>


// ***************************************************
// Compiler Defines
// ***************************************************
  #define C_EXPORT extern "C"
  #define C_IMPORT extern "C"

#ifndef stat
  #define lstat stat
#endif
#ifndef _fcloseall
  #define _fcloseall _fcloseall
#endif
#ifndef MAX_PATH
  #define MAX_PATH 2048
#endif
#ifndef CALLBACK
  #define CALLBACK
#endif

// *************************************************
//                System Variables
// *************************************************

char    *AR_fgets_retval;
int     ScanError;
char    InputBuffer[1048576];

// *************************************************
//            User Global Variables
// *************************************************

static PCHAR   *G_argv;
static int     G_argc;
static int     A;
static char    B[2048];



// *************************************************
//               Standard Macros
// *************************************************



// *************************************************
//               Standard Prototypes
// *************************************************

int     str_cmp(char*, char*);
char*   BCX_TmpStr(size_t);
char*   mid (char*, int, int=-1);
char*   left (char*,int);

char*   RemoveStr (char*,char*);
int     instr_b(char*,char*,int=0,int=0);
char    *MakeLCaseTbl(void);
char    *_stristr_(char*,char*);
char    *_strstr_(char*,char*);
int     scan (char *input, char *format, ... );
int     Split (char [][2048], char*, char*, int=0);


// *************************************************
//            User Global Initialized Arrays
// *************************************************


// *************************************************
//                  Main Program
// *************************************************

int main(int argc, char *argv[])
{
  G_argc = argc;
  G_argv = argv;
  printf("Enter A Number ");
  A=0;
  AR_fgets_retval=fgets(InputBuffer,sizeof(InputBuffer),stdin);
  InputBuffer[strlen(InputBuffer)-1]=0;
  ScanError = scan(InputBuffer,"%d",&A);
 
  *InputBuffer=0;
  for(;;)
  {
    if(A>1&&A<10)
      {
        printf("%s\n",">1 And <10 ");
        break;
      }
    if(A>10&&A<20)
      {
        printf("%s\n",">10 And <20");
        break;
      }
    if(A==31||A==32||A==33)
      {
        printf("%s\n","31,32,33");
        break;
      }
      // case else
      {
        printf("%s\n","No special case found");
      }
    break;
  }
  printf("\n");
  printf("Type one, two, qwerty, or other ");
  *B=0;
  AR_fgets_retval=fgets(InputBuffer,sizeof(InputBuffer),stdin);
  InputBuffer[strlen(InputBuffer)-1]=0;
  ScanError = scan(InputBuffer,"%s",B);
 
  *InputBuffer=0;
  for(;;)
  {
    if(str_cmp(B,"one")==0 ||  str_cmp(B,"two")==0)
      {
        printf("%s\n","one, two");
        break;
      }
    if(str_cmp(B,"qwerty")==0)
      {
        printf("%s\n","qwerty");
        break;
      }
      // case else
      {
        printf("%s\n","else");
      }
    break;
  }
  return 0;   //  End of main program
  }

// *************************************************
//                 Runtime Functions
// *************************************************

char *BCX_TmpStr (size_t Bites)
{
  static int   StrCnt;
  static char *StrFunc[2048];
  StrCnt=(StrCnt + 1) & 2047;
  if(StrFunc[StrCnt]) free (StrFunc[StrCnt]);
    #if defined BCX_MAX_VAR_SIZE
  if(Bites*sizeof(char)>BCX_MAX_VAR_SIZE)
  {
  printf("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n",(int)(Bites*sizeof(char)),BCX_MAX_VAR_SIZE);
  abort();
  }
  #endif
  return StrFunc[StrCnt]=(char*)calloc(Bites+128,sizeof(char));
}


int str_cmp (char *a, char *b)
{
  int counter=0;
  for(;;)
   {
    if((a[counter]^b[counter]))
     {
      if((UINT) a[counter]>= (UINT) b[counter])
      return  1;
      return -1;
     }
    if(!a[counter]) return 0;
    counter++;
   }
}


char *left (char *S, int length)
{
  int tmplen = strlen(S);
  if(length<1) return BCX_TmpStr(1);
  if(length<tmplen) tmplen=length;
  char *strtmp = BCX_TmpStr(tmplen);
  return (char*)memcpy(strtmp,S,tmplen);
}


char *mid (char *S, int start, int length)
{
  char *strtmp;
  int tmplen = strlen(S);
  if(start>tmplen||start<1) return BCX_TmpStr(1);
  if (length<0 || length>(tmplen-start)+1)
    length = (tmplen-start)+1;
  strtmp = BCX_TmpStr(length);
  return (char*)memcpy(strtmp,&S[start-1],length);
}


char *RemoveStr (char *a, char *b)
{
  char *strtmp, *p, *d;
  int  tmplen;
  strtmp = d = BCX_TmpStr(strlen(a));
  if(!b || !*b) return strcpy(strtmp,a);
  p=_strstr_(a,b); tmplen = strlen(b);
  while(p)
   {
     memcpy(d,a,p-a);
     d+= (p-a);
     a=p+tmplen;
     p=_strstr_(a,b);
   }
  strcpy(d,a);
  return strtmp;
}



int instr_b(char* mane,char* match,int offset,int sensflag)
{
  char *s;
  if (!mane || !match || ! *match || offset>(int)strlen(mane)) return 0;
  if (sensflag)
    s = _stristr_(offset>0 ? mane+offset-1 : mane,match);
  else
    s = _strstr_(offset>0 ? mane+offset-1 : mane,match);
  return s ? (int)(s-mane)+1 : 0;
}


char  *MakeLCaseTbl (void)
{
  static char tbl[256];
  if(!tbl['a'])
    {
      int i; for (i=0; i < 256; i++)
        tbl[i] = (char)(int)tolower(i);
    }
  return tbl;
}


char *_stristr_(char *String, char *Pattern)
{
  int   mi=-1;
  char *LowCase = MakeLCaseTbl();
  while(Pattern[++mi])
   {
     if(String[mi]==0) return 0;
     if(LowCase[(unsigned char)String[mi]]!=LowCase[(unsigned char)Pattern[mi]])
       { String++; mi=-1; }
   }
  return String;
}


char *_strstr_(char *String, char *Pattern)
{
  int   mi=-1;
  while(Pattern[++mi])
   {
     if(String[mi]==0) return 0;
     if(String[mi]!=Pattern[mi])
       { String++; mi=-1; }
   }
  return String;
}


int scan(char *input, char *format, ... )
{
  int c,d ;
  char     *s_;
  int      *intptr;
  float    *floatptr;
  double   *doubleptr;
  char     A[50][2048];
  va_list  marker;
  c = 0;
  d = Split(A,input,",");
  va_start(marker, format); //Initialize arguments
  while(d && *format)
   {
     if(*format == '%') format++;
     if(*format == 's')
       {
         s_ = va_arg(marker, char *);
         strcpy(s_, A[c]);
         c++;
         d--;
       }
  if(*format == 'd')
    {
      intptr = va_arg(marker, int *);
      *intptr = atoi(A[c]);
      c++;
      d--;
    }
  if(*format == 'g')
    {
      floatptr = va_arg(marker, float *);
      *floatptr = atof(A[c]);
      c++;
      d--;
    }
 if(*format == 'l')
    {
      format++;
      doubleptr = va_arg(marker, double *);
      *doubleptr = atof(A[c]);
      c++;
      d--;
     }
  format++;
   }
  va_end(marker);              // Reset variable arguments
  if(d) return(1);             // More data than variables
  if(*format == 0) return(0);  // OK
  return(-1);                  // More variables than data
}


int Split (char Buf[][2048], char *T, char *Delim, int Flg)
{
  int  Begin = 0;
  int  Count = 0;
  int  Quote = 0;
  int  Index,i;
  int  lenT  = strlen(T);
  char Chr34[2]={34,0};
  for(Index=1;Index<=lenT;Index++)
    {
      if(instr_b(Delim,mid(T,Index,1))&&!Quote)
        {
          strcpy(Buf[Count],(char*)mid(T,Begin,Index-Begin));
          if ((Flg & 2) == 0)  // 0 if old version
           Count++;
          else
           if (Buf[Count][0] != 0) Count++;
           Begin=0;
           if((Flg & 1) == 1)   // 1 if true
              strcpy(Buf[Count++],(char*)mid(T,Index,1));
        }
   else
     {
       if(strcmp(mid(T,Index,1),Chr34)==0) Quote=!Quote;
       if(Begin==0) Begin=Index;
     }
   }
  if(Begin)
     strcpy(Buf[Count++],(char*)mid(T,Begin,Index-Begin));
  if((Flg & 1) == 0)   // 0 if false
      for(i=0;i<Count;i++) strcpy(Buf[i],(char*)RemoveStr(Buf[i],Chr34));
  return Count;
}



SteveA

  • Guest
Re: BxbAsm
« Reply #191 on: April 27, 2012, 07:40:05 AM »
It's not really about using fgets or _getche, or ...

This statement:
Quote
  Input "Enter A Number ", A

isn't exactly the same as:
Quote
  INPUT ;"First: "; first$; " Initial: "; init$; " Last: "; last$

What I'm saying is that the bxbasm routines use win32 cursor controls to reposition the cursor when entering multiple variables.

For instance:
if, when entering a variable value or character string, the [enter] key is pressed, the cursor will end up on the next line.
The Bxb routines prevent that from happening, (via the win32 API functions).

I don't have BCX installed, but try my example, using BCX.
What is the code that is generated ?
Does it control cursor re-positioning or does the cursor drop to the next line, when the [enter] key is pressed ?

Offline John

  • Forum Support / SB Dev
  • Posts: 3597
    • ScriptBasic Open Source Project
Re: BxbAsm
« Reply #192 on: April 27, 2012, 08:46:55 AM »
FWIW:  ScriptBasic only supports a minimal set of screen control functions and relies on an extension module for extended support. At this point, INPUT with a single input and support for new line and tab should be adequate for a console Basic.

Are you going to be supporting redirection? (STDIN/STDOUT/STDERR)
 

jcfuller

  • Guest
Re: BxbAsm
« Reply #193 on: April 27, 2012, 10:21:48 AM »
Steve,
  Bcx has only one prompt but multi vars. Must be entered separated by commas.

INPUT "Enter values ->",a!,b#,c$,d%,e$[5],f$

James


SteveA

  • Guest
Re: BxbAsm
« Reply #194 on: April 27, 2012, 10:45:42 AM »
Bcx has only one prompt but multi vars. Must be entered separated by commas.

INPUT "Enter values ->",a!,b#,c$,d%,e$[5],f$


Okay,...
Bxb was designed this way (multiple prompts) to mirror QuickBasic.

But, looking at it again, you already figured out how to convert the "LOCATE" statement, so it actually might work.
Because, the INPUT routines call "locate" to reposition the cursor.