Span text

Ian's Assembler/Machine Code Sinewave Demo Program Main Source Code Page
Version 3.0

Main C/Assembler source file for this program.

The assembler is embedded in this C program file in the routine zsinewave.
It compiles using Visual Studios Express 2015
.
The original code skeleton was generated by LCC wedit.
To download all the necessary source files (in a zip file), Click Here (NB: I would advise you to download the zip file, not cut and paste the code off this page.)
Back to program download page
More about this program

Text of the Source file:-

To view the assembler code in this progam click here
================
/*@@ Wedit generated application. Written Mon Dec 07 00:04:24 2015
@@header: c:\test\vs\asm_sine\asm_sineres.h
@@resources: c:\test\vs\asm_sine\asm_sine.rc
Do not edit outside the indicated areas */
/*<---------------------------------------------------------------------->*/
/*<---------------------------------------------------------------------->*/
#include <windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <string.h>
#include "asm_sineres.h"
/*<---------------------------------------------------------------------->*/
HINSTANCE hInst; // Instance handle
HWND hwndMain; //Main window handle

LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam);

/*<---------------------------------------------------------------------->*/
/*@@0->@@*/

/*
Ian's Sinewave Machince Code Plotting Demo Program version 2.7 6/12/15
works ok on windows 8.1 and windows 10 computers.

This is a c file, compiled by Visual Studios Express 2015.
I don't know how to make Visual Studios Express compile code for other(earlier) versions of windows.
The assembler code is embedded in this C program in the routine zsinewave.

*/

//void izconv2(char *src);
TCHAR gtext[300];
short gclen;
HDC hDC; //global hDC
HPEN redhpen;

void izconv2(char *src) {
short x;
//short len;
x = 0;
gclen = strlen(src);
while (x < gclen) {
gtext[x] = src[x];
x++;

}

 

}

static BOOL InitApplication(void)
{
WNDCLASS wc;

memset(&wc,0,sizeof(WNDCLASS));
wc.style = CS_HREDRAW|CS_VREDRAW |CS_DBLCLKS ;
wc.lpfnWndProc = (WNDPROC)MainWndProc;
wc.hInstance = hInst;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "asm_sineWndClass";
wc.lpszMenuName = MAKEINTRESOURCE(IDMAINMENU);
wc.hCursor = LoadCursor(NULL,IDC_ARROW);
wc.hIcon = LoadIcon(NULL,IDI_APPLICATION);
if (!RegisterClass(&wc))
return 0;
/*@@0<-@@*/
// ---TODO--- Call module specific initialization routines here

return 1;
}

/*<---------------------------------------------------------------------->*/
/*@@1->@@*/
HWND Createasm_sineWndClassWnd(void)
{
char s[] = "Ian's Sinewave Machine Code Plotting Demo Version 2.7";
izconv2(s);

return CreateWindow("asm_sineWndClass",gtext,
WS_MINIMIZEBOX|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_MAXIMIZEBOX|
WS_CAPTION|WS_BORDER|WS_SYSMENU|WS_THICKFRAME,
CW_USEDEFAULT,0,CW_USEDEFAULT,0,
NULL,
NULL,
hInst,
NULL);
}
/*@@1<-@@*/
/*<---------------------------------------------------------------------->*/
/* --- The following code comes from c:\lcc\lib\wizard\defOnCmd.tpl. */
void MainWndProc_OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch(id) {
// ---TODO--- Add new menu commands here
/*@@NEWCOMMANDS@@*/
case IDM_EXIT:
PostMessage(hwnd,WM_CLOSE,0,0);
break;
}
}

/*<---------------------------------------------------------------------->*/
/*@@2->@@*/

//This is the C-code line plotting interface routine that is called by the assembler routine
// zsinewave()

void zsimpline(long x1, long y1, long x2, long y2) {
MoveToEx(hDC, (int)(x1), (int)(y1), NULL);
LineTo(hDC, (int)x2, (int)y2);
}

/* ==============================*/
/*Machine code plotting routine
The algorithm it uses is the iterative loop
y=y+y2*c;
y2=y2-y*c;
where c is a constant fraction that determines the frequence per unit iteration.
This oscillates like an electronic LCR (coil an capacitor) circuit
and creates a sinewave.
The value in eax is y, and in ebx is y2.
ecx is the x co-ordinate which corresponds to time.

eax, ebx and ecx are 32 bit registers in the computer core CPU.

*/

