Last active
March 31, 2025 16:40
-
-
Save autch/4a20b86657a2ee8b411fb7cd558ab4b1 to your computer and use it in GitHub Desktop.
The "mexican hat" demo in MS-DOS QBasic, LSI C-86 and DJGPP v2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* for DJGPP v2: | |
* gcc -s -O3 -o mex32.exe mex32.c | |
* OR | |
* gcc -s -O3 -DUSE_BIOS -o mex32b.exe mex32.c | |
*/ | |
#include <stdio.h> | |
#include <math.h> | |
#include <stdlib.h> | |
#include <dpmi.h> | |
#include <go32.h> | |
#include <dos.h> | |
#include <sys/farptr.h> | |
#include <pc.h> | |
#include "VGA.H" | |
void setvideo(int mode) | |
{ | |
__dpmi_regs regs; | |
regs.h.ah = 0; | |
regs.h.al = (char)mode; | |
__dpmi_int(0x10, ®s); | |
} | |
int getvideo() | |
{ | |
__dpmi_regs regs; | |
regs.h.ah = 0x0f; | |
__dpmi_int(0x10, ®s); | |
return regs.h.al; | |
} | |
void init_vga() | |
{ | |
_farsetsel(_dos_ds); | |
#ifndef USE_BIOS | |
ENABLE_VRAM_ACCESS(); | |
VGA_SET_WRITE_MODE(2); | |
VGA_SET_LOGICAL_OP(VGA_AND); | |
VGA_SET_ROTATE(0); | |
VGA_SET_RESET(0); | |
VGA_ENABLE_SET_RESET(0); | |
VGA_SET_BIT_MASK(0xff); | |
SEQ_PLANE_WRITE_ENABLE(0x0f); | |
#endif | |
} | |
#ifdef USE_BIOS | |
void gr_pset(int x, int y, char cl) | |
{ | |
__dpmi_regs regs; | |
regs.h.ah = 0x0c; | |
regs.h.al = cl | 0x80; | |
regs.x.cx = x; | |
regs.x.dx = y; | |
regs.h.bh = 0; | |
__dpmi_int(0x10, ®s); | |
} | |
#else | |
volatile unsigned char pixel; /* volatile is needed to prevent dead store elimination */ | |
void gr_pset(int x, int y, char cl) | |
{ | |
unsigned long offset; | |
offset = (320 * y + x) >> 3; | |
VGA_SET_BIT_MASK(0x80 >> (x & 0x07)); | |
pixel = _farnspeekb(0xa0000 + offset); | |
_farnspokeb(0xa0000 + offset, cl); | |
} | |
#endif | |
#define dr (3.14159265 / 180.0) | |
void draw() | |
{ | |
int d[160]; | |
float r, x, y, z; | |
int i, sx, sy; | |
int zz, c; | |
for(i = 0; i < 160; i++) | |
{ | |
d[i] = 100; | |
} | |
for(y = -180; y <= 180; y += 6) { | |
for(x = -180; x <= 180; x += 4) { | |
r = dr * sqrt(x * x + y * y); | |
z = 100 * cos(r) - 30 * cos(3 * r); | |
sx = (int)(80 + x / 3 - y / 6); | |
sy = (int)(40 - y / 6 - z / 4); | |
if(sx >= 0 && sx < 160 && d[sx] > sy) { | |
zz = (int)((z + 100) * 0.035) + 1; | |
c = 0; | |
if(zz & 1) c |= 1; | |
if((zz == 2) || (zz == 3) || (zz >= 6)) c |= 2; | |
if(zz >= 4) c |= 4; | |
if(c != 0) { | |
gr_pset(sx * 2, sy * 2, c); | |
} | |
d[sx] = sy; | |
} | |
} | |
} | |
} | |
int main() | |
{ | |
int oldmode; | |
oldmode = getvideo(); | |
setvideo(0x0d); | |
init_vga(); | |
draw(); | |
getchar(); | |
setvideo(oldmode); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SCREEN 7 | |
DIM d(160) AS INTEGER | |
DIM r AS SINGLE, x AS SINGLE, y AS SINGLE, z AS SINGLE | |
DIM i AS INTEGER, sx AS INTEGER, sy AS INTEGER | |
DIM zz AS INTEGER, c AS INTEGER | |
FOR i = 1 TO 159 | |
d(i) = 100 | |
NEXT | |
CONST dr = 3.1415932# / 180 | |
FOR y = -180 TO 180 STEP 6 | |
FOR x = -180 TO 180 STEP 4 | |
r = dr * SQR(x * x + y * y) | |
z = 100 * COS(r) - 30 * COS(3 * r) | |
sx = INT(80 + x / 3 - y / 6) | |
sy = INT(40 - y / 6 - z / 4) | |
IF (sx >= 0) AND (sx < 160) THEN | |
IF d(sx) > sy THEN | |
zz = INT((z + 100) * .035) + 1 | |
c = 0 | |
IF zz AND 1 THEN c = c OR 1 | |
IF (zz = 2) OR (zz = 3) OR (zz >= 6) THEN c = c OR 2 | |
IF zz >= 4 THEN c = c OR 4 | |
IF c <> 0 THEN PSET (sx * 2, sy * 2), c | |
d(sx) = sy | |
END IF | |
END IF | |
NEXT | |
NEXT |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* for LSI C-86: | |
* lcc -o mexican.exe mexican.c -lmathlib -ltinymain.obj | |
* OR | |
* lcc -o mex_bios.exe -DUSE_BIOS mexican.c -lmathlib -ltinymain.obj | |
*/ | |
#include <stdio.h> | |
#include <math.h> | |
#include <stdlib.h> | |
#include <dos.h> | |
#include <machine.h> | |
#include "VGA.H" | |
void setvideo(int mode) | |
{ | |
union REGS regs; | |
regs.h.ah = 0; | |
regs.h.al = (char)mode; | |
int86(0x10, ®s, ®s); | |
} | |
int getvideo() | |
{ | |
union REGS regs; | |
regs.h.ah = 0x0f; | |
int86(0x10, ®s, ®s); | |
return regs.h.al; | |
} | |
void init_vga() | |
{ | |
ENABLE_VRAM_ACCESS(); | |
VGA_SET_WRITE_MODE(2); | |
VGA_SET_LOGICAL_OP(VGA_AND); | |
VGA_SET_ROTATE(0); | |
VGA_SET_RESET(0); | |
VGA_ENABLE_SET_RESET(0); | |
VGA_SET_BIT_MASK(0xff); | |
SEQ_PLANE_WRITE_ENABLE(0x0f); | |
} | |
static const unsigned char _gr_bittable[8] = | |
{ | |
0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, | |
}; | |
#ifdef USE_BIOS | |
void gr_pset(int x, int y, char cl) | |
{ | |
union REGS regs; | |
regs.h.ah = 0x0c; | |
regs.h.al = cl | 0x80; | |
regs.x.cx = x; | |
regs.x.dx = y; | |
regs.h.bh = 0; | |
int86(0x10, ®s, ®s); | |
} | |
#else | |
volatile unsigned char pixel; /* volatile is needed to prevent dead store elimination */ | |
void gr_pset(int x, int y, char cl) | |
{ | |
unsigned char far *p = MK_FP(0xa000, 0x0000); | |
unsigned long offset; | |
offset = (320 * y + x) >> 3; | |
VGA_SET_BIT_MASK(0x80 >> (x & 0x07) /*_gr_bittable[x & 0x07]*/); | |
pixel = p[offset]; | |
p[offset] = cl; | |
} | |
#endif | |
#define dr (3.14159265 / 180.0) | |
void draw() | |
{ | |
int d[160]; | |
float r, x, y, z; | |
int i, sx, sy; | |
int zz, c; | |
for(i = 0; i < 160; i++) | |
{ | |
d[i] = 100; | |
} | |
for(y = -180; y <= 180; y += 6) { | |
for(x = -180; x <= 180; x += 4) { | |
r = dr * sqrt(x * x + y * y); | |
z = 100 * cos(r) - 30 * cos(3 * r); | |
sx = (int)(80 + x / 3 - y / 6); | |
sy = (int)(40 - y / 6 - z / 4); | |
if(sx >= 0 && sx < 160 && d[sx] > sy) { | |
zz = (int)((z + 100) * 0.035) + 1; | |
c = 0; | |
if(zz & 1) c |= 1; | |
if((zz == 2) || (zz == 3) || (zz >= 6)) c |= 2; | |
if(zz >= 4) c |= 4; | |
if(c != 0) { | |
gr_pset(sx * 2, sy * 2, c); | |
} | |
d[sx] = sy; | |
} | |
} | |
} | |
} | |
int main() | |
{ | |
int oldmode; | |
oldmode = getvideo(); | |
setvideo(0x0d); | |
#ifndef USE_BIOS | |
init_vga(); | |
#endif | |
draw(); | |
getchar(); | |
setvideo(oldmode); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
' Ported for PicoCalc, https://www.clockworkpi.com/picocalc | |
Const c1 = RGB(0, 0, 255) | |
Const c2 = RGB(0, 255, 0) | |
Const c4 = RGB(255, 0, 0) | |
Dim d(160) As INTEGER | |
Dim r As FLOAT, x As FLOAT, y As FLOAT, z As FLOAT | |
Dim i As INTEGER, sx As INTEGER, sy As INTEGER | |
Dim zz As INTEGER, c As INTEGER | |
For i = 1 To 159 | |
d(i) = 100 | |
Next | |
Const dr = 3.1415932 / 180 | |
For y = -180 To 180 Step 6 | |
For x = -180 To 180 Step 4 | |
r = dr * Sqr(x * x + y * y) | |
z = 100 * Cos(r) - 30 * Cos(3 * r) | |
sx = Int(80 + x / 3 - y / 6) | |
sy = Int(40 - y / 6 - z / 4) | |
If (sx >= 0) And (sx < 160) Then | |
If d(sx) > sy Then | |
zz = Int((z + 100) * .035) + 1 | |
c = 0 | |
If zz And 1 Then c = c Or c1 | |
If (zz = 2) Or (zz = 3) Or (zz >= 6) Then c = c Or c2 | |
If zz >= 4 Then c = c Or c4 | |
If c <> 0 Then | |
Pixel sx * 2, sy * 2, c | |
End If | |
d(sx) = sy | |
End If | |
End If | |
Next | |
Next |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef VGA_H | |
#define VGA_H | |
#define VGA_AREG 0x03ce | |
#define VGA_DREG 0x03cf | |
#define SEQ_AREG 0x03c4 | |
#define SEQ_DREG 0x03c5 | |
#define VA(n) outp(VGA_AREG, (n)) | |
#define VD(n) outp(VGA_DREG, (n)) | |
#define SA(n) outp(SEQ_AREG, (n)) | |
#define SD(n) outp(SEQ_DREG, (n)) | |
#define VGA(idx, n) { VA(idx); VD(n); } | |
#define SEQ(idx, n) { SA(idx); SD(n); } | |
#define RV() inp(VGA_DREG) | |
#define RS() inp(SEQ_DREG) | |
#define SEQ_PLANE_WRITE_ENABLE(n) SEQ(0x02, (n)) | |
#define VGA_READ_PLANE_SELECT(n) VGA(0x04, (n)) | |
#define VGA_ENABLE_SET_RESET(n) VGA(0x01, (n)) | |
#define VGA_SET_RESET(n) VGA(0x00, (n)) | |
#define VGA_SET_BIT_MASK(n) VGA(0x08, (n)) | |
#define VGA_SET_WRITE_MODE(n) { VA(0x05); VD((RV() & 0xfc) | (n)); } | |
#define VGA_SET_LOGICAL_OP(n) { VA(0x03); VD((RV() & 0x18) | (n)); } | |
#define VGA_NOP 0x00 | |
#define VGA_AND 0x01 | |
#define VGA_OR 0x02 | |
#define VGA_XOR 0x03 | |
#define VGA_SET_ROTATE(n) { VA(0x03); VD((RV() & 0x07) | (n)); } | |
#define ENABLE_VRAM_ACCESS() outp(0x03c2, inp(0x03cc) | 2) | |
#endif /* !VGA_H */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment