mirror of
https://github.com/cc65/cc65.git
synced 2025-04-01 02:31:56 +00:00
Add KIM-1 Support
This commit is contained in:
parent
30dc9b8d1a
commit
799aec23a6
28
asminc/kim1.inc
Normal file
28
asminc/kim1.inc
Normal file
@ -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
|
||||
; ---------------------------------------------------------------------------
|
||||
|
41
cfg/kim1.cfg
Normal file
41
cfg/kim1.cfg
Normal file
@ -0,0 +1,41 @@
|
||||
# kim1.cfg (4k)
|
||||
#
|
||||
# for unexpanded Kim-1
|
||||
#
|
||||
# ld65 --config kim1.cfg -o <prog>.bin <prog>.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;
|
||||
}
|
||||
|
67
include/kim1.h
Normal file
67
include/kim1.h
Normal file
@ -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
|
@ -27,6 +27,7 @@ TARGETS = apple2 \
|
||||
$(CBMS) \
|
||||
$(GEOS) \
|
||||
gamate \
|
||||
kim1 \
|
||||
lynx \
|
||||
nes \
|
||||
none \
|
||||
|
47
libsrc/kim1/crt0.s
Normal file
47
libsrc/kim1/crt0.s
Normal file
@ -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
|
||||
|
5
libsrc/kim1/ctype.s
Normal file
5
libsrc/kim1/ctype.s
Normal file
@ -0,0 +1,5 @@
|
||||
; Character specification table.
|
||||
;
|
||||
; uses the "common" definition
|
||||
|
||||
.include "ctype_common.inc"
|
51
libsrc/kim1/read.s
Normal file
51
libsrc/kim1/read.s
Normal file
@ -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
|
39
libsrc/kim1/tapeio.s
Normal file
39
libsrc/kim1/tapeio.s
Normal file
@ -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
|
49
libsrc/kim1/write.s
Normal file
49
libsrc/kim1/write.s
Normal file
@ -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
|
@ -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 \
|
||||
|
56
samples/kim1/Makefile
Normal file
56
samples/kim1/Makefile
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
# 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
|
||||
|
||||
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)
|
BIN
samples/kim1/kimHello
Normal file
BIN
samples/kim1/kimHello
Normal file
Binary file not shown.
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;
|
||||
}
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -742,6 +742,7 @@ TARGETS := \
|
||||
creativision \
|
||||
cx16 \
|
||||
gamate \
|
||||
kim1 \
|
||||
lunix \
|
||||
lynx \
|
||||
nes \
|
||||
|
Loading…
x
Reference in New Issue
Block a user