In recent weeks I concentrate on the software part of my project. First I cleaned up my code and put in on github as mentioned in previous blog update. Since then I added KbHit implementation and detection of RTC and Banked RAM to the firmware. I enhanced existing functions in enhshell.c to use added functionality. I also added small programs that provide one or few related functions in smaller package than the enhshell.c. Since I am still using serial port to load programs to the computer, I wanted to save on loading times.
I plan to create smaller standalone images of all functions currently implemented in enhshell.c.
I also plan to add few new tools that will help me to turn the computer into fully self hosting platform: text editor and on-line symbolic machine code assembler / disassembler.
Then I will move to further expand the hardware of my computer - build generic I/O card, control panel, local console (keyboard and CRT controller) and mass storage interface.
Updated kernel jump table and system internals documentation:
Programming API /
Kernal Jump Table:
Function
|
Address (hex)
|
Parameters
|
Return
|
Description
|
CallDS1685Init
|
FFD2
|
RegB, RegA, RegXB,
RegXA
|
RegC in Acc
|
Initialize RTC
chip.
|
CallDS1685ReadClock
|
FFD5
|
n/a
|
Data is returned
via hardware stack. Calling subroutine is responsible for allocating 8 bytes
on stack before calling this function. Clock data are stored in following
order below the subroutine return address: seconds, minutes, hours,
dayofweek, date, month, year, century. Valid return data on stack only if Acc
> 0 (Acc = # of bytes on stack). Calling subroutine still should
de-allocate stack space by calling PLA x 8 after reading or discarding
returned data.
|
Read RTC clock
data.
|
CallDS1685SetClock
|
FFD8
|
Parameters are
passed via hardware stack: seconds, minutes, hours, day of week, day of
month, month, year, century. Calling subroutine is responsible for allocating
8 bytes on stack and filling the space with valid input data before calling
this function. Calling subroutine is also responsible for freeing stack space
(PLA x 8).
|
n/a
|
Set date/time of
RTC chip.
|
CallDS1685SetTime
|
FFDB
|
Parameters are
passed via hardware stack: seconds, minutes, hour. Calling subroutine is
responsible for allocating space on stack and filling it with valid input
data before calling this function.
Calling subroutine is also responsible for freeing stack space (PLA x
3).
|
n/a
|
Set time of RTC
chip.
|
CallDS1685StoreRam
|
FFDE
|
BankNum, RamAddr,
RamVal
|
n/a
|
Store a value in
non-volatile RTC memory bank.
|
CallDS1685ReadRam
|
FFE1
|
BankNum, RamAddr
|
value in Acc
|
Read value from
non-volatile RTC memory bank.
|
CallReadMem
|
FFE4
|
PromptLine
(contains hexadecimal address range)
|
n/a (output)
|
Machine code
monitor function - read memory.
|
CallWriteMem
|
FFE7
|
PromptLine
(contains hexadecimal address and values)
|
n/a (memory is
modified)
|
Machine code
monitor function - write memory.
|
CallExecute
|
FFEA
|
PromptLine
(contains hexadecimal address)
|
n/a (code is
executed)
|
Machine code
monitor function - execute code in memory.
|
CallGetCh
|
FFED
|
n/a
|
Character code in
Acc
|
Standard I/O
function - get character.
|
CallPutCh
|
FFF0
|
Character code in
Acc.
|
n/a (output)
|
Standard I/O
function - put/print character.
|
CallGets
|
FFF3
|
n/a (input)
|
PromptLine,
PromptLen
|
Standard I/O
function - get string.
|
CallPuts
|
FFF6
|
StrPtr
|
n/a (output)
|
Standard I/O
function - put/print string.
|
CallBankRamSel
|
FFCF
|
Banked RAM bank #
in Acc. (0..7)
|
n/a (selects RAM
bank, updates shadow register in RAM)
|
Banked RAM bank
selection.
|
CallKbHit
|
FFCC
|
n/a
|
Character in Acc
or 0 if buffer empty.
|
Check if there is
character in RX buffer (equivalent of check if key was pressed since this is
UART I/O).
|
WARNING:
Disable
interrupts before calling any RTC function:
SEI
<call
to RTC API>
CLI
Registers, buffers,
memory:
RTC
RAM shadow:
RegB = $F6
RegA = $F7
RegXB = $F8
RegXA = $F9
RegC = $FA
Temp = $FB
BankNum = $FC
RamAddr = $FD
RamVal = $FE
UART
Pointers
UartRxInPt = $F2 ; Rx head pointer, for chars placed
in buf
UartRxOutPt
= $F3 ; Rx tail pointer, for
chars taken from buf
Uart
Queues (after stack)
UartTxQue = $200 ; 256 byte output queue
UartRxQue = $300 ; 256 byte input queue
MOS Prompt variables
PromptLine = $80 ; Prompt line (entered by user)
PromptMax = $50 ; An 80-character line is permitted
; ($80 to $CF)
PromptLen = $D0 ; Location of length variable
MOS I/O Function variables
StrPtr = $E0 ; String pointer for I/O functions
Other variables:
Timer64Hz
= $E2 ; 4-byte (32-bit)
counter
; incremented 64 times / sec
; $E2,$E3,$E4,$E5 (unsigned long,
; little
endian)
RamBankNum
= $E6 ; Current Banked
RAM bank#.
DetectedDevices = $E7 ; Flags indicating devices detected
; by
system during startup.
Detected
devices flags:
DEVPRESENT_RTC
|
%10000000
|
DEVPRESENT_NORTC
|
%01111111
|
DEVPRESENT_EXTRAM
|
%01000000
|
DEVPRESENT_NOEXTRAM
|
%10111111
|
DEVPRESENT_BANKRAM
|
100000
|
DEVPRESENT_NOBRAM
|
%11011111
|
DEVPRESENT_UART
|
010000
|
DEVPRESENT_NOUART
|
%11101111
|
DEVNOEXTRAM
|
DEVPRESENT_NOEXTRAM
& DEVPRESENT_NOBRAM
|
Customizable jump vectors
Program loaded and run in RAM can
modify these vectors
to drive custom I/O console hardware
and attach/change
handler to IRQ procedure. Interrupt
flag should be
set before changes are applied and
cleared when ready.
Custom IRQ handler routine should
make a jump to standard
handler at the end. Custom I/O
function routine should
end with RTS.
StoreAcc = $11 ;
Temporary Accumulator store.
IrqVect = $0012 ;
Customizable IRQ vector
GetChVect = $0014 ;
Custom GetCh function jump vector
PutChVect = $0016 ;
Custom PutCh function jump vector
GetsVect = $0018 ;
Custom Gets function jump vector
PutsVect = $001a ;
Custom Puts function jump vector
I/O
space / address range:
$C000
.. $C7FF, 8 pages (8 x 256 bytes):
Internal
(non-buffered) I/O bus:
$C000
.. $C0FF - slot 0 (RAM bank switching register)
$C100
.. $C1FF - slot 1 (RTC registers)
$C200
.. $C2FF - slot 2 (Reserved for Prioritized Interrupt Controller)
$C300
.. $C3FF - slot 3 (Reserved for built in I/O parallel interface PIA or VIA)
External
(buffered/expansion) I/O bus:
$C400
.. $C4FF - slot 4 (UART)
$C500
.. $C5FF - slot 5
$C600
.. $C6FF - slot 6
$C700
.. $C7FF - slot 7
RAM
bank switching.
NOTE:
Because RAM bank switching hardware register is write only, we cannot read from
it to determine which bank is selected. The purpose of bank#
RAM register at $E6 is just that - remembering last selected bank#.
Address:
|
$C000
|
Value:
|
$00 .. $07
|
Banked memory:
|
$8000 .. $BFFF
|
Bank number RAM register:
|
$E6
|
Memory
map:
$0000 - $7FFF: Base RAM, 32 kB. $0000 - $03FF space is used by the system.
$6000
- $7FFF: Optional Video RAM, 8 kB. (takes away from Base RAM, leaving 24 kB for
general purpose)
$8000
- $BFFF: Banked RAM, 16 kB space x 8 banks = 128 kB.
$C000
- $C7FF: I/O space, 8 slots x 256 Bytes = 2 kB.
$C800
- $FFFF: EPROM, 14 kB.
System programs:
System programs currently consist of:
enhshell.c
- combines rudimentary command line interface with additional functions for
RTC, Banked RAM and more.
setdt.c
- program that allows to set and show date / time.
date.c - programs that shows date / time.
d2hexbin.c
- conversion tool from decimal to hexadecimal / binary code.
Programs
written in C (CC65) or CA65 assembly for MKHBC-8-Rx computer / MKHBC OS use
library written in C and assembly languages which implements standard C library
(CC65), I/O console and RTC functions and are compiled into library archive
mkhbcos.lib.
Corresponding
C header files are:
- mkhbcos_ansi.h - ANSI terminal API
- mkhbcos_ds1685.h - DS1685 RTC API
- mkhbcos_lcd.h - standard LCD 16x2 API
- mkhbcos_ml.h - C header with definitions of MKHBCOS API and internals
- mkhbcos_ml.inc - assembly header with definitions for MKHBCOS API and internals
- mkhbcos_serialio.h - serial I/O API
Thank you for visiting my blog.
---
MK
Feb 13 2018