Merge branch 'master' into feature/plus4-tgi-driver
This commit is contained in:
362
samples/Makefile
362
samples/Makefile
@@ -92,15 +92,15 @@ ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),)
|
||||
|
||||
# For this one, see https://www.horus.com/~hias/atari/
|
||||
DIR2ATR ?= dir2atr
|
||||
|
||||
DISK_c64 = samples.d64
|
||||
DISK_plus4 = samples.d64
|
||||
DISK_apple2 = samples.dsk
|
||||
DISK_apple2enh = samples.dsk
|
||||
DISK_atari = samples.atr
|
||||
DISK_atarixl = samples.atr
|
||||
endif
|
||||
|
||||
DISK_c64 = samples.d64
|
||||
DISK_apple2 = samples.dsk
|
||||
DISK_apple2enh = samples.dsk
|
||||
DISK_atari = samples.atr
|
||||
DISK_atarixl = samples.atr
|
||||
DISK_plus4 = samples.d64
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# System-dependent settings
|
||||
# For convenience, these groups and lines are sorted alphabetically, first
|
||||
@@ -133,7 +133,7 @@ LDFLAGS_tgidemo_atarixl = --start-addr 0x4000
|
||||
# --------------------------------------------------------------------------
|
||||
# Generic rules
|
||||
|
||||
.PHONY: all mostlyclean clean install zip samples disk
|
||||
.PHONY: samples all mostlyclean clean install zip disk platforms
|
||||
|
||||
%: %.c
|
||||
%: %.s
|
||||
@@ -154,36 +154,18 @@ else
|
||||
$(CL) $(LDFLAGS_$(@F)_$(SYS)) $(LDFLAGS) -o $@ -t $(SYS) -m $@.map $^ $(SYS).lib
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Lists of subdirectories
|
||||
|
||||
# disasm depends on cpp
|
||||
DIRLIST = tutorial geos atari2600 atari5200 apple2 gamate lynx supervision sym1 kim1 cbm
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Lists of executables
|
||||
|
||||
EXELIST_c64 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
fire \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
mousedemo \
|
||||
multdemo \
|
||||
nachtm \
|
||||
ovrldemo \
|
||||
plasma \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_plus4 = \
|
||||
ascii \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
plasma \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_apple2 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
diodemo \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
@@ -193,12 +175,15 @@ EXELIST_apple2 = \
|
||||
multdemo \
|
||||
ovrldemo \
|
||||
sieve \
|
||||
terminal \
|
||||
tinyshell \
|
||||
tgidemo
|
||||
|
||||
EXELIST_apple2enh = $(EXELIST_apple2)
|
||||
|
||||
EXELIST_atari = \
|
||||
ascii \
|
||||
checkversion \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
@@ -206,15 +191,178 @@ EXELIST_atari = \
|
||||
multdemo \
|
||||
ovrldemo \
|
||||
sieve \
|
||||
terminal \
|
||||
tinyshell \
|
||||
tgidemo
|
||||
|
||||
EXELIST_atarixl = $(EXELIST_atari)
|
||||
|
||||
EXELIST_atari2600 = \
|
||||
atari2600hello
|
||||
|
||||
notavailable
|
||||
|
||||
EXELIST_atari5200 = \
|
||||
notavailable
|
||||
|
||||
EXELIST_atmos = \
|
||||
ascii \
|
||||
checkversion \
|
||||
hello \
|
||||
mandelbrot \
|
||||
sieve \
|
||||
terminal \
|
||||
tgidemo
|
||||
|
||||
EXELIST_bbc = \
|
||||
notavailable
|
||||
|
||||
EXELIST_c64 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
mousedemo \
|
||||
multdemo \
|
||||
ovrldemo \
|
||||
sieve \
|
||||
terminal \
|
||||
tinyshell \
|
||||
tgidemo
|
||||
|
||||
EXELIST_c128 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
mousedemo \
|
||||
sieve \
|
||||
terminal \
|
||||
tinyshell \
|
||||
tgidemo
|
||||
|
||||
EXELIST_c16 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
enumdevdir \
|
||||
tinyshell \
|
||||
hello
|
||||
|
||||
EXELIST_cbm510 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mousedemo \
|
||||
terminal \
|
||||
tinyshell \
|
||||
sieve
|
||||
|
||||
EXELIST_cbm610 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
gunzip65 \
|
||||
hello \
|
||||
terminal \
|
||||
tinyshell \
|
||||
sieve
|
||||
|
||||
EXELIST_creativision = \
|
||||
ascii \
|
||||
hello
|
||||
|
||||
EXELIST_cx16 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
mousedemo \
|
||||
sieve \
|
||||
tinyshell \
|
||||
tgidemo
|
||||
|
||||
EXELIST_gamate = \
|
||||
hello
|
||||
|
||||
EXELIST_geos-cbm = \
|
||||
ascii \
|
||||
checkversion \
|
||||
diodemo
|
||||
|
||||
EXELIST_geos-apple = \
|
||||
ascii
|
||||
|
||||
EXELIST_lunix = \
|
||||
notavailable
|
||||
|
||||
EXELIST_lynx = \
|
||||
notavailable
|
||||
|
||||
EXELIST_nes = \
|
||||
hello
|
||||
|
||||
EXELIST_osic1p = \
|
||||
notavailable
|
||||
|
||||
EXELIST_pce = \
|
||||
hello
|
||||
|
||||
EXELIST_pet = \
|
||||
ascii \
|
||||
checkversion \
|
||||
enumdevdir \
|
||||
hello \
|
||||
tinyshell \
|
||||
sieve
|
||||
|
||||
EXELIST_plus4 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
enumdevdir \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
terminal \
|
||||
tinyshell \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_sim6502 = \
|
||||
checkversion \
|
||||
gunzip65
|
||||
|
||||
EXELIST_sim65c02 = $(EXELIST_sim6502)
|
||||
|
||||
EXELIST_supervision = \
|
||||
supervisionhello
|
||||
notavailable
|
||||
|
||||
EXELIST_sym1 = \
|
||||
notavailable
|
||||
|
||||
EXELIST_kim1 = \
|
||||
notavailable
|
||||
|
||||
EXELIST_telestrat = \
|
||||
ascii \
|
||||
checkversion \
|
||||
gunzip65 \
|
||||
hello \
|
||||
mandelbrot \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
EXELIST_vic20 = \
|
||||
ascii \
|
||||
checkversion \
|
||||
enumdevdir \
|
||||
hello \
|
||||
mandelbrot \
|
||||
sieve \
|
||||
tgidemo
|
||||
|
||||
# Unlisted targets will try to build everything.
|
||||
# That lets us learn what they cannot build, and what settings
|
||||
@@ -223,15 +371,76 @@ ifndef EXELIST_$(SYS)
|
||||
EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)}
|
||||
endif
|
||||
|
||||
define SUBDIR_recipe
|
||||
|
||||
@+$(MAKE) -C $(dir) --no-print-directory $@
|
||||
|
||||
endef # SUBDIR_recipe
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Rules to make the binaries and the disk
|
||||
|
||||
samples: $(EXELIST_$(SYS))
|
||||
$(foreach dir,$(DIRLIST),$(SUBDIR_recipe))
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: generic samples not available for" $(SYS)
|
||||
endif
|
||||
|
||||
disk: $(DISK_$(SYS))
|
||||
|
||||
all:
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# List of every supported platform
|
||||
TARGETS := \
|
||||
apple2 \
|
||||
apple2enh \
|
||||
atari \
|
||||
atarixl \
|
||||
atari2600 \
|
||||
atari5200 \
|
||||
atmos \
|
||||
bbc \
|
||||
c128 \
|
||||
c16 \
|
||||
c64 \
|
||||
cbm510 \
|
||||
cbm610 \
|
||||
creativision \
|
||||
cx16 \
|
||||
gamate \
|
||||
kim1 \
|
||||
lunix \
|
||||
lynx \
|
||||
nes \
|
||||
osic1p \
|
||||
pce \
|
||||
pet \
|
||||
plus4 \
|
||||
sim6502 \
|
||||
sim65c02 \
|
||||
supervision \
|
||||
sym1 \
|
||||
telestrat \
|
||||
vic20
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Rule to make the binaries for every platform
|
||||
|
||||
define TARGET_recipe
|
||||
|
||||
@echo making samples for: $(T)
|
||||
@$(MAKE) -j2 SYS:=$(T)
|
||||
@$(MAKE) --no-print-directory clean SYS:=$(T)
|
||||
|
||||
endef # TARGET_recipe
|
||||
|
||||
platforms:
|
||||
$(foreach T,$(TARGETS),$(TARGET_recipe))
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Overlay rules. Overlays need special ld65 configuration files. Also, the
|
||||
# overlay file-names are shortenned to fit the Atari's 8.3-character limit.
|
||||
@@ -252,21 +461,58 @@ ifneq ($(filter multdemo,$(EXELIST_$(SYS))),)
|
||||
OVERLAYLIST += $(foreach I,1 2 3,multdemo.$I)
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# TGI programs on the VIC-20 need a special ld65 configuration file.
|
||||
|
||||
ifeq ($(SYS),vic20)
|
||||
mandelbrot.o: override CFLAGS += -D DYN_DRV=0
|
||||
mandelbrot: mandelbrot.o
|
||||
$(LD) $(LDFLAGS) -o $@ -C vic20-tgi.cfg -m $@.map $^ $(SYS).lib
|
||||
|
||||
# tgidemo needs at least 16K of RAM expansion.
|
||||
tgidemo.o: override CFLAGS += -D DYN_DRV=0
|
||||
tgidemo: tgidemo.o
|
||||
$(LD) -D __HIMEM__=0x6000 $(LDFLAGS) -o $@ -C vic20-tgi.cfg -m $@.map $^ $(SYS).lib
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# some programs link against getsp.o
|
||||
|
||||
getsp.o: getsp.s
|
||||
$(AS) $(ASFLAGS) -t $(SYS) $<
|
||||
|
||||
ifneq ($(SYS),vic20)
|
||||
tinyshell: tinyshell.o getsp.o
|
||||
$(LD) $(LDFLAGS) -t $(SYS) -o $@ $^ $(SYS).lib
|
||||
endif
|
||||
|
||||
# some programs need more memory on the vic20
|
||||
ifeq ($(SYS),vic20)
|
||||
tinyshell: tinyshell.o getsp.o
|
||||
$(LD) $(LDFLAGS) -o $@ -C vic20-32k.cfg -m $@.map $^ $(SYS).lib
|
||||
endif
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Rule to make a CBM disk with all samples. Needs the c1541 program that comes
|
||||
# with the VICE emulator.
|
||||
|
||||
define D64_WRITE_recipe
|
||||
define D64_WRITE_PRG_recipe
|
||||
|
||||
$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)) >$(NULLDEV)
|
||||
$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),p >$(NULLDEV)
|
||||
|
||||
endef # D64_WRITE_recipe
|
||||
endef # D64_WRITE_PRG_recipe
|
||||
|
||||
define D64_WRITE_SEQ_recipe
|
||||
|
||||
$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),s >$(NULLDEV)
|
||||
|
||||
endef # D64_WRITE_SEQ_recipe
|
||||
|
||||
samples.d64: samples
|
||||
@$(C1541) -format samples,AA d64 $@ >$(NULLDEV)
|
||||
$(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_recipe))
|
||||
$(foreach file,$(OVERLAYLIST),$(D64_WRITE_recipe))
|
||||
$(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_recipe))
|
||||
@$(C1541) -format "samples,00" d64 $@ >$(NULLDEV)
|
||||
$(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe))
|
||||
$(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe))
|
||||
$(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_SEQ_recipe))
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Rule to make an Apple II disk with all samples. Needs the AppleCommander
|
||||
@@ -321,15 +567,36 @@ INSTALL = install
|
||||
samplesdir = $(PREFIX)/share/cc65/samples
|
||||
|
||||
install:
|
||||
$(if $(PREFIX),,$(error variable "PREFIX" must be set))
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/geos
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/tutorial
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/atari2600
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/atari5200
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/apple2
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/cbm
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/gamate
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/supervision
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/disasm
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/kim1
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/lynx
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/sim65
|
||||
$(INSTALL) -d $(DESTDIR)$(samplesdir)/sym1
|
||||
$(INSTALL) -m0644 *.* $(DESTDIR)$(samplesdir)
|
||||
$(INSTALL) -m0644 README $(DESTDIR)$(samplesdir)
|
||||
$(INSTALL) -m0644 readme.txt $(DESTDIR)$(samplesdir)
|
||||
$(INSTALL) -m0644 Makefile $(DESTDIR)$(samplesdir)
|
||||
$(INSTALL) -m0644 geos/*.* $(DESTDIR)$(samplesdir)/geos
|
||||
$(INSTALL) -m0644 tutorial/*.* $(DESTDIR)$(samplesdir)/tutorial
|
||||
$(INSTALL) -m0644 atari2600/*.* $(DESTDIR)$(samplesdir)/atari2600
|
||||
$(INSTALL) -m0644 atari5200/*.* $(DESTDIR)$(samplesdir)/atari5200
|
||||
$(INSTALL) -m0644 apple2/*.* $(DESTDIR)$(samplesdir)/apple2
|
||||
$(INSTALL) -m0644 cbm/*.* $(DESTDIR)$(samplesdir)/cbm
|
||||
$(INSTALL) -m0644 gamate/*.* $(DESTDIR)$(samplesdir)/gamate
|
||||
$(INSTALL) -m0644 supervision/*.* $(DESTDIR)$(samplesdir)/supervision
|
||||
$(INSTALL) -m0644 disasm/*.* $(DESTDIR)$(samplesdir)/disasm
|
||||
$(INSTALL) -m0644 kim1/*.* $(DESTDIR)$(samplesdir)/kim1
|
||||
$(INSTALL) -m0644 lynx/*.* $(DESTDIR)$(samplesdir)/lynx
|
||||
$(INSTALL) -m0644 sim65/*.* $(DESTDIR)$(samplesdir)/sim65
|
||||
$(INSTALL) -m0644 sym1/*.* $(DESTDIR)$(samplesdir)/sym1
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Packaging rules
|
||||
@@ -341,8 +608,11 @@ zip:
|
||||
# Clean-up rules
|
||||
|
||||
mostlyclean:
|
||||
@$(DEL) *.lbl *.map *.o *.s 2>$(NULLDEV)
|
||||
@$(DEL) *.lbl *.map *.o 2>$(NULLDEV)
|
||||
# we cant use .s since we have asm files in the directory that we want to keep
|
||||
@$(DEL) ${patsubst %.c,%.s,$(wildcard *.c)} 2>$(NULLDEV)
|
||||
|
||||
clean: mostlyclean
|
||||
@$(DEL) $(EXELIST_$(SYS)) $(DISK_$(SYS)) 2>$(NULLDEV)
|
||||
@$(DEL) multdemo.? ovrldemo.? 2>$(NULLDEV)
|
||||
$(foreach dir,$(DIRLIST),$(SUBDIR_recipe))
|
||||
|
||||
94
samples/apple2/Makefile
Normal file
94
samples/apple2/Makefile
Normal file
@@ -0,0 +1,94 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= apple2
|
||||
|
||||
# For this one see https://applecommander.github.io/
|
||||
AC ?= ac.jar
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_apple2 = \
|
||||
hgrshow \
|
||||
hgrtest \
|
||||
dhgrshow
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: apple2 tests not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
disk: hgr.dsk dhgr.dsk
|
||||
|
||||
hgr.dsk: hgrshow hgrtest
|
||||
cp prodos.dsk $@
|
||||
java -jar $(AC) -as $@ hgrshow <hgrshow
|
||||
java -jar $(AC) -as $@ hgrtest <hgrtest
|
||||
java -jar $(AC) -p $@ astronaut.hgr bin 0x2000 <astronaut.hgr
|
||||
java -jar $(AC) -p $@ chips.hgr bin 0x2000 <chips.hgr
|
||||
java -jar $(AC) -p $@ macrometer.hgr bin 0x2000 <macrometer.hgr
|
||||
java -jar $(AC) -p $@ mariner.hgr bin 0x2000 <mariner.hgr
|
||||
java -jar $(AC) -p $@ rose.hgr bin 0x2000 <rose.hgr
|
||||
java -jar $(AC) -p $@ werner.hgr bin 0x2000 <werner.hgr
|
||||
java -jar $(AC) -p $@ winston.hgr bin 0x2000 <winston.hgr
|
||||
|
||||
hgrshow: hgrshow.c
|
||||
$(CL) -Oirs -t apple2 --start-addr 0x4000 -m hgrshow.map $^
|
||||
|
||||
hgrtest: hgrtest.c werner.s
|
||||
$(CL) -Oirs -t apple2 -C apple2-hgr.cfg -m hgrtest.map $^
|
||||
|
||||
dhgr.dsk: dhgrshow
|
||||
cp prodos.dsk $@
|
||||
java -jar $(AC) -as $@ dhgrshow <dhgrshow
|
||||
java -jar $(AC) -p $@ catface.dhgr bin 0x2000 <catface.dhgr
|
||||
java -jar $(AC) -p $@ gatsby.dhgr bin 0x2000 <gatsby.dhgr
|
||||
java -jar $(AC) -p $@ girl.dhgr bin 0x2000 <girl.dhgr
|
||||
java -jar $(AC) -p $@ monarch.dhgr bin 0x2000 <monarch.dhgr
|
||||
java -jar $(AC) -p $@ superman.dhgr bin 0x2000 <superman.dhgr
|
||||
java -jar $(AC) -p $@ venice.dhgr bin 0x2000 <venice.dhgr
|
||||
|
||||
dhgrshow: dhgrshow.c
|
||||
$(CL) -Oirs -t apple2enh --start-addr 0x4000 -m dhgrshow.map $^
|
||||
|
||||
clean:
|
||||
@$(DEL) hgr.dsk dhgr.dsk 2>$(NULLDEV)
|
||||
@$(DEL) hgrshow hgrshow.map 2>$(NULLDEV)
|
||||
@$(DEL) hgrtest hgrtest.map 2>$(NULLDEV)
|
||||
@$(DEL) dhgrshow dhgrshow.map 2>$(NULLDEV)
|
||||
BIN
samples/apple2/astronaut.hgr
Normal file
BIN
samples/apple2/astronaut.hgr
Normal file
Binary file not shown.
BIN
samples/apple2/catface.dhgr
Normal file
BIN
samples/apple2/catface.dhgr
Normal file
Binary file not shown.
BIN
samples/apple2/chips.hgr
Normal file
BIN
samples/apple2/chips.hgr
Normal file
Binary file not shown.
46
samples/apple2/dhgrshow.c
Normal file
46
samples/apple2/dhgrshow.c
Normal file
@@ -0,0 +1,46 @@
|
||||
// cl65 -t apple2enh --start-addr 0x4000 dhgrshow.c
|
||||
|
||||
#include <tgi.h>
|
||||
#include <conio.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <peekpoke.h>
|
||||
|
||||
void main (void)
|
||||
{
|
||||
unsigned old;
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
|
||||
old = videomode (VIDEOMODE_80x24);
|
||||
tgi_install (a2e_hi_tgi);
|
||||
tgi_init ();
|
||||
POKE (0xC05E, 0);
|
||||
|
||||
dir = opendir (".");
|
||||
while (ent = readdir (dir)) {
|
||||
char *ext;
|
||||
int hgr;
|
||||
|
||||
ext = strrchr (ent->d_name, '.');
|
||||
if (!ext || strcasecmp (ext, ".dhgr"))
|
||||
continue;
|
||||
|
||||
hgr = open (ent->d_name, O_RDONLY);
|
||||
POKE (0xC055, 0);
|
||||
read (hgr, (void*)0x2000, 0x2000);
|
||||
POKE (0xC054, 0);
|
||||
read (hgr, (void*)0x2000, 0x2000);
|
||||
close (hgr);
|
||||
|
||||
if (cgetc () == '\r')
|
||||
break;
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
POKE (0xC05F, 0);
|
||||
tgi_uninstall ();
|
||||
videomode (old);
|
||||
}
|
||||
BIN
samples/apple2/gatsby.dhgr
Normal file
BIN
samples/apple2/gatsby.dhgr
Normal file
Binary file not shown.
BIN
samples/apple2/girl.dhgr
Normal file
BIN
samples/apple2/girl.dhgr
Normal file
Binary file not shown.
37
samples/apple2/hgrshow.c
Normal file
37
samples/apple2/hgrshow.c
Normal file
@@ -0,0 +1,37 @@
|
||||
// cl65 -t apple2 --start-addr 0x4000 hgrshow.c
|
||||
|
||||
#include <tgi.h>
|
||||
#include <conio.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
void main (void)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
|
||||
tgi_install (a2_hi_tgi);
|
||||
tgi_init ();
|
||||
|
||||
dir = opendir (".");
|
||||
while (ent = readdir (dir)) {
|
||||
char *ext;
|
||||
int hgr;
|
||||
|
||||
ext = strrchr (ent->d_name, '.');
|
||||
if (!ext || strcasecmp (ext, ".hgr"))
|
||||
continue;
|
||||
|
||||
hgr = open (ent->d_name, O_RDONLY);
|
||||
read (hgr, (void*)0x2000, 0x2000);
|
||||
close (hgr);
|
||||
|
||||
if (cgetc () == '\r')
|
||||
break;
|
||||
}
|
||||
closedir (dir);
|
||||
|
||||
tgi_uninstall ();
|
||||
}
|
||||
26
samples/apple2/hgrtest.c
Normal file
26
samples/apple2/hgrtest.c
Normal file
@@ -0,0 +1,26 @@
|
||||
// cl65 -t apple2 -C apple2-hgr.cfg hgrtest.c werner.s
|
||||
|
||||
#include <tgi.h>
|
||||
#include <conio.h>
|
||||
|
||||
#pragma code-name (push, "LOWCODE")
|
||||
|
||||
void say (const char* text)
|
||||
{
|
||||
tgi_setcolor (TGI_COLOR_BLACK);
|
||||
tgi_outtextxy (41, 33, text);
|
||||
}
|
||||
|
||||
#pragma code-name (pop)
|
||||
|
||||
void main (void)
|
||||
{
|
||||
tgi_install (a2_hi_tgi);
|
||||
tgi_init ();
|
||||
cgetc ();
|
||||
|
||||
say ("Hi Dude !");
|
||||
cgetc ();
|
||||
|
||||
tgi_uninstall ();
|
||||
}
|
||||
BIN
samples/apple2/macrometer.hgr
Normal file
BIN
samples/apple2/macrometer.hgr
Normal file
Binary file not shown.
BIN
samples/apple2/mariner.hgr
Normal file
BIN
samples/apple2/mariner.hgr
Normal file
Binary file not shown.
BIN
samples/apple2/monarch.dhgr
Normal file
BIN
samples/apple2/monarch.dhgr
Normal file
Binary file not shown.
BIN
samples/apple2/rose.hgr
Normal file
BIN
samples/apple2/rose.hgr
Normal file
Binary file not shown.
BIN
samples/apple2/superman.dhgr
Normal file
BIN
samples/apple2/superman.dhgr
Normal file
Binary file not shown.
BIN
samples/apple2/venice.dhgr
Normal file
BIN
samples/apple2/venice.dhgr
Normal file
Binary file not shown.
BIN
samples/apple2/werner.hgr
Normal file
BIN
samples/apple2/werner.hgr
Normal file
Binary file not shown.
2
samples/apple2/werner.s
Normal file
2
samples/apple2/werner.s
Normal file
@@ -0,0 +1,2 @@
|
||||
.segment "HGR"
|
||||
.incbin "werner.hgr"
|
||||
BIN
samples/apple2/winston.hgr
Normal file
BIN
samples/apple2/winston.hgr
Normal file
Binary file not shown.
59
samples/atari2600/Makefile
Normal file
59
samples/atari2600/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= atari2600
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
SP = $(CC65_HOME)/bin/sp65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65)
|
||||
endif
|
||||
|
||||
EXELIST_atari2600 = \
|
||||
hello
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: atari 2600 samples not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
hello: hello.c
|
||||
$(CL) -t $(SYS) -O -o hello -m hello.map hello.c
|
||||
|
||||
clean:
|
||||
@$(DEL) $(EXELIST_atari2600) 2>$(NULLDEV)
|
||||
@$(DEL) *.map 2>$(NULLDEV)
|
||||
56
samples/atari5200/Makefile
Normal file
56
samples/atari5200/Makefile
Normal file
@@ -0,0 +1,56 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= atari5200
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_atari5200 = \
|
||||
hello
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: atari 5200 tests not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
hello: hello.c
|
||||
$(CL) -t atari5200 -o hello hello.c
|
||||
|
||||
clean:
|
||||
@$(DEL) hello 2>$(NULLDEV)
|
||||
109
samples/atari5200/hello.c
Normal file
109
samples/atari5200/hello.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
** Fancy hello world program using cc65.
|
||||
**
|
||||
** Ullrich von Bassewitz (ullrich@von-bassewitz.de)
|
||||
**
|
||||
** TEST version for atari5200 conio, using all four colors
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <conio.h>
|
||||
#include <joystick.h>
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
static const char Text [] = "Hello world!";
|
||||
static unsigned char colors[] = { COLOR_WHITE, COLOR_GREEN, COLOR_RED, COLOR_BLACK };
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned char XSize, YSize;
|
||||
unsigned char PosY;
|
||||
unsigned char i = 0;
|
||||
|
||||
/* Set screen colors */
|
||||
(void) textcolor (COLOR_WHITE);
|
||||
(void) bordercolor (COLOR_BLACK);
|
||||
(void) bgcolor (COLOR_BLACK);
|
||||
|
||||
/* Clear the screen, put cursor in upper left corner */
|
||||
clrscr ();
|
||||
|
||||
/* Ask for the screen size */
|
||||
screensize (&XSize, &YSize);
|
||||
|
||||
/* Install joystick driver */
|
||||
joy_install (joy_static_stddrv);
|
||||
|
||||
while (1) {
|
||||
/* Draw a border around the screen */
|
||||
|
||||
/* Top line */
|
||||
cputc (CH_ULCORNER);
|
||||
chline (XSize - 2);
|
||||
cputc (CH_URCORNER);
|
||||
|
||||
/* Vertical line, left side */
|
||||
cvlinexy (0, 1, YSize - 2);
|
||||
|
||||
/* Bottom line */
|
||||
cputc (CH_LLCORNER);
|
||||
chline (XSize - 2);
|
||||
cputc (CH_LRCORNER);
|
||||
|
||||
/* Vertical line, right side */
|
||||
cvlinexy (XSize - 1, 1, YSize - 2);
|
||||
|
||||
/* Write the greeting in the mid of the screen */
|
||||
gotoxy ((XSize - strlen (Text)) / 2, YSize / 2);
|
||||
cprintf ("%s", Text);
|
||||
|
||||
PosY = wherey ();
|
||||
textcolor (colors[i]); /* switch to color #0 */
|
||||
cputsxy(3, ++PosY, "COLOR 0");
|
||||
textcolor ((colors[i] + 1) & 3); /* switch to color #1 */
|
||||
cputsxy(3, ++PosY, "COLOR 1");
|
||||
textcolor ((colors[i] + 2) & 3); /* switch to color #2 */
|
||||
cputsxy(3, ++PosY, "COLOR 2");
|
||||
textcolor ((colors[i] + 3) & 3); /* switch to color #3 */ /* color #3 is the background color. So written text isn't visible. */
|
||||
cputsxy(3, ++PosY, "COLOR 3");
|
||||
|
||||
/* Wait for the user to press and release a button */
|
||||
while (!joy_read (JOY_1))
|
||||
;
|
||||
while (joy_read (JOY_1))
|
||||
;
|
||||
|
||||
i = (i + 1) & 3;
|
||||
|
||||
/* Change colors */
|
||||
textcolor (colors[i]);
|
||||
bgcolor ((colors[i] + 3) & 3);
|
||||
|
||||
/* Clear the screen again */
|
||||
clrscr ();
|
||||
}
|
||||
/* not reached */
|
||||
|
||||
joy_uninstall ();
|
||||
|
||||
/* Done */
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
176
samples/cbm/Makefile
Normal file
176
samples/cbm/Makefile
Normal file
@@ -0,0 +1,176 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= c64
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
SP = $(CC65_HOME)/bin/sp65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65)
|
||||
endif
|
||||
|
||||
ifneq ($(filter disk samples.%,$(MAKECMDGOALS)),)
|
||||
ifdef CC65_HOME
|
||||
TARGET_PATH = $(CC65_HOME)/target
|
||||
else
|
||||
TARGET_PATH := $(if $(wildcard ../target),../target,$(shell $(CL) --print-target-path))
|
||||
endif
|
||||
|
||||
# If TARGET_PATH contains spaces then it is presumed to contain escaped spaces. GNU make
|
||||
# has very limited support for paths containing spaces. $(wildcard) is the only function
|
||||
# that is aware of escaped spaces. However, $(wildcard) never returns paths with escaped
|
||||
# spaces !!! So if it e.g. finds 4 files in a path with 2 spaces then one ends up with a
|
||||
# return value consisting of 12 plain words :-((
|
||||
#
|
||||
# Fortunately we can work around that behaviour here because we know that the files we
|
||||
# are looking for have known extensions. So we can $(filter) the in our example above 12
|
||||
# words for file extensions so we come up with 4 path fragments. Then we remove those
|
||||
# path fragments with $(notdir) from the file names.
|
||||
#
|
||||
# So far so good. But here we want to process files from different paths in a single
|
||||
# recipe further down below and therefore want to prepend the paths to the files with
|
||||
# $(addprefix). However, $(foreach) isn't aware of escaped spaces (only $(wildcard) is).
|
||||
# Therefore, we need to replace the spaces with some other character temporarily in order
|
||||
# to have $(foreach) generate one invocation per file. We use the character '?' for that
|
||||
# purpose here, just because it is known to not be part of file names.
|
||||
#
|
||||
# Inside the recipe generated per file we then replace the '?' again with a space. As we
|
||||
# want to be compatible with cmd.exe for execution we're not using an escaped space but
|
||||
# rather double-quote the whole path.
|
||||
#
|
||||
# Note: The "strange" $(wildcard) further down below just serves the purpose to unescape
|
||||
# spaces for cmd.exe. This could have as well been done with another $(subst).
|
||||
|
||||
SUBST_TARGET_PATH := $(subst \$(SPACE),?,$(TARGET_PATH))
|
||||
|
||||
EMD := $(wildcard $(TARGET_PATH)/$(SYS)/drv/emd/*)
|
||||
MOU := $(wildcard $(TARGET_PATH)/$(SYS)/drv/mou/*)
|
||||
TGI := $(wildcard $(TARGET_PATH)/$(SYS)/drv/tgi/*)
|
||||
|
||||
EMD := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/emd/,$(notdir $(filter %.emd,$(EMD))))
|
||||
MOU := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/mou/,$(notdir $(filter %.mou,$(MOU))))
|
||||
TGI := $(addprefix $(SUBST_TARGET_PATH)/$(SYS)/drv/tgi/,$(notdir $(filter %.tgi,$(TGI))))
|
||||
|
||||
# This one comes with the VICE emulator.
|
||||
# See http://vice-emu.sourceforge.net/
|
||||
C1541 ?= c1541
|
||||
endif
|
||||
|
||||
DISK_$(SYS) = samples.d64
|
||||
|
||||
EXELIST_c64 = \
|
||||
fire \
|
||||
plasma \
|
||||
nachtm \
|
||||
hello
|
||||
|
||||
EXELIST_c128 = \
|
||||
fire \
|
||||
plasma \
|
||||
nachtm \
|
||||
hello
|
||||
|
||||
EXELIST_cbm510 = \
|
||||
fire \
|
||||
plasma \
|
||||
nachtm
|
||||
|
||||
EXELIST_cbm610 = \
|
||||
nachtm
|
||||
|
||||
EXELIST_plus4 = \
|
||||
plasma \
|
||||
hello
|
||||
|
||||
EXELIST_c16 = \
|
||||
hello
|
||||
|
||||
EXELIST_pet = \
|
||||
notavailable
|
||||
|
||||
EXELIST_vic20 = \
|
||||
hello
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
disk: $(DISK_$(SYS))
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: cbm samples not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
fire: fire.c
|
||||
$(CL) -t $(SYS) -O -o fire -m fire.map fire.c
|
||||
plasma: plasma.c
|
||||
$(CL) -t $(SYS) -O -o plasma -m plasma.map plasma.c
|
||||
nachtm: nachtm.c
|
||||
$(CL) -t $(SYS) -O -o nachtm -m nachtm.map nachtm.c
|
||||
hello: hello-asm.s
|
||||
# Use separate assembler ...
|
||||
$(AS) -t $(SYS) hello-asm.s
|
||||
# ... and linker commands ...
|
||||
$(LD) -C $(SYS)-asm.cfg -o hello -m hello-asm.map -u __EXEHDR__ hello-asm.o $(SYS).lib
|
||||
@$(DEL) hello-asm.o 2>$(NULLDEV)
|
||||
# ... or compile & link utility
|
||||
# $(CL) -C $(SYS)-asm.cfg -o hello -m hello-asm.map -u __EXEHDR__ hello-asm.s
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Rule to make a CBM disk with all samples. Needs the c1541 program that comes
|
||||
# with the VICE emulator.
|
||||
|
||||
define D64_WRITE_PRG_recipe
|
||||
|
||||
$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),p >$(NULLDEV)
|
||||
|
||||
endef # D64_WRITE_PRG_recipe
|
||||
|
||||
define D64_WRITE_SEQ_recipe
|
||||
|
||||
$(C1541) -attach $@ -write "$(subst ?,$(SPACE),$(file))" $(notdir $(file)),s >$(NULLDEV)
|
||||
|
||||
endef # D64_WRITE_SEQ_recipe
|
||||
|
||||
samples.d64: samples
|
||||
@$(C1541) -format "samples,00" d64 $@ >$(NULLDEV)
|
||||
$(foreach file,$(EXELIST_$(SYS)),$(D64_WRITE_PRG_recipe))
|
||||
# $(foreach file,$(OVERLAYLIST),$(D64_WRITE_PRG_recipe))
|
||||
# $(foreach file,$(EMD) $(MOU) $(TGI),$(D64_WRITE_SEQ_recipe))
|
||||
|
||||
clean:
|
||||
@$(DEL) $(EXELIST_$(SYS)) 2>$(NULLDEV)
|
||||
@$(DEL) *.map 2>$(NULLDEV)
|
||||
@$(DEL) $(DISK_$(SYS)) 2>$(NULLDEV)
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
|
||||
/* Use static local variables for speed */
|
||||
#pragma static-locals (1);
|
||||
#pragma static-locals (1)
|
||||
|
||||
|
||||
|
||||
15
samples/cbm/hello-asm.s
Normal file
15
samples/cbm/hello-asm.s
Normal file
@@ -0,0 +1,15 @@
|
||||
;
|
||||
; Sample assembly program for Commodore machines
|
||||
;
|
||||
|
||||
.include "cbm_kernal.inc"
|
||||
|
||||
ldx #$00
|
||||
: lda text,x
|
||||
beq out
|
||||
jsr CHROUT
|
||||
inx
|
||||
bne :-
|
||||
out: rts
|
||||
|
||||
text: .asciiz "hello world!"
|
||||
@@ -972,12 +972,12 @@ static void MakeNiceScreen (void)
|
||||
|
||||
/* Clear the screen hide the cursor, set colors */
|
||||
#ifdef __CBM610__
|
||||
textcolor (COLOR_WHITE);
|
||||
(void)textcolor (COLOR_WHITE);
|
||||
#else
|
||||
textcolor (COLOR_GRAY3);
|
||||
(void)textcolor (COLOR_GRAY3);
|
||||
#endif
|
||||
bordercolor (COLOR_BLACK);
|
||||
bgcolor (COLOR_BLACK);
|
||||
(void)bordercolor (COLOR_BLACK);
|
||||
(void)bgcolor (COLOR_BLACK);
|
||||
clrscr ();
|
||||
cursor (0);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*****************************************************************************\
|
||||
** plasma test program for cc65. **
|
||||
** **
|
||||
** (w)2001 by groepaz/hitmen **
|
||||
** (w)2001 by groepaz **
|
||||
** **
|
||||
** Cleanup and porting by Ullrich von Bassewitz. **
|
||||
** **
|
||||
@@ -51,8 +51,7 @@
|
||||
|
||||
|
||||
/* Use static local variables for speed */
|
||||
#pragma static-locals (1);
|
||||
|
||||
#pragma static-locals (1)
|
||||
|
||||
|
||||
static const unsigned char sinustable[0x100] = {
|
||||
@@ -131,8 +130,6 @@ static void doplasma (register unsigned char* scrn)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void makechar (void)
|
||||
{
|
||||
static const unsigned char bittab[8] = {
|
||||
@@ -147,7 +144,7 @@ static void makechar (void)
|
||||
for (i = 0; i < 8; ++i){
|
||||
b = 0;
|
||||
for (ii = 0; ii < 8; ++ii) {
|
||||
if ((rand() & 0xFF) > s) {
|
||||
if ((rand() & 0xFFu) > s) {
|
||||
b |= bittab[ii];
|
||||
}
|
||||
}
|
||||
40
samples/checkversion.c
Normal file
40
samples/checkversion.c
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
/* Until 2.19 the __CC65__ macro was defined as (VER_MAJOR * 0x100) + (VER_MINOR * 0x10),
|
||||
* which caused it to contain broken values in compiler releases 2.16 to 2.19. The
|
||||
* macro was fixed some time after 2.19 to (VER_MAJOR * 0x100) + VER_MINOR.
|
||||
*
|
||||
* The following strategy can be used to still compare for less or greater versions,
|
||||
* should this really be necessary or wanted - it is not recommended afterall.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#if ((__CC65__ >> 8) > 3) || ((__CC65__ & 0x000f) > 0)
|
||||
/* compiler version is 2.19-git or higher */
|
||||
# define VER_MAJOR ((__CC65__ >> 8) & 0xff)
|
||||
# define VER_MINOR (__CC65__ & 0xff)
|
||||
#elif ((__CC65__ >> 8) == 3)
|
||||
/* broken values in version 2.16 - 2.19-git before the bug was fixed */
|
||||
# define VER_MAJOR 2
|
||||
# define VER_MINOR (((__CC65__ >> 4) & 0x0f) + 16)
|
||||
#else
|
||||
/* values before 2.16 */
|
||||
# define VER_MAJOR ((__CC65__ >> 8) & 0xff)
|
||||
# define VER_MINOR ((__CC65__ >> 4) & 0x0f)
|
||||
#endif
|
||||
|
||||
/* define a new value that will work for comparing all versions */
|
||||
#define VERSION ((VER_MAJOR << 8) + VER_MINOR)
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("__CC65__ defined as %04x\n", __CC65__);
|
||||
printf("compiler version is %u.%u\n", VER_MAJOR, VER_MINOR);
|
||||
if (__CC65__ == VERSION) {
|
||||
printf("__CC65__ is defined correctly as (VER_MAJOR * 0x100) + VER_MINOR\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
printf("__CC65__ is incorrectly defined as (VER_MAJOR * 0x100) + (VER_MINOR * 0x10)\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
2
samples/disasm/.gitignore
vendored
Normal file
2
samples/disasm/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.s
|
||||
image.bin
|
||||
59
samples/disasm/Makefile
Normal file
59
samples/disasm/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
# Sample makefile using a preprocessor against info files
|
||||
# and the --sync-lines option
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
DA = $(CC65_HOME)/bin/da65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
DA := $(if $(wildcard ../../bin/da65*),../../bin/da65,da65)
|
||||
endif
|
||||
|
||||
CPP = cpp
|
||||
#CPPFLAGS = -DTEST_ERROR
|
||||
|
||||
ASMS = fixed.s bank0.s bank1.s
|
||||
DAIS = fixed.dai bank0.dai bank1.dai
|
||||
|
||||
.SUFFIXES: .da .dai .s
|
||||
|
||||
samples: image.bin $(ASMS)
|
||||
|
||||
$(DAIS): fixed.da
|
||||
|
||||
.da.dai:
|
||||
$(CPP) -o $@ $(CPPFLAGS) $<
|
||||
|
||||
.dai.s:
|
||||
$(DA) --sync-lines -o $@ -i $< image.bin
|
||||
|
||||
image.bin: image.s image.cfg
|
||||
$(CL) -t none -C image.cfg -o image.bin image.s
|
||||
|
||||
clean:
|
||||
@$(DEL) $(ASMS) 2>$(NULLDEV)
|
||||
@$(DEL) $(DAIS) 2>$(NULLDEV)
|
||||
@$(DEL) image.bin 2>$(NULLDEV)
|
||||
|
||||
16
samples/disasm/bank0.da
Normal file
16
samples/disasm/bank0.da
Normal file
@@ -0,0 +1,16 @@
|
||||
// Da65 input file before preprocessed by cpp
|
||||
// Bank0 ROM map
|
||||
|
||||
#define TARGET_BANK 0
|
||||
global {
|
||||
inputoffs $00010;
|
||||
inputsize $4000;
|
||||
startaddr $8000;
|
||||
cpu "6502";
|
||||
};
|
||||
|
||||
#include "fixed.da"
|
||||
|
||||
label { addr $8000; name "Bank0ProcA"; };
|
||||
label { addr $8123; name "Bank0ProcB"; };
|
||||
range { start $A000; end $BFFF; name "Bank0Data"; type ByteTable; };
|
||||
16
samples/disasm/bank1.da
Normal file
16
samples/disasm/bank1.da
Normal file
@@ -0,0 +1,16 @@
|
||||
// Da65 input file before preprocessed by cpp
|
||||
// Bank1 ROM map
|
||||
|
||||
#define TARGET_BANK 1
|
||||
global {
|
||||
inputoffs $04010;
|
||||
inputsize $4000;
|
||||
startaddr $8000;
|
||||
cpu "6502";
|
||||
};
|
||||
|
||||
#include "fixed.da"
|
||||
|
||||
range { start $8000; end $AFFF; name "Bank1Data"; type ByteTable; };
|
||||
label { addr $B000; name "Bank1ProcA"; };
|
||||
label { addr $B123; name "Bank1ProcB"; };
|
||||
30
samples/disasm/fixed.da
Normal file
30
samples/disasm/fixed.da
Normal file
@@ -0,0 +1,30 @@
|
||||
// Da65 input file before preprocessed by cpp
|
||||
// RAM and Fixed ROM map
|
||||
|
||||
#ifndef FIXED_DA_INCLUDED
|
||||
#define FIXED_DA_INCLUDED
|
||||
|
||||
#ifndef TARGET_BANK
|
||||
#define TARGET_BANK -1
|
||||
global {
|
||||
inputoffs $0C010;
|
||||
inputsize $4000;
|
||||
startaddr $C000;
|
||||
cpu "6502";
|
||||
};
|
||||
#endif /* !defined(TARGET_BANK) */
|
||||
|
||||
// ---- RAM map ----
|
||||
label { addr $00; name "VariableA"; };
|
||||
label { addr $01; name "VariableB"; };
|
||||
label { addr $0100; name "Stack"; size $0100; };
|
||||
#if defined(TEST_ERROR) && TARGET_BANK == 0
|
||||
erroneous_line;
|
||||
#endif
|
||||
|
||||
// ---- Fixed ROM map ----
|
||||
label { addr $C000; name "CommonProcA"; };
|
||||
label { addr $C123; name "CommonProcB"; };
|
||||
range { start $E123; end $FFFF; name "CommonData"; type ByteTable; };
|
||||
|
||||
#endif /* !defined(FIXED_DA_INCLUDED) */
|
||||
15
samples/disasm/image.cfg
Normal file
15
samples/disasm/image.cfg
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
MEMORY {
|
||||
HEADER: file = %O, start = $0000, size = $0010, fill = yes;
|
||||
BANK00: file = %O, start = $8000, size = $4000, fill = yes;
|
||||
BANK01: file = %O, start = $8000, size = $4000, fill = yes;
|
||||
BANK02: file = %O, start = $8000, size = $4000, fill = yes;
|
||||
FIXED: file = %O, start = $c000, size = $4000, fill = yes;
|
||||
}
|
||||
SEGMENTS {
|
||||
HDR: load = HEADER, type = rw, optional = yes, define = yes;
|
||||
BANK0: load = BANK00, type = rw, optional = yes, define = yes;
|
||||
BANK1: load = BANK01, type = rw, optional = yes, define = yes;
|
||||
BANK2: load = BANK02, type = rw, optional = yes, define = yes;
|
||||
FIX: load = FIXED, type = rw, optional = yes, define = yes;
|
||||
}
|
||||
@@ -11,36 +11,52 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <device.h>
|
||||
#include <dirent.h>
|
||||
#include <cc65.h>
|
||||
|
||||
|
||||
void printdir (char *newdir)
|
||||
/* returns true for error, false for OK */
|
||||
bool printdir (char *newdir)
|
||||
{
|
||||
char olddir[FILENAME_MAX];
|
||||
char curdir[FILENAME_MAX];
|
||||
char *olddir;
|
||||
char *curdir;
|
||||
DIR *dir;
|
||||
struct dirent *ent;
|
||||
char *subdirs = NULL;
|
||||
unsigned dirnum = 0;
|
||||
unsigned num;
|
||||
|
||||
getcwd (olddir, sizeof (olddir));
|
||||
olddir = malloc (FILENAME_MAX);
|
||||
if (olddir == NULL) {
|
||||
perror ("cannot allocate memory");
|
||||
return true;
|
||||
}
|
||||
|
||||
getcwd (olddir, FILENAME_MAX);
|
||||
if (chdir (newdir)) {
|
||||
|
||||
/* If chdir() fails we just print the
|
||||
** directory name - as done for files.
|
||||
*/
|
||||
printf (" Dir %s\n", newdir);
|
||||
return;
|
||||
free (olddir);
|
||||
return false;
|
||||
}
|
||||
|
||||
curdir = malloc (FILENAME_MAX);
|
||||
if (curdir == NULL) {
|
||||
perror ("cannot allocate memory");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We call getcwd() in order to print the
|
||||
** absolute pathname for a subdirectory.
|
||||
*/
|
||||
getcwd (curdir, sizeof (curdir));
|
||||
getcwd (curdir, FILENAME_MAX);
|
||||
printf (" Dir %s:\n", curdir);
|
||||
free (curdir);
|
||||
|
||||
/* Calling opendir() always with "." avoids
|
||||
** fiddling around with pathname separators.
|
||||
@@ -65,18 +81,27 @@ void printdir (char *newdir)
|
||||
closedir (dir);
|
||||
|
||||
for (num = 0; num < dirnum; ++num) {
|
||||
printdir (subdirs + FILENAME_MAX * num);
|
||||
if (printdir (subdirs + FILENAME_MAX * num))
|
||||
break;
|
||||
}
|
||||
free (subdirs);
|
||||
|
||||
chdir (olddir);
|
||||
free (olddir);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void main (void)
|
||||
{
|
||||
unsigned char device;
|
||||
char devicedir[FILENAME_MAX];
|
||||
char *devicedir;
|
||||
|
||||
devicedir = malloc (FILENAME_MAX);
|
||||
if (devicedir == NULL) {
|
||||
perror ("cannot allocate memory");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calling getfirstdevice()/getnextdevice() does _not_ turn on the motor
|
||||
** of a drive-type device and does _not_ check for a disk in the drive.
|
||||
@@ -88,7 +113,7 @@ void main (void)
|
||||
/* Calling getdevicedir() _does_ check for a (formatted) disk in a
|
||||
** floppy-disk-type device and returns NULL if that check fails.
|
||||
*/
|
||||
if (getdevicedir (device, devicedir, sizeof (devicedir))) {
|
||||
if (getdevicedir (device, devicedir, FILENAME_MAX)) {
|
||||
printdir (devicedir);
|
||||
} else {
|
||||
printf (" N/A\n");
|
||||
@@ -100,4 +125,6 @@ void main (void)
|
||||
if (doesclrscrafterexit ()) {
|
||||
getchar ();
|
||||
}
|
||||
|
||||
free (devicedir);
|
||||
}
|
||||
|
||||
57
samples/gamate/Makefile
Normal file
57
samples/gamate/Makefile
Normal file
@@ -0,0 +1,57 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= gamate
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_gamate = \
|
||||
nachtm.bin
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: gamate tests not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
nachtm.bin: nachtm.c
|
||||
$(CL) -Os -l nachtm.lst -t gamate -o nachtm.bin nachtm.c
|
||||
../../util/gamate/gamate-fixcart nachtm.bin
|
||||
|
||||
clean:
|
||||
@$(DEL) nachtm.bin nachtm.lst 2>$(NULLDEV)
|
||||
1157
samples/gamate/nachtm.c
Normal file
1157
samples/gamate/nachtm.c
Normal file
File diff suppressed because it is too large
Load Diff
146
samples/geos/Makefile
Normal file
146
samples/geos/Makefile
Normal file
@@ -0,0 +1,146 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= geos-cbm
|
||||
|
||||
# Comes with the VICE emulator, see http://vice-emu.sourceforge.net/
|
||||
C1541 ?= c1541
|
||||
|
||||
# If SYS was given on the commandline, redirect "c64" to "geos-cbm" and
|
||||
# "apple2enh" to "geos-apple"
|
||||
ifeq ($(origin SYS),command line)
|
||||
ifeq ($(SYS),c64)
|
||||
override SYS = geos-cbm
|
||||
$(info GEOS: c64 -> geos-cbm)
|
||||
endif
|
||||
ifeq ($(SYS),apple2enh)
|
||||
override SYS = geos-apple
|
||||
$(info GEOS: apple2enh -> geos-apple)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
SP = $(CC65_HOME)/bin/sp65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65)
|
||||
endif
|
||||
|
||||
DIRLIST = grc
|
||||
|
||||
define SUBDIR_recipe
|
||||
|
||||
@+$(MAKE) SYS=$(SYS) -C $(dir) --no-print-directory $@
|
||||
|
||||
endef # SUBDIR_recipe
|
||||
|
||||
EXELIST_geos-cbm = \
|
||||
bitmap-demo.cvt \
|
||||
filesel.cvt \
|
||||
geosver.cvt \
|
||||
getid.cvt \
|
||||
hello1.cvt \
|
||||
hello2.cvt \
|
||||
overlay-demo.cvt \
|
||||
vector-demo.cvt \
|
||||
yesno.cvt
|
||||
|
||||
EXELIST_geos-apple = \
|
||||
bitmap-demo.cvt \
|
||||
filesel.cvt \
|
||||
hello1.cvt \
|
||||
hello2.cvt \
|
||||
overlay-demo.cvt \
|
||||
vector-demo.cvt \
|
||||
yesno.cvt
|
||||
|
||||
# omitted: dialog.c grphstr.c inittab.c menu.c
|
||||
# TODO: geosconio.cvt rmvprot.cvt
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
$(foreach dir,$(DIRLIST),$(SUBDIR_recipe))
|
||||
|
||||
define samples-geos
|
||||
$(C1541) -attach $(0).d64 -geoswrite $(1);
|
||||
endef
|
||||
|
||||
samples-geos: $(EXELIST_$(SYS))
|
||||
$(C1541) -format "$@,01" d64 $@.d64
|
||||
$(foreach tool,$(EXELIST_$(SYS)),$(call samples-geos,$(tool)))
|
||||
else
|
||||
samples:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: geos samples not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
endif
|
||||
|
||||
bitmap.c: logo.pcx
|
||||
$(SP) -r logo.pcx -c geos-bitmap -w bitmap.c,ident=bitmap
|
||||
|
||||
bitmap-demo.cvt: bitmap.c bitmap-demores.grc bitmap-demo.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m bitmap-demo.map bitmap-demores.grc bitmap-demo.c
|
||||
|
||||
filesel.cvt: fileselres.grc filesel.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m filesel.map fileselres.grc filesel.c
|
||||
|
||||
geosconio.cvt: geosconiores.grc geosconio.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m geosconio.map geosconiores.grc geosconio.c
|
||||
|
||||
geosver.cvt: geosverres.grc geosver.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m geosver.map geosverres.grc geosver.c
|
||||
|
||||
getid.cvt: getidres.grc getid.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m getid.map getidres.grc getid.c
|
||||
|
||||
hello1.cvt: hello1res.grc hello1.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m hello1.map hello1res.grc hello1.c
|
||||
|
||||
hello2.cvt: hello2res.grc hello2.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m hello2.map hello2res.grc hello2.c
|
||||
|
||||
overlay-demo.cvt: overlay-demores.grc overlay-demo.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m overlay-demo.map overlay-demores.grc overlay-demo.c
|
||||
|
||||
rmvprot.cvt: rmvprotres.grc rmvprot.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m rmvprot.map rmvprotres.grc rmvprot.c
|
||||
|
||||
vector-demo.cvt: vector-demores.grc vector-demo.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m vector-demo.map vector-demores.grc vector-demo.c
|
||||
|
||||
yesno.cvt: yesnores.grc yesno.c
|
||||
$(CL) -t $(SYS) -O -o $@ -m yesno.map yesnores.grc yesno.c
|
||||
|
||||
|
||||
clean:
|
||||
@$(DEL) overlay-demores.h 2>$(NULLDEV)
|
||||
@$(DEL) bitmap.c 2>$(NULLDEV)
|
||||
@$(DEL) *.cvt 2>$(NULLDEV)
|
||||
@$(DEL) *.map 2>$(NULLDEV)
|
||||
$(foreach dir,$(DIRLIST),$(SUBDIR_recipe))
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Note:
|
||||
/* Note:
|
||||
** This is just a sample piece of code that shows how to use some structs -
|
||||
** it may not even run.
|
||||
*/
|
||||
@@ -28,5 +28,5 @@ static const dlgBoxStr myDialog = {
|
||||
|
||||
void main (void)
|
||||
{
|
||||
DoDlgBox (&myDialog);
|
||||
DoDlgBox (&myDialog);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
GEOSLib example
|
||||
|
||||
|
||||
using DlgBoxFileSelect
|
||||
|
||||
|
||||
Maciej 'YTM/Elysium' Witkowiak
|
||||
<ytm@elysium.pl>
|
||||
|
||||
|
||||
26.12.1999
|
||||
*/
|
||||
|
||||
|
||||
@@ -9,16 +9,16 @@ void main(void)
|
||||
char ch;
|
||||
|
||||
DlgBoxOk("Now the screen will be", "cleared.");
|
||||
|
||||
|
||||
clrscr();
|
||||
|
||||
|
||||
DlgBoxOk("Now a character will be", "written at 20,20");
|
||||
|
||||
|
||||
gotoxy(20, 20);
|
||||
cputc('A');
|
||||
|
||||
DlgBoxOk("Now a string will be", "written at 0,1");
|
||||
|
||||
|
||||
cputsxy(0, 1, CBOLDON "Just" COUTLINEON "a " CITALICON "string." CPLAINTEXT );
|
||||
|
||||
DlgBoxOk("Write text and finish it", "with a dot.");
|
||||
@@ -31,7 +31,7 @@ void main(void)
|
||||
cursor(0);
|
||||
|
||||
DlgBoxOk("Seems that it is all for conio.", "Let's test mouse routines.");
|
||||
|
||||
|
||||
mouse_init(1);
|
||||
cputsxy(0, 2, CBOLDON "Now you can't see mouse (press any key)" CPLAINTEXT);
|
||||
mouse_hide();
|
||||
|
||||
@@ -8,8 +8,8 @@ struct window wholeScreen = {0, SC_PIX_HEIGHT-1, 0, SC_PIX_WIDTH-1};
|
||||
void main (void)
|
||||
{
|
||||
unsigned char os = get_ostype();
|
||||
unsigned char *machine = NULL;
|
||||
unsigned char *version = NULL;
|
||||
char *machine = NULL;
|
||||
char *version = NULL;
|
||||
unsigned char good = 1;
|
||||
|
||||
SetPattern(0);
|
||||
@@ -57,6 +57,6 @@ void main (void)
|
||||
}
|
||||
|
||||
Sleep(10*50);
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ const graphicStr Table = {
|
||||
|
||||
void Exit(void)
|
||||
{
|
||||
exit(0);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
void Menu = {
|
||||
|
||||
70
samples/geos/grc/Makefile
Normal file
70
samples/geos/grc/Makefile
Normal file
@@ -0,0 +1,70 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= geos-cbm
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
GRC = $(CC65_HOME)/bin/grc65
|
||||
else
|
||||
AS := $(if $(wildcard ../../../bin/ca65*),../../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../../bin/cc65*),../../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../../bin/cl65*),../../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../../bin/ld65*),../../../bin/ld65,ld65)
|
||||
GRC := $(if $(wildcard ../../../bin/grc65*),../../../bin/grc65,grc65)
|
||||
endif
|
||||
|
||||
EXELIST_geos-cbm = \
|
||||
test.s \
|
||||
vlir.cvt
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: grc sample not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
endif
|
||||
|
||||
test.s: test.grc
|
||||
$(GRC) -s test.s test.grc
|
||||
|
||||
vlir.cvt: vlir.grc vlir0.s vlir1.s vlir2.s
|
||||
# using separate calls here for demonstration purposes:
|
||||
$(GRC) -t $(SYS) -s vlir.s vlir.grc
|
||||
$(AS) -t $(SYS) vlir.s
|
||||
$(AS) -t $(SYS) vlir0.s
|
||||
$(AS) -t $(SYS) vlir1.s
|
||||
$(AS) -t $(SYS) vlir2.s
|
||||
$(LD) -t $(SYS) -o vlir.cvt vlir.o vlir0.o vlir1.o vlir2.o $(SYS).lib
|
||||
|
||||
# you can also do the above in one command:
|
||||
# $(CL) -t $(SYS) -o vlir.cvt vlir.grc vlir0.s vlir1.s vlir2.s
|
||||
|
||||
clean:
|
||||
@$(DEL) test.s test.h 2>$(NULLDEV)
|
||||
@$(DEL) vlir.s vlir.cvt vlir.c vlir.h 2>$(NULLDEV)
|
||||
@$(DEL) *.o 2>$(NULLDEV)
|
||||
35
samples/geos/grc/test.grc
Normal file
35
samples/geos/grc/test.grc
Normal file
@@ -0,0 +1,35 @@
|
||||
; This is the proposed syntax of a general GEOS resource file for the upcoming resource compiler.
|
||||
|
||||
; token MENU, topname (will be escaped with _), x,y of top-left corner, bottom-right will be
|
||||
; counted according to BSW font table (in x) and a multiply 15 (14?) in y
|
||||
|
||||
; Note that MENU is either MENU and SUBMENU
|
||||
; Note that if you want to use any C operators (like '|', '&' etc.) do it WITHOUT spaces
|
||||
; between arguments (parser is simple and weak)
|
||||
|
||||
; format: MENU "name" left,top ALIGN { "itemname" TYPE pointer ... }
|
||||
|
||||
MENU subMenu1 15,0 VERTICAL
|
||||
{
|
||||
"subitem1" MENU_ACTION smenu1
|
||||
"mubitem2" MENU_ACTION|DYN_SUB_MENU smenu2
|
||||
"subitem3" MENU_ACTION smenu3
|
||||
}
|
||||
|
||||
MENU mainMenu 0,0 HORIZONTAL
|
||||
{
|
||||
"sub menu1" SUB_MENU subMenu1 ; goes for _subMenu1
|
||||
"quit" MENU_ACTION EnterDeskTop ; goes for _EnterDeskTop
|
||||
}
|
||||
|
||||
; format: HEADER GEOS_TYPE "dosname" "classname" "version"
|
||||
|
||||
HEADER APPLICATION "123456789 1234567" "Class Name" "V1.0.0"
|
||||
{
|
||||
; not all fields are required, default and current values will be used
|
||||
author "Maciej Witkowiak" ; always in quotes!
|
||||
info "Information text" ; always in quotes!
|
||||
; date yy mm dd hh ss ; always 5 fields!
|
||||
; dostype seq ; can be PRG, SEQ, USR
|
||||
mode c64only ; can be any, 40only, 80only, c64only
|
||||
}
|
||||
12
samples/geos/grc/vlir.grc
Normal file
12
samples/geos/grc/vlir.grc
Normal file
@@ -0,0 +1,12 @@
|
||||
HEADER APPLICATION "test" "TestApp" "V1.0" {
|
||||
structure VLIR
|
||||
dostype USR
|
||||
author "Maciej Witkowiak"
|
||||
info "This is just an example."
|
||||
}
|
||||
|
||||
MEMORY {
|
||||
stacksize 0x0000
|
||||
overlaysize 0x1000
|
||||
overlaynums 0 1 2
|
||||
}
|
||||
78
samples/geos/grc/vlir0.s
Normal file
78
samples/geos/grc/vlir0.s
Normal file
@@ -0,0 +1,78 @@
|
||||
; Maciej 'YTM/Elysium' Witkowiak
|
||||
; 06.06.2002
|
||||
|
||||
; This is the source for the main VLIR-structured program part
|
||||
|
||||
; include some GEOS defines
|
||||
|
||||
.include "../../../libsrc/geos-common/const.inc"
|
||||
.include "../../../libsrc/geos-cbm/jumptab.inc"
|
||||
.include "../../../libsrc/geos-cbm/geossym.inc"
|
||||
.include "../../../libsrc/geos-common/geosmac.inc"
|
||||
|
||||
; import load addresses for all VLIR chains
|
||||
; these labels are defined upon linking with ld65
|
||||
|
||||
.import __OVERLAYADDR__
|
||||
.import __OVERLAYSIZE__
|
||||
|
||||
; import names of functions defined (and exported) in each VLIR part
|
||||
; of your application
|
||||
; here I used an OVERLAYx_ prefix to prevent name clashes
|
||||
|
||||
.import OVERLAY1_Function1
|
||||
.import OVERLAY2_Function1
|
||||
|
||||
; segments "STARTUP", "CODE", "DATA", "RODATA" and "BSS" all go to VLIR0 chain
|
||||
|
||||
.segment "STARTUP"
|
||||
; code segment for VLIR 0 chain
|
||||
ProgExec:
|
||||
LoadW r0, paramString ; show something
|
||||
jsr DoDlgBox
|
||||
|
||||
MoveW dirEntryBuf+OFF_DE_TR_SC, r1
|
||||
LoadW r4, fileHeader
|
||||
jsr GetBlock ; load back VLIR t&s table
|
||||
bnex error
|
||||
|
||||
lda #1
|
||||
jsr PointRecord ; we want next module (#1)
|
||||
LoadW r2, __OVERLAYSIZE__ ; length - as many bytes as we have room for
|
||||
LoadW r7, __OVERLAYADDR__ ; all VLIR segments have the same load address
|
||||
jsr ReadRecord ; load it
|
||||
bnex error
|
||||
jsr OVERLAY1_Function1 ; execute something
|
||||
|
||||
lda #2
|
||||
jsr PointRecord ; next module
|
||||
LoadW r2, __OVERLAYSIZE__
|
||||
LoadW r7, __OVERLAYADDR__
|
||||
jsr ReadRecord ; load it
|
||||
bnex error
|
||||
jsr OVERLAY2_Function1 ; execute something
|
||||
|
||||
error: jmp EnterDeskTop ; end of application
|
||||
|
||||
.segment "RODATA"
|
||||
; read-only data segment
|
||||
paramString:
|
||||
.byte DEF_DB_POS | 1
|
||||
.byte DBTXTSTR, TXT_LN_X, TXT_LN_2_Y
|
||||
.word line1
|
||||
.byte DBTXTSTR, TXT_LN_X, TXT_LN_3_Y
|
||||
.word line2
|
||||
.byte OK, DBI_X_0, DBI_Y_2
|
||||
.byte NULL
|
||||
|
||||
line1: .byte BOLDON, "Hello World!",0
|
||||
line2: .byte OUTLINEON,"Hello",PLAINTEXT," world!",0
|
||||
|
||||
.segment "DATA"
|
||||
; read/write initialized data segment
|
||||
counter: .word 0
|
||||
|
||||
.segment "BSS"
|
||||
; read/write uninitialized data segment
|
||||
; this space doesn't go into output file, only its size and
|
||||
; position is remembered
|
||||
45
samples/geos/grc/vlir1.s
Normal file
45
samples/geos/grc/vlir1.s
Normal file
@@ -0,0 +1,45 @@
|
||||
; Maciej 'YTM/Elysium' Witkowiak
|
||||
; 06.06.2002
|
||||
|
||||
; This is the source for the loadable VLIR-structured program part
|
||||
|
||||
; include some GEOS defines
|
||||
|
||||
.include "../../../libsrc/geos-common/const.inc"
|
||||
.include "../../../libsrc/geos-cbm/jumptab.inc"
|
||||
.include "../../../libsrc/geos-cbm/geossym.inc"
|
||||
.include "../../../libsrc/geos-common/geosmac.inc"
|
||||
|
||||
; export names of functions that will be used in the main program
|
||||
|
||||
.export OVERLAY1_Function1
|
||||
.export OVERLAY1_Function2
|
||||
|
||||
|
||||
; go into OVERLAY1 segment - everything that is here will go into
|
||||
; VLIR chain #1
|
||||
|
||||
.segment "OVERLAY1"
|
||||
|
||||
OVERLAY1_Function1: jmp Function1 ; jump table, not really necessary
|
||||
OVERLAY1_Function2: jmp Function2
|
||||
; etc.
|
||||
|
||||
; rodata - if this is defined in .segment "RODATA"
|
||||
; it will end up in the VLIR0 part, you don't want that
|
||||
paramString:
|
||||
.byte DEF_DB_POS | 1
|
||||
.byte DBTXTSTR, TXT_LN_X, TXT_LN_2_Y
|
||||
.word line1
|
||||
.byte DBTXTSTR, TXT_LN_X, TXT_LN_3_Y
|
||||
.word line2
|
||||
.byte OK, DBI_X_0, DBI_Y_2
|
||||
.byte NULL
|
||||
|
||||
line1: .byte "This is in module 1",0
|
||||
line2: .byte "This is in module 1",0
|
||||
|
||||
; code
|
||||
Function1: LoadW r0, paramString
|
||||
jsr DoDlgBox
|
||||
Function2: rts
|
||||
36
samples/geos/grc/vlir2.s
Normal file
36
samples/geos/grc/vlir2.s
Normal file
@@ -0,0 +1,36 @@
|
||||
; Maciej 'YTM/Elysium' Witkowiak
|
||||
; 06.06.2002
|
||||
|
||||
; This is the source for the loadable VLIR-structured program part
|
||||
|
||||
; similar to vlir1.s except the fact that this is chain #2
|
||||
|
||||
.include "../../../libsrc/geos-common/const.inc"
|
||||
.include "../../../libsrc/geos-cbm/jumptab.inc"
|
||||
.include "../../../libsrc/geos-cbm/geossym.inc"
|
||||
.include "../../../libsrc/geos-common/geosmac.inc"
|
||||
|
||||
.export OVERLAY2_Function1
|
||||
.export OVERLAY2_Function2
|
||||
|
||||
.segment "OVERLAY2"
|
||||
|
||||
OVERLAY2_Function1: jmp Function1
|
||||
OVERLAY2_Function2: jmp Function2
|
||||
; etc.
|
||||
|
||||
paramString:
|
||||
.byte DEF_DB_POS | 1
|
||||
.byte DBTXTSTR, TXT_LN_X, TXT_LN_2_Y
|
||||
.word line1
|
||||
.byte DBTXTSTR, TXT_LN_X, TXT_LN_3_Y
|
||||
.word line2
|
||||
.byte OK, DBI_X_0, DBI_Y_2
|
||||
.byte NULL
|
||||
|
||||
Function2: LoadW r0, paramString
|
||||
jsr DoDlgBox
|
||||
Function1: rts
|
||||
|
||||
line1: .byte "This is in module 2",0
|
||||
line2: .byte "This is in module 2",0
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
GEOSLib example
|
||||
|
||||
|
||||
Hello, world example - with DBox
|
||||
|
||||
|
||||
Maciej 'YTM/Elysium' Witkowiak
|
||||
<ytm@elysium.pl>
|
||||
|
||||
|
||||
26.12.1999
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ void main (void)
|
||||
|
||||
DlgBoxOk(CBOLDON "Hello, world" CPLAINTEXT,
|
||||
"This is written in C!");
|
||||
|
||||
|
||||
// Normal apps exit from main into system's mainloop, and app finish
|
||||
// when user selects it from icons or menu, but here we want to exit
|
||||
// immediately.
|
||||
@@ -26,7 +26,7 @@ void main (void)
|
||||
// MainLoop();
|
||||
// we can do:
|
||||
// (nothing as this is the end of main function)
|
||||
// exit(0);
|
||||
// exit(EXIT_SUCCESS);
|
||||
// return;
|
||||
|
||||
return;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
GEOSLib example
|
||||
|
||||
|
||||
Hello, world example - using graphic functions
|
||||
|
||||
|
||||
Maciej 'YTM/Alliance' Witkowiak
|
||||
<ytm@friko.onet.pl>
|
||||
|
||||
|
||||
26.12.1999
|
||||
*/
|
||||
|
||||
@@ -25,18 +25,18 @@ void main (void)
|
||||
SetPattern(0);
|
||||
InitDrawWindow(&wholeScreen);
|
||||
Rectangle();
|
||||
|
||||
|
||||
// Now some texts
|
||||
PutString(COUTLINEON "This is compiled using cc65!" CPLAINTEXT, 20, 10);
|
||||
PutString(CBOLDON "This is bold", 30, 10);
|
||||
PutString(CULINEON "and this is bold and underline!", 40, 10);
|
||||
PutString(CPLAINTEXT "This is plain text", 50, 10);
|
||||
|
||||
|
||||
// Wait for 5 secs...
|
||||
// Note that this is multitasking sleep, and if there are any icons/menus onscreen,
|
||||
// they would be usable, in this case you have only pointer usable
|
||||
Sleep(5*50);
|
||||
|
||||
|
||||
// Normal apps exit from main into system's mainloop, and app finish
|
||||
// when user selects it from icons or menu, but here we want to exit
|
||||
// immediately.
|
||||
@@ -44,7 +44,7 @@ void main (void)
|
||||
// MainLoop();
|
||||
// we can do:
|
||||
// (nothing as this is the end of main function)
|
||||
// exit(0);
|
||||
// exit(EXIT_SUCCESS);
|
||||
// return;
|
||||
|
||||
return;
|
||||
|
||||
@@ -27,39 +27,39 @@ void show(char *name)
|
||||
** rather place the all the code of certain source files into the overlay by
|
||||
** compiling them with --code-name OVERLAY1.
|
||||
*/
|
||||
#pragma code-name(push, "OVERLAY1");
|
||||
#pragma code-name(push, "OVERLAY1")
|
||||
|
||||
void foo(void)
|
||||
{
|
||||
/* Functions resident in an overlay can access all program variables and
|
||||
** constants at any time without any precautions because those are never
|
||||
** placed in overlays. The string constant "One" is an example for such
|
||||
** placed in overlays. The string constant "One" is an example for such
|
||||
** a constant resident in the main program.
|
||||
*/
|
||||
show("One");
|
||||
}
|
||||
|
||||
#pragma code-name(pop);
|
||||
#pragma code-name(pop)
|
||||
|
||||
|
||||
#pragma code-name(push, "OVERLAY2");
|
||||
#pragma code-name(push, "OVERLAY2")
|
||||
|
||||
void bar(void)
|
||||
{
|
||||
show("Two");
|
||||
}
|
||||
|
||||
#pragma code-name(pop);
|
||||
#pragma code-name(pop)
|
||||
|
||||
|
||||
#pragma code-name(push, "OVERLAY3");
|
||||
#pragma code-name(push, "OVERLAY3")
|
||||
|
||||
void foobar (void)
|
||||
{
|
||||
show("Three");
|
||||
}
|
||||
|
||||
#pragma code-name(pop);
|
||||
#pragma code-name(pop)
|
||||
|
||||
|
||||
void main(int /*argc*/, char *argv[])
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
/*
|
||||
GEOSLib example
|
||||
|
||||
|
||||
This small application removes GEOS disk write protection tag.
|
||||
e.g. boot disk is always protected after boot-up
|
||||
|
||||
|
||||
Maciej 'YTM/Elysium' Witkowiak
|
||||
<ytm@elysium.pl>
|
||||
|
||||
|
||||
21.03.2000
|
||||
*/
|
||||
|
||||
@@ -60,7 +60,7 @@ void main(void)
|
||||
{
|
||||
// Here we clear the screen. Not really needed anyway...
|
||||
GraphicsString(&clearScreen);
|
||||
|
||||
|
||||
// Get the name of current disk to show it in dialog box
|
||||
GetPtrCurDkNm(diskName);
|
||||
|
||||
|
||||
12
samples/getsp.s
Normal file
12
samples/getsp.s
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
.export _getsp
|
||||
.importzp sp
|
||||
|
||||
.proc _getsp
|
||||
|
||||
ldx sp+1
|
||||
lda sp
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
117
samples/kim1/Makefile
Normal file
117
samples/kim1/Makefile
Normal file
@@ -0,0 +1,117 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= kim1
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_kim1 = \
|
||||
kimHello.bin \
|
||||
kimSieve.bin \
|
||||
kimLife.bin \
|
||||
kimTest.bin \
|
||||
kimGFX.bin
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: kim1 tests not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
subs.o: subs.asm
|
||||
$(AS) subs.asm -o subs.o
|
||||
|
||||
ramfont.o: ramfont.asm
|
||||
$(AS) ramfont.asm -o ramfont.o
|
||||
|
||||
kimLife.bin: kimLife.c
|
||||
$(CL) -t kim1 -C kim1-60k.cfg -Oi -o kimLife.bin kimLife.c
|
||||
|
||||
kimTest.bin: kimTest.c
|
||||
$(CL) -t kim1 -C kim1-60k.cfg -Oi -o kimTest.bin kimTest.c
|
||||
|
||||
kimGFX.bin: kimGFX.c subs.o ramfont.o
|
||||
$(CL) -t kim1 --listing kimGFX.lst -C kim1-mtuE000.cfg -o kimGFX.bin kimGFX.c subs.o ramfont.o -Ln kimgfx.lbl
|
||||
|
||||
kimSieve.bin: kimSieve.c
|
||||
$(CL) -t kim1 -C kim1-60k.cfg -O -o kimSieve.bin kimSieve.c
|
||||
|
||||
kimHello.bin: kimHello.c
|
||||
$(CL) -t kim1 -O -o kimHello.bin kimHello.c
|
||||
|
||||
# To build an intel-format file for the CORSHAM SD card reader
|
||||
|
||||
kimLife.hex: kimLife.bin
|
||||
srec_cat kimLife.bin -binary -offset 0x2000 -o kimLife.hex -Intel -address-length=2
|
||||
|
||||
kimTest.hex: kimTest.bin
|
||||
srec_cat kimTest.bin -binary -offset 0x2000 -o kimTest.hex -Intel -address-length=2
|
||||
|
||||
kimGFX.hex: kimGFX.bin ramfont.o
|
||||
srec_cat kimGFX.bin -binary -offset 0x2000 -o kimGFX.hex -Intel -address-length=2
|
||||
|
||||
# To build a paper tape file for uploading to the KIM-1 via terminal
|
||||
|
||||
kimLife.ptp: kimLife.bin
|
||||
srec_cat kimLife.bin -binary -offset 0x2000 -o kimLife.ptp -MOS_Technologies
|
||||
|
||||
kimGFX.ptp: kimGFX.bin
|
||||
srec_cat kimGFX.bin -binary -offset 0x2000 -o kimGFX.ptp -MOS_Technologies
|
||||
|
||||
kimTest.ptp: kimTest.bin
|
||||
srec_cat kimTest.bin -binary -offset 0x2000 -o kimTest.ptp -MOS_Technologies
|
||||
|
||||
clean:
|
||||
@$(DEL) kimSieve.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimHello.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimLife.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimLife.ptp 2>$(NULLDEV)
|
||||
@$(DEL) kimLife.hex 2>$(NULLDEV)
|
||||
@$(DEL) kimTest.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimTest.ptp 2>$(NULLDEV)
|
||||
@$(DEL) kimTest.hex 2>$(NULLDEV)
|
||||
@$(DEL) kimGFX.bin 2>$(NULLDEV)
|
||||
@$(DEL) kimGFX.ptp 2>$(NULLDEV)
|
||||
@$(DEL) kimGFX.hex 2>$(NULLDEV)
|
||||
@$(DEL) kimgfx.lbl 2>$(NULLDEV)
|
||||
@$(DEL) kimGFX.lst 2>$(NULLDEV)
|
||||
@$(DEL) subs.o 2>$(NULLDEV)
|
||||
@$(DEL) ramfont.o 2>$(NULLDEV)
|
||||
|
||||
|
||||
|
||||
0
samples/kim1/font.rom
Normal file
0
samples/kim1/font.rom
Normal file
290
samples/kim1/kimGFX.c
Normal file
290
samples/kim1/kimGFX.c
Normal file
@@ -0,0 +1,290 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Simple Graphics Test for KIM-1 with MTU Visible Memory Board
|
||||
//
|
||||
// Assumes the MTU Visible Memory Board mapped at 0xA000 for 8K of video RAM
|
||||
//
|
||||
// davepl@davepl.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h> // For printf
|
||||
#include <stdlib.h> // For rand, srand
|
||||
#include <string.h> // For memcpy
|
||||
#include <ctype.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
extern void ClearScreen(void); // In subs.asm
|
||||
extern void ScrollScreen(void);
|
||||
extern void DrawCircle(void);
|
||||
extern void SetPixel(void);
|
||||
extern void ClearPixel(void);
|
||||
extern void DrawChar(void);
|
||||
extern void Demo(void);
|
||||
extern void __fastcall__ Delay(byte loops);
|
||||
extern void __fastcall__ DrawLine(byte bSet);
|
||||
extern byte __fastcall__ AscToPet(byte in);
|
||||
extern byte __fastcall__ PetToAsc(byte in);
|
||||
extern byte __fastcall__ ReverseBits(byte in);
|
||||
extern void __fastcall__ CharOut(byte asci_char);
|
||||
extern byte __fastcall__ getch();
|
||||
extern unsigned char font8x8_basic[256][8];
|
||||
|
||||
extern int x1cord;
|
||||
extern int y1cord;
|
||||
extern int x2cord;
|
||||
extern int y2cord;
|
||||
extern int cursorX;
|
||||
extern int cursorY;
|
||||
|
||||
// If in zeropage:
|
||||
//
|
||||
// #pragma zpsym("x1cord")
|
||||
// #pragma zpsym("x2cord")
|
||||
// #pragma zpsym("y1cord")
|
||||
// #pragma zpsym("y2cord")
|
||||
|
||||
// Screen memory is placed at A000-BFFF, 320x200 pixels, mapped right to left within each horizontal byte
|
||||
|
||||
byte * screen = (byte *) 0xA000;
|
||||
|
||||
// Cursor position
|
||||
|
||||
#define SCREEN_WIDTH 320
|
||||
#define SCREEN_HEIGHT 200
|
||||
#define CHARWIDTH 8
|
||||
#define CHARHEIGHT 8
|
||||
#define BYTESPERROW (SCREEN_WIDTH / 8)
|
||||
#define BYTESPERCHARROW (BYTESPERROW * 8)
|
||||
#define CHARSPERROW (SCREEN_WIDTH / CHARWIDTH)
|
||||
#define ROWSPERCOLUMN (SCREEN_HEIGHT / CHARHEIGHT)
|
||||
|
||||
// SETPIXEL
|
||||
//
|
||||
// 0 <= x < 320
|
||||
// 0 <= y < 200
|
||||
//
|
||||
// Draws a pixel on the screen in white or black at pixel pos x, y
|
||||
|
||||
void SETPIXEL(int x, int y, byte b)
|
||||
{
|
||||
x1cord = x;
|
||||
y1cord = y;
|
||||
|
||||
if (b)
|
||||
SetPixel();
|
||||
else
|
||||
ClearPixel();
|
||||
}
|
||||
|
||||
// DRAWPIXEL
|
||||
//
|
||||
// 0 <= x < 320
|
||||
// 0 <= y < 200
|
||||
//
|
||||
// Turns on a screen pixel at pixel pos x,y
|
||||
|
||||
void DRAWPIXEL(int x, int y)
|
||||
{
|
||||
x1cord = x;
|
||||
y1cord = y;
|
||||
SetPixel();
|
||||
}
|
||||
|
||||
int c;
|
||||
|
||||
void DrawText(char * psz)
|
||||
{
|
||||
while (*psz)
|
||||
{
|
||||
while (cursorX >= CHARSPERROW)
|
||||
{
|
||||
cursorX -= CHARSPERROW;
|
||||
cursorY += 1;
|
||||
}
|
||||
|
||||
// If we've gone off the bottom of the screen, we scroll the screen and back up to the last line again
|
||||
|
||||
if (cursorY >= ROWSPERCOLUMN)
|
||||
{
|
||||
cursorY = ROWSPERCOLUMN - 1;
|
||||
ScrollScreen();
|
||||
}
|
||||
|
||||
// If we output a newline we advanced the cursor down one line and reset it to the left
|
||||
|
||||
if (*psz == 0x0A)
|
||||
{
|
||||
cursorX = 0;
|
||||
cursorY++;
|
||||
psz++;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = *psz;
|
||||
|
||||
__asm__ ("ldx %v", cursorX);
|
||||
__asm__ ("ldy %v", cursorY);
|
||||
__asm__ ("lda %v", c);
|
||||
DrawChar();
|
||||
cursorX++;
|
||||
psz++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTextAt(int x, int y, char * psz)
|
||||
{
|
||||
cursorX = x;
|
||||
cursorY = y;
|
||||
DrawText(psz);
|
||||
}
|
||||
|
||||
// Something like Bresenham's algorithm for drawing a line
|
||||
/*
|
||||
void DrawLine(int x0, int y0, int x1, int y1, byte val)
|
||||
{
|
||||
int dx = abs(x1 - x0), sx = x0 < x1 ? 1 : -1;
|
||||
int dy = abs(y1 - y0), sy = y0 < y1 ? 1 : -1;
|
||||
int err = (dx > dy ? dx : -dy) / 2, e2;
|
||||
|
||||
while (1)
|
||||
{
|
||||
SETPIXEL(x0, y0, val);
|
||||
|
||||
if (x0 == x1 && y0 == y1)
|
||||
break;
|
||||
|
||||
e2 = err;
|
||||
|
||||
if (e2 > -dx)
|
||||
{
|
||||
err -= dy;
|
||||
x0 += sx;
|
||||
}
|
||||
if (e2 < dy)
|
||||
{
|
||||
err += dx;
|
||||
y0 += sy;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// DrawCircle
|
||||
//
|
||||
// Draw a circle without sin, cos, or floating point!
|
||||
|
||||
void DrawCircleC(int x0, int y0, int radius, byte)
|
||||
{
|
||||
x1cord = x0;
|
||||
y1cord = y0;
|
||||
y2cord = radius;
|
||||
DrawCircle();
|
||||
}
|
||||
|
||||
void DrawLineC(int x1, int y1, int x2, int y2, byte bSet)
|
||||
{
|
||||
x1cord = x1;
|
||||
y1cord = y1;
|
||||
x2cord = x2;
|
||||
y2cord = y2;
|
||||
DrawLine(bSet);
|
||||
}
|
||||
|
||||
// MirrorFont
|
||||
//
|
||||
// RAM font is backwards left-right relative to the way memory is laid out on the KIM-1, so we swap all the
|
||||
// bytes in place by reversing the order of the bits in every byte
|
||||
|
||||
void MirrorFont()
|
||||
{
|
||||
int c;
|
||||
byte * pb = (byte *) font8x8_basic;
|
||||
|
||||
for (c = 0; c < 128 * 8; c++)
|
||||
pb[c] = ReverseBits(pb[c]);
|
||||
}
|
||||
|
||||
// DrawScreenMoire
|
||||
//
|
||||
// Draws a moire pattern on the screen without clearing it first
|
||||
|
||||
void DrawMoire(int left, int top, int right, int bottom, byte pixel)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (x = left; x < right; x += 6)
|
||||
DrawLineC(x, top, right - x + left, bottom, pixel);
|
||||
|
||||
for (y = top; y < bottom; y += 6)
|
||||
DrawLineC(left, y, right, bottom - y + top, pixel);
|
||||
}
|
||||
|
||||
void DrawScreenMoire(int left, int top, int right, int bottom)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
DrawLineC(left, top, right, top, 1);
|
||||
DrawLineC(left, bottom, right, bottom, 1);
|
||||
DrawLineC(left, top, left, bottom, 1);
|
||||
DrawLineC(right, top, right, bottom, 1);
|
||||
|
||||
left++; top++; right--; bottom--;
|
||||
|
||||
for (x = left; x < right; x += 6)
|
||||
DrawLineC(x, top, right - x + left, bottom, 1);
|
||||
for (y = top; y < bottom; y += 6)
|
||||
DrawLineC(left, y, right, bottom - y + top, 1);
|
||||
for (x = left; x < right; x += 6)
|
||||
DrawLineC(x, top, right - x + left, bottom, 0);
|
||||
for (y = top; y < bottom; y += 6)
|
||||
DrawLineC(left, y, right, bottom - y + top, 0);
|
||||
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
|
||||
int i;
|
||||
int c = 0;
|
||||
|
||||
Demo();
|
||||
|
||||
CharOut('R');
|
||||
CharOut('E');
|
||||
CharOut('A');
|
||||
CharOut('D');
|
||||
CharOut('Y');
|
||||
CharOut('.');
|
||||
CharOut('\n');
|
||||
|
||||
|
||||
while(1)
|
||||
{
|
||||
c = toupper(getch());
|
||||
if (c != EOF)
|
||||
CharOut(c);
|
||||
}
|
||||
|
||||
// Clear the screen memory
|
||||
while(1)
|
||||
{
|
||||
Demo();
|
||||
DrawScreenMoire(0,30, 319, 199);
|
||||
Delay(10);
|
||||
|
||||
Demo();
|
||||
for (i = 5; i < 80; i+=5)
|
||||
{
|
||||
DrawCircleC(SCREEN_WIDTH/2, SCREEN_HEIGHT/2 + 20, i, 1);
|
||||
DrawCircleC(SCREEN_WIDTH/4, SCREEN_HEIGHT/2 + 20, i, 1);
|
||||
DrawCircleC(SCREEN_WIDTH*3/4, SCREEN_HEIGHT/2 + 20, i, 1);
|
||||
}
|
||||
|
||||
Delay(10);
|
||||
|
||||
}
|
||||
|
||||
printf("Done, exiting...\r\n");
|
||||
return 0;
|
||||
}
|
||||
24
samples/kim1/kimHello.c
Normal file
24
samples/kim1/kimHello.c
Normal file
@@ -0,0 +1,24 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Hello World for KIM-1
|
||||
//
|
||||
// Dave Plummer based on Sym-1 sample by Wayne Parham
|
||||
//
|
||||
// davepl@davepl.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <kim1.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
char str[100];
|
||||
char c = 0x00;
|
||||
|
||||
printf ("\nHello World!\n\n");
|
||||
printf ("Type a line and press ENTER, please.\n\n");
|
||||
|
||||
gets( str );
|
||||
|
||||
printf ("\n\nThanks: %s\n\n", str);
|
||||
return 0;
|
||||
}
|
||||
52
samples/kim1/kimKeyDisp.c
Normal file
52
samples/kim1/kimKeyDisp.c
Normal file
@@ -0,0 +1,52 @@
|
||||
/* Example illustrating scandisplay() and getkey() functions. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <kim1.h>
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int i, j, k, l;
|
||||
int last = 15;
|
||||
|
||||
printf("\nKIM-1 Demo\n");
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
for (j = 0; j < 16; j++) {
|
||||
for (k = 0; k < 16; k++) {
|
||||
scandisplay(i, j, k);
|
||||
|
||||
l = getkey();
|
||||
|
||||
if (l != last) {
|
||||
switch (l) {
|
||||
case 0x0: case 0x1: case 0x2: case 0x3:
|
||||
case 0x4: case 0x5: case 0x6: case 0x7:
|
||||
case 0x8: case 0x9: case 0xa: case 0xb:
|
||||
case 0xc: case 0xd: case 0xe: case 0xf:
|
||||
printf("Key pressed: %X\n", l);
|
||||
break;
|
||||
case 0x10:
|
||||
printf("Key pressed: AD\n");
|
||||
break;
|
||||
case 0x11:
|
||||
printf("Key pressed: DA\n");
|
||||
break;
|
||||
case 0x12:
|
||||
printf("Key pressed: +\n");
|
||||
break;
|
||||
case 0x13:
|
||||
printf("Key pressed: GO\n");
|
||||
break;
|
||||
case 0x14:
|
||||
printf("Key pressed: PC\n");
|
||||
break;
|
||||
}
|
||||
|
||||
last = l;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
144
samples/kim1/kimLife.c
Normal file
144
samples/kim1/kimLife.c
Normal file
@@ -0,0 +1,144 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Conway's Game of Life for KIM-1
|
||||
//
|
||||
// Assumes the MTU Visible Memory Board mapped at 0x8000 for 8K of video RAM
|
||||
//
|
||||
// Dave Plummer on a rainy Thursday
|
||||
//
|
||||
// davepl@davepl.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h> // For printf
|
||||
#include <stdlib.h> // For rand, srand
|
||||
#include <string.h> // For memcpy
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
// World size
|
||||
|
||||
#define WIDTH 320
|
||||
#define HEIGHT 200
|
||||
#define NUMBITS 64000
|
||||
#define NUMBYTES 8000
|
||||
#define DENSITY 50
|
||||
|
||||
// Screen memory is placed at 8000, our world copy at A000, and they use the same layout so
|
||||
// that we can memcpy from one to the other without translating
|
||||
|
||||
byte * world = (byte *) 0x8000;
|
||||
byte * new_world = (byte *) 0xA000;
|
||||
|
||||
// BITARRAY
|
||||
//
|
||||
// Access individual bits in a block of memory
|
||||
|
||||
// Access to the screen bitmap
|
||||
|
||||
byte GETBIT(byte *p, int n)
|
||||
{
|
||||
return (p[n >> 3] & (1 << (n & 7))) ? 1 : 0;
|
||||
}
|
||||
|
||||
void SETBIT(byte *p, int n)
|
||||
{
|
||||
p[n >> 3] |= (1 << (n & 7));
|
||||
}
|
||||
|
||||
void CLRBIT(byte *p, int n)
|
||||
{
|
||||
p[n >> 3] &= ~(1 << (n & 7));
|
||||
}
|
||||
|
||||
void SETPIXEL(byte * p, int x, int y, byte b)
|
||||
{
|
||||
if (b)
|
||||
SETBIT(p, y * WIDTH + x);
|
||||
else
|
||||
CLRBIT(p, y * WIDTH + x);
|
||||
}
|
||||
|
||||
byte GETPIXEL(byte *p, int x, int y)
|
||||
{
|
||||
return GETBIT(p, y * WIDTH + x);
|
||||
}
|
||||
|
||||
// RandomFillWorld
|
||||
//
|
||||
// Populates the initial world with random cells
|
||||
|
||||
void RandomFillWorld()
|
||||
{
|
||||
int x, y;
|
||||
|
||||
// I need a better way to see the RNG or it'll be the same game every time!
|
||||
srand(0);
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
{
|
||||
for (y = 0; y < HEIGHT; y++)
|
||||
{
|
||||
byte b = ((rand() % 100) < DENSITY) ? 1 : 0;
|
||||
SETPIXEL(world, x, y, b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// CountNeighbors
|
||||
//
|
||||
// Count the number of live cells around the given spot, excluding the actual spot specified
|
||||
|
||||
int CountNeighbors(int x, int y)
|
||||
{
|
||||
int i, j, nx, ny, count = 0;
|
||||
|
||||
for (j = -1; j <= 1; j++)
|
||||
{
|
||||
for (i = -1; i <= 1; i++)
|
||||
{
|
||||
if (i != 0 || j != 0)
|
||||
{
|
||||
nx = (x + i + WIDTH) % WIDTH;
|
||||
ny = (y + j + HEIGHT) % HEIGHT;
|
||||
count += GETPIXEL(world, nx, ny) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
// UpdateWorld
|
||||
//
|
||||
// Applies the rules of Conway's Game of Life to the cells
|
||||
|
||||
void UpdateWorld()
|
||||
{
|
||||
int x, y;
|
||||
|
||||
for (y = 0; y < HEIGHT; y++)
|
||||
{
|
||||
for (x = 0; x < WIDTH; x++)
|
||||
{
|
||||
int neighbors = CountNeighbors(x, y);
|
||||
if (GETPIXEL(world, x, y))
|
||||
SETPIXEL(new_world, x, y, (neighbors == 2 || neighbors == 3));
|
||||
else
|
||||
SETPIXEL(new_world, x, y, (neighbors == 3));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
printf("\r\nStarting Conway's Game of Life: Randomizing World...\r\n");
|
||||
RandomFillWorld();
|
||||
printf("World Ready, Running!\r\n");
|
||||
|
||||
for (;;)
|
||||
{
|
||||
UpdateWorld();
|
||||
printf("[");
|
||||
memcpy(world, new_world, NUMBYTES);
|
||||
printf("]");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
125
samples/kim1/kimSieve.c
Normal file
125
samples/kim1/kimSieve.c
Normal file
@@ -0,0 +1,125 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short int ushort;
|
||||
typedef unsigned long int ulong;
|
||||
|
||||
#define LIMIT 100000L
|
||||
|
||||
// BITARRAY
|
||||
//
|
||||
// My bit-access macros pre-divide by two on the presumption that you'll never
|
||||
// try try access both odd and even bits!
|
||||
|
||||
#define GETBIT(array, bit) (array[bit >> 4] & (1 << ((bit >> 1) & 7)))
|
||||
#define SETBIT(array, bit) (array[bit >> 4] |= (1 << ((bit >> 1) & 7)))
|
||||
#define CLRBIT(array, bit) (array[bit >> 4] &= ~(1 << ((bit >> 1) & 7)))
|
||||
|
||||
// RepeatChar
|
||||
//
|
||||
// Outputs a given character N times
|
||||
|
||||
void RepeatChar(char c, size_t count)
|
||||
{
|
||||
while (count--)
|
||||
putc(c, stdout);
|
||||
}
|
||||
|
||||
// sqrti
|
||||
//
|
||||
// Binary search integer square root
|
||||
|
||||
ushort sqrti(ulong num)
|
||||
{
|
||||
long i;
|
||||
ulong ret = 0;
|
||||
|
||||
for(i = 15; i >= 0; i--)
|
||||
{
|
||||
ulong temp = ret | (1L << (ulong)i);
|
||||
if(temp * temp <= num)
|
||||
{
|
||||
ret = temp;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
// main()
|
||||
//
|
||||
// CC65 main function receives no parameters
|
||||
|
||||
int main(void)
|
||||
{
|
||||
// CC65 cannot mix code and data so we have to declare all variables here in the function prolog
|
||||
|
||||
ulong iNumber;
|
||||
ushort currentFactor;
|
||||
ulong numBytesAllocated, rootOfLimit;
|
||||
byte *array;
|
||||
ulong countOfPrimes;
|
||||
|
||||
rootOfLimit = sqrti(LIMIT);
|
||||
puts("\r\n\r\n");
|
||||
RepeatChar('*', 70);
|
||||
puts("\r\n** Prime Number Sieve - Dave Plummer 2022 **");
|
||||
RepeatChar('*', 70);
|
||||
|
||||
printf("\r\n\r\nCalculating primes to %ld using a sqrt of %ld...\r\n", LIMIT, rootOfLimit);
|
||||
|
||||
// Calculate how much memory should be allocated
|
||||
|
||||
numBytesAllocated = (LIMIT + 15) / 16;
|
||||
array = malloc(numBytesAllocated);
|
||||
if (!array)
|
||||
{
|
||||
printf("Unable to allocate %ld bytes for %ld bits\r\n", numBytesAllocated, LIMIT);
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Allocated %ld bytes for %ld slots\r\n", numBytesAllocated, LIMIT);
|
||||
|
||||
// Preset all the bits to true
|
||||
|
||||
for (iNumber = 0; iNumber < numBytesAllocated; iNumber++)
|
||||
array[iNumber] = 0xFF;
|
||||
}
|
||||
|
||||
// Search for next unmarked factor
|
||||
|
||||
currentFactor = 3;
|
||||
while (currentFactor <= rootOfLimit)
|
||||
{
|
||||
ulong num, n;
|
||||
|
||||
for (num = currentFactor; num <= LIMIT; num += 2)
|
||||
{
|
||||
if (GETBIT(array, num))
|
||||
{
|
||||
currentFactor = num;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (n = (ulong) currentFactor * currentFactor; n <= LIMIT; n += currentFactor * 2)
|
||||
CLRBIT(array, n);
|
||||
|
||||
currentFactor += 2;
|
||||
}
|
||||
|
||||
// Display results
|
||||
//
|
||||
// printf("The following primes were found at or below %ld:\r\n2, ", LIMIT);
|
||||
|
||||
countOfPrimes = 1;
|
||||
for (iNumber = 3; iNumber <= LIMIT; iNumber += 2)
|
||||
if (GETBIT(array, iNumber))
|
||||
countOfPrimes++;
|
||||
|
||||
printf("[END: Count = %ld]\r\n", countOfPrimes);
|
||||
|
||||
free(array);
|
||||
return 1;
|
||||
}
|
||||
262
samples/kim1/kimTest.c
Normal file
262
samples/kim1/kimTest.c
Normal file
@@ -0,0 +1,262 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Diagnostics Test for KIM-1
|
||||
//
|
||||
// Dave Plummer
|
||||
// davepl@davepl.com
|
||||
//
|
||||
// Memory test examples by Michael Barr
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h> // For printf
|
||||
#include <stdlib.h> // For rand, srand
|
||||
#include <string.h> // For memcpy
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
// RepeatChar
|
||||
//
|
||||
// Outputs a given character N times
|
||||
|
||||
void RepeatChar(char c, size_t count)
|
||||
{
|
||||
while (count--)
|
||||
putc(c, stdout);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestDataBus()
|
||||
*
|
||||
* Description: Test the data bus wiring in a memory region by
|
||||
* performing a walking 1's test at a fixed address
|
||||
* within that region. The address (and hence the
|
||||
* memory region) is selected by the caller.
|
||||
*
|
||||
* Returns: 0 if the test succeeds.
|
||||
* A non-zero result is the first pattern that failed.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
byte memTestDataBus(volatile byte * address)
|
||||
{
|
||||
byte pattern;
|
||||
|
||||
// Perform a walking 1's test at the given address.
|
||||
|
||||
for (pattern = 1; pattern != 0; pattern <<= 1)
|
||||
{
|
||||
// Write the test pattern.
|
||||
*address = pattern;
|
||||
|
||||
// Read it back and check it
|
||||
if (*address != pattern)
|
||||
{
|
||||
printf("\r\nmemTestDataBus: FAILED at %04x with pattern %02x\r\n", address, pattern);
|
||||
return (pattern);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestAddressBus()
|
||||
*
|
||||
* Description: Test the address bus wiring in a memory region by
|
||||
* performing a walking 1's test on the relevant bits
|
||||
* of the address and checking for aliasing. This test
|
||||
* will find single-bit address failures such as stuck
|
||||
* -high, stuck-low, and shorted pins. The base address
|
||||
* and size of the region are selected by the caller.
|
||||
*
|
||||
* Notes: For best results, the selected base address should
|
||||
* have enough LSB 0's to guarantee single address bit
|
||||
* changes. For example, to test a 64-Kbyte region,
|
||||
* select a base address on a 64-Kbyte boundary. Also,
|
||||
* select the region size as a power-of-two--if at all
|
||||
* possible.
|
||||
*
|
||||
* Returns: NULL if the test succeeds.
|
||||
* A non-zero result is the first address at which an
|
||||
* aliasing problem was uncovered. By examining the
|
||||
* contents of memory, it may be possible to gather
|
||||
* additional information about the problem.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
byte * memTestAddressBus(volatile byte * baseAddress, unsigned long nBytes)
|
||||
{
|
||||
unsigned long addressMask = (nBytes/sizeof(byte) - 1);
|
||||
unsigned long offset;
|
||||
unsigned long testOffset;
|
||||
|
||||
byte pattern = (byte) 0xAAAAAAAA;
|
||||
byte antipattern = (byte) 0x55555555;
|
||||
|
||||
|
||||
//Write the default pattern at each of the power-of-two offsets.
|
||||
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
baseAddress[offset] = pattern;
|
||||
}
|
||||
|
||||
// Check for address bits stuck high.
|
||||
|
||||
testOffset = 0;
|
||||
baseAddress[testOffset] = antipattern;
|
||||
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
if (baseAddress[offset] != pattern)
|
||||
{
|
||||
printf("\r\nmemTestAddressBus: FAILED at %04x with pattern %02x\r\n", baseAddress+offset, pattern);
|
||||
return ((byte *) &baseAddress[offset]);
|
||||
}
|
||||
if (offset % 1024 == 0)
|
||||
printf(".");
|
||||
}
|
||||
|
||||
baseAddress[testOffset] = pattern;
|
||||
|
||||
|
||||
// Check for address bits stuck low or shorted.
|
||||
|
||||
for (testOffset = 1; (testOffset & addressMask) != 0; testOffset <<= 1)
|
||||
{
|
||||
baseAddress[testOffset] = antipattern;
|
||||
|
||||
if (baseAddress[0] != pattern)
|
||||
{
|
||||
return ((byte *) &baseAddress[testOffset]);
|
||||
}
|
||||
|
||||
for (offset = 1; (offset & addressMask) != 0; offset <<= 1)
|
||||
{
|
||||
if ((baseAddress[offset] != pattern) && (offset != testOffset))
|
||||
{
|
||||
printf("\r\nmemTestAddressBus: FAILED at %04x with pattern %02x\r\n", baseAddress+offset, pattern);
|
||||
return ((byte *) &baseAddress[testOffset]);
|
||||
}
|
||||
}
|
||||
baseAddress[testOffset] = pattern;
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
*
|
||||
* Function: memTestDevice()
|
||||
*
|
||||
* Description: Test the integrity of a physical memory device by
|
||||
* performing an increment/decrement test over the
|
||||
* entire region. In the process every storage bit
|
||||
* in the device is tested as a zero and a one. The
|
||||
* base address and the size of the region are
|
||||
* selected by the caller.
|
||||
*
|
||||
* Returns: NULL if the test succeeds.
|
||||
*
|
||||
* A non-zero result is the first address at which an
|
||||
* incorrect value was read back. By examining the
|
||||
* contents of memory, it may be possible to gather
|
||||
* additional information about the problem.
|
||||
*
|
||||
**********************************************************************/
|
||||
|
||||
byte * memTestDevice(volatile byte * baseAddress, unsigned long nBytes)
|
||||
{
|
||||
unsigned long offset;
|
||||
unsigned long nWords = nBytes / sizeof(byte);
|
||||
|
||||
byte pattern;
|
||||
byte antipattern;
|
||||
|
||||
|
||||
// Fill memory with a known pattern.
|
||||
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
baseAddress[offset] = pattern;
|
||||
|
||||
// Check each location and invert it for the second pass.
|
||||
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
{
|
||||
if (offset % 1024 == 0)
|
||||
printf("%04X ", (int) &baseAddress[offset]);
|
||||
|
||||
if (baseAddress[offset] != pattern)
|
||||
{
|
||||
printf("\r\nmemTestDevice: FAILED at %04x with pattern %02x\r\n", (int) &baseAddress[offset], pattern);
|
||||
return ((byte *) &baseAddress[offset]);
|
||||
}
|
||||
|
||||
antipattern = ~pattern;
|
||||
baseAddress[offset] = antipattern;
|
||||
|
||||
}
|
||||
|
||||
// Check each location for the inverted pattern and zero it.
|
||||
|
||||
for (pattern = 1, offset = 0; offset < nWords; pattern++, offset++)
|
||||
{
|
||||
if (offset % 1024 == 0)
|
||||
printf("%04X ", (int) &baseAddress[offset]);
|
||||
|
||||
antipattern = ~pattern;
|
||||
if (baseAddress[offset] != antipattern)
|
||||
{
|
||||
printf("\r\nmemTestDevice: FAILED at %04x with antipattern %02x\r\n", (int) &baseAddress[offset], pattern);
|
||||
return ((byte *) &baseAddress[offset]);
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
// TestMemory
|
||||
//
|
||||
// Run all three memory tests
|
||||
|
||||
byte TestMemory(byte * startAddress, unsigned long size)
|
||||
{
|
||||
if ((memTestDataBus(startAddress) != 0) ||
|
||||
(memTestAddressBus(startAddress, size) != NULL) ||
|
||||
(memTestDevice(startAddress, size) != NULL))
|
||||
{
|
||||
return (-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
printf("\r\nTesting KIM-1...\r\n");
|
||||
RepeatChar('-', 39);
|
||||
|
||||
printf("\r\nTesting RIOT RAM: 1780-17BF\r\n");
|
||||
if (TestMemory((byte *)0x1780, 0x17BF - 0x1780))
|
||||
return 0;
|
||||
|
||||
printf("\r\nTesting RIOT RAM: 17C0-17E6\r\n");
|
||||
if (TestMemory((byte *)0x17C0, 0x17E6 - 0x17C0))
|
||||
return 0;
|
||||
|
||||
printf("\r\nTesting Memory: 0400-13FF\r\n");
|
||||
if (TestMemory((byte *)0x0400, 0x13FF - 0x0400))
|
||||
return 0;
|
||||
|
||||
printf("\r\nTesting Memory: 4000-DFFF\r\n");
|
||||
if (TestMemory((byte *)0x4000, 0xDFFF - 0x4000))
|
||||
return 0;
|
||||
|
||||
printf("\r\nPASS!\r\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
272
samples/kim1/ramfont.asm
Normal file
272
samples/kim1/ramfont.asm
Normal file
@@ -0,0 +1,272 @@
|
||||
;-----------------------------------------------------------------------------------
|
||||
; KIMGFX: Simple pixel graphics for the MOS/Commodore KIM-1
|
||||
;-----------------------------------------------------------------------------------
|
||||
; (c) Plummer's Software Ltd, 04/25/2023 Created
|
||||
; David Plummer
|
||||
;-----------------------------------------------------------------------------------
|
||||
;
|
||||
; File: ramfont.s
|
||||
; Magnetic OCR (check number style) Font data
|
||||
;
|
||||
;-----------------------------------------------------------------------------------
|
||||
|
||||
.segment "CODE"
|
||||
.export _font8x8_basic
|
||||
|
||||
_font8x8_basic:
|
||||
.byte $1c, $22, $4a, $56, $4c, $20, $1e, $00 ; PETSCII code 0
|
||||
.byte $3c, $24, $24, $7e, $62, $62, $62, $00 ; PETSCII code 1
|
||||
.byte $78, $44, $44, $7c, $62, $62, $7e, $00 ; PETSCII code 2
|
||||
.byte $7e, $42, $40, $60, $60, $62, $7e, $00 ; PETSCII code 3
|
||||
.byte $7c, $46, $42, $62, $62, $66, $7c, $00 ; PETSCII code 4
|
||||
.byte $7e, $40, $40, $7c, $60, $60, $7e, $00 ; PETSCII code 5
|
||||
.byte $7e, $40, $40, $7e, $60, $60, $60, $00 ; PETSCII code 6
|
||||
.byte $7e, $42, $40, $6e, $62, $62, $7e, $00 ; PETSCII code 7
|
||||
.byte $42, $42, $42, $7e, $62, $62, $62, $00 ; PETSCII code 8
|
||||
.byte $08, $08, $08, $0c, $0c, $0c, $0c, $00 ; PETSCII code 9
|
||||
.byte $04, $04, $04, $06, $06, $46, $7e, $00 ; PETSCII code 10
|
||||
.byte $42, $44, $48, $7c, $62, $62, $62, $00 ; PETSCII code 11
|
||||
.byte $40, $40, $40, $60, $60, $60, $7e, $00 ; PETSCII code 12
|
||||
.byte $7e, $4a, $4a, $6a, $6a, $6a, $6a, $00 ; PETSCII code 13
|
||||
.byte $7e, $42, $42, $62, $62, $62, $62, $00 ; PETSCII code 14
|
||||
.byte $7e, $46, $42, $42, $42, $42, $7e, $00 ; PETSCII code 15
|
||||
.byte $7e, $42, $42, $7e, $60, $60, $60, $00 ; PETSCII code 16
|
||||
.byte $7e, $42, $42, $42, $4a, $4e, $7e, $00 ; PETSCII code 17
|
||||
.byte $7c, $44, $44, $7c, $62, $62, $62, $00 ; PETSCII code 18
|
||||
.byte $7e, $42, $40, $7e, $06, $46, $7e, $00 ; PETSCII code 19
|
||||
.byte $3e, $10, $10, $18, $18, $18, $18, $00 ; PETSCII code 20
|
||||
.byte $42, $42, $42, $62, $62, $62, $7e, $00 ; PETSCII code 21
|
||||
.byte $62, $62, $62, $66, $24, $24, $3c, $00 ; PETSCII code 22
|
||||
.byte $4a, $4a, $4a, $6a, $6a, $6a, $7e, $00 ; PETSCII code 23
|
||||
.byte $42, $42, $66, $18, $66, $62, $62, $00 ; PETSCII code 24
|
||||
.byte $22, $22, $22, $3e, $18, $18, $18, $00 ; PETSCII code 25
|
||||
.byte $7e, $42, $06, $18, $60, $62, $7e, $00 ; PETSCII code 26
|
||||
.byte $3c, $20, $20, $20, $20, $20, $3c, $00 ; PETSCII code 27
|
||||
.byte $00, $40, $20, $10, $08, $04, $02, $00 ; PETSCII code 28
|
||||
.byte $3c, $04, $04, $04, $04, $04, $3c, $00 ; PETSCII code 29
|
||||
.byte $00, $08, $1c, $2a, $08, $08, $14, $14 ; PETSCII code 30
|
||||
.byte $00, $00, $10, $20, $7f, $20, $10, $00 ; PETSCII code 31
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 32
|
||||
.byte $08, $08, $08, $0c, $0c, $00, $0c, $00 ; PETSCII code 33
|
||||
.byte $6c, $24, $6c, $00, $00, $00, $00, $00 ; PETSCII code 34
|
||||
.byte $24, $24, $7e, $24, $7e, $24, $24, $00 ; PETSCII code 35
|
||||
.byte $08, $3e, $20, $3e, $06, $3e, $08, $00 ; PETSCII code 36
|
||||
.byte $00, $62, $64, $08, $10, $26, $46, $00 ; PETSCII code 37
|
||||
.byte $3c, $20, $24, $7e, $64, $64, $7c, $00 ; PETSCII code 38
|
||||
.byte $1c, $18, $10, $00, $00, $00, $00, $00 ; PETSCII code 39
|
||||
.byte $04, $08, $10, $10, $10, $08, $04, $00 ; PETSCII code 40
|
||||
.byte $20, $10, $08, $08, $08, $10, $20, $00 ; PETSCII code 41
|
||||
.byte $08, $2a, $1c, $3e, $1c, $2a, $08, $00 ; PETSCII code 42
|
||||
.byte $00, $08, $08, $3e, $08, $08, $00, $00 ; PETSCII code 43
|
||||
.byte $00, $00, $00, $00, $00, $18, $18, $08 ; PETSCII code 44
|
||||
.byte $00, $00, $00, $7e, $00, $00, $00, $00 ; PETSCII code 45
|
||||
.byte $00, $00, $00, $00, $00, $18, $18, $00 ; PETSCII code 46
|
||||
.byte $00, $02, $04, $08, $10, $20, $40, $00 ; PETSCII code 47
|
||||
.byte $7e, $62, $52, $4a, $46, $46, $7e, $00 ; PETSCII code 48
|
||||
.byte $18, $08, $08, $18, $18, $1a, $3e, $00 ; PETSCII code 49
|
||||
.byte $7e, $42, $02, $7e, $60, $60, $7e, $00 ; PETSCII code 50
|
||||
.byte $7c, $44, $04, $1e, $06, $46, $7e, $00 ; PETSCII code 51
|
||||
.byte $44, $44, $44, $44, $7e, $0c, $0c, $00 ; PETSCII code 52
|
||||
.byte $7e, $40, $7e, $06, $06, $46, $7e, $00 ; PETSCII code 53
|
||||
.byte $7e, $42, $40, $7e, $46, $46, $7e, $00 ; PETSCII code 54
|
||||
.byte $7e, $02, $02, $06, $06, $06, $06, $00 ; PETSCII code 55
|
||||
.byte $3c, $24, $24, $7e, $46, $46, $7e, $00 ; PETSCII code 56
|
||||
.byte $7e, $42, $42, $7e, $06, $06, $06, $00 ; PETSCII code 57
|
||||
.byte $00, $00, $18, $00, $00, $18, $00, $00 ; PETSCII code 58
|
||||
.byte $00, $00, $18, $00, $00, $18, $18, $08 ; PETSCII code 59
|
||||
.byte $0e, $18, $30, $60, $30, $18, $0e, $00 ; PETSCII code 60
|
||||
.byte $00, $00, $7e, $00, $7e, $00, $00, $00 ; PETSCII code 61
|
||||
.byte $70, $18, $0c, $06, $0c, $18, $70, $00 ; PETSCII code 62
|
||||
.byte $7e, $02, $02, $7e, $60, $00, $60, $00 ; PETSCII code 63
|
||||
.byte $00, $00, $00, $00, $ff, $00, $00, $00 ; PETSCII code 64
|
||||
.byte $08, $1c, $3e, $7f, $7f, $1c, $3e, $00 ; PETSCII code 65
|
||||
.byte $10, $10, $10, $10, $10, $10, $10, $10 ; PETSCII code 66
|
||||
.byte $00, $00, $00, $ff, $00, $00, $00, $00 ; PETSCII code 67
|
||||
.byte $00, $00, $ff, $00, $00, $00, $00, $00 ; PETSCII code 68
|
||||
.byte $00, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 69
|
||||
.byte $00, $00, $00, $00, $00, $ff, $00, $00 ; PETSCII code 70
|
||||
.byte $20, $20, $20, $20, $20, $20, $20, $20 ; PETSCII code 71
|
||||
.byte $04, $04, $04, $04, $04, $04, $04, $04 ; PETSCII code 72
|
||||
.byte $00, $00, $00, $00, $e0, $10, $08, $08 ; PETSCII code 73
|
||||
.byte $08, $08, $08, $04, $03, $00, $00, $00 ; PETSCII code 74
|
||||
.byte $08, $08, $08, $10, $e0, $00, $00, $00 ; PETSCII code 75
|
||||
.byte $80, $80, $80, $80, $80, $80, $80, $ff ; PETSCII code 76
|
||||
.byte $80, $40, $20, $10, $08, $04, $02, $01 ; PETSCII code 77
|
||||
.byte $01, $02, $04, $08, $10, $20, $40, $80 ; PETSCII code 78
|
||||
.byte $ff, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 79
|
||||
.byte $ff, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 80
|
||||
.byte $00, $3c, $7e, $7e, $7e, $7e, $3c, $00 ; PETSCII code 81
|
||||
.byte $00, $00, $00, $00, $00, $00, $ff, $00 ; PETSCII code 82
|
||||
.byte $36, $7f, $7f, $7f, $3e, $1c, $08, $00 ; PETSCII code 83
|
||||
.byte $40, $40, $40, $40, $40, $40, $40, $40 ; PETSCII code 84
|
||||
.byte $00, $00, $00, $00, $03, $04, $08, $08 ; PETSCII code 85
|
||||
.byte $81, $42, $24, $18, $18, $24, $42, $81 ; PETSCII code 86
|
||||
.byte $00, $3c, $42, $42, $42, $42, $3c, $00 ; PETSCII code 87
|
||||
.byte $08, $1c, $2a, $77, $2a, $08, $08, $00 ; PETSCII code 88
|
||||
.byte $02, $02, $02, $02, $02, $02, $02, $02 ; PETSCII code 89
|
||||
.byte $08, $1c, $3e, $7f, $3e, $1c, $08, $00 ; PETSCII code 90
|
||||
.byte $08, $08, $08, $08, $ff, $08, $08, $08 ; PETSCII code 91
|
||||
.byte $a0, $50, $a0, $50, $a0, $50, $a0, $50 ; PETSCII code 92
|
||||
.byte $08, $08, $08, $08, $08, $08, $08, $08 ; PETSCII code 93
|
||||
.byte $00, $00, $01, $3e, $54, $14, $14, $00 ; PETSCII code 94
|
||||
.byte $ff, $7f, $3f, $1f, $0f, $07, $03, $01 ; PETSCII code 95
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 96
|
||||
.byte $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0 ; PETSCII code 97
|
||||
.byte $00, $00, $00, $00, $ff, $ff, $ff, $ff ; PETSCII code 98
|
||||
.byte $ff, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 99
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $ff ; PETSCII code 100
|
||||
.byte $80, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 101
|
||||
.byte $aa, $55, $aa, $55, $aa, $55, $aa, $55 ; PETSCII code 102
|
||||
.byte $01, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 103
|
||||
.byte $00, $00, $00, $00, $aa, $55, $aa, $55 ; PETSCII code 104
|
||||
.byte $ff, $fe, $fc, $f8, $f0, $e0, $c0, $80 ; PETSCII code 105
|
||||
.byte $03, $03, $03, $03, $03, $03, $03, $03 ; PETSCII code 106
|
||||
.byte $08, $08, $08, $08, $0f, $08, $08, $08 ; PETSCII code 107
|
||||
.byte $00, $00, $00, $00, $0f, $0f, $0f, $0f ; PETSCII code 108
|
||||
.byte $08, $08, $08, $08, $0f, $00, $00, $00 ; PETSCII code 109
|
||||
.byte $00, $00, $00, $00, $f8, $08, $08, $08 ; PETSCII code 110
|
||||
.byte $00, $00, $00, $00, $00, $00, $ff, $ff ; PETSCII code 111
|
||||
.byte $00, $00, $00, $00, $0f, $08, $08, $08 ; PETSCII code 112
|
||||
.byte $08, $08, $08, $08, $ff, $00, $00, $00 ; PETSCII code 113
|
||||
.byte $00, $00, $00, $00, $ff, $08, $08, $08 ; PETSCII code 114
|
||||
.byte $08, $08, $08, $08, $f8, $08, $08, $08 ; PETSCII code 115
|
||||
.byte $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0 ; PETSCII code 116
|
||||
.byte $e0, $e0, $e0, $e0, $e0, $e0, $e0, $e0 ; PETSCII code 117
|
||||
.byte $07, $07, $07, $07, $07, $07, $07, $07 ; PETSCII code 118
|
||||
.byte $ff, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 119
|
||||
.byte $ff, $ff, $ff, $00, $00, $00, $00, $00 ; PETSCII code 120
|
||||
.byte $00, $00, $00, $00, $00, $ff, $ff, $ff ; PETSCII code 121
|
||||
.byte $01, $01, $01, $01, $01, $01, $01, $ff ; PETSCII code 122
|
||||
.byte $00, $00, $00, $00, $f0, $f0, $f0, $f0 ; PETSCII code 123
|
||||
.byte $0f, $0f, $0f, $0f, $00, $00, $00, $00 ; PETSCII code 124
|
||||
.byte $08, $08, $08, $08, $f8, $00, $00, $00 ; PETSCII code 125
|
||||
.byte $f0, $f0, $f0, $f0, $00, $00, $00, $00 ; PETSCII code 126
|
||||
.byte $f0, $f0, $f0, $f0, $0f, $0f, $0f, $0f ; PETSCII code 127
|
||||
.byte $1c, $22, $4a, $56, $4c, $20, $1e, $00 ; PETSCII code 128
|
||||
.byte $00, $00, $3c, $04, $7c, $64, $7c, $00 ; PETSCII code 129
|
||||
.byte $40, $40, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 130
|
||||
.byte $00, $00, $7e, $42, $60, $62, $7e, $00 ; PETSCII code 131
|
||||
.byte $02, $02, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 132
|
||||
.byte $00, $00, $7e, $42, $7e, $60, $7e, $00 ; PETSCII code 133
|
||||
.byte $1e, $12, $10, $7c, $18, $18, $18, $00 ; PETSCII code 134
|
||||
.byte $00, $00, $7e, $42, $62, $7e, $02, $7e ; PETSCII code 135
|
||||
.byte $40, $40, $7e, $42, $62, $62, $62, $00 ; PETSCII code 136
|
||||
.byte $18, $00, $10, $10, $18, $18, $18, $00 ; PETSCII code 137
|
||||
.byte $0c, $00, $08, $0c, $0c, $0c, $44, $7c ; PETSCII code 138
|
||||
.byte $40, $40, $44, $48, $78, $64, $64, $00 ; PETSCII code 139
|
||||
.byte $10, $10, $10, $10, $18, $18, $18, $00 ; PETSCII code 140
|
||||
.byte $00, $00, $7f, $49, $6d, $6d, $6d, $00 ; PETSCII code 141
|
||||
.byte $00, $00, $7e, $42, $62, $62, $62, $00 ; PETSCII code 142
|
||||
.byte $00, $00, $7e, $42, $62, $62, $7e, $00 ; PETSCII code 143
|
||||
.byte $00, $00, $7e, $42, $62, $7e, $40, $40 ; PETSCII code 144
|
||||
.byte $00, $00, $7e, $42, $46, $7e, $02, $02 ; PETSCII code 145
|
||||
.byte $00, $00, $7e, $40, $60, $60, $60, $00 ; PETSCII code 146
|
||||
.byte $00, $00, $7e, $40, $7e, $06, $7e, $00 ; PETSCII code 147
|
||||
.byte $10, $10, $7c, $10, $18, $18, $18, $00 ; PETSCII code 148
|
||||
.byte $00, $00, $42, $42, $62, $62, $7e, $00 ; PETSCII code 149
|
||||
.byte $00, $00, $62, $62, $66, $24, $3c, $00 ; PETSCII code 150
|
||||
.byte $00, $00, $49, $49, $6d, $6d, $7f, $00 ; PETSCII code 151
|
||||
.byte $00, $00, $42, $42, $3c, $62, $62, $00 ; PETSCII code 152
|
||||
.byte $00, $00, $62, $62, $42, $7e, $02, $7e ; PETSCII code 153
|
||||
.byte $00, $00, $7e, $06, $18, $60, $7e, $00 ; PETSCII code 154
|
||||
.byte $3c, $20, $20, $20, $20, $20, $3c, $00 ; PETSCII code 155
|
||||
.byte $00, $40, $20, $10, $08, $04, $02, $00 ; PETSCII code 156
|
||||
.byte $3c, $04, $04, $04, $04, $04, $3c, $00 ; PETSCII code 157
|
||||
.byte $00, $08, $1c, $2a, $08, $08, $14, $14 ; PETSCII code 158
|
||||
.byte $00, $00, $10, $20, $7f, $20, $10, $00 ; PETSCII code 159
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 160
|
||||
.byte $08, $08, $08, $0c, $0c, $00, $0c, $00 ; PETSCII code 161
|
||||
.byte $6c, $24, $6c, $00, $00, $00, $00, $00 ; PETSCII code 162
|
||||
.byte $24, $24, $7e, $24, $7e, $24, $24, $00 ; PETSCII code 163
|
||||
.byte $08, $3e, $20, $3e, $06, $3e, $08, $00 ; PETSCII code 164
|
||||
.byte $00, $62, $64, $08, $10, $26, $46, $00 ; PETSCII code 165
|
||||
.byte $3c, $20, $24, $7e, $64, $64, $7c, $00 ; PETSCII code 166
|
||||
.byte $1c, $18, $10, $00, $00, $00, $00, $00 ; PETSCII code 167
|
||||
.byte $04, $08, $10, $10, $10, $08, $04, $00 ; PETSCII code 168
|
||||
.byte $20, $10, $08, $08, $08, $10, $20, $00 ; PETSCII code 169
|
||||
.byte $08, $2a, $1c, $3e, $1c, $2a, $08, $00 ; PETSCII code 170
|
||||
.byte $00, $08, $08, $3e, $08, $08, $00, $00 ; PETSCII code 171
|
||||
.byte $00, $00, $00, $00, $00, $18, $18, $08 ; PETSCII code 172
|
||||
.byte $00, $00, $00, $7e, $00, $00, $00, $00 ; PETSCII code 173
|
||||
.byte $00, $00, $00, $00, $00, $18, $18, $00 ; PETSCII code 174
|
||||
.byte $00, $02, $04, $08, $10, $20, $40, $00 ; PETSCII code 175
|
||||
.byte $7e, $62, $52, $4a, $46, $46, $7e, $00 ; PETSCII code 176
|
||||
.byte $38, $08, $08, $18, $18, $1a, $3e, $00 ; PETSCII code 177
|
||||
.byte $7e, $42, $02, $7e, $60, $60, $7e, $00 ; PETSCII code 178
|
||||
.byte $7c, $44, $04, $1e, $06, $46, $7e, $00 ; PETSCII code 179
|
||||
.byte $44, $44, $44, $44, $7e, $0c, $0c, $00 ; PETSCII code 180
|
||||
.byte $7e, $40, $7e, $06, $06, $46, $7e, $00 ; PETSCII code 181
|
||||
.byte $7e, $42, $40, $7e, $46, $46, $7e, $00 ; PETSCII code 182
|
||||
.byte $7e, $02, $02, $06, $06, $06, $06, $00 ; PETSCII code 183
|
||||
.byte $3c, $24, $24, $7e, $46, $46, $7e, $00 ; PETSCII code 184
|
||||
.byte $7e, $42, $42, $7e, $06, $06, $06, $00 ; PETSCII code 185
|
||||
.byte $00, $00, $18, $00, $00, $18, $00, $00 ; PETSCII code 186
|
||||
.byte $00, $00, $18, $00, $00, $18, $18, $08 ; PETSCII code 187
|
||||
.byte $0e, $18, $30, $60, $30, $18, $0e, $00 ; PETSCII code 188
|
||||
.byte $00, $00, $7e, $00, $7e, $00, $00, $00 ; PETSCII code 189
|
||||
.byte $70, $18, $0c, $06, $0c, $18, $70, $00 ; PETSCII code 190
|
||||
.byte $7e, $02, $02, $7e, $60, $00, $60, $00 ; PETSCII code 191
|
||||
.byte $00, $00, $00, $00, $ff, $00, $00, $00 ; PETSCII code 192
|
||||
.byte $3c, $24, $24, $7e, $62, $62, $62, $00 ; PETSCII code 193
|
||||
.byte $78, $44, $44, $7c, $62, $62, $7e, $00 ; PETSCII code 194
|
||||
.byte $7e, $42, $40, $60, $60, $62, $7e, $00 ; PETSCII code 195
|
||||
.byte $7c, $46, $42, $62, $62, $66, $7c, $00 ; PETSCII code 196
|
||||
.byte $7e, $40, $40, $78, $60, $60, $7e, $00 ; PETSCII code 197
|
||||
.byte $7e, $40, $40, $7e, $60, $60, $60, $00 ; PETSCII code 198
|
||||
.byte $7e, $42, $40, $6e, $62, $62, $7e, $00 ; PETSCII code 199
|
||||
.byte $42, $42, $42, $7e, $62, $62, $62, $00 ; PETSCII code 200
|
||||
.byte $08, $08, $08, $0c, $0c, $0c, $0c, $00 ; PETSCII code 201
|
||||
.byte $04, $04, $04, $06, $06, $46, $7e, $00 ; PETSCII code 202
|
||||
.byte $42, $44, $48, $7c, $62, $62, $62, $00 ; PETSCII code 203
|
||||
.byte $40, $40, $40, $60, $60, $60, $7e, $00 ; PETSCII code 204
|
||||
.byte $7e, $4a, $4a, $6a, $6a, $6a, $6a, $00 ; PETSCII code 205
|
||||
.byte $7e, $42, $42, $62, $62, $62, $62, $00 ; PETSCII code 206
|
||||
.byte $7e, $46, $42, $42, $42, $42, $7e, $00 ; PETSCII code 207
|
||||
.byte $7e, $42, $42, $7e, $60, $60, $60, $00 ; PETSCII code 208
|
||||
.byte $7e, $42, $42, $42, $4a, $4e, $7e, $00 ; PETSCII code 209
|
||||
.byte $7c, $44, $44, $7c, $62, $62, $62, $00 ; PETSCII code 210
|
||||
.byte $7e, $42, $40, $7e, $06, $46, $7e, $00 ; PETSCII code 211
|
||||
.byte $3e, $10, $10, $18, $18, $18, $18, $00 ; PETSCII code 212
|
||||
.byte $42, $42, $42, $62, $62, $62, $7e, $00 ; PETSCII code 213
|
||||
.byte $62, $62, $62, $66, $24, $24, $3c, $00 ; PETSCII code 214
|
||||
.byte $4a, $4a, $4a, $6a, $6a, $6a, $7e, $00 ; PETSCII code 215
|
||||
.byte $42, $42, $66, $3c, $66, $62, $62, $00 ; PETSCII code 216
|
||||
.byte $22, $22, $22, $3e, $18, $18, $18, $00 ; PETSCII code 217
|
||||
.byte $7e, $42, $06, $18, $60, $62, $7e, $00 ; PETSCII code 218
|
||||
.byte $08, $08, $08, $08, $ff, $08, $08, $08 ; PETSCII code 219
|
||||
.byte $a0, $50, $a0, $50, $a0, $50, $a0, $50 ; PETSCII code 220
|
||||
.byte $08, $08, $08, $08, $08, $08, $08, $08 ; PETSCII code 221
|
||||
.byte $cc, $cc, $33, $33, $cc, $cc, $33, $33 ; PETSCII code 222
|
||||
.byte $cc, $66, $33, $99, $cc, $66, $33, $99 ; PETSCII code 223
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 224
|
||||
.byte $f0, $f0, $f0, $f0, $f0, $f0, $f0, $f0 ; PETSCII code 225
|
||||
.byte $00, $00, $00, $00, $ff, $ff, $ff, $ff ; PETSCII code 226
|
||||
.byte $ff, $00, $00, $00, $00, $00, $00, $00 ; PETSCII code 227
|
||||
.byte $00, $00, $00, $00, $00, $00, $00, $ff ; PETSCII code 228
|
||||
.byte $80, $80, $80, $80, $80, $80, $80, $80 ; PETSCII code 229
|
||||
.byte $aa, $55, $aa, $55, $aa, $55, $aa, $55 ; PETSCII code 230
|
||||
.byte $01, $01, $01, $01, $01, $01, $01, $01 ; PETSCII code 231
|
||||
.byte $00, $00, $00, $00, $aa, $55, $aa, $55 ; PETSCII code 232
|
||||
.byte $99, $33, $66, $cc, $99, $33, $66, $cc ; PETSCII code 233
|
||||
.byte $03, $03, $03, $03, $03, $03, $03, $03 ; PETSCII code 234
|
||||
.byte $08, $08, $08, $08, $0f, $08, $08, $08 ; PETSCII code 235
|
||||
.byte $00, $00, $00, $00, $0f, $0f, $0f, $0f ; PETSCII code 236
|
||||
.byte $08, $08, $08, $08, $0f, $00, $00, $00 ; PETSCII code 237
|
||||
.byte $00, $00, $00, $00, $f8, $08, $08, $08 ; PETSCII code 238
|
||||
.byte $00, $00, $00, $00, $00, $00, $ff, $ff ; PETSCII code 239
|
||||
.byte $00, $00, $00, $00, $0f, $08, $08, $08 ; PETSCII code 240
|
||||
.byte $08, $08, $08, $08, $ff, $00, $00, $00 ; PETSCII code 241
|
||||
.byte $00, $00, $00, $00, $ff, $08, $08, $08 ; PETSCII code 242
|
||||
.byte $08, $08, $08, $08, $f8, $08, $08, $08 ; PETSCII code 243
|
||||
.byte $c0, $c0, $c0, $c0, $c0, $c0, $c0, $c0 ; PETSCII code 244
|
||||
.byte $e0, $e0, $e0, $e0, $e0, $e0, $e0, $e0 ; PETSCII code 245
|
||||
.byte $07, $07, $07, $07, $07, $07, $07, $07 ; PETSCII code 246
|
||||
.byte $ff, $ff, $00, $00, $00, $00, $00, $00 ; PETSCII code 247
|
||||
.byte $ff, $ff, $ff, $00, $00, $00, $00, $00 ; PETSCII code 248
|
||||
.byte $00, $00, $00, $00, $00, $ff, $ff, $ff ; PETSCII code 249
|
||||
.byte $01, $02, $44, $48, $50, $60, $40, $00 ; PETSCII code 250
|
||||
.byte $00, $00, $00, $00, $f0, $f0, $f0, $f0 ; PETSCII code 251
|
||||
.byte $0f, $0f, $0f, $0f, $00, $00, $00, $00 ; PETSCII code 252
|
||||
.byte $08, $08, $08, $08, $f8, $00, $00, $00 ; PETSCII code 253
|
||||
.byte $f0, $f0, $f0, $f0, $00, $00, $00, $00 ; PETSCII code 254
|
||||
.byte $f0, $f0, $f0, $f0, $0f, $0f, $0f, $0f ; PETSCII code 255
|
||||
1140
samples/kim1/subs.asm
Normal file
1140
samples/kim1/subs.asm
Normal file
File diff suppressed because it is too large
Load Diff
59
samples/lynx/Makefile
Normal file
59
samples/lynx/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= lynx
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_lynx = \
|
||||
hello.lnx \
|
||||
mandelbrot.lnx \
|
||||
tgidemo.lnx
|
||||
|
||||
.PHONY: samples clean
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples:
|
||||
# recipe used to skip systems that will not work with any program in this dir
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: Lynx tests not available for" $(SYS)
|
||||
else
|
||||
# Suppress the "nothing to be done for 'samples' message.
|
||||
@echo "" > $(NULLDEV)
|
||||
endif
|
||||
endif
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lnx
|
||||
|
||||
%.lnx : %.c
|
||||
$(CL) -t $(SYS) -Oris -m $*.map -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(DEL) *.o *.map *.lnx 2>$(NULLDEV)
|
||||
43
samples/lynx/hello.c
Normal file
43
samples/lynx/hello.c
Normal file
@@ -0,0 +1,43 @@
|
||||
/* Atari Lynx version of samples/hello.c, using TGI instead of conio */
|
||||
|
||||
#include <tgi.h>
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
static const char Text[] = "Hello world!";
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
void main (void)
|
||||
{
|
||||
unsigned int XMax, YMax;
|
||||
|
||||
tgi_install (tgi_static_stddrv);
|
||||
tgi_init ();
|
||||
|
||||
/* Set screen color. */
|
||||
tgi_setcolor (TGI_COLOR_WHITE);
|
||||
|
||||
/* Clear the screen. */
|
||||
tgi_clear();
|
||||
|
||||
/* Ask for the screen size. */
|
||||
XMax = tgi_getmaxx ();
|
||||
YMax = tgi_getmaxy ();
|
||||
|
||||
/* Draw a frame around the screen. */
|
||||
tgi_line (0, 0, XMax, 0);
|
||||
tgi_lineto (XMax, YMax);
|
||||
tgi_lineto (0, YMax);
|
||||
tgi_lineto (0, 0);
|
||||
|
||||
/* Write the greeting in the middle of the screen. */
|
||||
tgi_outtextxy ((tgi_getxres () - tgi_gettextwidth (Text)) / 2,
|
||||
(tgi_getyres () - tgi_gettextheight (Text)) / 2, Text);
|
||||
}
|
||||
86
samples/lynx/mandelbrot.c
Normal file
86
samples/lynx/mandelbrot.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/*****************************************************************************\
|
||||
** mandelbrot sample program for Atari Lynx **
|
||||
** **
|
||||
** (w) 2002 by groepaz/hitmen, TGI support by Stefan Haubenthal **
|
||||
\*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <tgi.h>
|
||||
|
||||
|
||||
|
||||
/* Graphics definitions */
|
||||
#define SCREEN_X (tgi_getxres())
|
||||
#define SCREEN_Y (tgi_getyres())
|
||||
#define MAXCOL (tgi_getcolorcount())
|
||||
|
||||
#define maxiterations 32
|
||||
#define fpshift (10)
|
||||
#define tofp(_x) ((_x)<<fpshift)
|
||||
#define fromfp(_x) ((_x)>>fpshift)
|
||||
#define fpabs(_x) (abs(_x))
|
||||
|
||||
#define mulfp(_a,_b) ((((signed long)_a)*(_b))>>fpshift)
|
||||
#define divfp(_a,_b) ((((signed long)_a)<<fpshift)/(_b))
|
||||
|
||||
/* Use static local variables for speed */
|
||||
#pragma static-locals (1)
|
||||
|
||||
|
||||
|
||||
static void mandelbrot (signed short x1, signed short y1, signed short x2,
|
||||
signed short y2)
|
||||
{
|
||||
/* */
|
||||
register signed short r, r1, i;
|
||||
register signed short xs, ys, xx, yy;
|
||||
register signed short x, y;
|
||||
register unsigned char count;
|
||||
register unsigned char maxcol = MAXCOL;
|
||||
|
||||
/* Calc stepwidth */
|
||||
xs = ((x2 - x1) / (SCREEN_X));
|
||||
ys = ((y2 - y1) / (SCREEN_Y));
|
||||
|
||||
yy = y1;
|
||||
for (y = 0; y < (SCREEN_Y); y++) {
|
||||
yy += ys;
|
||||
xx = x1;
|
||||
for (x = 0; x < (SCREEN_X); x++) {
|
||||
xx += xs;
|
||||
/* Do iterations */
|
||||
r = 0;
|
||||
i = 0;
|
||||
for (count = 0; (count < maxiterations) &&
|
||||
(fpabs (r) < tofp (2)) && (fpabs (i) < tofp (2));
|
||||
++count) {
|
||||
r1 = (mulfp (r, r) - mulfp (i, i)) + xx;
|
||||
/* i = (mulfp(mulfp(r,i),tofp(2)))+yy; */
|
||||
i = (((signed long) r * i) >> (fpshift - 1)) + yy;
|
||||
r = r1;
|
||||
}
|
||||
if (count == maxiterations) {
|
||||
tgi_setcolor (0);
|
||||
} else {
|
||||
tgi_setcolor (count % maxcol);
|
||||
}
|
||||
/* Set pixel */
|
||||
tgi_setpixel (x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main (void)
|
||||
{
|
||||
/* Install the graphics driver */
|
||||
tgi_install (tgi_static_stddrv);
|
||||
|
||||
/* Initialize graphics */
|
||||
tgi_init ();
|
||||
tgi_clear ();
|
||||
|
||||
/* Calc mandelbrot set */
|
||||
mandelbrot (tofp (-2), tofp (-2), tofp (2), tofp (2));
|
||||
}
|
||||
179
samples/lynx/tgidemo.c
Normal file
179
samples/lynx/tgidemo.c
Normal file
@@ -0,0 +1,179 @@
|
||||
/* Tgidemo modified for the Atari Lynx.
|
||||
**
|
||||
** Press any of the Lynx's option buttons to go to the next screen.
|
||||
*/
|
||||
|
||||
#include <cc65.h>
|
||||
#include <conio.h>
|
||||
#include <tgi.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#define COLOR_BACK TGI_COLOR_BLACK
|
||||
#define COLOR_FORE TGI_COLOR_WHITE
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Data */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* Driver stuff */
|
||||
static unsigned MaxX;
|
||||
static unsigned MaxY;
|
||||
static unsigned AspectRatio;
|
||||
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Code */
|
||||
/*****************************************************************************/
|
||||
|
||||
|
||||
|
||||
/* The Lynx draws too fast. This function delays
|
||||
** the drawing so that we can watch it.
|
||||
*/
|
||||
static void wait (unsigned char ticks)
|
||||
{
|
||||
clock_t T = clock () + ticks;
|
||||
|
||||
while (clock () < T) {}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoCircles (void)
|
||||
{
|
||||
unsigned char I;
|
||||
unsigned char Color = COLOR_BACK;
|
||||
const unsigned X = MaxX / 2;
|
||||
const unsigned Y = MaxY / 2;
|
||||
const unsigned Limit = (X < Y) ? Y : X;
|
||||
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
|
||||
tgi_line (0, 0, MaxX, MaxY);
|
||||
tgi_line (0, MaxY, MaxX, 0);
|
||||
while (!kbhit ()) {
|
||||
Color = (Color == COLOR_FORE) ? COLOR_BACK : COLOR_FORE;
|
||||
tgi_setcolor (Color);
|
||||
for (I = 10; I <= Limit; I += 10) {
|
||||
tgi_ellipse (X, Y, I, tgi_imulround (I, AspectRatio));
|
||||
wait (9);
|
||||
}
|
||||
}
|
||||
|
||||
cgetc ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoCheckerboard (void)
|
||||
{
|
||||
unsigned X, Y;
|
||||
unsigned char Color = COLOR_BACK;
|
||||
|
||||
tgi_clear ();
|
||||
|
||||
while (1) {
|
||||
for (Y = 0; Y <= MaxY - 2; Y += 10) {
|
||||
for (X = 0; X <= MaxX; X += 10) {
|
||||
Color = (Color == COLOR_FORE) ? COLOR_BACK : COLOR_FORE;
|
||||
tgi_setcolor (Color);
|
||||
tgi_bar (X, Y, X+9, Y+9);
|
||||
if (kbhit ()) {
|
||||
cgetc ();
|
||||
return;
|
||||
}
|
||||
wait (1);
|
||||
}
|
||||
Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE;
|
||||
}
|
||||
Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoDiagram (void)
|
||||
{
|
||||
int XOrigin, YOrigin;
|
||||
int Amp;
|
||||
int X, Y;
|
||||
unsigned I;
|
||||
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
|
||||
/* Determine zero and amplitude */
|
||||
YOrigin = MaxY / 2;
|
||||
XOrigin = 10;
|
||||
Amp = (MaxY - 19) / 2;
|
||||
|
||||
/* Y axis */
|
||||
tgi_line (XOrigin, 10, XOrigin, MaxY-10);
|
||||
tgi_line (XOrigin-2, 12, XOrigin, 10);
|
||||
tgi_lineto (XOrigin+2, 12);
|
||||
|
||||
/* X axis */
|
||||
tgi_line (XOrigin, YOrigin, MaxX-10, YOrigin);
|
||||
tgi_line (MaxX-12, YOrigin-2, MaxX-10, YOrigin);
|
||||
tgi_lineto (MaxX-12, YOrigin+2);
|
||||
|
||||
/* Sine */
|
||||
tgi_gotoxy (XOrigin, YOrigin);
|
||||
for (I = 0; I <= 360; ++I) {
|
||||
/* Calculate the next points */
|
||||
X = (int)(((long)(MaxX - 19) * I) / 360);
|
||||
Y = (int)(((long)Amp * -_sin (I)) / 256);
|
||||
|
||||
/* Draw the line */
|
||||
tgi_lineto (XOrigin + X, YOrigin + Y);
|
||||
}
|
||||
|
||||
cgetc ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void DoLines (void)
|
||||
{
|
||||
unsigned X;
|
||||
const unsigned Min = (MaxX < MaxY) ? MaxX : MaxY;
|
||||
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
|
||||
for (X = 0; X <= Min; X += 10) {
|
||||
tgi_line (0, 0, Min, X);
|
||||
tgi_line (0, 0, X, Min);
|
||||
tgi_line (Min, Min, 0, Min-X);
|
||||
tgi_line (Min, Min, Min-X, 0);
|
||||
wait (9);
|
||||
}
|
||||
|
||||
cgetc ();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void main (void)
|
||||
{
|
||||
/* Install the driver */
|
||||
tgi_install (tgi_static_stddrv);
|
||||
tgi_init ();
|
||||
|
||||
/* Get stuff from the driver */
|
||||
MaxX = tgi_getmaxx ();
|
||||
MaxY = tgi_getmaxy ();
|
||||
AspectRatio = tgi_getaspectratio ();
|
||||
|
||||
/* Do graphics stuff */
|
||||
DoCircles ();
|
||||
DoCheckerboard ();
|
||||
DoDiagram ();
|
||||
DoLines ();
|
||||
}
|
||||
@@ -31,6 +31,7 @@
|
||||
/* Workaround missing clock stuff */
|
||||
#ifdef __APPLE2__
|
||||
# define clock() 0
|
||||
# undef CLK_TCK
|
||||
# define CLK_TCK 1
|
||||
#endif
|
||||
|
||||
@@ -40,7 +41,7 @@
|
||||
#endif
|
||||
|
||||
/* Use static local variables for speed */
|
||||
#pragma static-locals (1);
|
||||
#pragma static-locals (1)
|
||||
|
||||
|
||||
|
||||
@@ -51,6 +52,7 @@ void mandelbrot (signed short x1, signed short y1, signed short x2,
|
||||
register signed short r, r1, i;
|
||||
register signed short xs, ys, xx, yy;
|
||||
register signed short x, y;
|
||||
register unsigned char maxcol = MAXCOL;
|
||||
|
||||
/* Calc stepwidth */
|
||||
xs = ((x2 - x1) / (SCREEN_X));
|
||||
@@ -76,10 +78,15 @@ void mandelbrot (signed short x1, signed short y1, signed short x2,
|
||||
if (count == maxiterations) {
|
||||
tgi_setcolor (0);
|
||||
} else {
|
||||
if (MAXCOL == 2) {
|
||||
switch (maxcol) {
|
||||
case 2:
|
||||
tgi_setcolor (1);
|
||||
} else {
|
||||
tgi_setcolor (count % MAXCOL);
|
||||
break;
|
||||
case 0: /* 256 colors */
|
||||
tgi_setcolor (count);
|
||||
break;
|
||||
default:
|
||||
tgi_setcolor (count % maxcol);
|
||||
}
|
||||
}
|
||||
/* Set pixel */
|
||||
|
||||
@@ -64,34 +64,34 @@ void log (char *msg)
|
||||
** rather place all the code of certain source files into the overlay by
|
||||
** compiling them with --code-name OVERLAY1.
|
||||
*/
|
||||
#pragma code-name (push, "OVERLAY1");
|
||||
#pragma code-name (push, "OVERLAY1")
|
||||
|
||||
void foo (void)
|
||||
{
|
||||
log ("Calling main from overlay 1");
|
||||
}
|
||||
|
||||
#pragma code-name (pop);
|
||||
#pragma code-name (pop)
|
||||
|
||||
|
||||
#pragma code-name (push, "OVERLAY2");
|
||||
#pragma code-name (push, "OVERLAY2")
|
||||
|
||||
void bar (void)
|
||||
{
|
||||
log ("Calling main from overlay 2");
|
||||
}
|
||||
|
||||
#pragma code-name (pop);
|
||||
#pragma code-name (pop)
|
||||
|
||||
|
||||
#pragma code-name (push, "OVERLAY3");
|
||||
#pragma code-name (push, "OVERLAY3")
|
||||
|
||||
void foobar (void)
|
||||
{
|
||||
log ("Calling main from overlay 3");
|
||||
}
|
||||
|
||||
#pragma code-name(pop);
|
||||
#pragma code-name(pop)
|
||||
|
||||
|
||||
unsigned char loademdriver (void)
|
||||
@@ -237,7 +237,7 @@ void main (void)
|
||||
|
||||
/* The linker makes sure that the call to foo() ends up at the right mem
|
||||
** addr. However it's up to user to make sure that the - right - overlay
|
||||
** is actually loaded before making the the call.
|
||||
** is actually loaded before making the call.
|
||||
*/
|
||||
foo ();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ void log (char *msg)
|
||||
** rather place all the code of certain source files into the overlay by
|
||||
** compiling them with --code-name OVERLAY1.
|
||||
*/
|
||||
#pragma code-name (push, "OVERLAY1");
|
||||
#pragma code-name (push, "OVERLAY1")
|
||||
|
||||
void foo (void)
|
||||
{
|
||||
@@ -51,27 +51,27 @@ void foo (void)
|
||||
log ("Calling main from overlay 1");
|
||||
}
|
||||
|
||||
#pragma code-name (pop);
|
||||
#pragma code-name (pop)
|
||||
|
||||
|
||||
#pragma code-name (push, "OVERLAY2");
|
||||
#pragma code-name (push, "OVERLAY2")
|
||||
|
||||
void bar (void)
|
||||
{
|
||||
log ("Calling main from overlay 2");
|
||||
}
|
||||
|
||||
#pragma code-name (pop);
|
||||
#pragma code-name (pop)
|
||||
|
||||
|
||||
#pragma code-name (push, "OVERLAY3");
|
||||
#pragma code-name (push, "OVERLAY3")
|
||||
|
||||
void foobar (void)
|
||||
{
|
||||
log ("Calling main from overlay 3");
|
||||
}
|
||||
|
||||
#pragma code-name(pop);
|
||||
#pragma code-name(pop)
|
||||
|
||||
|
||||
unsigned char loadfile (char *name, void *addr, void *size)
|
||||
@@ -112,7 +112,7 @@ void main (void)
|
||||
|
||||
/* The linker makes sure that the call to foo() ends up at the right mem
|
||||
** addr. However it's up to user to make sure that the - right - overlay
|
||||
** is actually loaded before making the the call.
|
||||
** is actually loaded before making the call.
|
||||
*/
|
||||
foo ();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
|
||||
This directory contains sample programs for the cc65 compiler.
|
||||
|
||||
The programs contained here are
|
||||
- used as samples and referenced from within the documentation (this is their
|
||||
main purpose)
|
||||
- installed into the filesystem
|
||||
- compiled (but NOT run) by the CI test
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
Below is a short description for each of the programs, together with a list
|
||||
of the supported platforms.
|
||||
|
||||
@@ -10,12 +18,19 @@ Please note:
|
||||
similar systems. If you're using Windows, then consider installing Cygwin
|
||||
or MSys2.
|
||||
|
||||
* The makefile specifies the C64 as the default target system because all
|
||||
but three of the programs run on that platform. When compiling for another
|
||||
system, you will have to change the line that specifies the target system
|
||||
at the top of the makefile, specify the system with SYS=<target> on the
|
||||
make command line, or set a SYS environment variable.
|
||||
* The makefile specifies the C64 as the default target system because most
|
||||
of the programs run on that platform. When compiling for another system,
|
||||
you will have to change the line that specifies the target system at the
|
||||
top of the makefile, specify the system with SYS=<target> on the make
|
||||
command line, or set a SYS environment variable. For example:
|
||||
|
||||
make SYS=apple2
|
||||
|
||||
* Use "make disk" to build a disk image with all sample programs.
|
||||
|
||||
* All programs in the root of the "samples" directory have been written to
|
||||
be portable and work on more than one target. Programs that are specific
|
||||
to a certain target live in a subdirectory with the name of the target.
|
||||
|
||||
List of supplied sample programs:
|
||||
|
||||
@@ -26,11 +41,6 @@ Description: Shows the ASCII (or ATASCII, PETSCII) codes of typed
|
||||
<greg.king5@verizon.com>.
|
||||
Platforms: All platforms with conio or stdio (compile time configurable).
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: atari2600hello
|
||||
Description: A "Hello world" type program.
|
||||
Platforms: Runs on only the Atari 2600 Video Console System.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: diodemo
|
||||
Description: A disc copy program written and contributed by Oliver
|
||||
@@ -47,12 +57,6 @@ Platforms: All systems with device enumeration and directory access
|
||||
(currently the Commodore machines, the Commander X16,
|
||||
and the Apple ][).
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: fire
|
||||
Description: Another graphics demo written by groepaz/hitmen.
|
||||
Platforms: The program currently is running on only the C64, but should
|
||||
be portable to the C128 and CBM510 (and maybe more machines).
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: gunzip65
|
||||
Description: A gunzip utility for 6502-based machines, written by Piotr
|
||||
@@ -71,11 +75,11 @@ Platforms: Runs on all platforms that support conio, which means:
|
||||
-----------------------------------------------------------------------------
|
||||
Name: mandelbrot
|
||||
Description: A mandelbrot demo using integer arithmetic. The demo was
|
||||
written by groepaz/hitmen, and converted to cc65 using TGI
|
||||
graphics by Stephan Haubenthal.
|
||||
written by groepaz, and converted to cc65 using TGI graphics
|
||||
by Stefan Haubenthal.
|
||||
Platforms: Runs on all platforms that have TGI support:
|
||||
Apple ][, Atari, C64, C128, Oric Atmos and Telestrat, GEOS,
|
||||
NES, and Lynx.
|
||||
and NES.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: mousedemo
|
||||
@@ -92,13 +96,6 @@ Platforms: All systems with an overlay linker config., disk directory
|
||||
access, and EMD support (currently the C64, the C128,
|
||||
the Atari, and the Apple ][).
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: nachtm
|
||||
Description: Plays "Eine kleine Nachtmusik" by Wolfgang Amadeus Mozart.
|
||||
Platforms: All systems that have the Commodore SID (Sound Interface
|
||||
Device):
|
||||
C64, C128, CBM510, CBM610.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: overlaydemo
|
||||
Description: Shows how to load overlay files from disk. Written and
|
||||
@@ -106,13 +103,6 @@ Description: Shows how to load overlay files from disk. Written and
|
||||
Platforms: All systems with an overlay linker config. (currently the C64,
|
||||
the C128, the Atari, and the Apple ][).
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: plasma
|
||||
Description: A fancy graphics demo written by groepaz/hitmen.
|
||||
Platforms: The program needs a VIC-II or a TED, so it runs on the following
|
||||
systems:
|
||||
C64, C128, CBM510, Plus/4.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: sieve
|
||||
Description: Implements the "Sieve of Eratosthenes" as a way to find all
|
||||
@@ -124,9 +114,9 @@ Platforms: All systems with conio and clock support:
|
||||
support).
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: supervisionhello
|
||||
Description: A "Hello world" type program.
|
||||
Platforms: Runs on only the Watara Supervision game console.
|
||||
Name: tinyshell
|
||||
Description: Simple ("tiny") shell to test filename and directory functions.
|
||||
Platforms: Runs on all platforms that have stdio support
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: tgidemo
|
||||
@@ -135,3 +125,124 @@ Description: Shows some of the graphics capabilities of the "Tiny Graphics
|
||||
Platforms: Runs on all platforms that have TGI support:
|
||||
Apple ][, Atari, C64, C128, Oric Atmos and Telestrat, GEOS,
|
||||
NES, and Lynx.
|
||||
|
||||
=============================================================================
|
||||
|
||||
Platform-specific samples follow:
|
||||
|
||||
atari 2600:
|
||||
-----------
|
||||
|
||||
Name: hello
|
||||
Description: A "Hello world" type program.
|
||||
Platforms: Runs on only the Atari 2600 Video Console System.
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
atari 5200:
|
||||
-----------
|
||||
|
||||
Name: hello
|
||||
Description: A "Hello world" type program.
|
||||
Platforms: Runs on only the Atari 5200 Video Console System.
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
apple2:
|
||||
-------
|
||||
|
||||
Name: hgrtest
|
||||
Description: shows how to incorporate a hires screen right into the binary,
|
||||
thus allowing to place content both below and above the hires
|
||||
video ram without multiple files nor copying stuff around (plus
|
||||
having a nice splash screen as bonus). It basically demos how to
|
||||
make use of apple2-hgr.cfg.
|
||||
|
||||
Name: hgrshow
|
||||
Description: is a (single) hires program showing how to load (single) hires
|
||||
screens from files without support from TGI. TGI could be used
|
||||
to "paint" on the loaded screens.
|
||||
|
||||
Name: dhgrshow
|
||||
Description: is a double hires program showing how to load double hires
|
||||
screens from files. TGI is used for most of the I/O address
|
||||
manipulation, but (in contrast to hgrshow) is not actually
|
||||
functional.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
cbm:
|
||||
----
|
||||
|
||||
Name: fire
|
||||
Description: Another graphics demo written by groepaz.
|
||||
Platforms: C64, C128, CBM510
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: nachtm
|
||||
Description: Plays "Eine kleine Nachtmusik" by Wolfgang Amadeus Mozart.
|
||||
Platforms: All systems that have the Commodore SID (Sound Interface
|
||||
Device):
|
||||
C64, C128, CBM510, CBM610.
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
Name: plasma
|
||||
Description: A fancy graphics demo written by groepaz.
|
||||
Platforms: The program needs a VIC-II or a TED, so it runs on the following
|
||||
systems:
|
||||
C64, C128, CBM510, Plus/4.
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
gamate:
|
||||
-------
|
||||
|
||||
Name: nachtm
|
||||
Description: Plays "Eine kleine Nachtmusik" by Wolfgang Amadeus Mozart.
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
lynx:
|
||||
-----
|
||||
|
||||
These programs are adapted for the Atari Lynx because its library has no conio
|
||||
output or stdio.
|
||||
|
||||
Name: hello
|
||||
Description: A nice "Hello world" type program that uses the TGI graphics
|
||||
library for output.
|
||||
|
||||
Name: mandelbrot
|
||||
Description: A mandelbrot demo using integer arithmetic. The demo was
|
||||
written by groepaz, and converted to cc65 using TGI graphics
|
||||
by Stefan Haubenthal.
|
||||
|
||||
Name: tgidemo
|
||||
Description: Shows some of the graphics capabilities of the "Tiny Graphics
|
||||
Interface".
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
sym1:
|
||||
-----
|
||||
|
||||
Name: symHello
|
||||
Description: Hello World for Sym-1
|
||||
|
||||
Name: symTiny
|
||||
Description: Hello World for Sym-1 (tiny version without printf)
|
||||
|
||||
Name: symDisplay
|
||||
Description: Sym-1 front panel display example
|
||||
|
||||
Name: symIO
|
||||
Description: Sym-1 digital I/O interface example
|
||||
|
||||
Name: symNotepad
|
||||
Description: Sym-1 Notepad
|
||||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
supervision:
|
||||
------------
|
||||
|
||||
Name: hello
|
||||
Description: A "Hello world" type program.
|
||||
Platforms: Runs on only the Watara Supervision game console.
|
||||
----------------------------------------------------------------------------
|
||||
@@ -38,7 +38,7 @@ static unsigned char Sieve[COUNT];
|
||||
|
||||
|
||||
|
||||
#pragma static-locals(1);
|
||||
#pragma static-locals(1)
|
||||
|
||||
|
||||
|
||||
|
||||
61
samples/sim65/Makefile
Normal file
61
samples/sim65/Makefile
Normal file
@@ -0,0 +1,61 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= sim6502
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_sim6502 = \
|
||||
cpumode_example.bin \
|
||||
timer_example.bin \
|
||||
trace_example.bin
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: sim65 tests not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .bin
|
||||
|
||||
%.bin : %.c
|
||||
$(CL) -t $(SYS) -Oris -m $*.map -o $@ $<
|
||||
|
||||
clean:
|
||||
@$(DEL) *.o *.map *.bin 2>$(NULLDEV)
|
||||
104
samples/sim65/cpumode_example.c
Normal file
104
samples/sim65/cpumode_example.c
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Sim65 cpu-mode switching example.
|
||||
*
|
||||
* Description
|
||||
* -----------
|
||||
*
|
||||
* We can inspect and manipulate the CPU model that sim65 emulates at runtime.
|
||||
*
|
||||
* Sim65 always runs in one of three modes:
|
||||
*
|
||||
* - 6502 mode: the 151 documented opcodes are supported; if the processor encounters
|
||||
* one of the 105 undocumented opcodes, the simulator ends with an
|
||||
* 'illegal opcode' message.
|
||||
* - 65C02 mode: the 105 undocumented opcodes now have well-defined behavior. Some
|
||||
* do useful things, while all others are now defined as NOPs.
|
||||
* - 6502X mode: the 105 undocumented opcodes don't have documented behavior, but
|
||||
* they /do/ have behavior on a real 6502. This behavior has been
|
||||
* figured out, and is deterministic (with minor exceptions).
|
||||
* In this mode, sim65 mimics the behavior of a real 6502 when
|
||||
* it encounters an undocumented opcode, rather than terminating.
|
||||
*
|
||||
* In the example below, we first switch to 6502X mode and execute a small
|
||||
* assembly code fragment, then repeat this in 65C02 mode.
|
||||
*
|
||||
* The code fragment is designed to distinguish between a 6502 and a 65C02
|
||||
* processor based on the behavior of the ADC function in decimal mode.
|
||||
*
|
||||
* Important Note:
|
||||
*
|
||||
* When running in a program compiled for the "sim6502" target, it is safe to switch to
|
||||
* 65C02 or 6502X mode, since the runtime library will only use plain 6502 opcodes, and
|
||||
* those work the same in 65C02 and 6502X mode.
|
||||
*
|
||||
* However, when running in a program compiled for the "sim65c02" target, it is NOT safe
|
||||
* to switch to 6502 or 6502X mode, since many routines in the runtime library use
|
||||
* 65C02-specific opcodes, and these will not work as expected when the CPU is switched
|
||||
* to 6502 or 6502X mode. When such an instruction is encountered, the program will
|
||||
* exhibit undefined behavior.
|
||||
*
|
||||
* For this reason, this program will only work when compiled for the "sim6502" target.
|
||||
*
|
||||
* Running the example
|
||||
* -------------------
|
||||
*
|
||||
* cl65 -t sim6502 -O cpumode_example.c -o cpumode_example.prg
|
||||
* sim65 cpumode_example.prg
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <sim65.h>
|
||||
|
||||
static bool __fastcall__ is_65c02(void)
|
||||
{
|
||||
/* This assembly routine loads 0 into AX on a 6502 (also on a 6502 on which decimal
|
||||
* mode is not implemented), and 1 on a 65C02.
|
||||
*
|
||||
* Note: this implementation triggers a "control reaches end of non-void function"
|
||||
* warning that can be safely ignored. While no return statement is present, the
|
||||
* return value is correctly loaded into AX by the assembly code.
|
||||
*/
|
||||
__asm__("sed");
|
||||
__asm__("ldx #0");
|
||||
__asm__("txa");
|
||||
__asm__("sbc #155");
|
||||
__asm__("asl");
|
||||
__asm__("rol");
|
||||
__asm__("and #1");
|
||||
__asm__("cld");
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
printf("CPU mode at startup ....... : %u\n", GET_CPU_MODE());
|
||||
printf("Is 65C02? ................. : %s\n", is_65c02() ? "YES" : "NO");
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Switching to 6502 mode ....\n");
|
||||
SET_CPU_MODE(SIM65_CPU_MODE_6502);
|
||||
printf("Current CPU mode .......... : %u\n", GET_CPU_MODE());
|
||||
printf("Is 65C02? ................. : %s\n", is_65c02() ? "YES" : "NO");
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Switching to 65C02 mode ...\n");
|
||||
SET_CPU_MODE(SIM65_CPU_MODE_65C02);
|
||||
printf("Current CPU mode .......... : %u\n", GET_CPU_MODE());
|
||||
printf("Is 65C02? ................. : %s\n", is_65c02() ? "YES" : "NO");
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Switching to 6502X mode ...\n");
|
||||
SET_CPU_MODE(SIM65_CPU_MODE_6502X);
|
||||
printf("Current CPU mode .......... : %u\n", GET_CPU_MODE());
|
||||
printf("Is 65C02? ................. : %s\n", is_65c02() ? "YES" : "NO");
|
||||
|
||||
printf("\n");
|
||||
|
||||
printf("Bye!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
117
samples/sim65/timer_example.c
Normal file
117
samples/sim65/timer_example.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Sim65 timer example.
|
||||
*
|
||||
* Description
|
||||
* -----------
|
||||
*
|
||||
* This example tests the clock cycle counter feature of sim65.
|
||||
*
|
||||
* The function 'timestamp' obtains the lower 32-bits of the clock cycle counter.
|
||||
*
|
||||
* The function 'calc_sum_terms' calculates the sum of a range of integers
|
||||
* starting at zero. It simply iterates over all terms, which means that its
|
||||
* runtime is a linear function of its input value.
|
||||
*
|
||||
* In the main function, we first derive an 'offset' value by getting two timestamp
|
||||
* values, with nothing happening in between. Ideally this should yield a 0 clock
|
||||
* cycle duration, but due to the overhead of calling the 'timestamp' function,
|
||||
* and the 'timestamp' function itself, the difference between these timestamp
|
||||
* will be non-zero. We store this value in the 'overhead' variable, and subtract
|
||||
* this value in later measurements.
|
||||
*
|
||||
* Next, we measure the duration of calling the function 'calc_sum_terms' with two
|
||||
* input values, 0, and 1. The duration includes storing the result in the 'result'
|
||||
* variable.
|
||||
*
|
||||
* Extrapolating from these two measurements, and assuming that the runtime of
|
||||
* calling 'calc_sum_terms' and storing its result scales linearly with its argument,
|
||||
* we can predict the duration of a call to 'calc_sum_terms' with a much larger
|
||||
* argument (max_terms = 10000).
|
||||
*
|
||||
* Finally, we actually measure the duration with max_terms = 10000. If the
|
||||
* duration measured is equal to the predicted value, we exit successfully. If not,
|
||||
* we exit with failure.
|
||||
*
|
||||
* Running the example
|
||||
* -------------------
|
||||
*
|
||||
* cl65 -t sim6502 -O timer_example.c -o timer_example.prg
|
||||
* sim65 timer_example.prg
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sim65.h>
|
||||
|
||||
static uint32_t timestamp(void)
|
||||
{
|
||||
peripherals.counter.select = COUNTER_SELECT_CLOCKCYCLE_COUNTER;
|
||||
peripherals.counter.latch = 0;
|
||||
return peripherals.counter.value32[0];
|
||||
}
|
||||
|
||||
static unsigned long calc_sum_terms(unsigned max_term)
|
||||
/* A function with a runtime that scales linearly with its argument. */
|
||||
{
|
||||
unsigned k;
|
||||
unsigned long sum = 0;
|
||||
for (k = 0; k <= max_term; ++k)
|
||||
{
|
||||
sum += k;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned max_term;
|
||||
unsigned long result;
|
||||
uint32_t t1, t2, overhead;
|
||||
int32_t d0, d1, duration;
|
||||
int32_t predicted_duration;
|
||||
|
||||
/* Calibration measurement of zero clock cycles, to determine the overhead. */
|
||||
|
||||
overhead = 0;
|
||||
t1 = timestamp();
|
||||
t2 = timestamp() - overhead;
|
||||
overhead = (t2 - t1);
|
||||
|
||||
/* Calculate call duration (including assignment of result) for argument value 0. */
|
||||
|
||||
max_term = 0;
|
||||
t1 = timestamp();
|
||||
result = calc_sum_terms(max_term);
|
||||
t2 = timestamp();
|
||||
d0 = (t2 - t1) - overhead;
|
||||
printf("max_term = %u -> result = %lu; duration = %ld\n", max_term, result, d0);
|
||||
|
||||
/* Calculate call duration (including assignment of result) for argument value 1. */
|
||||
|
||||
max_term = 1;
|
||||
t1 = timestamp();
|
||||
result = calc_sum_terms(max_term);
|
||||
t2 = timestamp();
|
||||
d1 = (t2 - t1) - overhead;
|
||||
printf("max_term = %u -> result = %lu; duration = %ld\n", max_term, result, d1);
|
||||
|
||||
/* Predict runtime for a much bigger argument value, 10000. */
|
||||
|
||||
max_term = 10000;
|
||||
predicted_duration = d0 + max_term * (d1 - d0);
|
||||
|
||||
printf("predicted duration for max_term = %u: %ld\n", max_term, predicted_duration);
|
||||
|
||||
/* Do the actual measurement for max_term = 10000.
|
||||
* Note: equality between the prediction and the measurement is only achieved if we compile with -O.
|
||||
*/
|
||||
|
||||
t1 = timestamp();
|
||||
result = calc_sum_terms(max_term);
|
||||
t2 = timestamp();
|
||||
duration = (t2 - t1) - overhead;
|
||||
printf("max_term = %u -> result = %lu; duration = %ld\n", max_term, result, duration);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
40
samples/sim65/trace_example.c
Normal file
40
samples/sim65/trace_example.c
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Sim65 trace functionailty example.
|
||||
*
|
||||
* Description
|
||||
* -----------
|
||||
*
|
||||
* The easiest way to use tracing in sim65 is to pass the '--trace' option
|
||||
* to sim65 while starting a program.
|
||||
*
|
||||
* However, it is also possiblke to enable and disable the trace functionality
|
||||
* at runtime, from within the C code itself. This can be useful to produce
|
||||
* runtime traces of small code fragments for debugging purposes.
|
||||
*
|
||||
* In this example, We use the TRACE_ON and TRACE_OFF macros provided in sim65.h
|
||||
* to trace what the CPU is doing during a single statement: the assignment of
|
||||
* a constant to a global variable.
|
||||
*
|
||||
* Running the example
|
||||
* -------------------
|
||||
*
|
||||
* cl65 -t sim6502 -O trace_example.c -o trace_example.prg
|
||||
* sim65 trace_example.prg
|
||||
*
|
||||
* Compiling and running the program like this will produce a trace of six 6502 instructions.
|
||||
* The first four instructions correspond to the 'x = 0x1234' assignment statement.
|
||||
* The last two instructions (ending in a store to address $FFCB) disable the trace facility.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sim65.h>
|
||||
|
||||
unsigned x;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
TRACE_ON();
|
||||
x = 0x1234;
|
||||
TRACE_OFF();
|
||||
return 0;
|
||||
}
|
||||
59
samples/supervision/Makefile
Normal file
59
samples/supervision/Makefile
Normal file
@@ -0,0 +1,59 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= supervision
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
SP = $(CC65_HOME)/bin/sp65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
SP := $(if $(wildcard ../../bin/sp65*),../../bin/sp65,sp65)
|
||||
endif
|
||||
|
||||
EXELIST_supervision = \
|
||||
hello
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: supervision samples not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
hello: hello.c
|
||||
$(CL) -t $(SYS) -O -o hello -m hello.map hello.c
|
||||
|
||||
clean:
|
||||
@$(DEL) $(EXELIST_supervision) 2>$(NULLDEV)
|
||||
@$(DEL) *.map 2>$(NULLDEV)
|
||||
95
samples/supervision/hello.c
Normal file
95
samples/supervision/hello.c
Normal file
@@ -0,0 +1,95 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* Watara Supervision sample C program */
|
||||
/* */
|
||||
/* Fabrizio Caruso (fabrizio_caruso@hotmail.com), 2019 */
|
||||
/* Greg King (greg.king5@verizon.net), 2021 */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <supervision.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Number of words per screen line (Remark: Last 4 words aren't displayed) */
|
||||
#define WORDS_PER_LINE (160/8+4)
|
||||
|
||||
struct sv_vram {
|
||||
unsigned int v[160/8][8][WORDS_PER_LINE];
|
||||
};
|
||||
#define SV_VRAM ((*(struct sv_vram *)0x4000).v)
|
||||
|
||||
/* Character definitions in 8x8 format */
|
||||
/* That format gives us a screen of 20 columns and 20 rows */
|
||||
static const unsigned char h_char[] = {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00};
|
||||
static const unsigned char e_char[] = {0x7E,0x60,0x60,0x78,0x60,0x60,0x7E,0x00};
|
||||
static const unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00};
|
||||
static const unsigned char o_char[] = {0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00};
|
||||
static const unsigned char w_char[] = {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00};
|
||||
static const unsigned char r_char[] = {0x7C,0x66,0x66,0x7C,0x78,0x6C,0x66,0x00};
|
||||
static const unsigned char d_char[] = {0x78,0x6C,0x66,0x66,0x66,0x6C,0x78,0x00};
|
||||
|
||||
static void clear_screen(void)
|
||||
{
|
||||
memset(SV_VIDEO, 0, 0x2000);
|
||||
}
|
||||
|
||||
/* Necessary conversion to have 2 bits per pixel with darkest hue */
|
||||
/* Remark: The Supervision uses 2 bits per pixel, and bits are mapped into pixels in reversed order */
|
||||
static unsigned int __fastcall__ double_reversed_bits(unsigned char)
|
||||
{
|
||||
__asm__("stz ptr2");
|
||||
__asm__("stz ptr2+1");
|
||||
__asm__("ldy #$08");
|
||||
L1: __asm__("lsr a");
|
||||
__asm__("php");
|
||||
__asm__("rol ptr2");
|
||||
__asm__("rol ptr2+1");
|
||||
__asm__("plp");
|
||||
__asm__("rol ptr2");
|
||||
__asm__("rol ptr2+1");
|
||||
__asm__("dey");
|
||||
__asm__("bne %g", L1);
|
||||
__asm__("lda ptr2");
|
||||
__asm__("ldx ptr2+1");
|
||||
return __AX__;
|
||||
}
|
||||
|
||||
static void display_char(const unsigned char x, const unsigned char y, const unsigned char *ch)
|
||||
{
|
||||
unsigned char k;
|
||||
|
||||
for(k=0;k<8;++k)
|
||||
{
|
||||
SV_VRAM[y][k][x] = double_reversed_bits(ch[k]);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_lcd(void)
|
||||
{
|
||||
SV_LCD.width = 160;
|
||||
SV_LCD.height = 160;
|
||||
}
|
||||
|
||||
static void hello(unsigned char x, unsigned char y)
|
||||
{
|
||||
display_char(x+ 0,y,h_char);
|
||||
display_char(x+ 1,y,e_char);
|
||||
display_char(x+ 2,y,l_char);
|
||||
display_char(x+ 3,y,l_char);
|
||||
display_char(x+ 4,y,o_char);
|
||||
|
||||
display_char(x+ 6,y,w_char);
|
||||
display_char(x+ 7,y,o_char);
|
||||
display_char(x+ 8,y,r_char);
|
||||
display_char(x+ 9,y,l_char);
|
||||
display_char(x+10,y,d_char);
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
init_lcd();
|
||||
clear_screen();
|
||||
|
||||
hello(2,3);
|
||||
hello(7,16);
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
/*****************************************************************************/
|
||||
/* */
|
||||
/* Watara Supervision sample C program */
|
||||
/* */
|
||||
/* Fabrizio Caruso (fabrizio_caruso@hotmail.com), 2019 */
|
||||
/* */
|
||||
/*****************************************************************************/
|
||||
|
||||
#include <supervision.h>
|
||||
#include <peekpoke.h>
|
||||
|
||||
// Number of bytes per screen line (Remark: Last 8 bytes are not displayed)
|
||||
#define BYTES_PER_LINE 48
|
||||
|
||||
// Character definitions in 8x8 format
|
||||
const unsigned char h_char[] = {0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00};
|
||||
const unsigned char e_char[] = {0x7E,0x60,0x60,0x78,0x60,0x60,0x7E,0x00};
|
||||
const unsigned char l_char[] = {0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00};
|
||||
const unsigned char o_char[] = {0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00};
|
||||
const unsigned char w_char[] = {0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00};
|
||||
const unsigned char r_char[] = {0x7C,0x66,0x66,0x7C,0x78,0x6C,0x66,0x00};
|
||||
const unsigned char d_char[] = {0x78,0x6C,0x66,0x66,0x66,0x6C,0x78,0x00};
|
||||
|
||||
void clear_screen(void)
|
||||
{
|
||||
unsigned short i;
|
||||
|
||||
for(i=0;i<0x2000;++i)
|
||||
{
|
||||
POKE(SV_VIDEO+i,0);
|
||||
}
|
||||
}
|
||||
|
||||
// Necessary conversion to have 2 bits per pixel with darkest hue
|
||||
// Remark: The Supervision uses 2 bits per pixel and bits are mapped into pixel in reversed order
|
||||
unsigned char reversed_map_one_to_two_lookup[16] =
|
||||
{
|
||||
0x00, 0xC0, 0x30, 0xF0, 0x0C, 0xCC, 0x3C, 0xFC,
|
||||
0x03, 0xC3, 0x33, 0xF3, 0x0F, 0xCF, 0x3F, 0xFF
|
||||
};
|
||||
|
||||
unsigned char left_map_one_to_two(unsigned char n)
|
||||
{
|
||||
return reversed_map_one_to_two_lookup[n >> 4];
|
||||
}
|
||||
|
||||
unsigned char right_map_one_to_two(unsigned char n)
|
||||
{
|
||||
return reversed_map_one_to_two_lookup[n&0x0F];
|
||||
}
|
||||
|
||||
void display_char(const unsigned char x, const unsigned char y, const unsigned char *ch)
|
||||
{
|
||||
unsigned char k;
|
||||
|
||||
for(k=0;k<8;++k)
|
||||
{ \
|
||||
SV_VIDEO[2*(y)+BYTES_PER_LINE*k+BYTES_PER_LINE*(x<<3)] = left_map_one_to_two(ch[k]);
|
||||
SV_VIDEO[2*(y)+BYTES_PER_LINE*k+BYTES_PER_LINE*(x<<3)+1] = right_map_one_to_two(ch[k]);
|
||||
}
|
||||
}
|
||||
|
||||
void init_lcd(void)
|
||||
{
|
||||
SV_LCD.width = 160;
|
||||
SV_LCD.height = 160;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
init_lcd();
|
||||
clear_screen();
|
||||
|
||||
display_char(3,2, h_char);
|
||||
display_char(3,3, e_char);
|
||||
display_char(3,4, l_char);
|
||||
display_char(3,5, l_char);
|
||||
display_char(3,6, o_char);
|
||||
|
||||
display_char(3,8, w_char);
|
||||
display_char(3,9, o_char);
|
||||
display_char(3,10,r_char);
|
||||
display_char(3,11,l_char);
|
||||
display_char(3,12,d_char);
|
||||
|
||||
while(1) {};
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
77
samples/sym1/Makefile
Normal file
77
samples/sym1/Makefile
Normal file
@@ -0,0 +1,77 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= sym1
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_sym1 = \
|
||||
symHello.bin symTiny.bin symDisplay.bin symIO.bin symNotepad.bin symExtendedMemory.bin
|
||||
|
||||
ifneq ($(EXELIST_$(SYS)),)
|
||||
samples: $(EXELIST_$(SYS))
|
||||
else
|
||||
samples: notavailable
|
||||
endif
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: sym1 tests not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
symHello.bin: symHello.c
|
||||
$(CL) -t sym1 -O -o symHello.bin symHello.c
|
||||
|
||||
symTiny.bin: symTiny.c
|
||||
$(CL) -t sym1 -O -o symTiny.bin symTiny.c
|
||||
|
||||
symDisplay.bin: symDisplay.c
|
||||
$(CL) -t sym1 -O -o symDisplay.bin symDisplay.c
|
||||
|
||||
symIO.bin: symIO.c
|
||||
$(CL) -t sym1 -C sym1-32k.cfg -O -o symIO.bin symIO.c
|
||||
|
||||
symNotepad.bin: symNotepad.c
|
||||
$(CL) -t sym1 -C sym1-32k.cfg -O -o symNotepad.bin symNotepad.c
|
||||
|
||||
symExtendedMemory.bin: symExtendedMemory.c
|
||||
$(CL) -t sym1 -C sym1-32k.cfg -O -o symExtendedMemory.bin symExtendedMemory.c
|
||||
|
||||
|
||||
clean:
|
||||
@$(DEL) symHello.bin 2>$(NULLDEV)
|
||||
@$(DEL) symTiny.bin 2>$(NULLDEV)
|
||||
@$(DEL) symDisplay.bin 2>$(NULLDEV)
|
||||
@$(DEL) symIO.bin 2>$(NULLDEV)
|
||||
@$(DEL) symNotepad.bin 2>$(NULLDEV)
|
||||
@$(DEL) symExtendedMemory.bin 2>$(NULLDEV)
|
||||
358
samples/sym1/symDisplay.c
Normal file
358
samples/sym1/symDisplay.c
Normal file
@@ -0,0 +1,358 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Sym-1 front panel display example
|
||||
//
|
||||
// Wayne Parham
|
||||
//
|
||||
// wayne@parhamdata.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sym1.h>
|
||||
|
||||
int main (void) {
|
||||
int delay = 10;
|
||||
int flashes = 255;
|
||||
int displayable = 1;
|
||||
int e = 0;
|
||||
int r = 0;
|
||||
int d = 0;
|
||||
int i = 0;
|
||||
int l = 0;
|
||||
int t = 0;
|
||||
int z = 0;
|
||||
char c = 0x00;
|
||||
char buffer[41] = { 0x00 };
|
||||
|
||||
puts ("\nType a message (40 chars max) and press ENTER, please:\n");
|
||||
|
||||
while ( (c != '\n') && (i < 40) ) {
|
||||
c = getchar();
|
||||
buffer[i] = c;
|
||||
i++;
|
||||
if ( i == 40 ) {
|
||||
puts ("\n\n--- Reached 40 character limit. ---");
|
||||
}
|
||||
}
|
||||
|
||||
i--; // index is one past end
|
||||
|
||||
while ( z == 0 ) {
|
||||
puts ("\n\nHow many times (0 for forever) to repeat?");
|
||||
c = getchar();
|
||||
if ( (c >= '0') && (c <= '9') ) {// between 1 and 9 loops allowed
|
||||
z = 1; // a number was pressed
|
||||
t = c - '0'; // convert char to int
|
||||
puts ("\n\nLook at the front panel.\n");
|
||||
}
|
||||
else {
|
||||
puts ("\nWhat?");
|
||||
z = 0; // keep asking for a number
|
||||
}
|
||||
}
|
||||
|
||||
z = 0;
|
||||
while ( (z < t) || (t == 0) ) {
|
||||
|
||||
z++;
|
||||
|
||||
putchar ( '\r' ); // Send CR to console
|
||||
|
||||
DISPLAY.d0 = DISP_SPACE; // Clear the display
|
||||
DISPLAY.d1 = DISP_SPACE;
|
||||
DISPLAY.d2 = DISP_SPACE;
|
||||
DISPLAY.d3 = DISP_SPACE;
|
||||
DISPLAY.d4 = DISP_SPACE;
|
||||
DISPLAY.d5 = DISP_SPACE;
|
||||
DISPLAY.d6 = DISP_SPACE;
|
||||
|
||||
for ( d = 0; d < flashes ; d++ ) {
|
||||
fdisp(); // Display
|
||||
}
|
||||
|
||||
for ( l = 0; l <= i; l++ ) {
|
||||
|
||||
displayable = 1; // Assume character is mapped
|
||||
|
||||
switch ( buffer[l] ) { // Put the typed charaters
|
||||
case '1': // into the display buffer
|
||||
DISPLAY.d6 = DISP_1; // one at a time
|
||||
break;
|
||||
case '2':
|
||||
DISPLAY.d6 = DISP_2;
|
||||
break;
|
||||
case '3':
|
||||
DISPLAY.d6 = DISP_3;
|
||||
break;
|
||||
case '4':
|
||||
DISPLAY.d6 = DISP_4;
|
||||
break;
|
||||
case '5':
|
||||
DISPLAY.d6 = DISP_5;
|
||||
break;
|
||||
case '6':
|
||||
DISPLAY.d6 = DISP_6;
|
||||
break;
|
||||
case '7':
|
||||
DISPLAY.d6 = DISP_7;
|
||||
break;
|
||||
case '8':
|
||||
DISPLAY.d6 = DISP_8;
|
||||
break;
|
||||
case '9':
|
||||
DISPLAY.d6 = DISP_9;
|
||||
break;
|
||||
case '0':
|
||||
DISPLAY.d6 = DISP_0;
|
||||
break;
|
||||
case 'A':
|
||||
DISPLAY.d6 = DISP_A;
|
||||
break;
|
||||
case 'a':
|
||||
DISPLAY.d6 = DISP_A;
|
||||
break;
|
||||
case 'B':
|
||||
DISPLAY.d6 = DISP_b;
|
||||
break;
|
||||
case 'b':
|
||||
DISPLAY.d6 = DISP_b;
|
||||
break;
|
||||
case 'C':
|
||||
DISPLAY.d6 = DISP_C;
|
||||
break;
|
||||
case 'c':
|
||||
DISPLAY.d6 = DISP_c;
|
||||
break;
|
||||
case 'D':
|
||||
DISPLAY.d6 = DISP_d;
|
||||
break;
|
||||
case 'd':
|
||||
DISPLAY.d6 = DISP_d;
|
||||
break;
|
||||
case 'E':
|
||||
DISPLAY.d6 = DISP_E;
|
||||
break;
|
||||
case 'e':
|
||||
DISPLAY.d6 = DISP_e;
|
||||
break;
|
||||
case 'F':
|
||||
DISPLAY.d6 = DISP_F;
|
||||
break;
|
||||
case 'f':
|
||||
DISPLAY.d6 = DISP_F;
|
||||
break;
|
||||
case 'G':
|
||||
DISPLAY.d6 = DISP_G;
|
||||
break;
|
||||
case 'g':
|
||||
DISPLAY.d6 = DISP_g;
|
||||
break;
|
||||
case 'H':
|
||||
DISPLAY.d6 = DISP_H;
|
||||
break;
|
||||
case 'h':
|
||||
DISPLAY.d6 = DISP_h;
|
||||
break;
|
||||
case 'I':
|
||||
DISPLAY.d6 = DISP_I;
|
||||
break;
|
||||
case 'i':
|
||||
DISPLAY.d6 = DISP_i;
|
||||
break;
|
||||
case 'J':
|
||||
DISPLAY.d6 = DISP_J;
|
||||
break;
|
||||
case 'j':
|
||||
DISPLAY.d6 = DISP_J;
|
||||
break;
|
||||
case 'K':
|
||||
DISPLAY.d6 = DISP_K;
|
||||
break;
|
||||
case 'k':
|
||||
DISPLAY.d6 = DISP_K;
|
||||
break;
|
||||
case 'L':
|
||||
DISPLAY.d6 = DISP_L;
|
||||
break;
|
||||
case 'l':
|
||||
DISPLAY.d6 = DISP_L;
|
||||
break;
|
||||
case 'M':
|
||||
DISPLAY.d0 = DISPLAY.d1;
|
||||
DISPLAY.d1 = DISPLAY.d2;
|
||||
DISPLAY.d2 = DISPLAY.d3;
|
||||
DISPLAY.d3 = DISPLAY.d4;
|
||||
DISPLAY.d4 = DISPLAY.d5;
|
||||
DISPLAY.d5 = DISP_M_1;
|
||||
DISPLAY.d6 = DISP_M_2;
|
||||
break;
|
||||
case 'm':
|
||||
DISPLAY.d0 = DISPLAY.d1;
|
||||
DISPLAY.d1 = DISPLAY.d2;
|
||||
DISPLAY.d2 = DISPLAY.d3;
|
||||
DISPLAY.d3 = DISPLAY.d4;
|
||||
DISPLAY.d4 = DISPLAY.d5;
|
||||
DISPLAY.d5 = DISP_M_1;
|
||||
DISPLAY.d6 = DISP_M_2;
|
||||
break;
|
||||
case 'N':
|
||||
DISPLAY.d6 = DISP_n;
|
||||
break;
|
||||
case 'n':
|
||||
DISPLAY.d6 = DISP_n;
|
||||
break;
|
||||
case 'O':
|
||||
DISPLAY.d6 = DISP_O;
|
||||
break;
|
||||
case 'o':
|
||||
DISPLAY.d6 = DISP_o;
|
||||
break;
|
||||
case 'P':
|
||||
DISPLAY.d6 = DISP_P;
|
||||
break;
|
||||
case 'p':
|
||||
DISPLAY.d6 = DISP_P;
|
||||
break;
|
||||
case 'Q':
|
||||
DISPLAY.d6 = DISP_q;
|
||||
break;
|
||||
case 'q':
|
||||
DISPLAY.d6 = DISP_q;
|
||||
break;
|
||||
case 'R':
|
||||
DISPLAY.d6 = DISP_r;
|
||||
break;
|
||||
case 'r':
|
||||
DISPLAY.d6 = DISP_r;
|
||||
break;
|
||||
case 'S':
|
||||
DISPLAY.d6 = DISP_S;
|
||||
break;
|
||||
case 's':
|
||||
DISPLAY.d6 = DISP_S;
|
||||
break;
|
||||
case 'T':
|
||||
DISPLAY.d6 = DISP_t;
|
||||
break;
|
||||
case 't':
|
||||
DISPLAY.d6 = DISP_t;
|
||||
break;
|
||||
case 'U':
|
||||
DISPLAY.d6 = DISP_U;
|
||||
break;
|
||||
case 'u':
|
||||
DISPLAY.d6 = DISP_u;
|
||||
break;
|
||||
case 'V':
|
||||
DISPLAY.d0 = DISPLAY.d1;
|
||||
DISPLAY.d1 = DISPLAY.d2;
|
||||
DISPLAY.d2 = DISPLAY.d3;
|
||||
DISPLAY.d3 = DISPLAY.d4;
|
||||
DISPLAY.d4 = DISPLAY.d5;
|
||||
DISPLAY.d5 = DISP_V_1;
|
||||
DISPLAY.d6 = DISP_V_2;
|
||||
break;
|
||||
case 'v':
|
||||
DISPLAY.d0 = DISPLAY.d1;
|
||||
DISPLAY.d1 = DISPLAY.d2;
|
||||
DISPLAY.d2 = DISPLAY.d3;
|
||||
DISPLAY.d3 = DISPLAY.d4;
|
||||
DISPLAY.d4 = DISPLAY.d5;
|
||||
DISPLAY.d5 = DISP_V_1;
|
||||
DISPLAY.d6 = DISP_V_2;
|
||||
break;
|
||||
case 'W':
|
||||
DISPLAY.d0 = DISPLAY.d1;
|
||||
DISPLAY.d1 = DISPLAY.d2;
|
||||
DISPLAY.d2 = DISPLAY.d3;
|
||||
DISPLAY.d3 = DISPLAY.d4;
|
||||
DISPLAY.d4 = DISPLAY.d5;
|
||||
DISPLAY.d5 = DISP_W_1;
|
||||
DISPLAY.d6 = DISP_W_2;
|
||||
break;
|
||||
case 'w':
|
||||
DISPLAY.d0 = DISPLAY.d1;
|
||||
DISPLAY.d1 = DISPLAY.d2;
|
||||
DISPLAY.d2 = DISPLAY.d3;
|
||||
DISPLAY.d3 = DISPLAY.d4;
|
||||
DISPLAY.d4 = DISPLAY.d5;
|
||||
DISPLAY.d5 = DISP_W_1;
|
||||
DISPLAY.d6 = DISP_W_2;
|
||||
break;
|
||||
case 'Y':
|
||||
DISPLAY.d6 = DISP_Y;
|
||||
break;
|
||||
case 'y':
|
||||
DISPLAY.d6 = DISP_Y;
|
||||
break;
|
||||
case 'Z':
|
||||
DISPLAY.d6 = DISP_Z;
|
||||
break;
|
||||
case 'z':
|
||||
DISPLAY.d6 = DISP_Z;
|
||||
break;
|
||||
case ' ':
|
||||
DISPLAY.d6 = DISP_SPACE;
|
||||
break;
|
||||
case '.':
|
||||
DISPLAY.d6 = DISP_PERIOD;
|
||||
break;
|
||||
case '-':
|
||||
DISPLAY.d6 = DISP_HYPHEN;
|
||||
break;
|
||||
case '\'':
|
||||
DISPLAY.d6 = DISP_APOSTR;
|
||||
break;
|
||||
case '"':
|
||||
DISPLAY.d6 = DISP_APOSTR;
|
||||
break;
|
||||
case '=':
|
||||
DISPLAY.d6 = DISP_EQUAL;
|
||||
break;
|
||||
case '_':
|
||||
DISPLAY.d6 = DISP_BOTTOM;
|
||||
break;
|
||||
case '/':
|
||||
DISPLAY.d6 = DISP_SLASH;
|
||||
break;
|
||||
case '\\':
|
||||
DISPLAY.d6 = DISP_BACKSLASH;
|
||||
break;
|
||||
default:
|
||||
displayable = 0; // Character not mapped
|
||||
}
|
||||
|
||||
if ( displayable ) {
|
||||
|
||||
putchar ( buffer[l] ); // Send it to the console
|
||||
|
||||
DISPLAY.d0 = DISPLAY.d1; // Scroll to the left
|
||||
DISPLAY.d1 = DISPLAY.d2;
|
||||
DISPLAY.d2 = DISPLAY.d3;
|
||||
DISPLAY.d3 = DISPLAY.d4;
|
||||
DISPLAY.d4 = DISPLAY.d5;
|
||||
DISPLAY.d5 = DISPLAY.d6;
|
||||
|
||||
for ( d = 0; d < flashes ; d++ ) {
|
||||
fdisp(); // Display
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( e = 0; e < 6; e++ ) { // Gradually fill the
|
||||
DISPLAY.d0 = DISPLAY.d1; // display with spaces
|
||||
DISPLAY.d1 = DISPLAY.d2;
|
||||
DISPLAY.d2 = DISPLAY.d3;
|
||||
DISPLAY.d3 = DISPLAY.d4;
|
||||
DISPLAY.d4 = DISPLAY.d5;
|
||||
DISPLAY.d5 = DISP_SPACE;
|
||||
DISPLAY.d6 = DISP_SPACE;
|
||||
for ( d = 0; d < flashes ; d++ ) {
|
||||
fdisp(); // Display
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts ("\n\nEnjoy your day!\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
101
samples/sym1/symExtendedMemory.c
Normal file
101
samples/sym1/symExtendedMemory.c
Normal file
@@ -0,0 +1,101 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Sym-1 Extended Memory
|
||||
//
|
||||
// Wayne Parham
|
||||
//
|
||||
// wayne@parhamdata.com
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Note: This program examines memory above the monitor ROM (8000-8FFF) to
|
||||
// Determine what, if any, memory is available. It then adds whatever
|
||||
// 4K segments it finds to the heap.
|
||||
//
|
||||
// Memory Segment Remark
|
||||
// 0x9000 Usually available
|
||||
// 0xA000 System I/O, always unavailable
|
||||
// 0xB000 Used by RAE, but normally available
|
||||
// 0xC000 Used by BASIC, normally unavailable
|
||||
// 0xD000 Used by BASIC, normally unavailable
|
||||
// 0xE000 Used by RAE, but normally available
|
||||
// 0xF000 Normally available, but only to FF7F
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <sym1.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define STD_MEM 0x7FFF // Last address of standard memory
|
||||
#define SEGMENT 0x9000 // First 4K segment of extended memory
|
||||
#define SEG_END 0x0FFF // Last location of segment
|
||||
#define BLOCK_SIZE 0x1000 // Size of segment
|
||||
#define TOP_END 0x0F7F // Last location of memory
|
||||
#define TOP_SIZE 0x0F80 // Size of top segment
|
||||
#define UNAVAILABLE 0xA000 // System I/O area
|
||||
|
||||
int main (void) {
|
||||
int error = 0;
|
||||
unsigned heap_size = 0x0000;
|
||||
char* segment = (char*) SEGMENT;
|
||||
|
||||
printf ( "Analyzing memory.\n\n" );
|
||||
|
||||
heap_size = _heapmemavail();
|
||||
|
||||
printf ( "Main memory has %u bytes available.\n", heap_size );
|
||||
|
||||
if ( heap_size > STD_MEM ) {
|
||||
printf ( "Extended memory already installed.\n" );
|
||||
} else {
|
||||
|
||||
while ( (int) segment < 0xEFFF ) { // Iterate through 4K memory blocks
|
||||
if( (int) segment != UNAVAILABLE ) {
|
||||
segment[0] = 0x00; // Check beginning of segment
|
||||
if ( segment[0] != 0x00 )
|
||||
error = 1;
|
||||
segment[0] = 0xFF;
|
||||
if ( segment[0] != 0xFF )
|
||||
error = 1;
|
||||
segment[SEG_END] = 0x00; // Check end of segment
|
||||
if ( segment[SEG_END] != 0x00 )
|
||||
error = 1;
|
||||
segment[SEG_END] = 0xFF;
|
||||
if ( segment[SEG_END] != 0xFF )
|
||||
error = 1;
|
||||
if ( ! error ) { // If memory found, add to the heap
|
||||
printf ( "Memory found at location %p, ", segment );
|
||||
_heapadd ( segment, BLOCK_SIZE );
|
||||
heap_size = _heapmemavail();
|
||||
printf( "so the system now has %u bytes available.\n", heap_size );
|
||||
} else {
|
||||
error = 0;
|
||||
}
|
||||
}
|
||||
segment += 0x1000; // Increment to next segment
|
||||
}
|
||||
|
||||
segment[0] = 0x00; // Check beginning of top memory segment
|
||||
if ( segment[0] != 0x00 )
|
||||
error = 1;
|
||||
segment[0] = 0xFF;
|
||||
if ( segment[0] != 0xFF )
|
||||
error = 1;
|
||||
segment[TOP_END] = 0x00; // Check end of usable memory
|
||||
if ( segment[TOP_END] != 0x00 )
|
||||
error = 1;
|
||||
segment[TOP_END] = 0xFF;
|
||||
if ( segment[TOP_END] != 0xFF )
|
||||
error = 1;
|
||||
if ( ! error ) { // If memory found, add to the heap
|
||||
printf ( "Memory found at location %p, ", segment );
|
||||
_heapadd ( segment, TOP_SIZE );
|
||||
heap_size = _heapmemavail();
|
||||
printf( "so the system now has %u bytes available.\n", heap_size );
|
||||
}
|
||||
}
|
||||
|
||||
puts ("\nEnjoy your day!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
39
samples/sym1/symHello.c
Normal file
39
samples/sym1/symHello.c
Normal file
@@ -0,0 +1,39 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Hello World for Sym-1
|
||||
//
|
||||
// Wayne Parham
|
||||
//
|
||||
// wayne@parhamdata.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sym1.h>
|
||||
|
||||
int main (void) {
|
||||
char c = 0x00;
|
||||
int d = 0x00;
|
||||
int l = 0x00;
|
||||
|
||||
printf ("\nHello World!\n\n");
|
||||
|
||||
for ( l = 0; l < 2; l++ ) {
|
||||
beep();
|
||||
for ( d = 0; d < 10 ; d++ ) {
|
||||
}
|
||||
}
|
||||
printf ("Type a line and press ENTER, please.\n\n");
|
||||
|
||||
while ( c != '\n' ) {
|
||||
c = getchar();
|
||||
}
|
||||
|
||||
printf ("\n\nThanks!\n\n");
|
||||
|
||||
for ( l = 0; l < 5; l++ ) {
|
||||
beep();
|
||||
for ( d = 0; d < 10 ; d++ ) {
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
172
samples/sym1/symIO.c
Normal file
172
samples/sym1/symIO.c
Normal file
@@ -0,0 +1,172 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Sym-1 digital I/O interface example
|
||||
//
|
||||
// Wayne Parham
|
||||
//
|
||||
// wayne@parhamdata.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <sym1.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main (void) {
|
||||
unsigned char ddr1a = 0x00;
|
||||
unsigned char ior1a = 0x00;
|
||||
unsigned char ddr1b = 0x00;
|
||||
unsigned char ior1b = 0x00;
|
||||
unsigned char ddr2a = 0x00;
|
||||
unsigned char ior2a = 0x00;
|
||||
unsigned char ddr2b = 0x00;
|
||||
unsigned char ior2b = 0x00;
|
||||
unsigned char ddr3a = 0x00;
|
||||
unsigned char ior3a = 0x00;
|
||||
unsigned char ddr3b = 0x00;
|
||||
unsigned char ior3b = 0x00;
|
||||
unsigned char val = 0x00;
|
||||
int going = 0x01;
|
||||
int instr = 0x01;
|
||||
int l = 0x00;
|
||||
char* vp = 0x00;
|
||||
char cmd[20] = { 0x00 };
|
||||
|
||||
while ( going ) {
|
||||
|
||||
putchar ( '\r' );
|
||||
for ( l = 0; l < 25; l++ ) {
|
||||
putchar ( '\n' );
|
||||
}
|
||||
|
||||
ddr1a = VIA1.ddra;
|
||||
ior1a = VIA1.pra;
|
||||
ddr1b = VIA1.ddrb;
|
||||
ior1b = VIA1.prb;
|
||||
ddr2a = VIA2.ddra;
|
||||
ior2a = VIA2.pra;
|
||||
ddr2b = VIA2.ddrb;
|
||||
ior2b = VIA2.prb;
|
||||
ddr3a = VIA3.ddra;
|
||||
ior3a = VIA3.pra;
|
||||
ddr3b = VIA3.ddrb;
|
||||
ior3b = VIA3.prb;
|
||||
|
||||
puts ("================== Digital I/O Status ==================");
|
||||
puts (" Port1A Port1B Port2A Port2B Port3A Port3B" );
|
||||
printf ("DDR %02X %02X %02X %02X %02X %02X\n\r",ddr1a,ddr1b,ddr2a,ddr2b,ddr3a,ddr3b);
|
||||
printf ("IOR %02X %02X %02X %02X %02X %02X\n\r",ior1a,ior1b,ior2a,ior2b,ior3a,ior3b);
|
||||
puts ("========================================================\n");
|
||||
|
||||
if ( instr ) {
|
||||
puts ("You can set any register by typing 'register value' so");
|
||||
puts ("as an example, to set register IOR2A with the top five");
|
||||
puts ("bits off and the bottom three on, type 'IOR2A 07'.");
|
||||
puts ("Press ENTER without any command to see register values");
|
||||
puts ("without changing any of them. Type 'help' to see these");
|
||||
puts ("instructions again and type 'quit' to end the program.\n");
|
||||
puts ("Available registers: DDR1A, IOR1A, DDR1B, IOR1B, DDR2A");
|
||||
puts ("IOR2A, DDR2B, IOR2B, DDR3A, IOR3A, DDR3B and IOR3B.");
|
||||
instr = 0;
|
||||
}
|
||||
|
||||
printf ("\n Command: ");
|
||||
|
||||
fgets ( cmd, sizeof(cmd)-1, stdin );
|
||||
cmd[strlen(cmd)-1] = '\0';
|
||||
|
||||
if ( strncasecmp(cmd, "quit", 4) == 0 ) {
|
||||
going = 0;
|
||||
}
|
||||
else if ( strncasecmp(cmd, "help", 4) == 0 ) {
|
||||
instr = 1;
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ddr1a", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA1.ddra = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ior1a", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA1.pra = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ddr1b", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA1.ddrb = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ior1b", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA1.prb = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ddr2a", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA2.ddra = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ior2a", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA2.pra = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ddr2b", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA2.ddrb = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ior2b", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA2.prb = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ddr3a", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA3.ddra = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ior3a", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA3.pra = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ddr3b", 5) == 0 ) {
|
||||
vp = strchr ( cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA3.ddrb = val;
|
||||
}
|
||||
}
|
||||
else if ( strncasecmp(cmd, "ior3b", 5) == 0 ) {
|
||||
vp = strchr (cmd, ' ' );
|
||||
if ( vp ) {
|
||||
val = (unsigned char) strtol( vp, NULL, 0 );
|
||||
VIA3.prb = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
puts ("\n\nEnjoy your day!\n\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
192
samples/sym1/symNotepad.c
Normal file
192
samples/sym1/symNotepad.c
Normal file
@@ -0,0 +1,192 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Sym-1 Notepad
|
||||
//
|
||||
// Wayne Parham
|
||||
//
|
||||
// wayne@parhamdata.com
|
||||
// --------------------------------------------------------------------------
|
||||
//
|
||||
// Note: This program requires RAM memory in locations 0xE000 - 0xEFFF
|
||||
// Alternatively, the tape I/O buffer location and size can be
|
||||
// changed by altering the defined TAPIO values below.
|
||||
//
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <sym1.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define TAPIO_ADDRESS 0xE000
|
||||
#define TAPIO_MAX_SIZE 0x0FFF
|
||||
|
||||
int main (void) {
|
||||
char c = 0x00;
|
||||
int l = 0x00;
|
||||
int p = 0x00;
|
||||
int error = 0x00;
|
||||
int running = 0x01;
|
||||
int writing = 0x01;
|
||||
int instruction_needed = 0x01;
|
||||
int heap_size = 0x00;
|
||||
char* tapio = (char*) TAPIO_ADDRESS;
|
||||
char* buffer;
|
||||
|
||||
heap_size = _heapmaxavail();
|
||||
|
||||
if ( heap_size > TAPIO_MAX_SIZE ) { // No need to malloc more than
|
||||
heap_size = TAPIO_MAX_SIZE; // the interface allows
|
||||
}
|
||||
|
||||
buffer = malloc ( heap_size );
|
||||
memset ( buffer, 0x00, heap_size );
|
||||
|
||||
if ( buffer == 0x00 ) {
|
||||
puts ("Memory full.");
|
||||
running = 0;
|
||||
}
|
||||
|
||||
tapio[0] = 0x00; // Check tape interface memory
|
||||
if ( tapio[0] != 0x00 )
|
||||
error = 1;
|
||||
|
||||
tapio[0] = 0xFF;
|
||||
if ( tapio[0] != 0xFF )
|
||||
error = 1;
|
||||
|
||||
tapio[TAPIO_MAX_SIZE] = 0x00;
|
||||
if ( tapio[TAPIO_MAX_SIZE] != 0x00 )
|
||||
error = 1;
|
||||
|
||||
tapio[TAPIO_MAX_SIZE] = 0xFF;
|
||||
if ( tapio[TAPIO_MAX_SIZE] != 0xFF )
|
||||
error = 1;
|
||||
|
||||
if ( error ) {
|
||||
printf ("\nNo memory at location %p, aborting.\n", tapio);
|
||||
running = 0;
|
||||
}
|
||||
else {
|
||||
memset ( tapio, 0, TAPIO_MAX_SIZE );
|
||||
}
|
||||
|
||||
|
||||
while ( running ) {
|
||||
|
||||
putchar ( '\r' );
|
||||
for ( l = 0; l < 25; l++ ) {
|
||||
putchar ( '\n' );
|
||||
}
|
||||
|
||||
puts ("===================== Sym-1 Notepad ====================");
|
||||
|
||||
if ( instruction_needed ) {
|
||||
puts ("Enter text and you can save it to tape for reloading");
|
||||
puts ("later. There are four special 'command' characters:\n");
|
||||
puts (" Control-S Save to tape");
|
||||
puts (" Control-L Load from tape");
|
||||
puts (" Control-C Clear memory");
|
||||
puts (" Control-X Exit");
|
||||
puts ("========================================================\n");
|
||||
}
|
||||
|
||||
while ( writing ) {
|
||||
|
||||
c = getchar();
|
||||
|
||||
if ( c == 0x08 ) { // Backspace
|
||||
if ( p > 0 ) {
|
||||
buffer[p] = 0x00;
|
||||
p--;
|
||||
}
|
||||
}
|
||||
else if ( c == 0x13 ) { // Save
|
||||
puts ("\n========================= Save =========================");
|
||||
puts ("\nPress any key to save.");
|
||||
c = getchar();
|
||||
for ( l = 0; l <= p; l++ ) {
|
||||
tapio[l] = buffer[l];
|
||||
}
|
||||
l++;
|
||||
tapio[l] = 0x00;
|
||||
puts ("Saving to tape.");
|
||||
error = dumpt ( 'N', tapio, tapio+p );
|
||||
if ( error ) {
|
||||
puts ("\nTape error.");
|
||||
}
|
||||
else
|
||||
{
|
||||
putchar ( '\r' );
|
||||
for ( l = 0; l < 25; l++ ) {
|
||||
putchar ( '\n' );
|
||||
}
|
||||
}
|
||||
puts ("===================== Sym-1 Notepad ====================\n");
|
||||
for ( l = 0; l <= p; l++ ) {
|
||||
putchar ( buffer[l] );
|
||||
}
|
||||
}
|
||||
else if ( c == 0x0C ) { // Load
|
||||
p = 0;
|
||||
puts ("\nLoading from tape.");
|
||||
memset ( buffer, 0, heap_size );
|
||||
memset ( tapio, 0, TAPIO_MAX_SIZE );
|
||||
error = loadt ( 'N' );
|
||||
if ( error ) {
|
||||
puts ("\nTape error.");
|
||||
puts ("===================== Sym-1 Notepad ====================\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( l = 0; l <= heap_size; l++ ) {
|
||||
buffer[l] = tapio[l];
|
||||
}
|
||||
|
||||
p = strlen ( buffer );
|
||||
|
||||
putchar ( '\r' );
|
||||
for ( l = 0; l < 25; l++ ) {
|
||||
putchar ( '\n' );
|
||||
}
|
||||
puts ("===================== Sym-1 Notepad ====================\n");
|
||||
|
||||
for ( l = 0; l <= p; l++ ) {
|
||||
putchar ( buffer[l] );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( c == 0x03 ) { // Clear
|
||||
p = 0;
|
||||
memset ( buffer, 0, heap_size );
|
||||
putchar ( '\r' );
|
||||
for ( l = 0; l < 25; l++ ) {
|
||||
putchar ( '\n' );
|
||||
}
|
||||
puts ("===================== Sym-1 Notepad ====================\n");
|
||||
}
|
||||
else if ( c == 0x18 ) { // Exit
|
||||
writing = 0;
|
||||
running = 0;
|
||||
}
|
||||
else {
|
||||
if ( p >= heap_size - 1 ) {
|
||||
puts ("\n========================= End =========================");
|
||||
puts ("Buffer full.");
|
||||
}
|
||||
else {
|
||||
if ( c == '\n' ) {
|
||||
putchar ( '\n' );
|
||||
}
|
||||
buffer[p] = c;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
free ( buffer );
|
||||
|
||||
puts ("\nEnjoy your day!\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
42
samples/sym1/symTiny.c
Normal file
42
samples/sym1/symTiny.c
Normal file
@@ -0,0 +1,42 @@
|
||||
// --------------------------------------------------------------------------
|
||||
// Hello World for Sym-1
|
||||
//
|
||||
// Uses only getchar, putchar and puts, generating smaller code than printf
|
||||
//
|
||||
// Wayne Parham
|
||||
//
|
||||
// wayne@parhamdata.com
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sym1.h>
|
||||
|
||||
int main (void) {
|
||||
char c = 0x00;
|
||||
int d = 0x00;
|
||||
int l = 0x00;
|
||||
|
||||
puts ("Hello World!\n");
|
||||
|
||||
puts ("Type a line and press ENTER, please:\n");
|
||||
|
||||
for ( l = 0; l < 2; l++ ) {
|
||||
beep();
|
||||
for ( d = 0; d < 10 ; d++ ) {
|
||||
}
|
||||
}
|
||||
|
||||
while ( c != '\n' ) {
|
||||
c = getchar();
|
||||
}
|
||||
|
||||
puts ("\n\nThanks!\n");
|
||||
|
||||
for ( l = 0; l < 5; l++ ) {
|
||||
beep();
|
||||
for ( d = 0; d < 10 ; d++ ) {
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
76
samples/terminal.c
Normal file
76
samples/terminal.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
** Minimalistic terminal program.
|
||||
**
|
||||
** Makes use of the serial drivers.
|
||||
**
|
||||
** 2022-12-23, Oliver Schmidt (ol.sc@web.de)
|
||||
**
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <cc65.h>
|
||||
#include <conio.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <serial.h>
|
||||
|
||||
|
||||
static void check (const char* msg, unsigned char err)
|
||||
{
|
||||
if (err == SER_ERR_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
printf ("%s:0x%02x\n", msg, err);
|
||||
if (doesclrscrafterexit ()) {
|
||||
cgetc ();
|
||||
}
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
||||
void main (void)
|
||||
{
|
||||
const struct ser_params par = {
|
||||
SER_BAUD_9600,
|
||||
SER_BITS_8,
|
||||
SER_STOP_1,
|
||||
SER_PAR_NONE,
|
||||
SER_HS_HW
|
||||
};
|
||||
|
||||
check ("ser_install", ser_install (ser_static_stddrv));
|
||||
|
||||
check ("ser_open", ser_open (&par));
|
||||
|
||||
atexit ((void (*)) ser_close);
|
||||
|
||||
printf ("Serial Port: 9600-8-1-N RTS/CTS\n"
|
||||
"Simple Term: Press ESC for exit\n");
|
||||
|
||||
while (1)
|
||||
{
|
||||
char chr;
|
||||
|
||||
if (kbhit ())
|
||||
{
|
||||
chr = cgetc ();
|
||||
|
||||
if (chr == CH_ESC) {
|
||||
putchar ('\n');
|
||||
return;
|
||||
}
|
||||
|
||||
if (ser_put (chr) == SER_ERR_OK) {
|
||||
putchar (chr);
|
||||
} else {
|
||||
putchar ('\a');
|
||||
}
|
||||
}
|
||||
|
||||
if (ser_get (&chr) == SER_ERR_OK) {
|
||||
putchar (chr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -38,8 +38,9 @@ static unsigned AspectRatio;
|
||||
static void CheckError (const char* S)
|
||||
{
|
||||
unsigned char Error = tgi_geterror ();
|
||||
|
||||
if (Error != TGI_ERR_OK) {
|
||||
printf ("%s: %d\n", S, Error);
|
||||
printf ("%s: %u\n", S, Error);
|
||||
if (doesclrscrafterexit ()) {
|
||||
cgetc ();
|
||||
}
|
||||
@@ -67,26 +68,27 @@ static void DoWarning (void)
|
||||
|
||||
static void DoCircles (void)
|
||||
{
|
||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_ORANGE };
|
||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLUE };
|
||||
unsigned char I;
|
||||
unsigned char Color = COLOR_FORE;
|
||||
unsigned X = MaxX / 2;
|
||||
unsigned Y = MaxY / 2;
|
||||
unsigned char Color = COLOR_BACK;
|
||||
const unsigned X = MaxX / 2;
|
||||
const unsigned Y = MaxY / 2;
|
||||
const unsigned Limit = (X < Y) ? Y : X;
|
||||
|
||||
tgi_setpalette (Palette);
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
tgi_line (0, 0, MaxX, MaxY);
|
||||
tgi_line (0, MaxY, MaxX, 0);
|
||||
while (!kbhit ()) {
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_line (0, 0, MaxX, MaxY);
|
||||
tgi_line (0, MaxY, MaxX, 0);
|
||||
Color = (Color == COLOR_FORE) ? COLOR_BACK : COLOR_FORE;
|
||||
tgi_setcolor (Color);
|
||||
for (I = 10; I < 240; I += 10) {
|
||||
for (I = 10; I <= Limit; I += 10) {
|
||||
tgi_ellipse (X, Y, I, tgi_imulround (I, AspectRatio));
|
||||
}
|
||||
Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE;
|
||||
}
|
||||
|
||||
cgetc ();
|
||||
tgi_clear ();
|
||||
}
|
||||
|
||||
|
||||
@@ -95,19 +97,19 @@ static void DoCheckerboard (void)
|
||||
{
|
||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK };
|
||||
unsigned X, Y;
|
||||
unsigned char Color;
|
||||
unsigned char Color = COLOR_BACK;
|
||||
|
||||
tgi_setpalette (Palette);
|
||||
Color = COLOR_BACK;
|
||||
tgi_clear ();
|
||||
|
||||
while (1) {
|
||||
for (Y = 0; Y <= MaxY; Y += 10) {
|
||||
for (X = 0; X <= MaxX; X += 10) {
|
||||
Color = (Color == COLOR_FORE) ? COLOR_BACK : COLOR_FORE;
|
||||
tgi_setcolor (Color);
|
||||
tgi_bar (X, Y, X+9, Y+9);
|
||||
Color = Color == COLOR_FORE ? COLOR_BACK : COLOR_FORE;
|
||||
if (kbhit ()) {
|
||||
cgetc ();
|
||||
tgi_clear ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -129,8 +131,9 @@ static void DoDiagram (void)
|
||||
|
||||
tgi_setpalette (Palette);
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
|
||||
/* Determine zero and aplitude */
|
||||
/* Determine zero and amplitude */
|
||||
YOrigin = MaxY / 2;
|
||||
XOrigin = 10;
|
||||
Amp = (MaxY - 19) / 2;
|
||||
@@ -158,7 +161,6 @@ static void DoDiagram (void)
|
||||
}
|
||||
|
||||
cgetc ();
|
||||
tgi_clear ();
|
||||
}
|
||||
|
||||
|
||||
@@ -167,19 +169,20 @@ static void DoLines (void)
|
||||
{
|
||||
static const unsigned char Palette[2] = { TGI_COLOR_WHITE, TGI_COLOR_BLACK };
|
||||
unsigned X;
|
||||
const unsigned Min = (MaxX < MaxY) ? MaxX : MaxY;
|
||||
|
||||
tgi_setpalette (Palette);
|
||||
tgi_setcolor (COLOR_FORE);
|
||||
tgi_clear ();
|
||||
|
||||
for (X = 0; X <= MaxY; X += 10) {
|
||||
tgi_line (0, 0, MaxY, X);
|
||||
tgi_line (0, 0, X, MaxY);
|
||||
tgi_line (MaxY, MaxY, 0, MaxY-X);
|
||||
tgi_line (MaxY, MaxY, MaxY-X, 0);
|
||||
for (X = 0; X <= Min; X += 10) {
|
||||
tgi_line (0, 0, Min, X);
|
||||
tgi_line (0, 0, X, Min);
|
||||
tgi_line (Min, Min, 0, Min-X);
|
||||
tgi_line (Min, Min, Min-X, 0);
|
||||
}
|
||||
|
||||
cgetc ();
|
||||
tgi_clear ();
|
||||
}
|
||||
|
||||
|
||||
@@ -203,7 +206,6 @@ int main (void)
|
||||
|
||||
tgi_init ();
|
||||
CheckError ("tgi_init");
|
||||
tgi_clear ();
|
||||
|
||||
/* Get stuff from the driver */
|
||||
MaxX = tgi_getmaxx ();
|
||||
|
||||
503
samples/tinyshell.c
Normal file
503
samples/tinyshell.c
Normal file
@@ -0,0 +1,503 @@
|
||||
/*
|
||||
** Simple ("tiny") shell to test filename and directory functions.
|
||||
** Copyright (c) 2013,2016 Christian Groessler, chris@groessler.org
|
||||
*/
|
||||
|
||||
#define VERSION_ASC "0.91"
|
||||
|
||||
#ifdef __ATARI__
|
||||
#define UPPERCASE /* define (e.g. for Atari) to convert filenames etc. to upper case */
|
||||
#define HAVE_SUBDIRS
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE2__
|
||||
#define HAVE_SUBDIRS
|
||||
#endif
|
||||
|
||||
#ifdef __CC65__
|
||||
#define CHECK_SP
|
||||
#endif
|
||||
|
||||
#define KEYB_BUFSZ 127
|
||||
#define PROMPT ">>> "
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#ifndef __CC65__
|
||||
#include <sys/stat.h>
|
||||
#include <sys/param.h>
|
||||
#define HAVE_SUBDIRS
|
||||
#else
|
||||
#define MAXPATHLEN 64
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef CHECK_SP
|
||||
extern unsigned int getsp(void); /* comes from getsp.s */
|
||||
#endif
|
||||
|
||||
#define CMD_NOTHING 0
|
||||
#define CMD_INVALID 1
|
||||
#define CMD_HELP 2
|
||||
#define CMD_QUIT 3
|
||||
#define CMD_LS 4
|
||||
#define CMD_MKDIR 5
|
||||
#define CMD_RMDIR 6
|
||||
#define CMD_CHDIR 7
|
||||
#define CMD_RM 8
|
||||
#define CMD_RENAME 9
|
||||
#define CMD_COPY 10
|
||||
#define CMD_PWD 11
|
||||
#define CMD_CLS 12
|
||||
#define CMD_VERBOSE 13
|
||||
#define CMD_EXEC 14
|
||||
|
||||
static unsigned char verbose;
|
||||
static unsigned char terminate;
|
||||
static unsigned char cmd;
|
||||
static char *cmd_asc, *arg1, *arg2, *arg3, *args; /* 'args': everything after command */
|
||||
static char keyb_buf[KEYB_BUFSZ + 1];
|
||||
static char keyb_buf2[KEYB_BUFSZ + 1];
|
||||
static size_t cpbuf_sz = 4096;
|
||||
|
||||
struct cmd_table {
|
||||
char *name;
|
||||
unsigned char code;
|
||||
} cmd_table[] = {
|
||||
{ "help", CMD_HELP },
|
||||
{ "quit", CMD_QUIT },
|
||||
{ "q", CMD_QUIT },
|
||||
{ "exit", CMD_QUIT },
|
||||
{ "ls", CMD_LS },
|
||||
{ "dir", CMD_LS },
|
||||
{ "md", CMD_MKDIR },
|
||||
#ifdef HAVE_SUBDIRS
|
||||
{ "mkdir", CMD_MKDIR },
|
||||
{ "rd", CMD_RMDIR },
|
||||
{ "rmdir", CMD_RMDIR },
|
||||
{ "cd", CMD_CHDIR },
|
||||
{ "chdir", CMD_CHDIR },
|
||||
#endif
|
||||
{ "rm", CMD_RM },
|
||||
{ "del", CMD_RM },
|
||||
{ "cp", CMD_COPY },
|
||||
{ "copy", CMD_COPY },
|
||||
{ "mv", CMD_RENAME },
|
||||
{ "ren", CMD_RENAME },
|
||||
{ "pwd", CMD_PWD },
|
||||
{ "exec", CMD_EXEC },
|
||||
#ifdef __ATARI__
|
||||
{ "cls", CMD_CLS },
|
||||
#endif
|
||||
{ "verbose", CMD_VERBOSE },
|
||||
{ NULL, 0 }
|
||||
};
|
||||
|
||||
static void banner(void)
|
||||
{
|
||||
puts("\"tiny\" command line shell, v" VERSION_ASC);
|
||||
puts("written by chris@groessler.org");
|
||||
puts("type 'help' for help\n");
|
||||
}
|
||||
|
||||
static void get_command(void)
|
||||
{
|
||||
unsigned char i = 0;
|
||||
|
||||
#ifdef CHECK_SP
|
||||
static char firstcall = 1;
|
||||
static unsigned int good_sp;
|
||||
unsigned int sp;
|
||||
if (firstcall)
|
||||
sp = good_sp = getsp();
|
||||
else
|
||||
sp = getsp();
|
||||
|
||||
if (sp != good_sp) {
|
||||
printf("SP: 0x%04X ***MISMATCH*** 0x%04X\n", sp, good_sp);
|
||||
}
|
||||
else if (verbose)
|
||||
printf("SP: 0x%04X\n", sp);
|
||||
#endif
|
||||
|
||||
arg1 = arg2 = arg3 = NULL;
|
||||
|
||||
/* issue prompt */
|
||||
printf(PROMPT);
|
||||
|
||||
/* get input from the user */
|
||||
if (! fgets(keyb_buf, KEYB_BUFSZ, stdin)) {
|
||||
puts("");
|
||||
cmd = CMD_QUIT;
|
||||
return;
|
||||
}
|
||||
|
||||
/* put everything after first string into 'args' */
|
||||
|
||||
strcpy(keyb_buf2, keyb_buf); /* use a backup copy for 'args' */
|
||||
|
||||
/* skip over the first non-whitespace item */
|
||||
cmd_asc = strtok(keyb_buf2, " \t\n");
|
||||
if (cmd_asc)
|
||||
args = strtok(NULL, ""); /* get everything */
|
||||
else
|
||||
*args = 0; /* no arguments */
|
||||
|
||||
/* split input into cmd, arg1, arg2, arg3 */
|
||||
|
||||
/* get and parse command */
|
||||
cmd_asc = strtok(keyb_buf, " \t\n");
|
||||
if (! cmd_asc) {
|
||||
cmd = CMD_NOTHING;
|
||||
return;
|
||||
}
|
||||
cmd = CMD_INVALID;
|
||||
while (cmd_table[i].name) {
|
||||
if (! strcmp(cmd_table[i].name, cmd_asc)) {
|
||||
cmd = cmd_table[i].code;
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
/* get arguments */
|
||||
arg1 = strtok(NULL, " \t\n");
|
||||
if (! arg1)
|
||||
return;
|
||||
arg2 = strtok(NULL, " \t\n");
|
||||
if (! arg2)
|
||||
return;
|
||||
arg3 = strtok(NULL, " \t\n");
|
||||
}
|
||||
|
||||
static void cmd_help(void)
|
||||
{
|
||||
puts("quit, exit - exit shell");
|
||||
puts("ls, dir - display current directory");
|
||||
puts(" and drive contents");
|
||||
puts("rm, del - delete file");
|
||||
puts("cp, copy - copy file");
|
||||
puts("mv, ren - rename file");
|
||||
puts("cd, chdir - change directory or drive");
|
||||
puts("md, mkdir - make directory or drive");
|
||||
puts("rd, rmdir - remove directory or drive");
|
||||
puts("exec - run program");
|
||||
#ifdef __ATARI__
|
||||
puts("cls - clear screen");
|
||||
#endif
|
||||
puts("verbose - set verbosity level");
|
||||
}
|
||||
|
||||
static void cmd_ls(void)
|
||||
{
|
||||
DIR *dir;
|
||||
char *arg;
|
||||
struct dirent *dirent;
|
||||
#ifdef __ATARI__
|
||||
char need_free = 0;
|
||||
#endif
|
||||
|
||||
if (arg2) {
|
||||
puts("usage: ls [dir]");
|
||||
return;
|
||||
}
|
||||
|
||||
/* print directory listing */
|
||||
if (arg1) {
|
||||
#ifdef UPPERCASE
|
||||
strupr(arg1);
|
||||
#endif
|
||||
#ifdef __ATARI__
|
||||
/* not sure if this shouldn't be done by the runtime lib */
|
||||
if (*(arg1 + strlen(arg1) - 1) == ':' || *(arg1 + strlen(arg1) - 1) == '>') {
|
||||
arg = malloc(strlen(arg1) + 4);
|
||||
if (! arg) {
|
||||
printf("malloc failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
need_free = 1;
|
||||
memcpy(arg, arg1, strlen(arg1) + 1);
|
||||
strcat(arg, "*.*");
|
||||
}
|
||||
else
|
||||
#endif
|
||||
arg = arg1;
|
||||
}
|
||||
else
|
||||
arg = ".";
|
||||
|
||||
if (verbose)
|
||||
printf("Buffer addr: %p\n", arg);
|
||||
dir = opendir(arg);
|
||||
#ifdef __ATARI__
|
||||
if (need_free) free(arg);
|
||||
#endif
|
||||
if (! dir) {
|
||||
puts("opendir failed");
|
||||
return;
|
||||
}
|
||||
|
||||
while (dirent = readdir(dir))
|
||||
puts(dirent->d_name);
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
||||
static void cmd_rm(void)
|
||||
{
|
||||
if (!arg1 || arg2) {
|
||||
puts("usage: rm <file>");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UPPERCASE
|
||||
strupr(arg1);
|
||||
#endif
|
||||
|
||||
if (unlink(arg1))
|
||||
printf("remove failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
#ifdef HAVE_SUBDIRS
|
||||
|
||||
static void cmd_mkdir(void)
|
||||
{
|
||||
if (!arg1 || arg2) {
|
||||
puts("usage: mkdir <dir>");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UPPERCASE
|
||||
strupr(arg1);
|
||||
#endif
|
||||
|
||||
if (mkdir(arg1, 0777))
|
||||
printf("mkdir failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
static void cmd_rmdir(void)
|
||||
{
|
||||
if (!arg1 || arg2) {
|
||||
puts("usage: rmdir <dir>");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UPPERCASE
|
||||
strupr(arg1);
|
||||
#endif
|
||||
|
||||
if (rmdir(arg1))
|
||||
printf("rmdir failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
static void cmd_chdir(void)
|
||||
{
|
||||
if (!arg1 || arg2) {
|
||||
puts("usage: cddir <dir>");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UPPERCASE
|
||||
strupr(arg1);
|
||||
#endif
|
||||
|
||||
if (chdir(arg1))
|
||||
printf("chdir failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
static void cmd_pwd(void)
|
||||
{
|
||||
char *buf;
|
||||
|
||||
if (arg1) {
|
||||
puts("usage: pwd");
|
||||
return;
|
||||
}
|
||||
|
||||
buf = malloc(MAXPATHLEN);
|
||||
if (! buf) {
|
||||
printf("malloc %u bytes failed: %s\n", MAXPATHLEN, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (verbose)
|
||||
printf("Buffer addr: %p\n", buf);
|
||||
if (!getcwd(buf, MAXPATHLEN)) {
|
||||
printf("getcwd failed: %s\n", strerror(errno));
|
||||
free(buf);
|
||||
return;
|
||||
}
|
||||
|
||||
puts(buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
#endif /* #ifdef HAVE_SUBDIRS */
|
||||
|
||||
static void cmd_rename(void)
|
||||
{
|
||||
if (!arg2 || arg3) {
|
||||
puts("usage: mv <oldname> <newname>");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UPPERCASE
|
||||
strupr(arg1);
|
||||
strupr(arg2);
|
||||
#endif
|
||||
|
||||
if (rename(arg1, arg2))
|
||||
printf("rename failed: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
static void cmd_exec(void)
|
||||
{
|
||||
char *progname, *arguments;
|
||||
|
||||
progname = strtok(args, " \t\n");
|
||||
if (! progname) {
|
||||
puts("usage: exec <progname> [arguments]");
|
||||
return;
|
||||
}
|
||||
arguments = strtok(NULL, "");
|
||||
|
||||
/*printf("exec: %s %s\n", progname, arguments ? arguments : "");*/
|
||||
(void)exec(progname, arguments);
|
||||
printf("exec error: %s\n", strerror(errno));
|
||||
}
|
||||
|
||||
static void cmd_copy(void)
|
||||
{
|
||||
int srcfd = -1, dstfd = -1;
|
||||
char *buf;
|
||||
int readsz, writesz;
|
||||
|
||||
if (!arg2 || arg3) {
|
||||
puts("usage: cp <src> <dest>");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef UPPERCASE
|
||||
strupr(arg1);
|
||||
strupr(arg2);
|
||||
#endif
|
||||
|
||||
buf = malloc(cpbuf_sz);
|
||||
if (! buf) {
|
||||
printf("malloc %u bytes failed: %s\n", cpbuf_sz, strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (verbose)
|
||||
printf("Buffer addr: %p\n", buf);
|
||||
|
||||
while (1) {
|
||||
if (srcfd == -1) {
|
||||
srcfd = open(arg1, O_RDONLY);
|
||||
if (srcfd < 0) {
|
||||
printf("open(%s) failed: %s\n", arg1, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
readsz = read(srcfd, buf, cpbuf_sz);
|
||||
if (readsz < 0) {
|
||||
printf("read error: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if (! readsz)
|
||||
break;
|
||||
|
||||
if (dstfd == -1) {
|
||||
dstfd = open(arg2, O_WRONLY | O_CREAT | O_TRUNC, 0777);
|
||||
if (dstfd < 0) {
|
||||
printf("open(%s) failed: %s\n", arg2, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
writesz = write(dstfd, buf, readsz);
|
||||
if (writesz < 0 || writesz != readsz) {
|
||||
printf("write error: %s\n", strerror(errno));
|
||||
break;
|
||||
}
|
||||
if (readsz != cpbuf_sz)
|
||||
break;
|
||||
}
|
||||
|
||||
free(buf);
|
||||
if (srcfd >= 0) close(srcfd);
|
||||
if (dstfd >= 0) close(dstfd);
|
||||
}
|
||||
|
||||
#ifdef __ATARI__
|
||||
static void cmd_cls(void)
|
||||
{
|
||||
printf("\f");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void cmd_verbose(void)
|
||||
{
|
||||
unsigned long verb;
|
||||
char *endptr;
|
||||
|
||||
if (!arg1 || arg2) {
|
||||
puts("usage: verbose <level>");
|
||||
return;
|
||||
}
|
||||
|
||||
verb = strtoul(arg1, &endptr, 10);
|
||||
if (verb > 255 || *endptr) {
|
||||
puts("invalid verbosity level");
|
||||
return;
|
||||
}
|
||||
|
||||
verbose = verb;
|
||||
printf("verbosity level set to %d\n", verbose);
|
||||
}
|
||||
|
||||
static void run_command(void)
|
||||
{
|
||||
switch (cmd) {
|
||||
default: puts("internal error"); return;
|
||||
case CMD_NOTHING: return;
|
||||
case CMD_INVALID: puts("invalid command"); return;
|
||||
case CMD_HELP: cmd_help(); return;
|
||||
case CMD_QUIT: terminate = 1; return;
|
||||
case CMD_LS: cmd_ls(); return;
|
||||
case CMD_RM: cmd_rm(); return;
|
||||
#ifdef HAVE_SUBDIRS
|
||||
case CMD_CHDIR: cmd_chdir(); return;
|
||||
case CMD_MKDIR: cmd_mkdir(); return;
|
||||
case CMD_RMDIR: cmd_rmdir(); return;
|
||||
case CMD_PWD: cmd_pwd(); return;
|
||||
#endif
|
||||
case CMD_EXEC: cmd_exec(); return;
|
||||
case CMD_RENAME: cmd_rename(); return;
|
||||
case CMD_COPY: cmd_copy(); return;
|
||||
#ifdef __ATARI__
|
||||
case CMD_CLS: cmd_cls(); return;
|
||||
#endif
|
||||
case CMD_VERBOSE: cmd_verbose(); return;
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
banner();
|
||||
|
||||
while (! terminate) {
|
||||
get_command();
|
||||
run_command();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Local Variables: */
|
||||
/* c-file-style: "cpg" */
|
||||
/* c-basic-offset: 4 */
|
||||
/* End: */
|
||||
95
samples/tutorial/Makefile
Normal file
95
samples/tutorial/Makefile
Normal file
@@ -0,0 +1,95 @@
|
||||
|
||||
# Run 'make SYS=<target>'; or, set a SYS env.
|
||||
# var. to build for another target system.
|
||||
SYS ?= c64
|
||||
|
||||
# Just the usual way to find out if we're
|
||||
# using cmd.exe to execute make rules.
|
||||
ifneq ($(shell echo),)
|
||||
CMD_EXE = 1
|
||||
endif
|
||||
|
||||
ifdef CMD_EXE
|
||||
NULLDEV = nul:
|
||||
DEL = -del /f
|
||||
RMDIR = rmdir /s /q
|
||||
else
|
||||
NULLDEV = /dev/null
|
||||
DEL = $(RM)
|
||||
RMDIR = $(RM) -r
|
||||
endif
|
||||
|
||||
ifdef CC65_HOME
|
||||
AS = $(CC65_HOME)/bin/ca65
|
||||
CC = $(CC65_HOME)/bin/cc65
|
||||
CL = $(CC65_HOME)/bin/cl65
|
||||
LD = $(CC65_HOME)/bin/ld65
|
||||
else
|
||||
AS := $(if $(wildcard ../../bin/ca65*),../../bin/ca65,ca65)
|
||||
CC := $(if $(wildcard ../../bin/cc65*),../../bin/cc65,cc65)
|
||||
CL := $(if $(wildcard ../../bin/cl65*),../../bin/cl65,cl65)
|
||||
LD := $(if $(wildcard ../../bin/ld65*),../../bin/ld65,ld65)
|
||||
endif
|
||||
|
||||
EXELIST_atari2600 = \
|
||||
notavailable
|
||||
|
||||
EXELIST_atari5200 = \
|
||||
notavailable
|
||||
|
||||
EXELIST_bbc = \
|
||||
notavailable
|
||||
|
||||
EXELIST_creativision = \
|
||||
notavailable
|
||||
|
||||
EXELIST_gamate = \
|
||||
notavailable
|
||||
|
||||
EXELIST_geos-cbm = \
|
||||
notavailable
|
||||
|
||||
EXELIST_geos-apple = \
|
||||
notavailable
|
||||
|
||||
EXELIST_lunix = \
|
||||
notavailable
|
||||
|
||||
EXELIST_lynx = \
|
||||
notavailable
|
||||
|
||||
EXELIST_nes = \
|
||||
notavailable
|
||||
|
||||
EXELIST_osic1p = \
|
||||
notavailable
|
||||
|
||||
EXELIST_pce = \
|
||||
notavailable
|
||||
|
||||
EXELIST_supervision = \
|
||||
notavailable
|
||||
|
||||
# Unlisted targets will try to build everything.
|
||||
# That lets us learn what they cannot build, and what settings
|
||||
# we need to use for programs that can be built and run.
|
||||
ifndef EXELIST_$(SYS)
|
||||
EXELIST_$(SYS) := ${patsubst %.c,%,$(wildcard *.c)}
|
||||
endif
|
||||
|
||||
samples: $(EXELIST_$(SYS))
|
||||
|
||||
hello: hello.c text.s
|
||||
$(CL) -t $(SYS) -o hello hello.c text.s
|
||||
|
||||
# empty target used to skip systems that will not work with any program in this dir
|
||||
notavailable:
|
||||
ifeq ($(MAKELEVEL),0)
|
||||
@echo "info: tutorial sample not available for" $(SYS)
|
||||
else
|
||||
# suppress the "nothing to be done for 'samples' message
|
||||
@echo > $(NULLDEV)
|
||||
endif
|
||||
|
||||
clean:
|
||||
@$(DEL) hello 2>$(NULLDEV)
|
||||
Reference in New Issue
Block a user