Re-worked the makefiles and includes to target z80 and gbz80 as well
[fw/sdcc] / device / lib / ds390 / tinibios.c
index bb4b3891d61fd38875aa5f58384f0b75abeb6336..13f87e12ca7c42d641e8910e30b008b4aa7902f2 100755 (executable)
@@ -1,3 +1,27 @@
+/*-------------------------------------------------------------------------
+  tinibios.c - startup and serial routines for the DS80C390 (tested on TINI)
+  
+   Written By - Johan Knol, johan.knol@iduna.nl
+    
+   This program 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 program 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 program; if not, write to the Free Software
+   Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+   
+   In other words, you are welcome to use, share and improve this program.
+   You are forbidden to forbid anyone else to use, share and improve
+   what you give them.   Help stamp out software-hoarding!  
+-------------------------------------------------------------------------*/
+
 #include <tinibios.h>
 #include <stdio.h>
 
@@ -20,7 +44,8 @@ unsigned char _sdcc_external_startup(void)
   // CKCON|=0xc0;
 
   // default stretch cycles for MOVX
-  CKCON = (CKCON&0xf8)|(CPU_MOVX_STRETCH&0x07);
+  //CKCON = (CKCON&0xf8)|(CPU_MOVX_STRETCH&0x07);
+  CKCON=0xf9;
 
   // use internal 4k RAM as data(stack) memory at 0x400000 and
   // move CANx memory access to 0x401000 and upwards
@@ -37,13 +62,13 @@ unsigned char _sdcc_external_startup(void)
     pop ar0; lsb
 
 
-    mov _ESP,#0x00; reinitialize the stack
-    mov _SP,#0x00
-
     mov _TA,#0xaa; timed access
     mov _TA,#0x55
     mov _ACON,#0x06; 24 bit addresses, 10 bit stack at 0x400000
 
+    mov _ESP,#0x00; reinitialize the stack
+    mov _SP,#0x00
+
     ; restore the 24-bit return address
     push ar0; lsb
     push ar1
@@ -313,9 +338,10 @@ static data unsigned char serial1Buffered;
 
 void Serial1Init (unsigned long baud, unsigned char buffered) {
   
-  if (baud=0) {
+  if (baud==0) {
     ES1=0; // disable interrupt
     SCON1 &= 0xef; // disable receiver
+    return; // and don't touch it
   }
 
   ES1 = 0; // disable channel 1 interrupt
@@ -333,7 +359,7 @@ void Serial1Init (unsigned long baud, unsigned char buffered) {
   // set the baud rate
   Serial1Baud(baud);
   
-  serial0Buffered=buffered;
+  serial1Buffered=buffered;
 
   if (buffered) {
     RI_1=TI_1=0; // clear "pending" interrupts
@@ -431,8 +457,7 @@ void Serial1Flush() {
 
 // now let's go for the clock stuff
 
-//#define TIMER_0_RELOAD_VALUE 18432000L/2/1000 // appr. 1ms
-
+// these REALLY need to be in data space for the irq routine!
 static data unsigned long milliSeconds=0;
 static data unsigned int timer0ReloadValue;
 
@@ -445,27 +470,52 @@ void ClockInit() {
   case 2:  // not tested yet
   default: timerReloadValue/=2; break;
   }
-  timer0ReloadValue=timerReloadValue;
+  timer0ReloadValue=~timerReloadValue;
   // initialise timer 0
   ET0=0; // disable timer interrupts initially
   TCON = (TCON&0xcc)|0x00; // stop timer, clear overflow
   TMOD = (TMOD&0xf0)|0x01; // 16 bit counter
-  CKCON|=0x80; // timer uses xtal/4
+  CKCON|=0x08; // timer uses xtal/4
   
-  TL0=~(timer0ReloadValue&0xff);
-  TH0=~(timer0ReloadValue>>8);
+  TL0=timer0ReloadValue&0xff;
+  TH0=timer0ReloadValue>>8;
   
   ET0=1; // enable timer interrupts
   TR0=1; // start timer
 }
 
-void ClockIrqHandler (void) interrupt 1 {
-  // we have lost some time here
-  TL0=~(timer0ReloadValue&0xff);
-  TH0=~(timer0ReloadValue>>8);
+// This needs to be SUPER fast. What we really want is:
+
+#if 0
+void junk_ClockIrqHandler (void) interrupt 10 {
+  TL0=timer0ReloadValue&0xff;
+  TH0=timer0ReloadValue>>8;
   milliSeconds++;
-  // that's all for now :)
 }
+#else
+// but look at the code, and the pushes and pops, so:
+void ClockIrqHandler (void) interrupt 1 _naked
+{
+  _asm
+    push acc
+    push psw
+    mov _TL0,_timer0ReloadValue
+    mov _TH0,_timer0ReloadValue+1
+    clr a
+    inc _milliSeconds+0
+    cjne a,_milliSeconds+0,_ClockIrqHandlerDone
+    inc _milliSeconds+1
+    cjne a,_milliSeconds+1,_ClockIrqHandlerDone
+    inc _milliSeconds+2
+    cjne a,_milliSeconds+2,_ClockIrqHandlerDone
+    inc _milliSeconds+3
+   _ClockIrqHandlerDone:
+    pop psw
+    pop acc
+    reti
+  _endasm;
+}
+#endif
 
 // we can't just use milliSeconds
 unsigned long ClockTicks(void) {