void zsinewave(void) {

//long a;
//long b;
long llastx;
long llasty;
long lplotf;
//long x;
__asm {
; save registers
push ecx
push edx
push ebx

mov lplotf, 0; clear plot flag
mov ecx, 30; x position on screen
mov eax, 100; y variable
mov ebx, 0; y rate of change variable
z2loop :
push eax
mov edx, 20; load multiplier
imul eax, edx; do multiplication
sar eax, 8; divide by 256, note arithmetic shift
add ebx, eax; have calculated the rate of change increment, now add to the rate of change
pop eax

push ebx
mov edx, 20; load multiplier
imul ebx, edx; do multiplication
sar ebx, 8; divide by 256, note arithmetic shift
sub eax, ebx; have calculated the y position increment, now subtract to the rate of change
; we subtract because that is required by the formula to create and oscillation
pop ebx

mov edx, 250
sub edx, eax; invert y position and add offset for screen plotting

; now plot if required
cmp lplotf, 1
jne skipplot
; plot
push eax
push ecx
push ebx; saving registers
push edx

; push parameteres
push edx; y position
push ecx; x position
push llasty; last y pos
push llastx; last x pos
; push 500
; push 300
; push 30
; push 30
call zsimpline; call plotting routine
add esp, 16; tidy up stack

; restore registers
pop edx
pop ebx
pop ecx
pop eax
skipplot :
mov lplotf, 1; set plot flat

; set last x etc.
mov llastx, ecx
mov llasty, edx
add ecx, 1; add 1 to x position
cmp ecx, 700; stop at x = 700
jne z2loop

pop ebx
pop edx
pop ecx

}

}

void asmtst_proc(void) {
char *s;
char lbuf[100];
int r;
//s = "char return is:";
//izconv2(s);
//TextOut(hDC, 20, 150, gtext, gclen);
redhpen = CreatePen(PS_SOLID, 0, 0x000000ff);
SelectObject(hDC, redhpen);
//zsimpline(30, 100, 100, 100);
//lbuf[0] = 'H';
//lbuf[0] = asmtst2();
//lbuf[0] = 'H';
//lbuf[1] = 0;
//r = asmtst2();
//sprintf_s(lbuf, "num:%d", r);
zsinewave();
s = "Sorry, that's all it does..";
izconv2(s);
TextOut(hDC, 15, 400, gtext, gclen);

 

}

LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
char *lbuf;
PAINTSTRUCT ps;

switch (msg) {
/*@@3->@@*/
case WM_PAINT:
hDC = BeginPaint(hwnd, &ps);
lbuf = "Ian's Sinewave Machince Code Plotting Demo Program version 2.7 6/12/15";

izconv2(lbuf);
TextOut(hDC, 15, 15, gtext, gclen);

lbuf = "The part of this program that calculates and plots the sinewave is";
izconv2(lbuf);
TextOut(hDC, 15, 35, gtext, gclen);

lbuf = "written in x86 assembler/machine code. See the website you got this from";
izconv2(lbuf);
TextOut(hDC, 15, 55, gtext, gclen);

lbuf = "to see the source code and for more info. (This version only works on a windows 8.1 or windows 10 computer.)";
izconv2(lbuf);
TextOut(hDC, 15, 75, gtext, gclen);
lbuf = "press 'p' to run the demo";
izconv2(lbuf);
TextOut(hDC, 15, 95, gtext, gclen);
EndPaint(hwnd, &ps);
return (0L);
case WM_CHAR:
//count++;
hDC = GetDC(hwnd);
if (wParam == 'p')asmtst_proc();
ReleaseDC(hwnd, hDC);
return 0L;

case WM_COMMAND:
HANDLE_WM_COMMAND(hwnd,wParam,lParam,MainWndProc_OnCommand);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd,msg,wParam,lParam);
}
/*@@3<-@@*/
return 0;
}
/*@@2<-@@*/

/*<---------------------------------------------------------------------->*/
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow)
{
MSG msg;
HANDLE hAccelTable;

hInst = hInstance;
if (!InitApplication())
return 0;
hAccelTable = LoadAccelerators(hInst,MAKEINTRESOURCE(IDACCEL));
if ((hwndMain = Createasm_sineWndClassWnd()) == (HWND)0)
return 0;
ShowWindow(hwndMain,SW_SHOW);
while (GetMessage(&msg,NULL,0,0)) {
if (!TranslateAccelerator(msg.hwnd,hAccelTable,&msg)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}