This is the low level counterpart of the thinBasic_Oxygen module, with an enhanced preprocessor making it significantly closer to a high level language, and much easier to use with system DLLs.
It can be used in any program by including the Oxygen DLL
Included are the Hellowin and Opengl2 demos - they are dynamically assembled and executed but it is also possible to store pre-assembled code as a binary file and execute it later. The binaries are generally relocatable code that does not require the fixup data contained in DLLs. As a result they are extremely compact - as an example the opengl demo is as an exe is around 35k. As a binary string configured to run in Asmophere it is about 6.5k
I've included the full source code and the CHM manual as it currently stands
This is the front end 'OXY' written in FreeBasic, incorporating the DLL interface.
' OxygenTestFB.bas
' Oxygen Assembler 'Asmosphere' project
' Charles E V Pegge
' 19 April 2008
' 03 July 2008 ' sync with thinbasic oxygeb
Extern "Windows-MS"
DECLARE FUNCTION o2_asm LIB "oxygen.dll" ALIAS "o2_asm" (byval as zstring ptr) AS long ' assemble
DECLARE FUNCTION o2_link LIB "oxygen.dll" ALIAS "o2_link" (byval as zstring ptr) AS long ' o2 link **
DECLARE FUNCTION o2_view LIB "oxygen.dll" ALIAS "o2_view" (byval as zstring ptr) AS zstring ptr ' o2 coding
DECLARE FUNCTION o2_asm_file LIB "oxygen.dll" ALIAS "o2_asm_file" (byval as zstring ptr) AS long ' assemble from file
DECLARE FUNCTION o2_view_file LIB "oxygen.dll" ALIAS "o2_view_file" (byval as zstring ptr) AS zstring ptr ' o2 coding from file
DECLARE FUNCTION o2_error LIB "oxygen.dll" ALIAS "o2_error" () AS zstring ptr ' error message if any
DECLARE FUNCTION o2_len LIB "oxygen.dll" ALIAS "o2_len" () AS long ' length of returned string
DECLARE FUNCTION o2_buf LIB "oxygen.dll" ALIAS "o2_buf" (byval as long) AS long ' buffer selector 0..511 (returns pointer)
DECLARE SUB o2_init LIB "oxygen.dll" ALIAS "o2_init" () ' initialise oxygen
DECLARE SUB o2_put LIB "oxygen.dll" ALIAS "o2_put" (byval p as any ptr, byval le as long) ' put code into current buffer
DECLARE SUB o2_get LIB "oxygen.dll" ALIAS "o2_get" (byref p as any ptr,byref le as long) ' get code pointer and length
DECLARE FUNCTION o2_exec LIB "oxygen.dll" ALIAS "o2_exec" () AS long ' execute code in current buffer
DECLARE FUNCTION o2_proc1 LIB "oxygen.dll" ALIAS "o2_proc1" () AS long ' execute code at entry point1 (steps of 8 bytes)
DECLARE FUNCTION o2_proc2 LIB "oxygen.dll" ALIAS "o2_proc2" () AS long ' execute code at entry point2 (steps of 8 bytes)
DECLARE FUNCTION o2_proc3 LIB "oxygen.dll" ALIAS "o2_proc3" () AS long ' execute code at entry point3 (steps of 8 bytes)
DECLARE FUNCTION o2_proc4 LIB "oxygen.dll" ALIAS "o2_proc4" () AS long ' execute code at entry point4 (steps of 8 bytes)
DECLARE FUNCTION o2_proc5 LIB "oxygen.dll" ALIAS "o2_proc5" () AS long ' execute code at entry point5 (steps of 8 bytes)
DECLARE FUNCTION o2_proc6 LIB "oxygen.dll" ALIAS "o2_proc6" () AS long ' execute code at entry point6 (steps of 8 bytes)
DECLARE FUNCTION o2_proc7 LIB "oxygen.dll" ALIAS "o2_proc7" () AS long ' execute code at entry point7 (steps of 8 bytes)
DECLARE FUNCTION o2_proc8 LIB "oxygen.dll" ALIAS "o2_proc8" () AS long ' execute code at entry point8 (steps of 8 bytes)
End Extern
' ** o2_link is automatically called by o2_asm when the assembly is successful.
function gets(byval p as long) as string
dim s as string
dim l as long
dim q as any ptr
l=o2_len()
s=space(l)
if l=0 then goto xgets
q=strptr(s)
asm
mov ecx,[l]
mov esi,[p]
mov edi,[q]
strpt:
mov al,[esi]
mov [edi],al
inc esi
inc edi
dec ecx
jg strpt
end asm
xgets:
function=s
end function
dim src AS zSTRING*256 ' source
dim erm AS zstring ptr ' error message
dim lis AS zstring ptr ' listing
dim as long a
o2_init
src=command$
'o2_buf(1)
o2_asm_file(@src)
erm=o2_error()
if len(*erm) then
print "Error: ";*erm
print
lis=o2_view_file(@src)
print "List:"+chr$(13)+chr$(10)+*lis
end
end if
a=o2_exec()
print a
erm=o2_error()
if len(*erm) then print *erm
end
And here is part of the Opengl demo code showing the extended Asmosphere syntax
; ASMOSPHERE SYNTAX
; -----------------
def null 0
def is
(
mov eax,%e
mov %b,eax
)
def is8
(
lea ecx,%e
lea edx,%b
mov eax,[ecx]
mov [edx],eax
mov eax,[ecx+4]
mov [edx+4],eax
)
type WNDCLASSEX
(
;48 bytes
4 cbsize
4 STYLE
4 lpfnwndproc
4 cbClsextra
4 cbWndExtra
4 hInstance
4 hIcon
4 hCursor
4 hbrBackground
4 lpszMenuName
4 lpszClassName
4 hIconSm
)
type MSG
(
; 28 bytes
4 hwnd;
4 message
4 wParam
4 lParam
4 time
8 pt
)
indexers `esi` offset 0 ascending ; all globals
esi=getmemory 4096
call WndProcLocate
mov [eax-4],esi ; store procs & globals table ptr
mov [eax-8],ebx ; store runtimes table ptr
;-------------
; DLL bindings
;-------------
var 4 kernel32,user32,GDI32,opengl32,glu32
kernel32=LoadLibrary `kernel32.dll`
user32 =LoadLibrary `user32.dll`
GDI32 =LoadLibrary `GDI32.dll`
opengl32=LoadLibrary `Opengl32.dll`
glu32 =LoadLibrary `glu32.dll`
bind kernel32
(
GetCommandLine GetCommandLineA ; @0
GetModuleHandle GetModuleHandleA ; @4
QueryPerformanceCounter QueryPerformanceCounter ; @4
QueryPerformanceFrequency QueryPerformanceFrequency ; @4
)
bind user32
(
GetActiveWindow GetActiveWindow ; @0
LoadIcon LoadIconA ; @8
LoadCursor LoadCursorA ; @8
RegisterClass RegisterClassA ; @4
RegisterClassEx RegisterClassExA ; @4
MessageBox MessageBoxA ; @4
CreateWindowEx CreateWindowExA ; @48
DestroyWindow DestroyWindow ; @4
ShowWindow ShowWindow ; @8
UpdateWindow UpdateWindow ; @4
GetMessage GetMessageA ; @16
TranslateMessage TranslateMessage ; @4
DispatchMessage DispatchMessageA ; @4
PostQuitMessage PostQuitMessage ; @4
BeginPaint BeginPaint ; @8
EndPaint EndPaint ; @8
GetClientRect GetClientRect ; @8
DrawText DrawTextA ; @20
PostMessage PostMessageA ; @16
DefWindowProc DefWindowProcA ; @16
SetTimer SetTimer ; @16
KillTimer KillTimer ; @8
GetDC GetDC ; @8
ReleaseDC ReleaseDC ; @4
ChangeDisplaySettings ChangeDisplaySettingsA
)
bind GDI32
(
SetPixelFormat SetPixelFormat
DeleteObject DeleteObject
SwapBuffers SwapBuffers
GetStockObject GetStockObject ; @4
ChoosePixelFormat ChoosePixelFormat
)
bind opengl32
(
glGetString glGetString
glGetIntegerv glGetIntegerv
glGenLists glGenLists
glDeleteLists glDeleteLists
glNewList glNewList
glBegin glBegin
glNormal3f glNormal3f
glVertex3f glVertex3f
glNormal3fv glNormal3fv
glVertex3fv glVertex3fv
glEnd glEnd
glEndList glEndList
glCallList glCallList
glPushMatrix glPushMatrix
glPopMatrix glPopMatrix
glRotatef glRotatef
glScalef glScalef
glTranslatef glTranslatef
glMaterialfv glMaterialfv
glMaterialf glMaterialf
glColor4fv glColor4fv
glClearColor glClearColor
glClear glClear
glLoadIdentity glLoadIdentity
glDisable glDisable
glEnable glEnable
glColor3f glColor3f
glDepthFunc glDepthFunc
glPolygonMode glPolygonMode
glBlendFunc glBlendFunc
glMatrixMode glMatrixMode
glOrtho glOrtho
glViewport glViewport
glScissor glScissor
glCullFace glCullFace
glFrontFace glFrontFace
glLightfv glLightfv
glVertex2i glVertex2i
glFinish glFinish
glDepthMask glDepthMask
glGetDoublev glGetDoublev
;----
; wgl
;----
wglCreateContext wglCreateContext
wglDeleteContext wglDeleteContext
wglMakeCurrent wglMakeCurrent
wglUseFontOutlines wglUseFontOutlinesA
wglGetCurrentDC wglGetCurrentDC
wglGetProcAddress wglGetProcAddress
)
bind glu32
(
gluLookAt gluLookAt
gluPerspective gluPerspective
)
;----------------------
; Opengl ARB extensions
;----------------------
var 4 glMultiTexCoord2fARB glActiveTextureARB
var 4 pa wglChoosePixelFormatARB
glMultiTexCoord2fARB = wglGetProcAddress `glMultiTexCoord2fARB`
glActiveTextureARB = wglGetProcAddress `glActiveTextureARB`
pa = wglGetProcAddress `wglGetExtensionsStringARB`
wglChoosePixelFormatARB = wglGetProcAddress `wglChoosePixelFormatARB`
;--------
; GLOBALS
;--------
var 4 viewport(4)
var 8 ModelView(16) Projection(16)
;static as single model_diffuse(0 TO 3) => { 1.0, 0.8, 0.8, 1.0 }
;static as single model_specular(0 TO 3) => { 0.6, 0.6, 0.6, 1.0 }
;static as single model_shininess = 20.0
var 16 model_diffuse model_specular
var 4 model_shininess
edx=data
(
ns 1.0 ns 0.8 ns 0.8 ns 1.0
ns 0.6 ns 0.6 ns 0.6 ns 1.0
ns 20.0
)
copyn &model_diffuse,edx,36 ; table values to variables
var 4 light_position(4) light_diffuse(4) light_specular(4) light_ambient(4)
var 8 half
edx=data
(
ns0.0 ns8.0 ns8.0 ns1.0
ns1.0 ns1.0 ns1.0 ns1.0
ns1.0 ns1.0 ns1.0 ns1.0
ns0.2 ns0.2 ns0.3 ns1.0
nd0.5
)
copyn &light_position,edx,72 ; copy table to arrays above
var 8 twopi
fldpi
fadd st(0),st(0)
fstp qword twopi
var 8 aspect
var 4 rot_x rot_y rot_z ; view rotation
var 4 wwidth wheight wwidthm wheightm
var 4 hWnd hDC npixelformat hRC
var 4 bselect kselect refresh
var 8 grtic1 grtic2
var 4 ReqShutdown
; WNDPROC globals
;----------------
var 4 mposX mPosy sPosX sPosY bLeft bMid bRight xpos
var 4 xpos ypos active_view
;============================================================
;============================================================
This is ***** recommended ( 5 stars, not a censored word ! :D )
Charles does an awesome job on this, and he is very kind he provides Oxygen in ThinBasic module form as well - that allows code gymnastics going from high level to low level for optimum code speed.
Thanks,
Petr