summaryrefslogtreecommitdiff
path: root/device/lib/tlcs90
diff options
context:
space:
mode:
authorXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
committerXavier ASUS <xavi92psx@gmail.com>2019-10-18 00:31:54 +0200
commit268a53de823a6750d6256ee1fb1e7707b4b45740 (patch)
tree42c1799a9a82b2f7d9790ee9fe181d72a7274751 /device/lib/tlcs90
downloadsdcc-gas-268a53de823a6750d6256ee1fb1e7707b4b45740.tar.gz
sdcc-3.9.0 fork implementing GNU assembler syntax
This fork aims to provide better support for stm8-binutils
Diffstat (limited to 'device/lib/tlcs90')
-rw-r--r--device/lib/tlcs90/Makefile97
-rw-r--r--device/lib/tlcs90/Makefile.in97
-rw-r--r--device/lib/tlcs90/README9
-rw-r--r--device/lib/tlcs90/__sdcc_call_hl.s37
-rw-r--r--device/lib/tlcs90/__sdcc_call_iy.s37
-rw-r--r--device/lib/tlcs90/abs.s61
-rw-r--r--device/lib/tlcs90/crt0.s510
-rw-r--r--device/lib/tlcs90/crt0_org.s466
-rw-r--r--device/lib/tlcs90/crtenter.s41
-rw-r--r--device/lib/tlcs90/divmixed.s58
-rw-r--r--device/lib/tlcs90/divsigned.s133
-rw-r--r--device/lib/tlcs90/divunsigned.s138
-rw-r--r--device/lib/tlcs90/heap.s44
-rw-r--r--device/lib/tlcs90/modmixed.s62
-rw-r--r--device/lib/tlcs90/modsigned.s53
-rw-r--r--device/lib/tlcs90/modunsigned.s57
-rw-r--r--device/lib/tlcs90/mul.s70
-rw-r--r--device/lib/tlcs90/mulchar.s79
-rw-r--r--device/lib/tlcs90/setjmp.s96
-rw-r--r--device/lib/tlcs90/strcpy.s48
-rw-r--r--device/lib/tlcs90/strlen.s47
-rw-r--r--device/lib/tlcs90/t90regs.s49
22 files changed, 2289 insertions, 0 deletions
diff --git a/device/lib/tlcs90/Makefile b/device/lib/tlcs90/Makefile
new file mode 100644
index 0000000..3f2f0e5
--- /dev/null
+++ b/device/lib/tlcs90/Makefile
@@ -0,0 +1,97 @@
+# libc/tlcs90 Makefile
+
+
+srcdir = .
+top_builddir = ../../..
+
+LIB_TYPE = RANLIB
+
+SCC = $(top_builddir)/bin/sdcc -mtlcs90
+SAS = $(top_builddir)/bin/sdastlcs90
+
+# override PORTDIR defined by super (parent) makefile
+override PORTDIR = ../build/tlcs90
+
+include $(srcdir)/../incl.mk
+
+Z80_FLOAT = $(COMMON_FLOAT)
+
+Z80_INT = $(COMMON_INT)
+
+Z80_LONG = $(COMMON_LONG) \
+ _divulong.c \
+ _mullong.c
+
+Z80_LONGLONG = $(COMMON_LONGLONG) \
+ _mullonglong.c \
+ _divslonglong.c \
+ _divulonglong.c \
+ _modslonglong.c \
+ _modulonglong.c
+
+Z80_SDCC = $(COMMON_SDCC) \
+ _itoa.c \
+ _ltoa.c \
+ _startup.c \
+ sprintf.c \
+ vprintf.c \
+ _strcmp.c \
+ __memcpy.c \
+ memcpy.c \
+ _memmove.c
+
+Z80SOURCES = $(addprefix ../,$(Z80_FLOAT) $(Z80_INT) $(Z80_LONG) $(Z80_LONGLONG) $(Z80_SDCC))
+Z8OBJECTS = $(patsubst %.c,%.rel,$(Z80_FLOAT) $(Z80_INT) $(Z80_LONG) $(Z80_LONGLONG) $(Z80_SDCC))
+
+OBJ = divunsigned.rel divsigned.rel divmixed.rel modunsigned.rel modsigned.rel modmixed.rel mul.rel mulchar.rel \
+ heap.rel strcpy.rel strlen.rel abs.rel __sdcc_call_hl.rel __sdcc_call_iy.rel crtenter.rel \
+ setjmp.rel
+
+LIB = tlcs90.lib
+CC = $(SCC)
+AS = $(SAS)
+ASFLAGS = -plosgff
+
+CFLAGS = -I$(srcdir)/../../include -I. --std-c11
+
+all: $(PORTDIR)/$(LIB) $(PORTDIR)/crt0.rel
+
+$(PORTDIR)/crt0.rel: crt0.rel
+ cp crt0.rel $(PORTDIR)/crt0.rel
+
+$(PORTDIR)/$(LIB): $(OBJ) $(Z8OBJECTS) Makefile
+ifeq ($(LIB_TYPE), SDCCLIB)
+ rm -f $@; \
+ $(top_builddir)/bin/sdcclib -a $@ $(OBJ) $(Z8OBJECTS)
+else
+ ifeq ($(LIB_TYPE), AR)
+ $(top_builddir)/bin/sdar -rcSD $@ $(OBJ) $(Z8OBJECTS)
+ else
+ ifeq ($(LIB_TYPE), RANLIB)
+ $(top_builddir)/bin/sdar -rcD $@ $(OBJ) $(Z8OBJECTS)
+ else
+ rm -f $@; \
+ for i in $(basename $(OBJ) $(Z8OBJECTS)); do echo $$i >>$@; done
+ cp $(OBJ) $(Z8OBJECTS) $(PORTDIR)
+ endif
+ endif
+endif
+
+%.rel: %.c
+ $(CC) $(CFLAGS) -c $<
+
+%.rel: %.s
+ @# TODO: sdas should place it\'s output in the current dir
+ test $(srcdir) = . || cp $< .
+ -$(AS) $(ASFLAGS) -I$(dir $<) $(notdir $<)
+ test $(srcdir) = . || rm $(notdir $<)
+
+%.rel: ../%.c
+ $(CC) $(CFLAGS) -c $<
+
+clean:
+ rm -f *.rel *.sym *.lst *~ $(CLEANSPEC) *.dump* *.asm *.lib
+
+distclean: clean
+ rm -f Makefile
+
diff --git a/device/lib/tlcs90/Makefile.in b/device/lib/tlcs90/Makefile.in
new file mode 100644
index 0000000..885bb25
--- /dev/null
+++ b/device/lib/tlcs90/Makefile.in
@@ -0,0 +1,97 @@
+# libc/tlcs90 Makefile
+
+VPATH = @srcdir@
+srcdir = @srcdir@
+top_builddir = @top_builddir@
+
+LIB_TYPE = @LIB_TYPE@
+
+SCC = $(top_builddir)/bin/sdcc -mtlcs90
+SAS = $(top_builddir)/bin/sdastlcs90
+
+# override PORTDIR defined by super (parent) makefile
+override PORTDIR = ../build/tlcs90
+
+include $(srcdir)/../incl.mk
+
+Z80_FLOAT = $(COMMON_FLOAT)
+
+Z80_INT = $(COMMON_INT)
+
+Z80_LONG = $(COMMON_LONG) \
+ _divulong.c \
+ _mullong.c
+
+Z80_LONGLONG = $(COMMON_LONGLONG) \
+ _mullonglong.c \
+ _divslonglong.c \
+ _divulonglong.c \
+ _modslonglong.c \
+ _modulonglong.c
+
+Z80_SDCC = $(COMMON_SDCC) \
+ _itoa.c \
+ _ltoa.c \
+ _startup.c \
+ sprintf.c \
+ vprintf.c \
+ _strcmp.c \
+ __memcpy.c \
+ memcpy.c \
+ _memmove.c
+
+Z80SOURCES = $(addprefix ../,$(Z80_FLOAT) $(Z80_INT) $(Z80_LONG) $(Z80_LONGLONG) $(Z80_SDCC))
+Z8OBJECTS = $(patsubst %.c,%.rel,$(Z80_FLOAT) $(Z80_INT) $(Z80_LONG) $(Z80_LONGLONG) $(Z80_SDCC))
+
+OBJ = divunsigned.rel divsigned.rel divmixed.rel modunsigned.rel modsigned.rel modmixed.rel mul.rel mulchar.rel \
+ heap.rel strcpy.rel strlen.rel abs.rel __sdcc_call_hl.rel __sdcc_call_iy.rel crtenter.rel \
+ setjmp.rel
+
+LIB = tlcs90.lib
+CC = $(SCC)
+AS = $(SAS)
+ASFLAGS = -plosgff
+
+CFLAGS = -I$(srcdir)/../../include -I. --std-c11
+
+all: $(PORTDIR)/$(LIB) $(PORTDIR)/crt0.rel
+
+$(PORTDIR)/crt0.rel: crt0.rel
+ cp crt0.rel $(PORTDIR)/crt0.rel
+
+$(PORTDIR)/$(LIB): $(OBJ) $(Z8OBJECTS) Makefile
+ifeq ($(LIB_TYPE), SDCCLIB)
+ rm -f $@; \
+ $(top_builddir)/bin/sdcclib -a $@ $(OBJ) $(Z8OBJECTS)
+else
+ ifeq ($(LIB_TYPE), AR)
+ $(top_builddir)/bin/sdar -rcSD $@ $(OBJ) $(Z8OBJECTS)
+ else
+ ifeq ($(LIB_TYPE), RANLIB)
+ $(top_builddir)/bin/sdar -rcD $@ $(OBJ) $(Z8OBJECTS)
+ else
+ rm -f $@; \
+ for i in $(basename $(OBJ) $(Z8OBJECTS)); do echo $$i >>$@; done
+ cp $(OBJ) $(Z8OBJECTS) $(PORTDIR)
+ endif
+ endif
+endif
+
+%.rel: %.c
+ $(CC) $(CFLAGS) -c $<
+
+%.rel: %.s
+ @# TODO: sdas should place it\'s output in the current dir
+ test $(srcdir) = . || cp $< .
+ -$(AS) $(ASFLAGS) -I$(dir $<) $(notdir $<)
+ test $(srcdir) = . || rm $(notdir $<)
+
+%.rel: ../%.c
+ $(CC) $(CFLAGS) -c $<
+
+clean:
+ rm -f *.rel *.sym *.lst *~ $(CLEANSPEC) *.dump* *.asm *.lib
+
+distclean: clean
+ rm -f Makefile
+
diff --git a/device/lib/tlcs90/README b/device/lib/tlcs90/README
new file mode 100644
index 0000000..259ca6d
--- /dev/null
+++ b/device/lib/tlcs90/README
@@ -0,0 +1,9 @@
+sdcc/device/lib/z80
+-------------------
+
+Z80 specific routines.
+
+Notes:
+* Cost of ld r,(ix+n): 19
+* Cost of ld r,(hl); inc hl: 7+6 = 13 and you don't have to pop ix
+ \ No newline at end of file
diff --git a/device/lib/tlcs90/__sdcc_call_hl.s b/device/lib/tlcs90/__sdcc_call_hl.s
new file mode 100644
index 0000000..9086c7b
--- /dev/null
+++ b/device/lib/tlcs90/__sdcc_call_hl.s
@@ -0,0 +1,37 @@
+;--------------------------------------------------------------------------
+; crtcall.s
+;
+; Copyright (C) 2011, Maarten Brock
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+ .area _CODE
+
+ .globl ___sdcc_call_hl
+
+; The Z80 has the jp (hl) instruction, which is perfect for implementing function pointers.
+
+___sdcc_call_hl:
+ jp (hl)
+
diff --git a/device/lib/tlcs90/__sdcc_call_iy.s b/device/lib/tlcs90/__sdcc_call_iy.s
new file mode 100644
index 0000000..8941745
--- /dev/null
+++ b/device/lib/tlcs90/__sdcc_call_iy.s
@@ -0,0 +1,37 @@
+;--------------------------------------------------------------------------
+; crtcall.s
+;
+; Copyright (C) 2011, Maarten Brock, 2015 Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+ .area _CODE
+
+ .globl ___sdcc_call_iy
+
+; The Z80 has the jp (iy) instruction, which is perfect for implementing function pointers.
+
+___sdcc_call_iy:
+ jp (iy)
+
diff --git a/device/lib/tlcs90/abs.s b/device/lib/tlcs90/abs.s
new file mode 100644
index 0000000..2aaa541
--- /dev/null
+++ b/device/lib/tlcs90/abs.s
@@ -0,0 +1,61 @@
+;--------------------------------------------------------------------------
+; abs.s
+;
+; Copyright (C) 2010, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+ .area _CODE
+
+ .globl _abs
+
+; 12B; 86T for nonnegative arguments, 78T for negative.
+_abs:
+ pop hl
+ pop de
+ push de
+ push hl
+ xor a, a
+ ld l, a
+ ld h, a
+ sbc hl, de
+ ret P
+ ex de, hl
+ ret
+
+; 14B; 59T for nonegative arguments, 94T for negative:
+;_abs:
+; pop de
+; pop hl
+; push hl
+; push de
+; bit 7, h
+; ret Z
+; xor a, a
+; ld e, a
+; ld d, a
+; ex de, hl
+; sbc hl, de
+; ret
+
diff --git a/device/lib/tlcs90/crt0.s b/device/lib/tlcs90/crt0.s
new file mode 100644
index 0000000..6c31350
--- /dev/null
+++ b/device/lib/tlcs90/crt0.s
@@ -0,0 +1,510 @@
+;; crt0_asm.s - tlcs90
+
+ .t90
+
+ .module crt0
+
+; .globl _meminit
+ .globl _main
+ ;; .globl _xxaddr
+ ;; .globl _xxby
+ ;; .globl _xxdata
+
+; .globl _ser_putchar_irq
+; .globl _ser_puts
+
+ ;; put as abs in dat at end of file..
+ ;.globl _ser_irq_flags
+ ;.globl _ser_char
+
+; .globl _xget_byte_asm
+; .globl _xset_byte_asm
+
+
+ ;; for interrupts the pc and af are pushed on the stack
+
+; .globl _irq_info_swi
+; .globl _irq_info_intwd
+; .globl _irq_info_intt0
+; .globl _irq_info_intt1
+; .globl _timer1_irq
+; .globl _irq_info_intt3
+; .globl _irq_info_intt4
+; .globl _irq_info_int1
+; .globl _irq_info_intt5
+
+ .globl _ticks16
+ .globl _xflag
+
+ ;; NOTE: header might get trashed by linker when code loc ist not used!?
+ .area _HEADER (ABS)
+
+ .org 0
+
+ .include "t90regs.s"
+
+ ;; _ser_irq_flags
+TX_ACTIVE .equ 0
+RX_READY .equ 1
+
+L0:
+ ;halt
+ ;jr L0
+ jp _astart
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+L10:
+ ; SWI
+ ;jp _swi_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+
+L18:
+ nop ; NMI
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+L20:
+ ; INTWD
+ ;jp _intwd_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L28:
+ reti ; INT0
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+L30:
+ ; INTT0
+ ;jp _intt0_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L38:
+ ; INTT1
+ ;jp _intt1_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L40:
+ ; INTAD
+ reti
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+L48:
+ ; INTT3
+ ;jp _intt3_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L50:
+ ; INTT4
+ ;jp _intt4_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L58:
+ ; INT1
+ ;jp _int1_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L60:
+ ; INTT5
+ ;jp _intt5_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L68:
+ reti ; INT2
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+L70:
+ ;jp _serial_rx_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L78:
+ ;jp _serial_tx_irq
+ nop
+ nop
+ nop
+
+ nop
+ nop
+ nop
+ nop
+ nop
+L80:
+ nop
+
+ .org 0x100
+
+_astart:
+ ld sp, #0x0FFA0 ; stack
+
+ ;halt
+ ;swi
+
+; or (P01CR), #0x04 ;
+
+; ld (P3), #0xF7
+; ld (P3CR), #0xA5 ; P30 = RXD, P31 = IN:PaperOut CN3, P32 = TXD, P33 = OUT:CN2.LF P34:IN, P37:IN
+
+; ld (P4), #0x00
+; ld (P4CR), #0x03 ; address output
+; ld (P7), #0x03
+; ld (P67CR), #0xF0
+; ld (SMMOD), #0xA0
+; ld (SMCR), #0x00
+; ld (T4MOD), #0x35
+; ld (P8), #0x08
+; ld (P8CR), #0x08
+; ld (T4FFCR), #0x01
+
+; ld (TMOD), #0x40
+
+ ;ld (SCMOD), #0x03 ; 9600
+; ld (SCMOD), #0x01 ; 19200
+; or (SCMOD), #0x08 ; 8-bit data
+; or (SCMOD), #0x20 ; receiver enable
+
+; ld (SCCR), #0x00
+
+; ld (WDMOD), #0xC0
+; ld (TRUN), #0x20 ; PRRUN, start prescaler
+; or (TRUN), #0xE0 ; BRATE, 19200 baud
+
+ ;; enable rx/tx irqs
+; set 0,(INTEL) ; tx
+; set 1,(INTEL) ; rx
+
+ ;call _boot1
+
+ ld hl, #s__DATA ; data start
+ ld a, #0x00
+
+clear_ram:
+ call _wd_reset_asm
+
+ cp hl, #0xFFC0 ; io start, 160 bytes data
+ jr z, zeroed_data
+
+ ld (hl),a
+ inc hl
+
+ jr clear_ram
+zeroed_data:
+
+ call _wd_reset_asm
+
+; res TX_ACTIVE,(_ser_irq_flags)
+
+ ;call _boot2
+; call _meminit
+
+ call _wd_reset_asm
+
+ ;; Initialise global variables
+
+ ;call _boot3
+
+ call gsinit
+
+ ;call _boot4
+
+ call _main
+ halt
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ .area _CODE
+
+ ;; get far byte using by
+
+;; _xget_byte_asm:
+;; push bc
+;; ld iy, (_xxaddr)
+;; ld b, (BY)
+;; ld a, (_xxby)
+;; ld (BY), a
+;; ld a,(iy)
+;; ld (BY), b
+;; ld (_xxdata), a
+;; pop bc
+;; ret
+
+;; _xset_byte_asm:
+;; push bc
+;; ld iy, (_xxaddr)
+;; ld b, (BY)
+;; ld a, (_xxby)
+;; ld (BY), a
+;; ld a, (_xxdata)
+;; ld (iy), a
+;; ld (BY), b
+;; pop bc
+;; ret
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; _serial_rx_irq:
+;; ld a, (SCBUF)
+;; ld (_ser_char), a
+;; set RX_READY, (_ser_irq_flags)
+;; reti
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; _serial_tx_irq:
+;; res TX_ACTIVE,(_ser_irq_flags)
+;; ld (IRFH), #0x0F ; clear tx request flag (vector 0x78/8 = 0x0F)
+;; reti
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; _swi_irq:
+;; push hl
+;; ld hl, 4(sp)
+;; ld (_swi_pc), hl ; pc
+;; ld hl, 2(sp)
+;; ld (_swi_af), hl ; af
+;; call _irq_info_swi
+;; pop hl
+;; reti
+;; _intwd_irq:
+;; call _irq_info_intwd
+;; reti
+;; _intt0_irq:
+;; call _irq_info_intt0
+;; reti
+;; _intt1_irq:
+;; ;call _irq_info_intt1
+;; ;exx
+
+;; ; hangs when exx is used?
+;; incw (_ticks16)
+
+;; ; hangs when exx is used?
+;; ;; ld hl, (_ticks16)
+;; ;; inc hl
+;; ;; ld (_ticks16), hl
+
+;; ld (WDCR), #0x4E
+;; ld (IRFL), #0x10;
+;; ;call _timer1_irq
+;; ;exx
+;; reti
+;; _intt3_irq:
+;; call _irq_info_intt3
+;; reti
+;; _intt4_irq:
+;; call _irq_info_intt4
+;; reti
+;; _int1_irq:
+;; call _irq_info_int1
+;; reti
+;; _intt5_irq:
+;; call _irq_info_intt5
+;; reti
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; _ser_putchar_irq:
+;; ld a, 2(sp)
+
+;; _ser_putchar_asm:
+
+;; loop1:
+
+;; ;; check tx active flag
+;; bit TX_ACTIVE,(_ser_irq_flags)
+;; jr z, send1
+
+;; di
+;; bit 0,(IRFH) ; check irq
+;; jr nz, send1
+;; ei
+
+;; nop
+;; nop
+;; call _wd_reset_asm
+;; jr loop1 ; loop, wait for irq
+
+;; send1:
+;; di
+;; ld (IRFH),#0x0F ; clear tx request flag (vector 0x78/8 = 0x0F)
+;; ld (SCBUF),a ; send
+;; set TX_ACTIVE,(_ser_irq_flags) ; tx active..
+;; ei
+;; ret
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;; _ser_puts:
+;; ld hl, 2(sp)
+
+;; ser_puts1:
+;; ld a,(hl)
+;; or a, a
+;; ret z
+
+;; call _ser_putchar_asm
+;; inc hl
+;; jr ser_puts1
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+_WatchDogDisable:
+ ld (WDMOD), #0x00 ; wd disable code
+ ld (WDCR), #0xB1 ; wd disable code
+ ret
+
+_wd_reset_asm:
+ ld (WDCR), #0x4E ; wd clear code
+
+.if 0
+ ; STAR ASIC? Not needed..
+ push bc
+ push iy
+
+ ld b,(BY)
+ ld (BY), #0x01
+ ld iy, #0x4001
+ set 1,(iy)
+ nop
+ nop
+ res 1,(iy)
+ ld (BY),b
+
+ pop iy
+ pop bc
+
+.endif
+
+ ret
+
+ ;; Ordering of segments for the linker.
+ .area _HOME
+ .area _CODE
+ .area _INITIALIZER
+ .area _GSINIT
+ .area _GSFINAL
+
+ .area _DATA
+ .area _INITIALIZED
+ .area _BSEG
+ .area _BSS
+ .area _HEAP
+
+ .area _CODE
+
+ .area _GSINIT
+gsinit::
+ ld bc, #l__INITIALIZER
+ ld a, b
+ or a, c
+ jr Z, gsinit_next
+ ld de, #s__INITIALIZED
+ ld hl, #s__INITIALIZER
+ ldir
+gsinit_next:
+
+ .area _GSFINAL
+ ret
+
+ .area _DATA
+; __sfr __at
+_ser_irq_flags = 0xffbf
+_ser_char = 0xffbe
+_swi_pc = 0xffbc
+_swi_af = 0xffba
+_ticks16 = 0xffb8
+_xflag = 0xffb7
+
diff --git a/device/lib/tlcs90/crt0_org.s b/device/lib/tlcs90/crt0_org.s
new file mode 100644
index 0000000..fbb750f
--- /dev/null
+++ b/device/lib/tlcs90/crt0_org.s
@@ -0,0 +1,466 @@
+;; crt0_asm.s - tlcs90
+
+ .t90
+
+ .module crt0
+
+ .globl _meminit
+ .globl _main
+ .globl _xxaddr
+ .globl _xxby
+ .globl _xxdata
+
+ .globl _ser_putchar_irq
+ .globl _ser_puts
+
+ ;; put as abs in dat at end of file..
+ ;.globl _ser_irq_flags
+ ;.globl _ser_char
+
+ .globl _xget_byte_asm
+ .globl _xset_byte_asm
+
+
+ ;; for interrupts the pc and af are pushed on the stack
+
+ .globl _irq_info_swi
+ .globl _irq_info_intwd
+ .globl _irq_info_intt0
+ .globl _irq_info_intt1
+ .globl _timer1_irq
+ .globl _irq_info_intt3
+ .globl _irq_info_intt4
+ .globl _irq_info_int1
+ .globl _irq_info_intt5
+
+ .globl _ticks16
+ .globl _xflag
+
+ ;; NOTE: header might get trashed by linker when code loc ist not used!?
+ .area _HEADER (ABS)
+
+ .org 0
+
+ .include "t90regs.s"
+
+ ;; _ser_irq_flags
+TX_ACTIVE .equ 0
+RX_READY .equ 1
+
+L0:
+ ;halt
+ ;jr L0
+ jp _astart
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+L10:
+ ; SWI
+ jp _swi_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+
+L18:
+ nop ; NMI
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+L20:
+ ; INTWD
+ jp _intwd_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L28:
+ reti ; INT0
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+L30:
+ ; INTT0
+ jp _intt0_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L38:
+ ; INTT1
+ jp _intt1_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L40:
+ ; INTAD
+ reti
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+L48:
+ ; INTT3
+ jp _intt3_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L50:
+ ; INTT4
+ jp _intt4_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L58:
+ ; INT1
+ jp _int1_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L60:
+ ; INTT5
+ jp _intt5_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L68:
+ reti ; INT2
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+L70:
+ jp _serial_rx_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L78:
+ jp _serial_tx_irq
+ nop
+ nop
+ nop
+ nop
+ nop
+L80:
+ nop
+
+ .org 0x100
+
+_astart:
+ ld sp, #0x0FFA0 ; stack
+
+ ;halt
+ ;swi
+
+ or (P01CR), #0x04
+
+ ld (P3), #0xF7
+ ld (P3CR), #0xA5 ; P30 = RXD, P31 = IN:PaperOut CN3, P32 = TXD, P33 = OUT:CN2.LF P34:IN, P37:IN
+
+ ld (P4), #0x00
+ ld (P4CR), #0x03 ; address output
+ ld (P7), #0x03
+ ld (P67CR), #0xF0
+ ld (SMMOD), #0xA0
+ ld (SMCR), #0x00
+ ld (T4MOD), #0x35
+ ld (P8), #0x08
+ ld (P8CR), #0x08
+ ld (T4FFCR), #0x01
+
+ ld (TMOD), #0x40
+
+ ;ld (SCMOD), #0x03 ; 9600
+ ld (SCMOD), #0x01 ; 19200
+ or (SCMOD), #0x08 ; 8-bit data
+ or (SCMOD), #0x20 ; receiver enable
+
+ ld (SCCR), #0x00
+
+ ld (WDMOD), #0xC0
+ ld (TRUN), #0x20 ; PRRUN, start prescaler
+ or (TRUN), #0xE0 ; BRATE, 19200 baud
+
+ ;; enable rx/tx irqs
+ set 0,(INTEL) ; tx
+ set 1,(INTEL) ; rx
+
+ ;call _boot1
+
+ ld hl, #0xFF20 ; data start
+ ld a, #0x00
+
+clear_ram:
+ call _wd_reset_asm
+
+ ld (hl),a
+ inc hl
+ cp hl, #0xFFC0 ; io start, 160 bytes data
+ jr nz, clear_ram
+
+ call _wd_reset_asm
+
+ res TX_ACTIVE,(_ser_irq_flags)
+
+ ;call _boot2
+ call _meminit
+
+ call _wd_reset_asm
+
+ ;; Initialise global variables
+
+ ;call _boot3
+
+ call gsinit
+
+ ;call _boot4
+
+ call _main
+ halt
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+ .area _CODE
+
+ ;; get far byte using by
+
+_xget_byte_asm:
+ push bc
+ ld iy, (_xxaddr)
+ ld b, (BY)
+ ld a, (_xxby)
+ ld (BY), a
+ ld a,(iy)
+ ld (BY), b
+ ld (_xxdata), a
+ pop bc
+ ret
+
+_xset_byte_asm:
+ push bc
+ ld iy, (_xxaddr)
+ ld b, (BY)
+ ld a, (_xxby)
+ ld (BY), a
+ ld a, (_xxdata)
+ ld (iy), a
+ ld (BY), b
+ pop bc
+ ret
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+_serial_rx_irq:
+ ld a, (SCBUF)
+ ld (_ser_char), a
+ set RX_READY, (_ser_irq_flags)
+ reti
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+_serial_tx_irq:
+ res TX_ACTIVE,(_ser_irq_flags)
+ ld (IRFH), #0x0F ; clear tx request flag (vector 0x78/8 = 0x0F)
+ reti
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+_swi_irq:
+ push hl
+ ld hl, 4(sp)
+ ld (_swi_pc), hl ; pc
+ ld hl, 2(sp)
+ ld (_swi_af), hl ; af
+ call _irq_info_swi
+ pop hl
+ reti
+_intwd_irq:
+ call _irq_info_intwd
+ reti
+_intt0_irq:
+ call _irq_info_intt0
+ reti
+_intt1_irq:
+ ;call _irq_info_intt1
+ ;exx
+
+ ; hangs when exx is used?
+ incw (_ticks16)
+
+ ; hangs when exx is used?
+ ;; ld hl, (_ticks16)
+ ;; inc hl
+ ;; ld (_ticks16), hl
+
+ ld (WDCR), #0x4E
+ ld (IRFL), #0x10;
+ ;call _timer1_irq
+ ;exx
+ reti
+_intt3_irq:
+ call _irq_info_intt3
+ reti
+_intt4_irq:
+ call _irq_info_intt4
+ reti
+_int1_irq:
+ call _irq_info_int1
+ reti
+_intt5_irq:
+ call _irq_info_intt5
+ reti
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+_ser_putchar_irq:
+ ld a, 2(sp)
+
+_ser_putchar_asm:
+
+loop1:
+
+ ;; check tx active flag
+ bit TX_ACTIVE,(_ser_irq_flags)
+ jr z, send1
+
+ di
+ bit 0,(IRFH) ; check irq
+ jr nz, send1
+ ei
+
+ nop
+ nop
+ call _wd_reset_asm
+ jr loop1 ; loop, wait for irq
+
+send1:
+ di
+ ld (IRFH),#0x0F ; clear tx request flag (vector 0x78/8 = 0x0F)
+ ld (SCBUF),a ; send
+ set TX_ACTIVE,(_ser_irq_flags) ; tx active..
+ ei
+ ret
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+_ser_puts:
+ ld hl, 2(sp)
+
+ser_puts1:
+ ld a,(hl)
+ or a, a
+ ret z
+
+ call _ser_putchar_asm
+ inc hl
+ jr ser_puts1
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+_WatchDogDisable:
+ ld (WDMOD), #0x00 ; wd disable code
+ ld (WDCR), #0xB1 ; wd disable code
+ ret
+
+_wd_reset_asm:
+ ld (WDCR), #0x4E ; wd clear code
+
+.if 0
+ ; STAR ASIC? Not needed..
+ push bc
+ push iy
+
+ ld b,(BY)
+ ld (BY), #0x01
+ ld iy, #0x4001
+ set 1,(iy)
+ nop
+ nop
+ res 1,(iy)
+ ld (BY),b
+
+ pop iy
+ pop bc
+
+.endif
+
+ ret
+
+ ;; Ordering of segments for the linker.
+ .area _HOME
+ .area _CODE
+ .area _INITIALIZER
+ .area _GSINIT
+ .area _GSFINAL
+
+ .area _DATA
+ .area _INITIALIZED
+ .area _BSEG
+ .area _BSS
+ .area _HEAP
+
+ .area _CODE
+
+ .area _GSINIT
+gsinit::
+ ld bc, #l__INITIALIZER
+ ld a, b
+ or a, c
+ jr Z, gsinit_next
+ ld de, #s__INITIALIZED
+ ld hl, #s__INITIALIZER
+ ldir
+gsinit_next:
+
+ .area _GSFINAL
+ ret
+
+ .area _DATA
+; __sfr __at
+_ser_irq_flags = 0xffbf
+_ser_char = 0xffbe
+_swi_pc = 0xffbc
+_swi_af = 0xffba
+_ticks16 = 0xffb8
+_xflag = 0xffb7
+
diff --git a/device/lib/tlcs90/crtenter.s b/device/lib/tlcs90/crtenter.s
new file mode 100644
index 0000000..0be714a
--- /dev/null
+++ b/device/lib/tlcs90/crtenter.s
@@ -0,0 +1,41 @@
+;--------------------------------------------------------------------------
+; crtenter.s
+;
+; Copyright (C) 2015, Alan Cox, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+ .area _CODE
+
+ .globl ___sdcc_enter_ix
+
+; Factor out some start of function code to reduce code size
+
+___sdcc_enter_ix:
+ pop hl ; return address
+ push ix ; save frame pointer
+ ld ix, #0
+ add ix, sp ; set ix to the stack frame
+ jp (hl) ; and return
+
diff --git a/device/lib/tlcs90/divmixed.s b/device/lib/tlcs90/divmixed.s
new file mode 100644
index 0000000..f7c983c
--- /dev/null
+++ b/device/lib/tlcs90/divmixed.s
@@ -0,0 +1,58 @@
+;--------------------------------------------------------------------------
+; divmixed.s
+;
+; Copyright (C) 2010, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+.globl __divsuchar
+.globl __divuschar
+
+__divsuchar:
+ ld hl, #2+1
+ add hl, sp
+
+ ld e, (hl)
+ dec hl
+ ld l, (hl)
+ ld h, #0
+
+ jp __div_signexte
+
+__divuschar:
+ ld hl, #2+1
+ ld d, h
+ add hl, sp
+
+ ld e, (hl)
+ dec hl
+ ld l, (hl)
+
+ ld a, l ; Sign extend
+ rlca
+ sbc a, a
+ ld h, a
+
+ jp __div16
+
diff --git a/device/lib/tlcs90/divsigned.s b/device/lib/tlcs90/divsigned.s
new file mode 100644
index 0000000..8699ab3
--- /dev/null
+++ b/device/lib/tlcs90/divsigned.s
@@ -0,0 +1,133 @@
+;--------------------------------------------------------------------------
+; divsigned.s
+;
+; Copyright (C) 2000-2010, Michael Hope, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+.area _CODE
+
+.globl __divsint
+.globl __divschar
+
+__divsint:
+ ld hl, 2 (sp)
+ ld de, 4 (sp)
+
+ jp __div16
+
+__divschar:
+ ld hl, #2+1
+ add hl, sp
+
+ ld e, (hl)
+ dec hl
+ ld l, (hl)
+
+__div8::
+ ld a, l ; Sign extend
+ rlca
+ sbc a, a
+ ld h, a
+__div_signexte::
+ ld a, e ; Sign extend
+ rlca
+ sbc a, a
+ ld d, a
+ ; Fall through to __div16
+
+ ;; signed 16-bit division
+ ;;
+ ;; Entry conditions
+ ;; HL = dividend
+ ;; DE = divisor
+ ;;
+ ;; Exit conditions
+ ;; HL = quotient
+ ;; DE = remainder
+ ;;
+ ;; Register used: AF,B,DE,HL
+__div16::
+ ;; Determine sign of quotient by xor-ing high bytes of dividend
+ ;; and divisor. Quotient is positive if signs are the same, negative
+ ;; if signs are different
+ ;; Remainder has same sign as dividend
+ ld a, h ; Get high byte of dividend
+ xor a, d ; Xor with high byte of divisor
+ rla ; Sign of quotient goes into the carry
+ ld a, h ; Get high byte of dividend
+ push af ; Save sign of both quotient and reminder
+
+ ; Take absolute value of dividend
+ rla
+ jr NC, .chkde ; Jump if dividend is positive
+ sub a, a ; Substract dividend from 0
+ sub a, l
+ ld l, a
+ sbc a, a ; Propagate borrow (A=0xFF if borrow)
+ sub a, h
+ ld h, a
+
+ ; Take absolute value of divisor
+.chkde:
+ bit 7, d
+ jr Z, .dodiv ; Jump if divisor is positive
+ sub a, a ; Subtract divisor from 0
+ sub a, e
+ ld e, a
+ sbc a, a ; Propagate borrow (A=0xFF if borrow)
+ sub a, d
+ ld d, a
+
+ ; Divide absolute values
+.dodiv:
+ call __divu16
+
+.fix_quotient:
+ ; Negate quotient if it is negative
+ pop af ; recover sign of quotient
+ ret NC ; Jump if quotient is positive
+ ld b, a
+ sub a, a ; Subtract quotient from 0
+ sub a, l
+ ld l, a
+ sbc a, a ; Propagate borrow (A=0xFF if borrow)
+ sub a, h
+ ld h, a
+ ld a, b
+ ret
+
+__get_remainder::
+ ; Negate remainder if it is negative and move it into hl
+ rla
+ ex de, hl
+ ret NC ; Return if remainder is positive
+ sub a, a ; Subtract remainder from 0
+ sub a, l
+ ld l, a
+ sbc a, a ; Propagate remainder (A=0xFF if borrow)
+ sub a, h
+ ld h, a
+ ret
+
diff --git a/device/lib/tlcs90/divunsigned.s b/device/lib/tlcs90/divunsigned.s
new file mode 100644
index 0000000..dd160ba
--- /dev/null
+++ b/device/lib/tlcs90/divunsigned.s
@@ -0,0 +1,138 @@
+;--------------------------------------------------------------------------
+; divunsigned.s
+;
+; Copyright (C) 2000-2012, Michael Hope, Philipp Klaus Krause, Marco Bodrato
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+ ;; Originally from GBDK by Pascal Felber.
+
+.area _CODE
+
+.globl __divuint
+.globl __divuchar
+
+__divuint:
+ ld hl, 2 (sp)
+ ld de, 4 (sp)
+
+ jr __divu16
+
+__divuchar:
+ ld hl,#2+1
+ add hl,sp
+
+ ld e,(hl)
+ dec hl
+ ld l,(hl)
+
+__divu8::
+ ld h,#0x00
+ ld d,h
+ ; Fall through to __divu16
+
+ ;; unsigned 16-bit division
+ ;;
+ ;; Entry conditions
+ ;; HL = dividend
+ ;; DE = divisor
+ ;;
+ ;; Exit conditions
+ ;; HL = quotient
+ ;; DE = remainder
+ ;; carry = 0
+ ;; If divisor is 0, quotient is set to "infinity", i.e HL = 0xFFFF.
+ ;;
+ ;; Register used: AF,B,DE,HL
+__divu16::
+ ;; Two algorithms: one assumes divisor <2^7, the second
+ ;; assumes divisor >=2^7; choose the applicable one.
+ ld a,e
+ and a,#0x80
+ or a,d
+ jr NZ,.morethan7bits
+ ;; Both algorithms "rotate" 24 bits (H,L,A) but roles change.
+
+ ;; unsigned 16/7-bit division
+.atmost7bits:
+ ld b,#16 ; bits in dividend and possible quotient
+ ;; Carry cleared by AND/OR, this "0" bit will pass trough HL.[*]
+ adc hl,hl
+.dvloop7:
+ ;; HL holds both dividend and quotient. While we shift a bit from
+ ;; MSB of dividend, we shift next bit of quotient in from carry.
+ ;; A holds remainder.
+ rla
+
+ ;; If remainder is >= divisor, next bit of quotient is 1. We try
+ ;; to compute the difference.
+ sub a,e
+ jr NC,.nodrop7 ; Jump if remainder is >= dividend
+ add a,e ; Otherwise, restore remainder
+ ;; The add above sets the carry, because sbc a,e did set it.
+.nodrop7:
+ ccf ; Complement borrow so 1 indicates a
+ ; successful substraction (this is the
+ ; next bit of quotient)
+ adc hl,hl
+ djnz .dvloop7
+ ;; Carry now contains the same value it contained before
+ ;; entering .dvloop7[*]: "0" = valid result.
+ ld e,a ; DE = remainder, HL = quotient
+ ret
+
+.morethan7bits:
+ ld b,#9 ; at most 9 bits in quotient.
+ ld a,l ; precompute the first 7 shifts, by
+ ld l,h ; doing 8
+ ld h,#0
+ rr l ; undoing 1
+.dvloop:
+ ;; Shift next bit of quotient into bit 0 of dividend
+ ;; Shift next MSB of dividend into LSB of remainder
+ ;; A holds both dividend and quotient. While we shift a bit from
+ ;; MSB of dividend, we shift next bit of quotient in from carry
+ ;; HL holds remainder
+ adc hl,hl ; HL < 2^(7+9), no carry, ever.
+
+ ;; If remainder is >= divisor, next bit of quotient is 1. We try
+ ;; to compute the difference.
+ sbc hl,de
+ jr NC,.nodrop ; Jump if remainder is >= dividend
+ add hl,de ; Otherwise, restore remainder
+ ;; The add above sets the carry, because sbc hl,de did set it.
+.nodrop:
+ ccf ; Complement borrow so 1 indicates a
+ ; successful substraction (this is the
+ ; next bit of quotient)
+ rla
+ djnz .dvloop
+ ;; Take care of the ninth quotient bit! after the loop B=0.
+ rl b ; BA = quotient
+ ;; Carry now contains "0" = valid result.
+ ld d,b
+ ld e,a ; DE = quotient, HL = remainder
+ ex de,hl ; HL = quotient, DE = remainder
+ ret
+
diff --git a/device/lib/tlcs90/heap.s b/device/lib/tlcs90/heap.s
new file mode 100644
index 0000000..9b3ebe4
--- /dev/null
+++ b/device/lib/tlcs90/heap.s
@@ -0,0 +1,44 @@
+;--------------------------------------------------------------------------
+; heap.s
+;
+; Copyright (C) 2001, Michael Hope
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+; Just stubs - not copyrightable
+
+ ;; Stubs that hook the heap in
+ .globl ___sdcc_heap_init
+
+ .area _GSINIT
+ call ___sdcc_heap_init
+
+ .area _HEAP
+___sdcc_heap::
+ ;; For now just allocate 1k of heap.
+ .ds 1023
+
+ .area _HEAP_END
+___sdcc_heap_end::
+ .ds 1
diff --git a/device/lib/tlcs90/modmixed.s b/device/lib/tlcs90/modmixed.s
new file mode 100644
index 0000000..8a87846
--- /dev/null
+++ b/device/lib/tlcs90/modmixed.s
@@ -0,0 +1,62 @@
+;--------------------------------------------------------------------------
+; modmixed.s
+;
+; Copyright (C) 2010, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+.globl __modsuchar
+.globl __moduschar
+
+__modsuchar:
+ ld hl,#2+1
+ add hl,sp
+
+ ld e,(hl)
+ dec hl
+ ld l,(hl)
+ ld h,#0
+
+ call __div_signexte
+
+ jp __get_remainder
+
+__moduschar:
+ ld hl,#2+1
+ ld d, h
+ add hl,sp
+
+ ld e,(hl)
+ dec hl
+ ld l,(hl)
+
+ ld a,l ; Sign extend
+ rlca
+ sbc a, a
+ ld h, a
+
+ call __div16
+
+ jp __get_remainder
+
diff --git a/device/lib/tlcs90/modsigned.s b/device/lib/tlcs90/modsigned.s
new file mode 100644
index 0000000..f0ab93f
--- /dev/null
+++ b/device/lib/tlcs90/modsigned.s
@@ -0,0 +1,53 @@
+;--------------------------------------------------------------------------
+; modsigned.s
+;
+; Copyright (C) 2009, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+.area _CODE
+
+.globl __modschar
+.globl __modsint
+
+__modschar:
+ ld hl,#2+1
+ add hl,sp
+
+ ld e,(hl)
+ dec hl
+ ld l,(hl)
+
+ call __div8
+
+ jp __get_remainder
+
+__modsint:
+ ld hl, 2 (sp)
+ ld de, 4 (sp)
+
+ call __div16
+
+ jp __get_remainder
+
diff --git a/device/lib/tlcs90/modunsigned.s b/device/lib/tlcs90/modunsigned.s
new file mode 100644
index 0000000..da8e58d
--- /dev/null
+++ b/device/lib/tlcs90/modunsigned.s
@@ -0,0 +1,57 @@
+;--------------------------------------------------------------------------
+; modunsigned.s
+;
+; Copyright (C) 2009-2010, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+.area _CODE
+
+.globl __moduchar
+.globl __moduint
+
+__moduchar:
+ ld hl,#2+1
+ add hl,sp
+
+ ld e,(hl)
+ dec hl
+ ld l,(hl)
+
+ call __divu8
+
+ ex de,hl
+
+ ret
+
+__moduint:
+ ld hl, 2 (sp)
+ ld de, 4 (sp)
+
+ call __divu16
+
+ ex de,hl
+
+ ret
+
diff --git a/device/lib/tlcs90/mul.s b/device/lib/tlcs90/mul.s
new file mode 100644
index 0000000..f4e0271
--- /dev/null
+++ b/device/lib/tlcs90/mul.s
@@ -0,0 +1,70 @@
+;--------------------------------------------------------------------------
+; mulchar.s
+;
+; Copyright (C) 2000, Michael Hope
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+.area _CODE
+
+.globl __mulint
+
+__mulint:
+ ld bc, 2 (sp)
+ ld de, 4 (sp)
+
+ ;; 16-bit multiplication
+ ;;
+ ;; Entry conditions
+ ;; bc = multiplicand
+ ;; de = multiplier
+ ;;
+ ;; Exit conditions
+ ;; hl = less significant word of product
+ ;;
+ ;; Register used: AF,BC,DE,HL
+__mul16::
+ xor a,a
+ ld l,a
+ or a,b
+ ld b,#16
+
+ ;; Optimise for the case when this side has 8 bits of data or
+ ;; less. This is often the case with support address calls.
+ jr NZ,2$
+ ld b,#8
+ ld a,c
+1$:
+ ;; Taken from z88dk, which originally borrowed from the
+ ;; Spectrum rom.
+ add hl,hl
+2$:
+ rl c
+ rla ;DLE 27/11/98
+ jr NC,3$
+ add hl,de
+3$:
+ djnz 1$
+ ret
+
diff --git a/device/lib/tlcs90/mulchar.s b/device/lib/tlcs90/mulchar.s
new file mode 100644
index 0000000..05db612
--- /dev/null
+++ b/device/lib/tlcs90/mulchar.s
@@ -0,0 +1,79 @@
+;--------------------------------------------------------------------------
+; mulchar.s
+;
+; Copyright (c) 2017, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+.area _CODE
+
+; unsigned char x unsigned char multiplication is done by code generation.
+
+.globl __mulsuchar
+.globl __muluschar
+.globl __mulschar
+
+; operands have different sign
+
+__mulsuchar:
+ ld hl,#2+1
+ ld b, h
+ add hl,sp
+
+ ld e,(hl)
+ dec hl
+ ld c,(hl)
+ jr signexte
+
+__muluschar:
+ ld hl,#2
+ ld b, h
+ add hl,sp
+
+ ld e,(hl)
+ inc hl
+ ld c,(hl)
+ jr signexte
+
+__mulschar:
+ ld hl,#2+1
+ add hl,sp
+
+ ld e,(hl)
+ dec hl
+ ld c,(hl)
+
+ ;; Need to sign extend before going in.
+ ld a,c
+ rla
+ sbc a,a
+ ld b,a
+signexte:
+ ld a,e
+ rla
+ sbc a,a
+ ld d,a
+
+ jp __mul16
+
diff --git a/device/lib/tlcs90/setjmp.s b/device/lib/tlcs90/setjmp.s
new file mode 100644
index 0000000..98be38f
--- /dev/null
+++ b/device/lib/tlcs90/setjmp.s
@@ -0,0 +1,96 @@
+;--------------------------------------------------------------------------
+; setjmp.s
+;
+; Copyright (C) 2011-2014, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+ .area _CODE
+
+ .globl ___setjmp
+
+___setjmp:
+ pop hl
+ pop iy
+ push af
+ push hl
+
+ ; Store return address.
+ ld 0(iy), l
+ ld 1(iy), h
+
+ ; Store stack pointer.
+ xor a, a
+ ld l, a
+ ld h, a
+ add hl, sp
+ ld 2(iy), l
+ ld 3(iy), h
+
+ ; Store frame pointer.
+ push ix
+ pop hl
+ ld 4(iy), l
+ ld 5(iy), h
+
+ ; Return 0.
+ ld l, a
+ ld h, a
+ ret
+
+.globl _longjmp
+
+_longjmp:
+ pop de
+ pop iy
+ pop de
+
+ ; Ensure that return value is non-zero.
+ ld a, e
+ or a, d
+ jr NZ, jump
+ inc de
+jump:
+
+ ; Restore frame pointer.
+ ld l, 4(iy)
+ ld h, 5(iy)
+ push hl
+ pop ix
+
+ ; Adjust stack pointer.
+ ld l, 2(iy)
+ ld h, 3(iy)
+ ld sp, hl
+ pop hl
+
+ ; Move return value into hl.
+ ex de, hl
+
+ ; Jump.
+ ld c, 0(iy)
+ ld b, 1(iy)
+ push bc
+ ret
+
diff --git a/device/lib/tlcs90/strcpy.s b/device/lib/tlcs90/strcpy.s
new file mode 100644
index 0000000..933f41b
--- /dev/null
+++ b/device/lib/tlcs90/strcpy.s
@@ -0,0 +1,48 @@
+;--------------------------------------------------------------------------
+; strcpy.s
+;
+; Copyright (C) 2012, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+ .area _CODE
+
+ .globl _strcpy
+
+_strcpy:
+ pop bc
+ pop de
+ pop hl
+ push hl
+ push de
+ push bc
+ push de
+ xor a, a
+loop:
+ cp a, (hl)
+ ldi
+ jr NZ, loop
+ pop hl
+ ret
+
diff --git a/device/lib/tlcs90/strlen.s b/device/lib/tlcs90/strlen.s
new file mode 100644
index 0000000..64f37da
--- /dev/null
+++ b/device/lib/tlcs90/strlen.s
@@ -0,0 +1,47 @@
+;--------------------------------------------------------------------------
+; strlen.s
+;
+; Copyright (C) 2008-2009, Philipp Klaus Krause
+;
+; This library is free software; you can redistribute it and/or modify it
+; under the terms of the GNU General Public License as published by the
+; Free Software Foundation; either version 2, or (at your option) any
+; later version.
+;
+; This library is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU General Public License for more details.
+;
+; You should have received a copy of the GNU General Public License
+; along with this library; see the file COPYING. If not, write to the
+; Free Software Foundation, 51 Franklin Street, Fifth Floor, Boston,
+; MA 02110-1301, USA.
+;
+; As a special exception, if you link this library with other files,
+; some of which are compiled with SDCC, to produce an executable,
+; this library does not by itself cause the resulting executable to
+; be covered by the GNU General Public License. This exception does
+; not however invalidate any other reasons why the executable file
+; might be covered by the GNU General Public License.
+;--------------------------------------------------------------------------
+
+ .area _CODE
+
+ .globl _strlen
+
+; The Z80 has the cpir instruction, which is perfect for implementing strlen().
+
+_strlen:
+ pop bc
+ pop hl
+ push hl
+ push bc
+ xor a, a
+ ld b, a
+ ld c, a
+ cpir
+ ld hl, #-1
+ sbc hl, bc ; C flag still cleared from xor above.
+ ret
+
diff --git a/device/lib/tlcs90/t90regs.s b/device/lib/tlcs90/t90regs.s
new file mode 100644
index 0000000..ea00dbf
--- /dev/null
+++ b/device/lib/tlcs90/t90regs.s
@@ -0,0 +1,49 @@
+P0 .equ 0x0ffc0
+P1 .equ 0x0ffc1
+P01CR .equ 0x0ffc2
+IRFL .equ 0x0ffc2
+IRFH .equ 0x0ffc3
+P2 .equ 0x0ffc4
+P2CR .equ 0x0ffc5
+P3 .equ 0x0ffc6
+P3CR .equ 0x0ffc7
+P4 .equ 0x0ffc8
+P4CR .equ 0x0ffc9
+P5 .equ 0x0ffca
+SMMOD .equ 0x0ffcb
+P6 .equ 0x0ffcc
+P7 .equ 0x0ffcd
+P67CR .equ 0x0ffce
+SMCR .equ 0x0ffcf
+P8 .equ 0x0ffd0
+P8CR .equ 0x0ffd1
+WDMOD .equ 0x0ffd2
+WDCR .equ 0x0ffd3
+TREG0 .equ 0x0ffd4
+TREG1 .equ 0x0ffd5
+TREG2 .equ 0x0ffd6
+TREG3 .equ 0x0ffd7
+TCLK .equ 0x0ffd8
+TFFCR .equ 0x0ffd9
+TMOD .equ 0x0ffda
+TRUN .equ 0x0ffdb
+CAP1L .equ 0x0ffdc
+CAP1H .equ 0x0ffdd
+CAP2L .equ 0x0ffde
+CAL2H .equ 0x0ffdf
+TREG4L .equ 0x0ffe0
+TREG4H .equ 0x0ffe1
+TREG5L .equ 0x0ffe2
+TREG5H .equ 0x0ffe3
+T4MOD .equ 0x0ffe4
+T4FFCR .equ 0x0ffe5
+INTEL .equ 0x0ffe6
+INTEH .equ 0x0ffe7
+DMAEH .equ 0x0ffe8
+SCMOD .equ 0x0ffe9
+SCCR .equ 0x0ffea
+SCBUF .equ 0x0ffeb
+BX .equ 0x0ffec
+BY .equ 0x0ffed
+ADREG .equ 0x0ffee
+ADMOD .equ 0x0ffef