/****************************************************************************
OS/A65 Version 2.0.0
Multitasking Operating System for 6502 Computers
Copyright (C) 1989-1998 Andre Fachat
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 of the License, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************/
/***************************************************************************
*
* This file is included in the RESET routine of the kernel,
* after the "sei:cld". The routine starting at the bginning
* of this file must initialize the hardware to the system RAM
* in the beginning and the system ROM in the end of the memory
* map. Also the system stack (pointer) is setup.
*
* In addition to that the system interrupt timer (needed for
* task preemtion) must be setup.
*
* After that the file must define the following macros:
*
* GETFREQ() returns a=0 for 1Mhz, a=128 for 2MHz
* LEDPORT address of LED port to signal hardware failures
* LED_LED bit of LED bit in LEDPORT address
* H_ERROR() if LEDPORT is not defined, then H_ERROR replaces
* the LED toggle routine if needed.
* CLRTIMER() clear the system interrupt timer interrupt
* KERNELIRQ() returns if an interrupt occured in the kernel
* or outside. Is checked by "BNE IRQ_in_Kernel"
* SAVEMEM() save system mem config for interrupt
* RESTOREMEM() restore system mem config after interrupt
* STARTMEM() This is used to alloc/enable memory pages found
* during kernel init. Takes mem size in AC as given
* by the kernel init. It is called _after_ inimem!
*/
/*
* init stack pointer for system stack
*/
ldx #<-1
txs
/*
* init memory configuration
*/
.(
#ifdef ROMTEST
ldx #7 ; only set RAM mapping, keep running ROM mapping
#else
ldx #15
#endif
res1 txa ;lda mmu,x
sta MMU,x
dex
#if SYSPAGE
bne res1
lda #SYSPAGE
sta MMU
#else
bpl res1
#endif /* SYSPAGE */
.)
/*
* CSA65 specific irq timer init, 50 Hz irq (well, i.e. line freq. irq)
* We assume that the reset - or a loader program has disabled all irq
*/
lda #SYS_IRQEN+SYS_EXTIO
sta SYSPORT
/*
* check zeropage RAM, jump to he_zero if failure
*/
#include "kernel/zerotest.a65"
/*
* check system RAM up to ROMSTART, jump to he_ram if failure
* returns available RAM in 256 byte blocks in AC
*/
.(
.zero
&cnt .byt 0
.text
#include "kernel/ramtest.a65"
cmp #MIN_MEM ; memory size at least needed
bcc he_ram
sta cnt
.)
jmp endmem
/*
* here we enable the memory pages found to be mapped by the MMU
* TODO: currently maximum 32k!!!!
*/
startmem .(
lsr
lsr
lsr
lsr
sta cnt
xl dec cnt
ldx cnt
#if SYSPAGE
cpx #SYSPAGE
beq x1
#else
bmi x1
#endif
/*
#ifdef ROMTEST
txa
ora #$10
tax
#endif
*/
jsr ENMEM
jmp xl
x1
rts
.)
#define STARTMEM() jsr startmem
/*
* determine the speed the CPU is running with. We use the 50 Hz toggle
* line for it.
*/
getfreq .(
sei
lda #SYS_IRQEN
sta SYSPORT
gf1 lda SYSPORT
bpl gf1
sta SYSPORT
bit SYSPORT
bmi gf1
lda #0
tay
tax
gf2 bit SYSPORT
bmi gfe
clc
adc #1
bne gf2
inx
bne gf2
iny
bne gf2
gfe cpx #8 ; more, then 2 MHZ
bcc gf3
lda #128 ; 2 MHz
rts
gf3 lda #0 ; 1 MHz
rts
.)
#define GETFREQ() jsr getfreq
/*
* system LED to indicate hardware failures
*/
#ifndef LEDPORT
#define LEDPORT SYSPORT
#define LED_LED SYS_LED
#endif
/*
* clear the scheduler preemption timer
*/
#define CLRTIMER() lda SYSPORT:sta SYSPORT
/*
* MMU systems may map task pages into kernel mem to make copying
* easier. This mapping has to be preserved during interrupt.
* SAVEMEM() saves the memory configuration, while RESTOREMEM()
* restores it, obviously.
* These routines are called _after_ "jsr memsys", so this routine
* has to preserve this mapping when called from kernel space,
* and so must memtask.
*/
/*
#define SAVEMEM lda MMU+1:pha:lda MMU+2:pha
#define RESTOREMEM() pla:sta MMU+2:pla:sta MMU+1
*/
#undef SAVEMEM
#undef RESTOREMEM
/*
* Check if we have an interrupt in the kernel
*/
#define KERNELIRQ() lda Syscnt:cmp #1
endmem