From 799aec23a64c9f11fa2591f5e8dc7a93ee298430 Mon Sep 17 00:00:00 2001 From: Dave Plummer Date: Sat, 4 Jun 2022 13:00:48 -0700 Subject: [PATCH 1/4] Add KIM-1 Support --- asminc/kim1.inc | 28 +++++++++++++++++ cfg/kim1.cfg | 41 ++++++++++++++++++++++++ include/kim1.h | 67 ++++++++++++++++++++++++++++++++++++++++ libsrc/Makefile | 1 + libsrc/kim1/crt0.s | 47 ++++++++++++++++++++++++++++ libsrc/kim1/ctype.s | 5 +++ libsrc/kim1/read.s | 51 ++++++++++++++++++++++++++++++ libsrc/kim1/tapeio.s | 39 +++++++++++++++++++++++ libsrc/kim1/write.s | 49 +++++++++++++++++++++++++++++ samples/Makefile | 6 +++- samples/kim1/Makefile | 56 +++++++++++++++++++++++++++++++++ samples/kim1/kimHello | Bin 0 -> 2789 bytes samples/kim1/kimHello.c | 24 ++++++++++++++ src/ca65/main.c | 4 +++ src/cc65/main.c | 4 +++ src/common/target.c | 2 ++ src/common/target.h | 1 + targettest/Makefile | 1 + 18 files changed, 425 insertions(+), 1 deletion(-) create mode 100644 asminc/kim1.inc create mode 100644 cfg/kim1.cfg create mode 100644 include/kim1.h create mode 100644 libsrc/kim1/crt0.s create mode 100644 libsrc/kim1/ctype.s create mode 100644 libsrc/kim1/read.s create mode 100644 libsrc/kim1/tapeio.s create mode 100644 libsrc/kim1/write.s create mode 100644 samples/kim1/Makefile create mode 100644 samples/kim1/kimHello create mode 100644 samples/kim1/kimHello.c diff --git a/asminc/kim1.inc b/asminc/kim1.inc new file mode 100644 index 000000000..f0d1555a7 --- /dev/null +++ b/asminc/kim1.inc @@ -0,0 +1,28 @@ +; --------------------------------------------------------------------------- +; +; KIM-1 definitions +; +; --------------------------------------------------------------------------- + + +RAMSTART := $0200 ; Entry point + +; --------------------------------------------------------------------------- +; Monitor Functions +; --------------------------------------------------------------------------- + + +OUTCHR := $1EA0 ; Output character +INTCHR := $1E5A ; Input character without case conversion +DUMPT := $1800 ; Dump memory to tape +LOADT := $1873 ; Load memory from tape +SAL := $17F5 ; Tape load address low +SAH := $17F6 ; Tape load address high +EAL := $17F7 ; Tape address end low +EAH := $17F8 ; Tape address end high +ID := $17F9 ; Tape Identification number + +; --------------------------------------------------------------------------- +; System Memory +; --------------------------------------------------------------------------- + diff --git a/cfg/kim1.cfg b/cfg/kim1.cfg new file mode 100644 index 000000000..69636065e --- /dev/null +++ b/cfg/kim1.cfg @@ -0,0 +1,41 @@ +# kim1.cfg (4k) +# +# for unexpanded Kim-1 +# +# ld65 --config kim1.cfg -o .bin .o + +FEATURES { + STARTADDRESS: default = $0200; + CONDES: segment = STARTUP, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = STARTUP, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; +} + +SYMBOLS { + __STACKSIZE__: type = weak, value = $0080; # 128 byte program stack + __STARTADDRESS__: type = export, value = %S; +} + +MEMORY { + ZP: file = %O, define = yes, start = $0000, size = $00EE; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $1000 - %S - __STACKSIZE__; + MAINROM: file = "", define = yes, start = $E000, size = $1000; + TOP: file = "", define = yes, start = $F000, size = $1000; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; + STARTUP: load = RAM, type = ro, define = yes; + CODE: load = RAM, type = ro, define = yes; + RODATA: load = RAM, type = ro, define = yes; + ONCE: load = RAM, type = ro, define = yes; + DATA: load = RAM, type = rw, define = yes; + BSS: load = RAM, type = bss, define = yes; +} + diff --git a/include/kim1.h b/include/kim1.h new file mode 100644 index 000000000..52e690c9d --- /dev/null +++ b/include/kim1.h @@ -0,0 +1,67 @@ +/*****************************************************************************/ +/* */ +/* kim1.h */ +/* */ +/* Kim-1 system-specific definitions */ +/* */ +/* */ +/* */ +/* (C) 2022 Dave Plummer */ +/* Email: davepl@davepl.com */ +/* */ +/* This software is provided 'as-is', without any expressed or implied */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + +#ifndef _KIM1_H +#define _KIM1_H + +/* Check for errors */ +#if !defined(__KIM1__) +# error This module may only be used when compiling for the Kim-1! +#endif + + + +/*****************************************************************************/ +/* Data */ +/*****************************************************************************/ + +/*****************************************************************************/ +/* Hardware */ +/*****************************************************************************/ + + +// Todo (davepl) +// +// #include <_6530.h> +// #define RIOT3 (*(struct __6530*)0x1700) // U25 +// #define RIOT2 (*(struct __6530*)0x1740) // U28 + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + +/* Read from tape */ +int __fastcall__ loadt (unsigned char); + +/* Write to tape */ +int __fastcall__ dumpt (unsigned char, const void*, const void*); + +/* End of sym1.h */ +#endif diff --git a/libsrc/Makefile b/libsrc/Makefile index 2018de801..627897d9b 100644 --- a/libsrc/Makefile +++ b/libsrc/Makefile @@ -27,6 +27,7 @@ TARGETS = apple2 \ $(CBMS) \ $(GEOS) \ gamate \ + kim1 \ lynx \ nes \ none \ diff --git a/libsrc/kim1/crt0.s b/libsrc/kim1/crt0.s new file mode 100644 index 000000000..7e7dd485b --- /dev/null +++ b/libsrc/kim1/crt0.s @@ -0,0 +1,47 @@ +; +; Startup code for cc65 (kim-1 version) +; + + .export _init, _exit + .export __STARTUP__ : absolute = 1 ; Mark as startup + + .import _main + .import initlib, donelib, copydata, zerobss + .import __RAM_START__, __RAM_SIZE__ ; Linker generated + .import __STACKSIZE__ ; Linker generated + + .include "zeropage.inc" + .include "kim1.inc" + + +; Place the startup code in a special segment + +.segment "STARTUP" + + +; A little light housekeeping + +_init: cld ; Clear decimal mode + +; Set cc65 argument stack pointer + + lda #<(__RAM_START__ + __RAM_SIZE__) + sta sp + lda #>(__RAM_START__ + __RAM_SIZE__) + sta sp+1 + +; Initialize memory storage + + jsr zerobss ; Clear BSS segment + jsr copydata ; Initialize DATA segment + jsr initlib ; Run constructors + +; Call main() + + jsr _main + +; Back from main (this is also the _exit entry). There may be a more elegant way to9 +; return to the monitor on the Kim-1, but I don't know it! + +_exit: brk + diff --git a/libsrc/kim1/ctype.s b/libsrc/kim1/ctype.s new file mode 100644 index 000000000..1301965eb --- /dev/null +++ b/libsrc/kim1/ctype.s @@ -0,0 +1,5 @@ +; Character specification table. +; +; uses the "common" definition + + .include "ctype_common.inc" diff --git a/libsrc/kim1/read.s b/libsrc/kim1/read.s new file mode 100644 index 000000000..5566a9f27 --- /dev/null +++ b/libsrc/kim1/read.s @@ -0,0 +1,51 @@ +; +; int __fastcall__ read (int fd, void* buf, unsigned count); +; + +.include "kim1.inc" + +.import popax, popptr1 +.importzp ptr1, ptr2, ptr3 + +.export _read + +.proc _read + + sta ptr3 + stx ptr3+1 ; Count in ptr3 + inx + stx ptr2+1 ; Increment and store in ptr2 + tax + inx + stx ptr2 + jsr popptr1 ; Buffer address in ptr1 + jsr popax + +begin: dec ptr2 + bne getch + dec ptr2+1 + beq done ; If buffer full, return + +getch: jsr INTCHR ; Get character using Monitor ROM call + ;jsr OUTCHR ; Echo it + and #$7F ; Clear top bit + cmp #$07 ; Check for '\a' + bne chkcr ; ...if BEL character + ;jsr BEEP ; Make beep sound TODO +chkcr: cmp #$0D ; Check for '\r' + bne putch ; ...if CR character + lda #$0A ; Replace with '\n' + jsr OUTCHR ; and echo it + +putch: ldy #$00 ; Put char into return buffer + sta (ptr1),y + inc ptr1 ; Increment pointer + bne begin + inc ptr1+1 + bne begin + +done: lda ptr3 + ldx ptr3+1 + rts ; Return count + +.endproc diff --git a/libsrc/kim1/tapeio.s b/libsrc/kim1/tapeio.s new file mode 100644 index 000000000..4a16d6b9c --- /dev/null +++ b/libsrc/kim1/tapeio.s @@ -0,0 +1,39 @@ +; +; int __fastcall__ loadt (unsigned char id); +; int __fastcall__ dumpt (unsigned char id, void* start_addr, void* end_addr); +; + +.include "kim1.inc" + +.import popa, popax, return0, return1 + +.export _loadt, _dumpt + +.segment "CODE" + +.proc _loadt: near + + sta ID ; Tape record ID to P1L + jsr LOADT ; Read data from tape + bcs error + jmp return0 ; Return 0 if sucessful +error: jmp return1 ; or 1 if not + +.endproc + +.proc _dumpt: near + + sta EAL ; End address + stx EAH + jsr popax + sta SAL ; Start address + stx SAH + jsr popa + sta ID ; Tape Record ID + ldx #$00 + jsr DUMPT ; Write data to tape + bcs error + jmp return0 ; Return 0 if sucessful +error: jmp return1 ; or 1 if not + +.endproc diff --git a/libsrc/kim1/write.s b/libsrc/kim1/write.s new file mode 100644 index 000000000..216f5031c --- /dev/null +++ b/libsrc/kim1/write.s @@ -0,0 +1,49 @@ +; +; int __fastcall__ write (int fd, const void* buf, int count); +; + +.include "kim1.inc" + +.import popax, popptr1 +.importzp ptr1, ptr2, ptr3 + +.export _write + +.proc _write + + sta ptr3 + stx ptr3+1 ; Count in ptr3 + inx + stx ptr2+1 ; Increment and store in ptr2 + tax + inx + stx ptr2 + jsr popptr1 ; Buffer address in ptr1 + jsr popax + +begin: dec ptr2 + bne outch + dec ptr2+1 + beq done + +outch: ldy #0 + lda (ptr1),y + jsr OUTCHR ; Send character using Monitor call + cmp #$07 ; Check for '\a' + bne chklf ; ...if BEL character +;jsr BEEP ; Make beep sound +chklf: cmp #$0A ; Check for 'n' + bne next ; ...if LF character + lda #$0D ; Add a carriage return + jsr OUTCHR + +next: inc ptr1 + bne begin + inc ptr1+1 + jmp begin + +done: lda ptr3 + ldx ptr3+1 + rts ; Return count + +.endproc diff --git a/samples/Makefile b/samples/Makefile index 4007e3522..cec4bed89 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -154,7 +154,7 @@ endif # Lists of subdirectories # disasm depends on cpp -DIRLIST = tutorial geos atari2600 atari5200 apple2 gamate lynx supervision sym1 cbm +DIRLIST = tutorial geos atari2600 atari5200 apple2 gamate lynx supervision sym1 kim1 cbm # -------------------------------------------------------------------------- # Lists of executables @@ -329,6 +329,9 @@ EXELIST_supervision = \ EXELIST_sym1 = \ notavailable +EXELIST_kim1 = \ + notavailable + EXELIST_telestrat = \ ascii \ checkversion \ @@ -395,6 +398,7 @@ TARGETS := \ creativision \ cx16 \ gamate \ + kim1 \ lunix \ lynx \ nes \ diff --git a/samples/kim1/Makefile b/samples/kim1/Makefile new file mode 100644 index 000000000..89600ad5a --- /dev/null +++ b/samples/kim1/Makefile @@ -0,0 +1,56 @@ + +# Run 'make SYS='; 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 + +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 + +kimHello.bin: kimHello.c + $(CL) -t kim1 -O -o kimHello.bin kimHello.c + +clean: + @$(DEL) kimHello.bin 2>$(NULLDEV) diff --git a/samples/kim1/kimHello b/samples/kim1/kimHello new file mode 100644 index 0000000000000000000000000000000000000000..5842567557dc9f321409d269970f08832b736d86 GIT binary patch literal 2789 zcmbVOTWl2989pPwHj|K(i1^Ur@f{@6caBR^#e^evV4CFt9Pc8bVHbVBy0T$R2rJ0ktL?4Nib zo8J=YZ<8)^P!)bIYN9})f5+@!{>KkCxqxB*K%{?2S`KParRkDPJQrCHdD} z0@!q1Hct~T-8U=R>2Yzg!)n|iY!z*Y=9&Z-6I^_pQ(G)ZbVziBX1ZQ%rU7*b56R8W zzS-W9rvhdCYxE5<>*1Q5z-yyl4%@htlkG^!b8X~$(5S~j+uJQr9m%C)In)>Rzec2U&e!Iy&9tvVtJlaZjs>yGJKl==tlO% zXy-%Q-io#@kV>@SXK-OY>rI55LlFu+v5UA_}tI20RRB<@m$XfCNhAl?vz z*O?A!QC=cGD&HgK$#}2_4)wDQE^2_eqDvcKzUV$#xl8D8#8IhNJ$09aiQy$4dPkw( zl=z_otb=D4E^yChsu-eC#o(0SAX^8=PTeG7SGHipjkp+>v<0Hw1`NNKE{b^vuV5Tv znu{uT$PBp0Kg`wzgN$(7hz7RuOMb#sIwHcIJEJ=fgQ2gno@@ial?cm!4FLHT1GeOY z!%SYuxB&&ugE=eeD@s|{Dk-h8Y)Hr00-4jb#%*%)dP*BlRCH}PrS&!D$#q?;H*OI= z3-PV*Y?p7563}_lm?KQ0-4gw(1Y*cVz%Lsb_;HnHO=UC3a>z!Ia6;a4+Lw-ui%@Ig zkOUrtWm_oNnsLM9_pKo!Oem-DMU)*zQWrOa$|I>LVuZn7Le%? z!UWJnm~h)AlO{pNp$>ErstQ_C2IlG~GW5Lci}Xqo&O<{IsGxu;$pD32=9iL}+H7^u zX5Ac5j#V=pCz8c#<{VdCbOL2z2H8-l$nMUYA0*3*P;ACapa#1FSvZb6* z&s&+D?S3H(nb42wp2(RkdQ!xtyanM{j&+s}CmhL>cq0*kl&UCStRl-ccnebss!a+S zJt%Vx8nZ>ej%(7W@t(q-^TfCu$86Q5BTRGDiQ8&bDH==WUvbG;?Qd{URcR?;zsmbC z4U@d`%(pQB_~2~nBi_H)ifg6yXN{5Aw9&#vHg|I3iVDpgfT0N4Cl1P2l~9^uOCG6d z7E8FOWUmX%~9jU$gh?>da zx+muh+bHcd_U(naBAfN}TFNrF$OU;6*YpA&(j9C*FWWjl@4yFytL@Z|2d7hZsI>$1-l@(MIr=3XX6;Y7of>)5}T24^F|l z#REB0Q0p@VWjUUc3X4su;S==xk5T8bo?iq>h60VneFaoFhFh3@+LGBvk?&8ZvrTj~ zod>kj9bD`H(c&56f^khH#8d2EOPyi2k6HY?_zEwPFiratJt9;w?x)ao*&IO5cuGx$ zbhY&;LUdG#9%~=jl4I0T;p03v)~}W7XLV1SPK{t&DoyM47A_Up69>}YE)&`trCnTRNqAu{5TWMvyKOpFlOxSER-TGIo*tPY4?Xl|Zg7xp|L(5s-+PK48p!P) z%xzQ@q-1jg0|)7=2j3jn^90wGUHRPyemKbG-lw10wD}v)Zs~jO`ES3lZTpT5&pf?( z%jUjK&u;ERNDzsv7+YU**j^a5Vv)0G$Y^e JbXnmD{{hxi-7)|G literal 0 HcmV?d00001 diff --git a/samples/kim1/kimHello.c b/samples/kim1/kimHello.c new file mode 100644 index 000000000..dcbfb4e67 --- /dev/null +++ b/samples/kim1/kimHello.c @@ -0,0 +1,24 @@ +// -------------------------------------------------------------------------- +// Hello World for Kim-1 +// +// Dave Plummer based on Sym-1 sample by Wayne Parham +// +// davepl@davepl.com +// -------------------------------------------------------------------------- + +#include +#include + +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; +} diff --git a/src/ca65/main.c b/src/ca65/main.c index b1ef3a3db..4146aaf11 100644 --- a/src/ca65/main.c +++ b/src/ca65/main.c @@ -342,6 +342,10 @@ static void SetSys (const char* Sys) NewSymbol ("__SYM1__", 1); break; + case TGT_KIM1: + NewSymbol ("__KIM1__", 1); + break; + default: AbEnd ("Invalid target name: '%s'", Sys); diff --git a/src/cc65/main.c b/src/cc65/main.c index c08616efa..f800ac43e 100644 --- a/src/cc65/main.c +++ b/src/cc65/main.c @@ -299,6 +299,10 @@ static void SetSys (const char* Sys) DefineNumericMacro ("__SYM1__", 1); break; + case TGT_KIM1: + DefineNumericMacro ("__KIM1__", 1); + break; + default: AbEnd ("Unknown target system '%s'", Sys); } diff --git a/src/common/target.c b/src/common/target.c index 4a851034a..ad62990bd 100644 --- a/src/common/target.c +++ b/src/common/target.c @@ -163,6 +163,7 @@ static const TargetEntry TargetMap[] = { { "geos", TGT_GEOS_CBM }, { "geos-apple", TGT_GEOS_APPLE }, { "geos-cbm", TGT_GEOS_CBM }, + { "kim1", TGT_KIM1 }, { "lunix", TGT_LUNIX }, { "lynx", TGT_LYNX }, { "module", TGT_MODULE }, @@ -219,6 +220,7 @@ static const TargetProperties PropertyTable[TGT_COUNT] = { { "c65", CPU_4510, BINFMT_BINARY, CTPET }, { "cx16", CPU_65C02, BINFMT_BINARY, CTPET }, { "sym1", CPU_6502, BINFMT_BINARY, CTNone }, + { "kim1", CPU_6502, BINFMT_BINARY, CTNone }, }; /* Target system */ diff --git a/src/common/target.h b/src/common/target.h index 7087048e2..7439fa621 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -87,6 +87,7 @@ typedef enum { TGT_C65, TGT_CX16, TGT_SYM1, + TGT_KIM1, // Added at end so as not to shift existing entries TGT_COUNT /* Number of target systems */ } target_t; diff --git a/targettest/Makefile b/targettest/Makefile index 0450bfd4e..23463ccd9 100644 --- a/targettest/Makefile +++ b/targettest/Makefile @@ -742,6 +742,7 @@ TARGETS := \ creativision \ cx16 \ gamate \ + kim1 \ lunix \ lynx \ nes \ From 8f9777d9e0d34b4be32ff09750980138d61e9e01 Mon Sep 17 00:00:00 2001 From: Dave Plummer Date: Mon, 6 Jun 2022 15:14:01 -0700 Subject: [PATCH 2/4] Fix ushot overflow, capitalization --- cfg/kim1-60k.cfg | 41 +++++++++++++ include/kim1.h | 4 +- libsrc/kim1/crt0.s | 2 +- samples/kim1/Makefile | 8 ++- samples/kim1/kimSieve.c | 125 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 cfg/kim1-60k.cfg create mode 100644 samples/kim1/kimSieve.c diff --git a/cfg/kim1-60k.cfg b/cfg/kim1-60k.cfg new file mode 100644 index 000000000..a6704d9dd --- /dev/null +++ b/cfg/kim1-60k.cfg @@ -0,0 +1,41 @@ +# kim1.cfg (4k) +# +# for unexpanded Kim-1 +# +# ld65 --config kim1.cfg -o .bin .o + +FEATURES { + STARTADDRESS: default = $2000; + CONDES: segment = STARTUP, + type = constructor, + label = __CONSTRUCTOR_TABLE__, + count = __CONSTRUCTOR_COUNT__; + CONDES: segment = STARTUP, + type = destructor, + label = __DESTRUCTOR_TABLE__, + count = __DESTRUCTOR_COUNT__; +} + +SYMBOLS { + __STACKSIZE__: type = weak, value = $0080; # 128 byte program stack + __STARTADDRESS__: type = export, value = %S; +} + +MEMORY { + ZP: file = %O, define = yes, start = $0000, size = $00EE; + CPUSTACK: file = "", define = yes, start = $0100, size = $0100; + RAM: file = %O, define = yes, start = %S, size = $E000 - %S - __STACKSIZE__; + MAINROM: file = "", define = yes, start = $E000, size = $1000; + TOP: file = "", define = yes, start = $F000, size = $1000; +} + +SEGMENTS { + ZEROPAGE: load = ZP, type = zp, define = yes; + STARTUP: load = RAM, type = ro, define = yes; + CODE: load = RAM, type = ro, define = yes; + RODATA: load = RAM, type = ro, define = yes; + ONCE: load = RAM, type = ro, define = yes; + DATA: load = RAM, type = rw, define = yes; + BSS: load = RAM, type = bss, define = yes; +} + diff --git a/include/kim1.h b/include/kim1.h index 52e690c9d..bb616f7a0 100644 --- a/include/kim1.h +++ b/include/kim1.h @@ -2,7 +2,7 @@ /* */ /* kim1.h */ /* */ -/* Kim-1 system-specific definitions */ +/* KIM-1 system-specific definitions */ /* */ /* */ /* */ @@ -33,7 +33,7 @@ /* Check for errors */ #if !defined(__KIM1__) -# error This module may only be used when compiling for the Kim-1! +# error This module may only be used when compiling for the KIM-1! #endif diff --git a/libsrc/kim1/crt0.s b/libsrc/kim1/crt0.s index 7e7dd485b..aefdc3545 100644 --- a/libsrc/kim1/crt0.s +++ b/libsrc/kim1/crt0.s @@ -1,5 +1,5 @@ ; -; Startup code for cc65 (kim-1 version) +; Startup code for cc65 (KIM-1 version) ; .export _init, _exit diff --git a/samples/kim1/Makefile b/samples/kim1/Makefile index 89600ad5a..74c415fdc 100644 --- a/samples/kim1/Makefile +++ b/samples/kim1/Makefile @@ -32,7 +32,8 @@ else endif EXELIST_kim1 = \ - kimHello.bin + kimHello.bin \ + kimSieve.bin ifneq ($(EXELIST_$(SYS)),) samples: $(EXELIST_$(SYS)) @@ -49,8 +50,13 @@ else @echo > $(NULLDEV) endif +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 clean: + @$(DEL) kimSieve.bin 2>$(NULLDEV) @$(DEL) kimHello.bin 2>$(NULLDEV) + diff --git a/samples/kim1/kimSieve.c b/samples/kim1/kimSieve.c new file mode 100644 index 000000000..29cd7c7e9 --- /dev/null +++ b/samples/kim1/kimSieve.c @@ -0,0 +1,125 @@ +#include +#include + +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; +} From cb8cb876ec741c96b506f03539165b12b5d342e7 Mon Sep 17 00:00:00 2001 From: Rutger van Bergen Date: Mon, 19 Sep 2022 19:56:57 +0200 Subject: [PATCH 3/4] Add documentation, make capitalization uniform --- asminc/kim1.inc | 13 ++-- cfg/kim1-60k.cfg | 6 +- cfg/kim1.cfg | 2 +- doc/index.sgml | 3 + doc/kim1.sgml | 148 ++++++++++++++++++++++++++++++++++++++++ libsrc/kim1/crt0.s | 4 +- samples/kim1/kimHello.c | 2 +- src/common/target.h | 2 +- 8 files changed, 165 insertions(+), 15 deletions(-) create mode 100644 doc/kim1.sgml diff --git a/asminc/kim1.inc b/asminc/kim1.inc index f0d1555a7..b1046b01c 100644 --- a/asminc/kim1.inc +++ b/asminc/kim1.inc @@ -7,22 +7,21 @@ RAMSTART := $0200 ; Entry point + ; --------------------------------------------------------------------------- ; Monitor Functions ; --------------------------------------------------------------------------- - - OUTCHR := $1EA0 ; Output character INTCHR := $1E5A ; Input character without case conversion DUMPT := $1800 ; Dump memory to tape LOADT := $1873 ; Load memory from tape + + +; --------------------------------------------------------------------------- +; System Memory +; --------------------------------------------------------------------------- SAL := $17F5 ; Tape load address low SAH := $17F6 ; Tape load address high EAL := $17F7 ; Tape address end low EAH := $17F8 ; Tape address end high ID := $17F9 ; Tape Identification number - -; --------------------------------------------------------------------------- -; System Memory -; --------------------------------------------------------------------------- - diff --git a/cfg/kim1-60k.cfg b/cfg/kim1-60k.cfg index a6704d9dd..087715560 100644 --- a/cfg/kim1-60k.cfg +++ b/cfg/kim1-60k.cfg @@ -1,8 +1,8 @@ -# kim1.cfg (4k) +# kim1-60k.cfg (4k) # -# for unexpanded Kim-1 +# for expanded KIM-1 # -# ld65 --config kim1.cfg -o .bin .o +# ld65 --config kim1-60k.cfg -o .bin .o FEATURES { STARTADDRESS: default = $2000; diff --git a/cfg/kim1.cfg b/cfg/kim1.cfg index 69636065e..f48fed80e 100644 --- a/cfg/kim1.cfg +++ b/cfg/kim1.cfg @@ -1,6 +1,6 @@ # kim1.cfg (4k) # -# for unexpanded Kim-1 +# for unexpanded KIM-1 # # ld65 --config kim1.cfg -o .bin .o diff --git a/doc/index.sgml b/doc/index.sgml index bb3ad5357..bfce63486 100644 --- a/doc/index.sgml +++ b/doc/index.sgml @@ -154,6 +154,9 @@ Topics specific to the Bit Corporation Gamate Console. + + Topics specific to the MOS Technology KIM-1. + Topics specific to the Atari Lynx Game Console. diff --git a/doc/kim1.sgml b/doc/kim1.sgml new file mode 100644 index 000000000..0c8b54311 --- /dev/null +++ b/doc/kim1.sgml @@ -0,0 +1,148 @@ + + +
+MOS Technology KIM-1 specific information for cc65 +<author><url url="mailto:dave@davepl.com" name="Dave Plummer"> + +<abstract> +An overview over the KIM-1 runtime system as it is implemented for the cc65 C compiler. +</abstract> + +<!-- Table of contents --> +<toc> + +<!-- Begin the document --> + +<sect>Overview<p> + +This file contains an overview of the KIM-1 runtime system as it comes with the cc65 C compiler. +It describes the memory layout, KIM-1 specific header files, available drivers, and any pitfalls +specific to the platform. + +Please note that KIM-1 specific functions are just mentioned here, they are described in detail +in the separate <url url="funcref.html" name="function reference">. Even functions marked as +"platform dependent" may be available on more than one platform. Please see the +function reference for more information. + +<sect>Binary format<p> + +The output format generated by the linker for the KIM-1 target is a raw binary BIN file, which +is essentially a memory image. You can convert this to a papertape format file using +Convert8bithexformat or KIMPaper, which are open-source conversion utility programs. +A papertape format files can be transferred to the KIM-1 using the RS-232 terminal port (TTY), +just as if the machine-code was entered by hand. Enter 'L' in the TTY and start the paper tape file +transfer. + +<p> + +Included with this distribution is a 4k configuration file and a 60k config file. The KIM-1 +on-board memory is limited to 4 kbytes but system memory can be increased to 60 kbytes of +contiguous RAM with aftermarket add-on boards. So choose the config file that matches your +system configuration before compiling and linking user programs. + +<sect>Memory layout<p> + +The ROMs and I/O areas are defined in the configuration files, as are most of the entry points +for useful subroutines in the KIM-1 monitor ROM. cc65 generated programs compiled and linked +using 4k config run in the memory range of $200 - $0FFF. The 60k config expands +this range to $DFFF. The starting memory location and entry point for running the program is +$200, so when the program is transferred to the KIM-1, it is executed by typing '200 G'. + +Special locations: + +<descrip> + <tag/Text screen/ + Conio support is not currently available for the KIM-1. But stdio console functions are available. + + <tag/Stack/ + The C runtime stack is located at $0FFF on 4kb KIM-1s, or at $DFFF for 60kb systems. + The stack always grows downwards. + + <tag/Heap/ + The C heap is located at the end of the program and grows towards the C runtime stack. + +</descrip><p> + +<sect>Platform specific header files<p> + +Programs containing KIM-1 code may use the <tt/kim.h/ header file. See the header file for more information. + +<sect>Loadable drivers<p> + +<sect1>Graphics drivers<p> + +No graphics drivers are currently available for the KIM-1. + +<sect1>Joystick drivers<p> + +No joystick driver is currently available for the KIM-1. + +<sect1>Mouse drivers<p> + +No mouse drivers are currently available for the KIM-1. + +<sect1>RS232 device drivers<p> + +No communication port drivers are currently available for the KIM-1. It has only the "master console" +e.g. stdin and stdout. + +<sect>Limitations<p> + +<sect1>Disk I/O<p> + +The existing library for the KIM-1 doesn't implement C file I/O. + +To be more specific, this limitation means that you cannot use any of the following functions (and a few others): + +<itemize> +<item>fopen +<item>fclose +<item>fread +<item>fwrite +<item>... +</itemize> + +<sect>Other hints<p> + +<sect1>kim1.h<p> +This header exposes KIM-1 specific I/O functions that are useful for reading and writing its ports and front panel. +See the <tt/kim1.h/ include file for a list of the functions available. + +<sect1>Limited memory applications<p> + +As stated earlier, there are config files for 4kb and 60kb systems. If you have 60kb RAM, then you will probably +want to use the kim1-60k configuration, but if not - if you are using the kim1-4k configuration - then you may +want to use functions like getchar, putchar, gets and puts rather than functions like scanf and printf. +Printf, for example, requires about 1KB because it needs to know how to process all the format specifiers. + +<sect1>Sample programs<p> + +These sample programs can be found in the samples/kim1 directory: + +<itemize> +<item>kimHello prints "Hello World!" and then inputs characters, which are echoed on the screen. + This program will run on both 4kb and 60kb systems.</item> +<item>kimSieve finds the prime numbers up to 100,000 using the Sieve of Eratosthenes algorithm, and prints how many + prime numbers were found. This program requires a 60kb system to run.</item> +</itemize> + +<sect>License<p> + +This software is provided 'as-is', without any expressed or implied warranty. In no event will the authors be held +liable for any damages arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter +it and redistribute it freely, subject to the following restrictions: + +<enum> +<item> The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. +<item> Altered source versions must be plainly marked as such, and must not + be misrepresented as being the original software. +<item> This notice may not be removed or altered from any source + distribution. +</enum> + +</article> diff --git a/libsrc/kim1/crt0.s b/libsrc/kim1/crt0.s index aefdc3545..f1fee86c1 100644 --- a/libsrc/kim1/crt0.s +++ b/libsrc/kim1/crt0.s @@ -40,8 +40,8 @@ _init: cld ; Clear decimal mode jsr _main -; Back from main (this is also the _exit entry). There may be a more elegant way to9 -; return to the monitor on the Kim-1, but I don't know it! +; Back from main (this is also the _exit entry). There may be a more elegant way to +; return to the monitor on the KIM-1, but I don't know it! _exit: brk diff --git a/samples/kim1/kimHello.c b/samples/kim1/kimHello.c index dcbfb4e67..0dca1345f 100644 --- a/samples/kim1/kimHello.c +++ b/samples/kim1/kimHello.c @@ -1,5 +1,5 @@ // -------------------------------------------------------------------------- -// Hello World for Kim-1 +// Hello World for KIM-1 // // Dave Plummer based on Sym-1 sample by Wayne Parham // diff --git a/src/common/target.h b/src/common/target.h index 7439fa621..0cec74b6e 100644 --- a/src/common/target.h +++ b/src/common/target.h @@ -87,7 +87,7 @@ typedef enum { TGT_C65, TGT_CX16, TGT_SYM1, - TGT_KIM1, // Added at end so as not to shift existing entries + TGT_KIM1, TGT_COUNT /* Number of target systems */ } target_t; From ab6840712b88e8c0249563d350c0b63d901a4a54 Mon Sep 17 00:00:00 2001 From: David W Plummer <davepl@davepl.com> Date: Mon, 19 Sep 2022 14:17:41 -0700 Subject: [PATCH 4/4] Update kim1.sgml --- doc/kim1.sgml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/kim1.sgml b/doc/kim1.sgml index 0c8b54311..6db9fc908 100644 --- a/doc/kim1.sgml +++ b/doc/kim1.sgml @@ -2,10 +2,10 @@ <article> <title>MOS Technology KIM-1 specific information for cc65 -<author><url url="mailto:dave@davepl.com" name="Dave Plummer"> +<author><url url="mailto:davepl@davepl.com" name="Dave Plummer"> <abstract> -An overview over the KIM-1 runtime system as it is implemented for the cc65 C compiler. +An overview of the KIM-1 runtime system as it is implemented for the cc65 C compiler. </abstract> <!-- Table of contents -->