Skip to content

Instantly share code, notes, and snippets.

@autch
Last active March 31, 2025 16:40
Show Gist options
  • Save autch/4a20b86657a2ee8b411fb7cd558ab4b1 to your computer and use it in GitHub Desktop.
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
/* 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, &regs);
}
int getvideo()
{
__dpmi_regs regs;
regs.h.ah = 0x0f;
__dpmi_int(0x10, &regs);
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, &regs);
}
#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);
}
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
/* 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, &regs, &regs);
}
int getvideo()
{
union REGS regs;
regs.h.ah = 0x0f;
int86(0x10, &regs, &regs);
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, &regs, &regs);
}
#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);
}
' 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
#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