Merge remote-tracking branch 'original/main' into merge-220530

This commit is contained in:
Vincent Barrilliot 2022-05-30 21:14:34 +02:00
commit adc37b784e
153 changed files with 29362 additions and 15690 deletions

1
.gitignore vendored
View file

@ -69,6 +69,7 @@ src/foenixmcp_ram.bin
src/foenixmcp_flash.bin
src/bin/archive/foenixmcp_u_flash_20211111_03.bin
src/bin/archive/foenixmcp_u_flash_20211112_06.bin
src/Shit2Flash.bin
src/bin/archive/foenixmcp_u_ram_20211206_02.bin
src/bin/archive/foenixmcp_u_ram_20211206_01.bin
src/bin/archive/foenixmcp_u_flash_20211206_02.bin

BIN
C256Mgr.zip Normal file

Binary file not shown.

View file

@ -1,5 +1,13 @@
import re
def tailpad(data):
datalen = len(data)
pad = datalen % 4
if pad > 0:
return data.ljust(datalen + pad, '0')
else:
return data
class SRECFile:
"""Read information from a Motorola SREC file."""
@ -52,7 +60,7 @@ class SRECFile:
address = int(m2.group(2), 16)
data = m2.group(3)
crc = int(m2.group(4), 16)
self.handler(address, data)
self.handler(address, tailpad(data))
elif code == 2:
# Unpack a record with a 24-bit address
@ -61,7 +69,7 @@ class SRECFile:
address = int(m2.group(2), 16)
data = m2.group(3)
crc = int(m2.group(4), 16)
self.handler(address, data)
self.handler(address, tailpad(data))
elif code == 3:
# Unpack a record with a 32-bit address
@ -70,4 +78,4 @@ class SRECFile:
address = int(m2.group(2), 16)
data = m2.group(3)
crc = int(m2.group(4), 16)
self.handler(address, data)
self.handler(address, tailpad(data))

2702
Doxyfile Normal file

File diff suppressed because it is too large Load diff

View file

@ -5,39 +5,43 @@
1. [x] A2560K "Moe" keyboard driver
1. [x] PS/2 keyboard driver
1. [x] Channel (Stream) driver model
1. [ ] System call library
1. [-] System call library (implemented by daschewie)
1. [x] Channel driver for console (raw output and ANSI output)
1. [ ] Channel driver for the serial ports
1. [ ] Channel driver for the parallel port
1. [ ] Channel driver for the MIDI ports
1. [-] Channel driver for the MIDI ports (skipping for 1.0)
1. [x] Block driver model
1. [x] SDC block driver
1. [x] PATA block driver
1. [ ] Floppy block driver
1. [x] FatFS library integration
1. [ ] Memory management
1. [x] Memory management
1. [x] PGX file loader
1. [x] PGZ file loader
1. [x] ELF file loader
1. [x] Command Line Interface
1. [ ] Mouse driver
1. [ ] Boot from media support (hard drive, SDC, floppy)
1. [X] Boot from SDC
1. [X] Boot from hard drive
1. [ ] Boot from floppy
## CLI Features
1. [x] Ability to load a file
1. [ ] Auto-run/configuration file
1. [x] Auto-run/configuration file
1. Built-in commands:
1. [x] DIR [path]
1. [x] COPY [path] TO [path]
1. [ ] RENAME [path] TO [path]
1. [x] RENAME [path] TO [path]
1. [x] DELETE [path]
1. [x] CD [path]
1. [x] PWD
1. [ ] FORMAT [drive] -- Format a drive... should this be built in?
1. [ ] PRINT [expression]
1. [-] PRINT [expression]
1. [x] POKE [address], [value] -- value to an address
1. [x] PEEK [address] -- value from an address
1. [ ] CALL [address] -- Start running assembly code
1. [x] CALL [address] -- Start running assembly code
1. [x] DUMP [address], [size]
1. [ ] SETCOLOR [lut], [index], [r], [g], [b] -- set a color LUT value
1. [x] SETTIME

View file

@ -31,7 +31,7 @@ Please refer to processor specific building instructions that will be included.
For the 65816 and 68000 computers, the project will be built using the VBCC
compiler.
### Building for the M68000 CPU
### Building for the M68000 CPU Family
Building this project requires the [VBCC](http://www.compilers.de/vbcc.html) compiler and the
```MAKE``` utility. Using your command line, go into the ```src``` directory and type:
@ -48,14 +48,29 @@ To remove binaries and intermediate files:
make clean
```
#### Built Options
#### Build Options
There are three option variables that can be set in the makefile:
* `CPU`: This specifies which CPU is the target. Currently only the M68000 is supported, with a CPU code of 32 (0x20).
* `MODEL`: This species which Foenix model is the target. Currently only the Foenix A2560K is supported, with a code of 13.
* `UNIT`: This specifies which Foenix model is the targetted machine for the build. There are currently two options:
1. `UNIT=a2560u`, this covers both the A2560U and A2560U+. It sets the CPU to be the M68000.
2. `UNIT=a2560k`, this covers the A2560K and sets the CPU to M68040.
* `MEMORY`: This species where in memory Foenix/MCP will run. There are two values here:
1. `MEMORY=ram`: This specifies that the MCP will run from RAM.
2. `MEMORY=flash`: This specifies that the MCP will be programmed to flash memory.
* `KBD_POLLED`: As a temporary feature, if this option variable is defined, it will specify to the kernel that polled I/O is to be used for keyboard access instead of interrupt driven I/O.
Examples:
```
make all UNIT=a2560u MEMORY=ram
```
Builds an SREC file suitable for loading into RAM of the A2560U/U+.
```
make all UNIT=a2560k MEMORY=flash
```
Builds a binary file suitable for programming the flash of the A2560K.
## License
Most of the source code for this kernel is made available under the open source

BIN
build/foenixmcp_a2560k.bin Normal file

Binary file not shown.

View file

@ -1,4 +1,4 @@
[DEFAULT]
port=COM6
port=COM5
labels=sample.lbl
flash_address=380000
flash_address=010000

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
docs/Memory Map.odg Normal file

Binary file not shown.

Binary file not shown.

16
docs/notes/LEDs.txt Normal file
View file

@ -0,0 +1,16 @@
so for your information, to program the RGB led for the keyboard Keys..
the addresses for each line (it starts at the bottom right)
FEC0_1000 (Space bar line)
FEC0_1020
FEC0_1040
FEC0_1060
FEC0_1080 (Number Keys)
FEC0_10A0 (Function Keys)
the color information is in a 16bits Value
4 bits for R/G/B
[3:0] Blue
[7:4] Green
[11:8] Red
So, you will need write Shorts for every LED
There are 16 column and 6 Rows... Obviously there will be holes and the LED might not line up properly.
So, I was thinking that it would be sweet to have some kind of RGB testing sweeps at boot time.

View file

@ -0,0 +1,49 @@
assign CS0 = ( Internal_Address[31:21] == 11'b0000_0000_000 ) & ( UserData | UserProgram | SuperData | SuperProgram ); //$00 (2M)
// System RAM
assign CS_MERA = ( Internal_Address[31:24] == 7'b0000_001 ) & ( UserData | UserProgram | SuperData | SuperProgram ); //$02000000 - $05FFFFFF 64Meg
// Video RAM
assign CS_VRAM_A = ( Internal_Address[31:21] == 11'b0000_0000_100 ) & ( UserData | SuperData ); //$080000 - 09FFFF (2M) (out of 8M)
assign CS_VRAM_B = ( Internal_Address[31:21] == 11'b0000_0000_101 ) & ( UserData | SuperData ); //$0A0000 - 0BFFFF (2M) (out of 8M)
assign CS_GABE = ( Internal_Address[31:17] == 15'b1111_1110_1100_000 ) & ( UserData | SuperData ); //$FEC0
assign CS_BEATRIX = ( Internal_Address[31:17] == 15'b1111_1110_1100_001 ) & ( UserData | SuperData ); //$FEC2
// Vicky Channel A
assign CS_VICKY_A = ( Internal_Address[31:17] == 15'b1111_1110_1100_010 ) & ( UserData | SuperData ); //$FEC4
assign CS_VICKY_MEM_A = ( Internal_Address[31:17] == 15'b1111_1110_1100_011 ) & ( UserData | SuperData ); //$FEC6
//$00C6_8000 - $00C9_FFFF - Reserved
// Vicky Channel B
assign CS_VICKY_B = ( Internal_Address[31:17] == 15'b1111_1110_1100_100 ) & ( UserData | SuperData ); //$FEC8
assign CS_VICKY_MEM_B = ( Internal_Address[31:17] == 15'b1111_1110_1100_101 ) & ( UserData | SuperData ); //$FECA
assign FLASH0 = ( Internal_Address[31:21] == 11'b1111_1111_111 ) & ( SuperData | SuperProgram ); //$FFE0_0000
VICKY_MASTER_REG[8] <= 32'h1008_1008; // FONT Manager - Font Container Size and FONT Size
VICKY_MASTER_REG[9] <= 32'h0000_1E50; // FONT - Horizontal # of Character, Vertical # FONT Line
always @ (*)
begin
case(CPU_A_i[4:2])
3'b000: begin CPU_D_o = {16'h0000, J0_BUTTON2_Input, J0_BUTTON1_Input, 1'b0, J0_BUTTON0_Input, J0_RIGHT_i, J0_LEFT_i, J0_DOWN_i, J0_UP_i, J1_BUTTON2_Input, J1_BUTTON1_Input, 1'b0, J1_BUTTON0_Input, J1_RIGHT_i, J1_LEFT_i, J1_DOWN_i, J1_UP_i}; end
3'b001: begin CPU_D_o = {16'h0000, SNES_CTRL_REG[15:7], SampleIsDone, SNES_CTRL_REG[5:0] }; end
3'b010: begin CPU_D_o = { SNES_PORT0_INPUT1, 4'b0000, SNES_PORT0_INPUT0, 4'b0000 }; end
3'b011: begin CPU_D_o = { SNES_PORT0_INPUT3, 4'b0000, SNES_PORT0_INPUT2, 4'b0000 }; end
3'b100: begin CPU_D_o = { SNES_PORT1_INPUT1, 4'b0000, SNES_PORT1_INPUT0, 4'b0000 }; end
3'b101: begin CPU_D_o = { SNES_PORT1_INPUT3, 4'b0000, SNES_PORT1_INPUT2, 4'b0000 }; end
3'b110: begin CPU_D_o = {6'b00_0000, F_SD_WP_i, F_SD_CD_i, 8'b0000_0000, 6'b00_0000, USER_i[1], USER_i[0], 6'b00_0000, BOOT_MODE_i[1], BOOT_MODE_i[0]}; end
3'b111: begin CPU_D_o = 32'hAAAA_5555; end
default: begin CPU_D_o = 32'hDEAF_B00B; end
endcase
end
assign NES_PORT_0_ENABLE = SNES_CTRL_REG[0];
assign NES_PORT_1_ENABLE = SNES_CTRL_REG[1];
assign NES_SNES_PORT_0_CHOICE = !SNES_CTRL_REG[2];
assign NES_SNES_PORT_1_CHOICE = !SNES_CTRL_REG[3];
This is new:
assign JOYSTICK0_RLY_o = SNES_CTRL_REG[8];
assign JOYSTICK1_RLY_o = SNES_CTRL_REG[9];
this control the relay to swap the Button1 and Button2 (I think) to relay the signal to the Analog Input of the Super IO
Mimiru Miru — Today at 9:46 PM
ahhh ok
c256foenix — Today at 9:46 PM
SNES_CTRL_REG[7] is start the Transfer

51
docs/notes/bootsector.md Normal file
View file

@ -0,0 +1,51 @@
## FAT32 Volume Boot Record Format
Windows 10 checks for the following (https://github.com/microsoft/Windows-driver-samples/blob/16022c593787aef040b8a37ef697316e07f1322e/filesys/fastfat/fsctrl.c#L2546):
* [offset=0x000, length=3] First byte must be: 0xE9, 0xEB, 0x49
* [offset=0x00B, length=2] BytesPerSector must be: 128, 256, 512, 1024, 2048, or 4096
* [offset=0x00D, length=1] SectorsPerCluster must be: 1, 2, 4, 8, 16, 32, 64, or 128
* [offset=0x00E, length=2] ReservedSectors must be > 0
* [offset=0x010, length=1] NumberOfFATs must be > 0
* Either [offset=0x013, length=2] Sectors or [offset=0x020, length=4] LargeSectors must be > 0
* [offset=0x016, length=2] SectorsPerFat > 0 or ([offset=0x024, length=4] LargeSectorsPerFAT > 0 and [offset=0x02A, length=2] FsVersion = 0)
* [offset=0x015, length=1] MediaType must be: 0xF0, 0xF8, 0xF9, 0xFB, 0xFD, 0xFE, 0xFF
* Either [offset=0x016, length=2] SectorPerFAT = 0 or RootEntries > 0
* Either [offset=0x016, length=2] SectorPerFAT > 0 or MirrorDisabled
Important Fields:
* 0x000 - 0x002 : Boot jump code {0xEB 0xFE 0x00}
* 0x003 - 0x00A : OEM Name
* 0x00B - 0x05A : BPB and Extended BPB
* 0x05B : CPU #
* 0x05C - 0x05D : Adjustment spot for checksum (?)
* 0x05E - 0x05F : Unused
* 0x060 - 0x1FC : Boot sector code area
* 0x1FD : Physical drive number (?)
* 0x1FE - 0x1FF : Signature: 0x55 0xAA
For Foenix/MCP: 16-bit big-endian checksum of entire sector must equal 0x2560
Checksum: `sum = ((sum & 1) << 15) + (sum >> 1) + *w++;`
### Boot Process from Floppy and SDC
1. Load VBR into memory at 0x00000400
2. Compute checksum and verify it comes to 0x2560
3. Check that 0x05B has the right CPU ID
4. Call to 0x00000460 as a subroutine
## Master Boot Record Format
* 0x000 - 0x1BD : Boot code area (approximate end point)
* 0x1BE - 0x1FD : Partition data
* 0x1FE - 0x1FF : Signature: 0x55 0xAA
For Foenix/MCP: 16-bit big-endian checksum of entire sector must equal 0x2560
### Boot Process for PATA drive
1. Load MBR into memory at 0x00000400
2. Compute checksum and verify it comes to 0x2560
3. Check that 0x05B has the right CPU ID
4. Call to 0x00000400 as a subroutine

View file

@ -1,4 +1,11 @@
#
# User may over-ride the UNIT and MEMORY parameters to specify target machine
# and where the MCP will run (ram or flash)
#
UNIT := a2560k
MEMORY := flash
# CPU_WDC65816 0x16 /* CPU code for the Western Design Center 65816 */
# CPU_M68000 0x20 /* CPU code for the Motorola 68000 */
# CPU_M68010 0x21 /* CPU code for the Motorola 68010 */
@ -6,7 +13,6 @@
# CPU_M68030 0x23 /* CPU code for the Motorola 68030 */
# CPU_M68040 0x24 /* CPU code for the Motorola 68040 */
# CPU_I486DX 0x34 /* CPU code for the Intel 486DX */
export CPU=32
# MODEL_FOENIX_FMX 0
# MODEL_FOENIX_C256U 1
@ -15,31 +21,67 @@ export CPU=32
# MODEL_FOENIX_A2560U_PLUS 6
# MODEL_FOENIX_A2560X 8
# MODEL_FOENIX_A2560U 9
# MODEL_FOENIX_A2560K 13
export MODEL=9
# MODEL_FOENIX_A2560K 11
# Determine target CPU and MODEL based on the UNIT
ifeq ($(UNIT),a2560k)
export CPU_NUMBER = 6 # M68040V
export VASM_CPU = -m68040 # VASM CPU flag
export VBCC_CPU = 68040 # VBCC CPU flag
export MODEL_NUMBER = 11 # A2560K
export cpu = m68040
else ifeq ($(UNIT),genx)
export CPU_NUMBER = 6 # M68040V
export VASM_CPU = -m68040 # VASM CPU flag
export VBCC_CPU = 68040 # VBCC CPU flag
export MODEL_NUMBER = 4 # GenX
export cpu = m68040
else ifeq ($(UNIT),a2560u)
export CPU_NUMBER = 0 # M680SEC00
export VASM_CPU = -m68000 # VASM CPU flag
export VBCC_CPU = 68000 # VBCC CPU flag
export MODEL_NUMBER = 9 # A2560U
export CFG_FILE = $(VBCC)/config/a2560u_ram
export cpu = m68k
endif
# Determine the correct configuration file (barring OS)
ifeq ($(MEMORY),ram)
export CFG_FILE = $(VBCC)/config/$(UNIT)_ram
else
export CFG_FILE = $(VBCC)/config/$(UNIT)_flash
endif
export AS = vasmm68k_mot
export ASFLAGS = -quiet -Fvobj -nowarn=62
export ASFLAGS = $(VASM_CPU) -quiet -Fvobj -nowarn=62
export CC = vc
export DEFINES = -DCPU=$(CPU) -DMODEL=$(MODEL) # -DKBD_POLLED
export DEFINES = -DCPU=$(CPU_NUMBER) -DMODEL=$(MODEL_NUMBER) # -DKBD_POLLED
ifeq ($(OS),Windows_NT)
#export CFLAGS = +$(VBCC)/config/m68k-foenix -I. -I$(CURDIR)/include -I$(CURDIR)
export CFLAGS = +$(VBCC)/config/a2560u_flash -I. -I$(CURDIR)/include -I$(CURDIR)
export CFLAGS = -cpu=$(VBCC_CPU) +$(CFG_FILE) -I. -I$(CURDIR)/include -I$(CURDIR)
export RM = cmd /C del /Q /F
else
#export CFLAGS = +$(VBCC)/config/m68k-foenix-linux -I. -I$(CURDIR)/include -I$(CURDIR)
export CFLAGS = +$(VBCC)/config/a2560u_flash-linux -I. -I$(CURDIR)/include -I$(CURDIR)
export CFLAGS = -cpu=$(VBCC_CPU) +$(CFG_FILE)_linux -I. -I$(CURDIR)/include -I$(CURDIR)
export RM = rm -f
endif
cpu = m68k
cpu_assembly_src := $(wildcard $(cpu)/*.s)
cpu_c_src := $(wildcard $(cpu)/*.c)
cpu_assembly_obj := $(subst .s,.o,$(cpu_assembly_src))
cpu_c_obj := $(subst .c,.o,$(cpu_c_src))
dev_c_src := $(wildcard dev/*.c)
dev_base_sources = dev/block.c dev/channel.c dev/console.c dev/fsys.c dev/pata.c dev/ps2.c dev/rtc.c dev/sdc.c dev/txt_screen.c dev/uart.c
ifeq ($(UNIT),a2560k)
dev_c_src := $(dev_base_sources) dev/fdc.c dev/kbd_mo.c dev/lpt.c dev/midi.c dev/txt_a2560k_a.o dev/txt_a2560k_b.o m68040/fdc_m68040.o
else
dev_c_src := $(dev_base_sources)
endif
dev_c_obj := $(subst .c,.o,$(dev_c_src))
snd_c_src := $(wildcard snd/*.c)
snd_c_obj := $(subst .c,.o,$(snd_c_src))
fat_c_src := $(wildcard fatfs/*.c)
@ -51,7 +93,11 @@ c_obj := $(subst .c,.o,$(c_src))
.PHONY: all $(cpu) dev fatfs snd cli
ifeq ($(MEMORY),ram)
all: foenixmcp.s68 $(cpu) dev snd cli
else
all: foenixmcp.bin $(cpu) dev snd cli
endif
$(cpu):
$(MAKE) --directory=$@
@ -71,6 +117,9 @@ cli:
foenixmcp.s68: $(c_obj) $(cpu) dev fatfs snd cli
$(CC) $(CFLAGS) $(DEFINES) -o foenixmcp.s68 $(c_obj) $(cpu_c_obj) $(dev_c_obj) $(fat_c_obj) $(snd_c_obj) $(cli_c_obj)
foenixmcp.bin: $(c_obj) $(cpu) dev fatfs snd cli
$(CC) $(CFLAGS) $(DEFINES) -o foenixmcp.bin $(c_obj) $(cpu_c_obj) $(dev_c_obj) $(fat_c_obj) $(snd_c_obj) $(cli_c_obj)
%.o: %.c $(DEPS)
$(CC) -S -c -o $@ $< $(CFLAGS) $(DEFINES)

Binary file not shown.

585
src/boot.c Normal file
View file

@ -0,0 +1,585 @@
/**
* @file boot.c
*
* Routines to support the boot process
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "boot.h"
#include "constants.h"
#include "errors.h"
#include "gabe_reg.h"
#include "log.h"
#include "simpleio.h"
#include "syscalls.h"
#include "sys_general.h"
#include "vicky_general.h"
#include "cli/cli.h"
#include "dev/kbd_mo.h"
#include "dev/txt_screen.h"
#include "rsrc/font/quadrotextFONT.h"
#if MODEL == MODEL_FOENIX_A2560U || MODEL == MODEL_FOENIX_A2560U_PLUS
#include "rsrc/bitmaps/splash_a2560u.h"
#elif MODEL == MODEL_FOENIX_A2560K
#include "rsrc/bitmaps/splash_a2560k.h"
#endif
#define SPLASH_WAIT_SEC 10 /* How many seconds to wait on the splash screen */
/*
* Important scan codes
*/
#define SC_F1 0x3B
#define SC_F2 0x3C
#define SC_F3 0x3D
#define SC_SPACE 0x39
#define SC_RETURN 0x1C
/* TODO: move this to constants.h */
#define BOOT_SECTOR_BUFFER ((unsigned char *)0x00004000)
#define BOOT_CODE_MBR_OFF 0x000 /* Offset to the code in the MBR */
#define BOOT_CPUID_MBR_OFF 0x004 /* Offset to the CPUID in the MBR */
#define BOOT_SIG_MBR_OFF 0x006 /* Offset to the boot signature in the MBR */
#define BOOT_SIG 0xF0E1 /* Foenix/MCP boot signature expected */
#define FDC_VBR_JUMP 0x000 // Intel 80x86 machine language jump... 3 bytes
#define FDC_VBR_OEMNAME 0x003 // OEM Name... 8 bytes
#define FDC_VBR_BPB 0x00B // BIOS Parameter Block
#define FDC_VBR_BYTES_PER_SECTOR 0x00B // Number of bytes per sector... 2 bytes
#define FDC_VBR_SECTORS_PER_CLUSTER 0x00D // Number of sectors per cluster... 1 byte
#define FDC_VBR_RESERVED_SECTORS 0x00E // Number of reserved sectors... 2 bytes
#define FDC_VBR_FAT_COUNT 0x010 // Number of file allocation tables... 1 byte
#define FDC_VBR_MAX_ROOT_ENTRIES 0x011 // Maximum number of root directory entries... 2 bytes
#define FDC_VBR_SECTORS 0x013 // Number of logical sectors in FAT12/16... 2 bytes
#define FDC_VBR_MEDIA_TYPE 0x015 // Media type code... 1 byte
#define FDC_VBR_SECTORS_PER_FAT 0x016 // Number of sectors per file allocation table... 2 bytes
#define FDC_VBR_SECTORS_PER_TRACK 0x018 // Number of sectors per track... 2 bytes
#define FDC_VBR_HEADS 0x01A // Number of heads... 2 bytes
#define FDC_VBR_HIDDEN_SECTORS 0x01C // Number of hidden sectors... 2 bytes
#define FDC_VBR_TOTAL_SECTORS 0x01E // Total number of sectors... 2 bytes
#define FDC_VBR_BOOT_CODE 0x060 // Start of boot sector code
#define BOOT_CODE_VBR_OFF FDC_VBR_BOOT_CODE /* Offset to the code in the VBR for floppy drives */
#define BOOT_CPUID_VBR_OFF BOOT_CODE_VBR_OFF+4 /* Offset to the CPUID in the VBR for floppy drives */
#define BOOT_SIG_VBR_OFF BOOT_CODE_VBR_OFF+6 /* Offset to the boot signature in the VBR for floppy drives */
const char * MCP_INIT_SDC = "/sd/system/mcp.init"; /**< Path to config file on the SD card */
const char * MCP_INIT_FDC = "/fd/system/mcp.init"; /**< Path to config file on the floppy drive */
const char * MCP_INIT_HDC = "/hd/system/mcp.init"; /**< Path to config file on the IDE drive */
// Colors for the A2560K keyboard LED matrix
const unsigned short kbd_colors[] = {0x000F, 0x0FF, 0x00F0, 0x0FF0, 0x0F70, 0x0F00};
/**
* On the A2560K, animate the LEDs based on the current time while we're waiting for a key press
*
* @param max_ticks the value of the jiffy counter when the boot screen will end
* @param ticks the current value of the jiffy counter
* @param min_ticks the starting value of the jiffy counter
*/
void boot_animate_keyboard(unsigned long max_ticks, unsigned long ticks, unsigned long min_ticks) {
#if MODEL == MODEL_FOENIX_A2560K
const int animation_steps = 7;
int current_step = (int)(((ticks - min_ticks) * animation_steps) / (max_ticks - min_ticks));
int i;
for (i = 0; i < current_step; i++) {
kbdmo_set_led_matrix_row(current_step - i - 1, kbd_colors[5 - i]);
}
#endif
}
/**
* Determine if a sector loaded from a device is bootable
*
* @param sector pointer to where the sector is stored in memory
* @param device the number of the block device
*
* @return 0 if not bootable, non-zero if bootable
*/
short is_bootable(unsigned char * sector, short device) {
switch(device) {
case BDEV_FDC:
// The SDC and HDC boot off the MBR...
// Check for the CPUID and boot signature
if ((sector[BOOT_CPUID_VBR_OFF] == CPU_M68000) ||
(sector[BOOT_CPUID_VBR_OFF] == CPU_M68040)) {
if ((sector[BOOT_SIG_VBR_OFF] == ((BOOT_SIG >> 8) & 0x00FF)) &&
(sector[BOOT_SIG_VBR_OFF+1] == (BOOT_SIG & 0x00FF))) {
// The CPU is supported, and the boot signature is correct
return 1;
}
}
break;
case BDEV_SDC:
case BDEV_HDC:
// The SDC and HDC boot off the MBR...
// Check for the CPUID and boot signature
if ((sector[BOOT_CPUID_MBR_OFF] == CPU_M68000) ||
(sector[BOOT_CPUID_MBR_OFF] == CPU_M68040)) {
if ((sector[BOOT_SIG_MBR_OFF] == ((BOOT_SIG >> 8) & 0x00FF)) &&
(sector[BOOT_SIG_MBR_OFF+1] == (BOOT_SIG & 0x00FF))) {
// The CPU is supported, and the boot signature is correct
return 1;
}
}
break;
default:
// Otherwise: we're not bootable
break;
}
// If we have reached this point, the sector is not bootable
return 0;
}
/**
* Run the code in the boot sector
*
* @param device the number of the block device for the sector
*/
void boot_sector_run(short device) {
FUNC_V_2_V boot_sector = 0;
switch(device) {
case BDEV_FDC:
// The FDC boots off the Volume Boot Record (offset 0x060)
boot_sector = (FUNC_V_2_V)(BOOT_SECTOR_BUFFER + BOOT_CODE_VBR_OFF);
boot_sector();
break;
case BDEV_SDC:
case BDEV_HDC:
// The SDC and HDC both boot off the MBR
boot_sector = (FUNC_V_2_V)(BOOT_SECTOR_BUFFER);
boot_sector();
break;
default:
break;
}
}
void make_key_name(const char * original, char * buffer) {
int x;
for (x = 0; x < strlen(original); x++) {
buffer[x] = 0x80 | original[x];
}
buffer[strlen(original)] = 0;
}
/*
* Load and display the boot splash screen on the graphics screen
*
* @return boot device selected by user
*/
short boot_screen() {
t_rect region;
short device = BOOT_DEFAULT;
short screen = 0;
char buffer[256];
char entry[50];
unsigned long target_jiffies = 0;
unsigned long min_jiffies = 0;
unsigned long current_jiffies = 0;
int i = 0;
const unsigned char * pixels;
volatile unsigned char * vram = VRAM_Bank0;
t_sys_info info;
char f1[3], f2[3], f3[3];
char space[10], cr_text[10];
// We'll display boot information on the common screen
screen = 0;
/* Turn off the screen */
txt_set_mode(screen, 0);
for (i = 0; i < 256; i++) {
LUT_0[4*i] = splashscreen_lut[4*i];
LUT_0[4*i+1] = splashscreen_lut[4*i+1];
LUT_0[4*i+2] = splashscreen_lut[4*i+2];
LUT_0[4*i+3] = splashscreen_lut[4*i+3];
}
/* Copy the bitmap to video RAM */
for (pixels = splashscreen_pix; *pixels != 0;) {
unsigned char count = *pixels++;
unsigned char pixel = *pixels++;
for (i = 0; i < count; i++) {
*vram++ = pixel;
}
}
/* Set up the bitmap */
*BM0_Addy_Pointer_Reg = 0;
*BM0_Control_Reg = 1;
/* Set a background color for the bitmap mode */
#if MODEL == MODEL_FOENIX_A2560K
*BackGroundControlReg_B = 0x00202020;
screen = 0;
#else
*BackGroundControlReg_A = 0x00202020;
screen = 0;
#endif
/* Display the splashscreen at 640x480 without a border */
txt_set_resolution(screen, 640, 680);
txt_set_border(screen, 0, 0);
txt_set_font(screen, 8, 8, quadrotextFONT);
region.origin.x = 0;
region.origin.y = 0;
region.size.width = 0;
region.size.height = 0;
txt_set_region(screen, &region);
txt_setsizes(screen);
txt_set_mode(screen, TXT_MODE_TEXT | TXT_MODE_BITMAP);
/* Disable the cursor, set the color, clear the text screen, and display the text message */
txt_set_cursor(screen, 0, 0, 0); // Disable the cursor
txt_set_color(screen, 15, 0); // White on transparent
txt_fill(screen, ' '); // Clear the screen
make_key_name("F1", f1);
make_key_name("F2", f2);
make_key_name("F3", f3);
make_key_name("SPACE", space);
make_key_name("RETURN", cr_text);
sprintf(buffer, "BOOT: %s=FLOPPY, %s=SD CARD, %s=HARD DRIVE, %s=DEFAULT, %s=SAFE", f1, f2, f3, space, cr_text);
txt_set_xy(screen, (80 - strlen(buffer)) / 2, 58);
sys_chan_write(screen, buffer, strlen(buffer));
// Get the information about the system
sys_get_info(&info);
region.origin.x = 49;
region.origin.y = 1;
region.size.width = 40;
region.size.height = 20;
txt_set_region(screen, &region);
sprintf(buffer, "\x1b[HFOENIX/MCP V: %02u.%04u.%04u\n", info.mcp_version, info.mcp_rev, info.mcp_build);
print(screen, buffer);
str_upcase(info.model_name, entry);
sprintf(buffer, " MODEL: %s\n", entry);
print(screen, buffer);
str_upcase(info.cpu_name, entry);
sprintf(buffer, " CPU: %s\n", entry);
print(screen, buffer);
sprintf(buffer, " CLOCK (KHZ): %u\n", info.cpu_clock_khz);
print(screen, buffer);
sprintf(buffer, " FPGA V: %u.%02u.%04u\n", (unsigned int)info.fpga_model, info.fpga_version, info.fpga_subver);
print(screen, buffer);
/* Wait until the target duration has been reached _or_ the user presses a key */
sprintf(buffer, "Booting from default device...\n");
min_jiffies = sys_time_jiffies();
target_jiffies = min_jiffies + SPLASH_WAIT_SEC * 60;
current_jiffies = sys_time_jiffies();
while (target_jiffies > current_jiffies) {
boot_animate_keyboard(target_jiffies, current_jiffies, min_jiffies);
short scan_code = sys_kbd_scancode();
if (scan_code != 0) {
switch (scan_code) {
case SC_F1:
device = BDEV_FDC;
strcpy(buffer, "Booting from floppy drive.\n");
break;
case SC_F2:
device = BDEV_SDC;
strcpy(buffer, "Booting from SD card.\n");
break;
case SC_F3:
device = BDEV_HDC;
strcpy(buffer, "Booting from hard drive.\n");
break;
case SC_RETURN:
device = BOOT_SAFE;
strcpy(buffer, "Booting directly to the command line.\n");
break;
default:
device = BOOT_DEFAULT;
break;
}
break;
}
current_jiffies = sys_time_jiffies();
}
txt_init_screen(screen);
txt_set_resolution(0, 0, 0); // Set the resolution based on the DIP switch
txt_set_resolution(1, 0, 0); // Set the resolution based on the DIP switch
print(screen, buffer);
#if MODEL == MODEL_FOENIX_A2560K
// Turn off the keyboard LEDs
kbdmo_set_led_matrix_fill(0);
#endif
return device;
}
/**
* Start the boot process after initializing the MCP
*
* @param device the number of the block device to use for booting (-1 to go straight to CLI)
*/
void boot_from_bdev(short device) {
char initial_path[10];
unsigned short boot_dip = 0; // The setting on the user and boot mode DIP switches
short bootable = 0; // Is the boot sector of the selected device bootable?
// Get the boot device
switch (device) {
case BOOT_DEFAULT:
// User chose the default. Look at the DIP switches to determine the boot source
boot_dip = *GABE_DIP_REG & GABE_DIP_BOOT_MASK;
switch (boot_dip) {
case 0x0000:
// Boot from IDE
device = BDEV_HDC;
log(LOG_INFO, "Boot DIP set for IDE");
strcpy(initial_path, "/hd");
break;
case 0x0001:
// Boot from SDC
device = BDEV_SDC;
log(LOG_INFO, "Boot DIP set for SDC");
strcpy(initial_path, "/sd");
break;
case 0x0002:
// Boot from Floppy
device = BDEV_FDC;
log(LOG_INFO, "Boot DIP set for FDC");
strcpy(initial_path, "/fd");
break;
default:
// Boot straight to REPL
log(LOG_INFO, "Boot DIP set for REPL");
strcpy(initial_path, "/sd");
device = -1;
break;
}
break;
default:
break;
}
if (device >= 0) {
int i;
for (i = 0; i < 512; i++) {
// Zero out the buffer
BOOT_SECTOR_BUFFER[i] = 0;
}
// Try to load the boot sector
short result = bdev_read(device, 0, BOOT_SECTOR_BUFFER, 512);
if (result > 0) {
// Check to see if it's bootable
bootable = is_bootable(BOOT_SECTOR_BUFFER, device);
}
}
if (bootable) {
// If bootable, run it
boot_sector_run(device);
} else {
// If not bootable...
// Get the screen for the CLI
short cli_screen = cli_txt_screen_get();
if (device >= 0) {
// Execute startup file on boot device (if present)
switch (device) {
case BDEV_SDC:
strcpy(initial_path, "/sd");
if (cli_exec_batch(cli_screen, MCP_INIT_SDC) != 0) {
cli_exec_batch(cli_screen, MCP_INIT_HDC);
}
break;
case BDEV_FDC:
strcpy(initial_path, "/fd");
if (cli_exec_batch(cli_screen, MCP_INIT_FDC) != 0) {
cli_exec_batch(cli_screen, MCP_INIT_HDC);
}
break;
case BDEV_HDC:
strcpy(initial_path, "/hd");
cli_exec_batch(cli_screen, MCP_INIT_HDC);
break;
default:
break;
}
}
// Start up the command shell
cli_start_repl(cli_screen, initial_path);
}
}
const unsigned char boot_from_file_sector[] = {
0x60, 0x00, 0x00, 0x06, // bra.w boot
CPU_M68000, 0x00, 0xf0, 0xe1, // dc.b CPU_M68000, 0, 0xf0, 0xe1
0x30, 0x3c, 0x00, 0x40, // boot: move.w #$40,d0
0x43, 0xfa, 0x00, 0x0e, // lea (path,pc),a1
0x22, 0x09, // move.l a1,d1
0x42, 0x82, // clr.l d2
0x42, 0x83, // clr.l d3
0x4e, 0x4f, // trap #15
0x4e, 0x71, // bootloop nop
0x60, 0xfc // bra bootloop
};
/**
* Make the indicated drive non booting by erasing the boot information
*
* @param device the number of the block device to use for booting (-1 to go straight to CLI)
* @return 0 on success, any other number is an error
*/
short boot_non_booting(short device) {
unsigned char * buffer;
short result = 0;
buffer = (unsigned char *)malloc(FSYS_SECTOR_SZ);
if (buffer != 0) {
// Try to read the current sector
short n = sys_bdev_read(device, 0, buffer, FSYS_SECTOR_SZ);
if (n == FSYS_SECTOR_SZ) {
short sector_offset = 0;
if (device == BDEV_FDC) {
// Point to the beginning of the boot code for the FDC (VBR)
sector_offset = BOOT_CODE_VBR_OFF;
} else {
// Point to the beginning of the boot code for the SDC/HDD (MBR)
sector_offset = BOOT_CODE_MBR_OFF;
}
// Boot record read... clear out the boot code
for (int i = 0; i < sizeof(boot_from_file_sector); i++) {
buffer[sector_offset + i] = 0;
}
// Try to write it back
n = sys_bdev_write(device, 0, buffer, FSYS_SECTOR_SZ);
if (n == FSYS_SECTOR_SZ) {
// Success!
result = 0;
} else {
result = DEV_CANNOT_WRITE;
}
} else {
result = DEV_CANNOT_READ;
}
} else {
result = ERR_OUT_OF_MEMORY;
}
// Clear up the memory we grabbed...
if (buffer) {
free(buffer);
}
return result;
}
/**
* Make the indicated drive booting from a file
*
* @param device the number of the block device to use for booting (-1 to go straight to CLI)
* @param path the path to the file to boot from
* @return 0 on success, any other number is an error
*/
short boot_set_file(short device, const char * path) {
unsigned char * buffer, x;
short result = 0, i = 0;
buffer = (unsigned char *)malloc(FSYS_SECTOR_SZ);
if (buffer != 0) {
// Try to read the current sector
bdev_init(device);
short n = sys_bdev_read(device, 0, buffer, FSYS_SECTOR_SZ);
if (n == FSYS_SECTOR_SZ) {
int sector_len = sizeof(boot_from_file_sector);
int sector_offset = 0;
int path_len = strlen(path);
if (device == BDEV_FDC) {
// Set up the floppy disk boot record
sector_offset = BOOT_CODE_VBR_OFF;
// Write 80x86 code to infinite loop at the start of the boot sector
// This will help maintain compatibility with MS-DOS and Windows machines
buffer[0] = 0xEB;
buffer[1] = 0xFF;
buffer[2] = 0x90;
} else {
// Set up the SDC or HDC master boot record
sector_offset = BOOT_CODE_MBR_OFF;
}
// Copy the boot code over
for (i = 0; i < sector_len; i++) {
buffer[sector_offset + i] = boot_from_file_sector[i];
}
// Insert the path
for (i = 0; i < path_len; i++) {
buffer[sector_offset + i + sector_len] = path[i];
}
buffer[sector_offset + sector_len + path_len] = 0;
// Try to write it back
n = sys_bdev_write(device, 0, buffer, FSYS_SECTOR_SZ);
if (n == FSYS_SECTOR_SZ) {
// Success!
result = 0;
} else {
result = DEV_CANNOT_WRITE;
}
} else {
result = DEV_CANNOT_READ;
}
} else {
result = ERR_OUT_OF_MEMORY;
}
// Clear up the memory we grabbed...
if (buffer) {
free(buffer);
}
return result;
}

44
src/boot.h Normal file
View file

@ -0,0 +1,44 @@
/**
* @file boot.h
*
* Routines to support the boot process
*/
#ifndef __BOOT_H
#define __BOOT_H
#define BOOT_DEFAULT -1
#define BOOT_SAFE -2
/*
* Load and display the boot splash screen on the graphics screen
*
* @return boot device selected by user
*/
extern short boot_screen();
/**
* Start the boot process after initializing the MCP
*
* @param device the number of the block device to use for booting (-1 to go straight to CLI)
*/
extern void boot_from_bdev(short device);
/**
* Make the indicated drive non booting by erasing the boot information
*
* @param device the number of the block device to use for booting (-1 to go straight to CLI)
* @return 0 on success, any other number is an error
*/
extern short boot_non_booting(short device);
/**
* Make the indicated drive booting from a file
*
* @param device the number of the block device to use for booting (-1 to go straight to CLI)
* @param path the path to the file to boot from
* @return 0 on success, any other number is an error
*/
extern short boot_set_file(short device, const char * path);
#endif

0
src/build.log Normal file
View file

View file

@ -1,4 +1,4 @@
[DEFAULT]
port=COM6
port=COM5
labels=sample.lbl
flash_address=380000
flash_address=010000

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,20 @@ typedef short (*cli_cmd_handler)(short screen, int argc, const char * argv[]);
* will look for an executable file with that name somewhere in the search path.
*/
/**
* Set the path of the command shell
*
* @param path the path to the command processor executable (0 or empty string for default)
*/
extern void cli_command_set(const char * path);
/**
* Gets the path of the command shell
*
* @param path pointer to the buffer to store the path (empty string means default)
*/
extern void cli_command_get(char * path);
/**
* Initialize the CLI
*
@ -26,11 +40,23 @@ typedef short (*cli_cmd_handler)(short screen, int argc, const char * argv[]);
*/
extern short cli_init();
/**
* Start the read-eval-print loop
*
* @param channel the channel to use for interactions
* @param init_cwd the initial current working directory
*/
extern short cli_start_repl(short channel, const char * init_cwd);
/**
* Reactivate the CLI's read-eval-print loop after a command has completed
*/
extern void cli_rerepl();
/**
* Enter the CLI's read-eval-print loop
*
* Inputs:
* channel = the console channel to use for I/O
* @param channel the channel to use for interactions
*/
extern short cli_repl(short channel);
@ -44,4 +70,32 @@ extern long cli_eval_number(const char * arg);
*/
extern short cmd_help(short channel, int argc, const char * argv[]);
/**
* Execute a batch file at the given path
*
* @param channel the number of the channel to write any messages to
* @param path the path to the configuration file to load
* @return 0 on success, any other number is an error
*/
extern short cli_exec_batch(short channel, const char * path);
/**
* Set the number of the screen to use for interactions
*
* @param screen the number of the text device to use
*/
extern void cli_txt_screen_set(short screen);
/**
* Get the number of the screen used for interactions
*
* @return the number of the text device to use
*/
extern short cli_txt_screen_get();
/**
* Indicate that the current working directory has changed
*/
extern void cli_flag_cwd();
#endif

View file

@ -1,6 +1,7 @@
#include <ctype.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "syscalls.h"
@ -8,8 +9,10 @@
#include "simpleio.h"
#include "cli.h"
#include "proc.h"
#include "boot.h"
#include "cli/dos_cmds.h"
#include "dev/block.h"
#include "dev/console.h"
#include "dev/fsys.h"
#include "dev/kbd_mo.h"
#include "fatfs/ff.h"
@ -96,12 +99,14 @@ short cmd_diskfill(short screen, int argc, const char * argv[]) {
short cmd_run(short screen, int argc, const char * argv[]) {
TRACE("cmd_run");
sys_chan_ioctrl(screen, CON_IOCTRL_ECHO_ON, 0, 0);
short result = proc_run(argv[0], argc, argv);
if (result < 0) {
err_print(screen, "Unable to execute file", result);
return -1;
}
sys_chan_ioctrl(screen, CON_IOCTRL_ECHO_OFF, 0, 0);
return result;
}
@ -143,88 +148,6 @@ short cmd_del(short screen, int argc, const char * argv[]) {
}
}
short cmd_copy(short screen, int argc, const char * argv[]) {
FRESULT find_result;
FRESULT result;
DIR dir; /* Directory object */
FILINFO src_info; /* File information */
FILINFO dst_info;
FIL src_file;
FIL dst_file;
BYTE buffer[4096]; /* File copy buffer */
UINT br, bw; /* File read/write count */
char path[MAX_PATH_LEN];
bool is_directory = false;
bool is_append_file = false;
TRACE("cmd_copy");
if (argc > 2) {
strcpy(path, argv[2]);
result = f_stat(argv[2], &dst_info);
if (result == FR_OK) {
is_directory = dst_info.fattrib & AM_DIR;
} else if (result == FR_NO_FILE) {
is_directory = false;
} else {
goto error;
}
find_result = f_findfirst(&dir, &src_info, "", argv[1]);
while (find_result == FR_OK && src_info.fname[0]) {
if (strcmp(src_info.fname, path) == 0) goto skip; // Skip copying file to self.
result = f_open(&src_file, src_info.fname, FA_READ);
if (result != FR_OK) goto error;
if (is_directory) {
sprintf(path, "%s/%s", dst_info.fname, src_info.fname);
result = f_open(&dst_file, path, FA_WRITE | FA_CREATE_ALWAYS);
} else if (is_append_file) {
result = f_open(&dst_file, path, FA_WRITE | FA_OPEN_APPEND);
} else {
result = f_open(&dst_file, path, FA_WRITE | FA_CREATE_ALWAYS);
}
if (result != FR_OK) goto error;
print(screen, (is_append_file) ? "Appending " : "Copying ");
print(screen, src_info.fname);
print(screen, " to ");
print(screen, path);
print(screen, "\n");
/* Copy source to destination */
for (;;) {
result = f_read(&src_file, buffer, sizeof buffer, &br); /* Read a chunk of data from the source file */
if (br == 0) break; /* error or eof */
result = f_write(&dst_file, buffer, br, &bw); /* Write it to the destination file */
if (bw < br) break; /* error or disk full */
}
f_close(&src_file);
f_close(&dst_file);
skip:
find_result = f_findnext(&dir, &src_info);
is_append_file = true; // If copying more than one file to a file, then open for append.
}
f_closedir(&dir);
return 0;
error:
err_print(screen, "Unable to copy file(s)", result);
f_close(&src_file);
f_close(&dst_file);
return result;
}
}
/*
* Change the directory
*/
@ -238,6 +161,7 @@ short cmd_cd(short screen, int argc, const char * argv[]) {
err_print(screen, "Unable to change directory", result);
return result;
} else {
cli_flag_cwd();
print(screen, "Changed to: ");
print(screen, argv[1]);
print(screen, "\n");
@ -286,18 +210,120 @@ short cmd_rename(short screen, int argc, const char * argv[]) {
return 0;
}
/**
* Structure to hold file and directory information for sorting
*/
typedef struct s_dir_entry {
t_file_info info;
struct s_dir_entry *next, *prev;
} t_dir_entry, *p_dir_entry;
/**
* Add a directory entry to a list of directory entries using simple insertion sort
*
* @param list_pointer a pointer to a pointer to a list of directory entries
* @param entry a pointer to a directory entry to add
*/
void dir_entry_insert(p_dir_entry * list_pointer, p_dir_entry entry) {
p_dir_entry list = *list_pointer;
if (list == 0) {
*list_pointer = entry;
entry->next = 0;
entry->prev = 0;
} else {
p_dir_entry x = list;
while (x != 0) {
if (strcmp(x->info.name, entry->info.name) >= 0) {
if (x->prev == 0) {
*list_pointer = entry;
entry->next = x;
entry->prev = 0;
x->prev = entry;
} else {
entry->prev = x->prev;
entry->next = x;
x->prev->next = entry;
x->prev = entry;
}
return;
} else {
if (x->next == 0) {
x->next = entry;
entry->prev = x;
entry->next = 0;
return;
} else {
x = x->next;
}
}
}
}
}
/**
* Examine the optional path/pattern argument and separate it into a path and a pattern
*
* @param arg the string describing the directory and pattern to search
* @param path a pointer to a pointer to a string... set to the path portion or 0 if no path
* @param pattern a pointer to a pointer to a string... set to the pattern poriton, or 0 if none provided
*/
void dir_parse_pattern(char * arg, char ** path, char ** pattern) {
*path = 0;
*pattern = 0;
if ((arg != 0) && (strlen(arg) > 0)) {
// And argument was provided... see if there is a pattern
if ((strchr(arg, '*') == 0) && (strchr(arg, '?') == 0)) {
// No pattern found... return the whole thing as path
*path = arg;
} else {
// Found a pattern... do we specify a folder?
char * x = strrchr(arg, '/');
if (x == 0) {
// No... it's all pattern
*pattern = arg;
} else {
// Yes... split the string into path and pattern at x
*x = 0;
*path = arg;
*pattern = x + 1;
}
}
}
}
short cmd_dir(short screen, int argc, const char * argv[]) {
short result;
short result = 0, dir = -1;
char buffer[80];
char arg[128];
t_file_info my_file;
char * path = "";
p_dir_entry directories = 0, files = 0, entry = 0, prev = 0;
char *path=0, *pattern = 0;
char label[40];
if (argc > 1) {
path = (char*)(argv[1]);
strcpy(arg, argv[1]);
dir_parse_pattern(arg, &path, &pattern);
}
if (path == 0) {
// Make the path the empty string if it was not provided
path = "";
}
if (pattern != 0) {
// A pattern was provided
dir = sys_fsys_findfirst(path, pattern, &my_file);
} else {
// No pattern... just open the path as a directory
dir = sys_fsys_opendir(path);
}
short dir = fsys_opendir(path);
if (dir >= 0) {
result = fsys_getlabel(path, label);
if ((result == 0) && (strlen(label) > 0)) {
@ -306,31 +332,74 @@ short cmd_dir(short screen, int argc, const char * argv[]) {
}
while (1) {
short result = fsys_readdir(dir, &my_file);
if ((result == 0) && (my_file.name[0] != 0)) {
if (pattern == 0) {
result = sys_fsys_readdir(dir, &my_file);
if (result != 0) break;
}
if (my_file.name[0] != 0) {
if ((my_file.attributes & AM_HID) == 0) {
if (my_file.attributes & AM_DIR) {
sprintf(buffer, "%s/\n", my_file.name);
chan_write(screen, buffer, strlen(buffer));
entry = (p_dir_entry)malloc(sizeof(t_dir_entry));
if (entry) {
memcpy(&entry->info, &my_file, sizeof(t_file_info));
dir_entry_insert(&directories, entry);
} else {
print(screen, "Unable to display directory... out of memory.\n");
return -1;
}
} else {
if (my_file.size < 1024) {
sprintf(buffer, "%-20.20s %d\n", my_file.name, (int)my_file.size);
} else if (my_file.size < 1024*1024) {
sprintf(buffer, "%-20.20s %d KB\n", my_file.name, (int)my_file.size / 1024);
entry = (p_dir_entry)malloc(sizeof(t_dir_entry));
if (entry) {
memcpy(&entry->info, &my_file, sizeof(t_file_info));
dir_entry_insert(&files, entry);
} else {
sprintf(buffer, "%-29.20s %d MB\n", my_file.name, (int)my_file.size / (1024*1024));
print(screen, "Unable to display directory... out of memory.\n");
return -1;
}
chan_write(screen, buffer, strlen(buffer));
}
}
} else {
break;
}
if (pattern != 0) {
result = fsys_findnext(dir, &my_file);
if (result != 0) {
break;
}
}
}
fsys_closedir(dir);
// Print the directories
entry = directories;
while (entry != 0) {
sprintf(buffer, "%s/\n", entry->info.name);
print(screen, buffer);
prev = entry;
entry = entry->next;
free(prev);
}
// Print the files
entry = files;
while (entry != 0) {
if (entry->info.size < 1024) {
sprintf(buffer, "%-20.20s %d B\n", entry->info.name, (int)entry->info.size);
} else if (my_file.size < 1024*1024) {
sprintf(buffer, "%-20.20s %d KB\n", entry->info.name, (int)entry->info.size / 1024);
} else {
sprintf(buffer, "%-29.20s %d MB\n", entry->info.name, (int)entry->info.size / (1024*1024));
}
print(screen, buffer);
prev = entry;
entry = entry->next;
free(prev);
}
} else {
err_print(screen, "Unable to open directory", dir);
return dir;
@ -428,6 +497,89 @@ short cmd_label(short screen, int argc, const char * argv[]) {
}
}
/**
* Command to make a device bootable by writing to the MBR or VBR
*
* MKBOOT <drive #> -r --- removes boot record
* MKBOOT <drive #> -b <boot record path> --- installs boot record
* MKBOOT <drive #> -s <start file path> --- defines a startup file
*/
short cmd_mkboot(short screen, int argc, const char * argv[]) {
const char * usage = "USAGE: MKBOOT <drive #> -r\n MKBOOT <drive #> -b <boot record path>\n MKBOOT <drive #> -s <start file path>\n";
short mode = 0;
unsigned char * boot_sector = 0;
unsigned char * new_boot_sector = 0;
char message[80];
short dev = 0;
short i = 0;
short result = 0;
// Parse the inputs...
if (argc == 3) {
// Must be -r
if (strcmp("-r", argv[2]) == 0) {
mode = 0;
dev = cli_eval_number(argv[1]);
} else {
print(screen, usage);
return -1;
}
} else if (argc == 4) {
// Can be either -b or -s
dev = cli_eval_number(argv[1]);
if (strcmp("-b", argv[2]) == 0) {
// -b
mode = 1;
} else if (strcmp("-s", argv[2]) == 0) {
// -s
mode = 2;
} else {
print(screen, usage);
return -1;
}
} else {
// Bad arguments...
print(screen, usage);
return -1;
}
switch (mode) {
case 0:
// Clear out the boot record
result = boot_non_booting(dev);
if (result != 0) {
sprintf(message, "Could not change boot record: %s\n", err_message(result));
print(screen, message);
} else {
print(screen, "Boot record updated.\n");
}
break;
case 2:
// Write a boot sector that loads and runs a file
result = boot_set_file(dev, argv[3]);
if (result != 0) {
sprintf(message, "Could not change boot record: %s\n", err_message(result));
print(screen, message);
} else {
print(screen, "Boot record updated.\n");
}
break;
default:
print(screen, "Unknown MKBOOT operation.\n");
result = -1;
break;
}
return result;
}
/*
* Format a drive
*

View file

@ -25,11 +25,6 @@ extern short cmd_mkdir(short screen, int argc, const char * argv[]);
*/
extern short cmd_del(short screen, int argc, const char * argv[]);
/*
* Copies file(s) to destination
*/
extern short cmd_copy(short screen, int argc, const char * argv[]);
/*
* Set the current working directory
*/
@ -84,4 +79,13 @@ extern short cmd_label(short screen, int argc, const char * argv[]);
*/
extern short cmd_format(short screen, int argc, const char * argv[]);
/**
* Command to make a device bootable by writing to the MBR or VBR
*
* MKBOOT <drive #> -r --- removes boot record
* MKBOOT <drive #> -b <boot record path> --- installs boot record
* MKBOOT <drive #> -s <start file path> --- defines a startup file
*/
extern short cmd_mkboot(short screen, int argc, const char * argv[]);
#endif

365
src/cli/dos_copy.c Normal file
View file

@ -0,0 +1,365 @@
/** @file: dos_copy.c
* Provide the various functions needed for the COPY command
*/
#include <stdlib.h>
#include <string.h>
#include "dos_copy.h"
#include "constants.h"
#include "errors.h"
#include "simpleio.h"
#include "syscalls.h"
#include "utilities.h"
#include "dev/fsys.h"
/*
* Custom error codes for the COPY command
*/
#define ERR_COPY_SELF -1000
#define ERR_COPY_SRC_IS_DIR -1001
#define ERR_COPY_DST_IS_DIR -1002
#define ERR_COPY_NO_SRC_DIR -1003
#define ERR_COPY_NO_DST_DIR -1004
/**
* COPY is a complicated command, hence getting its own file.
* The command needs to deal with several types of source and destination path types:
*
* For the source file(s):
* S1. Fully specified absolute path to a single source file
* S2. Relative path to a single source file
* S3. Absolute path to one or more source files (pattern matching)
* S4. Relative path to one or more source files (pattern matching)
*
* For the destination:
* D1. Absolute path to the directory to store the file (filename implied)
* D2. Relative path to the directory (filename inmplied)
* D3. Absolute path to the file to create (filename provided)
* D4. Relative path to the file to create (filename provided)
*
* There are limitations: D1 and D2 may be used only if the source and destination
* directories are different, since we can't have the same file name twice in a directory.
* D3 and D4 may only be used in conjunction with S1 and S2, since S3 and S4 can specify
* multiple files, which cannot be copied to a single file.
*
* Additional rules:
* 1. COPY will not support copying an entire directory.
* (This means all source paths _must_ include a filename or pattern)
* 2. A file cannot be copied to the same directory with the same name.
* 3. Patterns (wildcards) may not be used for directory names.
*/
/**
* Check to see if the path points to a directory
*
* @param path the path to check
* @return 1 if the path points to a directory, 0 otherwise
*/
short is_directory(const char * path) {
t_file_info file;
short result = sys_fsys_stat(path, &file);
if ((result < 0) || ((file.attributes & FSYS_AM_DIR) == 0)) {
return 0;
}
return 1;
}
/**
* Perform the actual copy of the files, given the full paths to the files
*
* @param src_path the path to the source file to be copied
* @param dst_path the path to the destination file (will be deleted if it already exists)
* @return 0 on success, a negative number on error
*/
static short fsys_copy(const char * src_path, const char * dst_path) {
unsigned char buffer[256];
t_file_info file;
short fd_src = -1;
short fd_dst = -1;
short result = 0;
short n = 0;
// Check to make sure the source and destination paths are not the same
if (strcicmp(src_path, dst_path) == 0) {
// the two paths are the same... this is an error
return ERR_COPY_SELF;
}
// Check the source to make sure it exists and is not a directory
result = sys_fsys_stat(src_path, &file);
if (result < 0) {
// There was an error... file not found most likely
return result;
} else {
if (file.attributes & FSYS_AM_DIR) {
// The source path was a directory... this isn't allowed
return ERR_COPY_SRC_IS_DIR;
}
}
// Check the destination to make sure it is not a directory, if it exists
if (is_directory(dst_path)) {
// The source path was a directory... this isn't allowed
return ERR_COPY_DST_IS_DIR;
}
// Try to open the source file...
fd_src = sys_fsys_open(src_path, FSYS_READ);
if (fd_src > 0) {
// Ok... now try to open and create the destination file for writing...
fd_dst = sys_fsys_open(dst_path, FSYS_WRITE | FSYS_CREATE_ALWAYS);
if (fd_dst > 0) {
// Copy the file...
do {
// Try to read a chunk of data from the file
n = sys_chan_read(fd_src, buffer, 256);
if (n > 0) {
// Try to write what we got
result = sys_chan_write(fd_dst, buffer, n);
}
} while ((n > 0) && (result >= 0));
sys_fsys_close(fd_src);
sys_fsys_close(fd_dst);
return 0;
} else {
// Close the source file and return the error
sys_fsys_close(fd_src);
return fd_dst;
}
} else {
// There was an error... just return it
return fd_src;
}
}
/**
* Copy one or more file when the source contains a pattern
*
* NOTE: it is an error if the source and destination paths are the same
*
* @param src_path the path to the directory containing the source files
* @param src_pattern the search pattern used to find the files
* @param dst_path the path to the directory in which to store the files
* @result 0 on success, negative number on error
*/
static short fsys_copy_pattern(const char * src_path, const char * src_pattern, const char * dst_path) {
char src_file_path[MAX_PATH_LEN];
char dst_file_path[MAX_PATH_LEN];
char tmp[80];
t_file_info file;
short result = 0;
short dir = -1;
// Make sure the source and destination paths are not the same
if (strcicmp(src_path, dst_path) == 0) {
// the two paths are the same... this is an error
return ERR_COPY_SELF;
}
// Make sure the src_path exists and is a directory
result = sys_fsys_stat(src_path, &file);
if ((result < 0) || ((file.attributes & FSYS_AM_DIR) == 0)) {
return ERR_COPY_NO_SRC_DIR;
}
// Make sure the dst_path exists and is a directory
result = sys_fsys_stat(dst_path, &file);
if ((result < 0) || ((file.attributes & FSYS_AM_DIR) == 0)) {
return ERR_COPY_NO_DST_DIR;
}
dir = sys_fsys_findfirst(src_path, src_pattern, &file);
if (dir < 0) {
// Could not open the source directory for some reason
return dir;
}
// Try to copy each match...
while (strlen(file.name) > 0) {
// Figure out the source and destination paths to copy
sprintf(src_file_path, "%s%s", src_path, file.name);
sprintf(dst_file_path, "%s/%s", dst_path, file.name);
// Try to actually copy them
result = fsys_copy(src_file_path, dst_file_path);
if (result < 0) {
sys_fsys_closedir(dir);
return result;
}
// Try to get the next match
result = sys_fsys_findnext(dir, &file);
if (result < 0) {
sys_fsys_closedir(dir);
return result;
}
}
sys_fsys_closedir(dir);
return 0;
}
/**
* Make sure the provided path is absolute.
*
* If the path is not absolute, tack the current working directory onto the front of the path
*
* @param path the path to verify
* @return 0 on success, any other number is an error
*/
short fsys_copy_path_absolute(char * path) {
char tmp_path[MAX_PATH_LEN];
char cwd[MAX_PATH_LEN];
short result = 0;
if (path[0] != '/') {
// Path is not absolute... let's get the current working directory and fix that
result = fsys_get_cwd(cwd, MAX_PATH_LEN);
if (result) {
return result;
}
// Make a new, absolute path
sprintf(tmp_path, "%s%s", cwd, path);
// And copy it over the old path
strncpy(path, tmp_path, MAX_PATH_LEN);
}
return 0;
}
static fsys_copy_error(short screen, short n) {
char line[80];
switch (n) {
case ERR_COPY_SELF:
print(screen, "Unable to copy a file onto itself.\n");
break;
case ERR_COPY_NO_SRC_DIR:
print(screen, "Unable to copy a file: no source directory found.\n");
break;
case ERR_COPY_NO_DST_DIR:
print(screen, "Unable to copy a file: no destination directory found.\n");
break;
case ERR_COPY_SRC_IS_DIR:
print(screen, "Unable to copy a file: cannot copy a directory.\n");
break;
case ERR_COPY_DST_IS_DIR:
print(screen, "Unable to copy a file: cannot copy to a directory.\n");
break;
default:
sprintf(line, "Unable to copy the files: %d\n", n);
print(screen, line);
break;
}
}
/**
* The DOS COPY command itself:
* COPY <src path> <dst path>
*/
short cmd_copy(short screen, int argc, char * argv[]) {
char *x = 0;
char *src_path = 0;
char *src_pattern = 0;
char *dst_path = 0;
char *dst_name = 0;
char *tmp_path = 0;
char * src_solidus = 0;
char * dst_solidus = 0;
short result = 0;
// Allocate memory for the paths, etc.
x = (char *)malloc(5 * MAX_PATH_LEN);
if (x == 0) {
print(screen, "Cannot copy: out of memory\n");
return -1;
}
// Distribute the memory across our buffers...
src_path = x;
src_pattern = src_path + MAX_PATH_LEN;
dst_path = src_pattern + MAX_PATH_LEN;
dst_name = dst_path + MAX_PATH_LEN;
tmp_path = dst_name + MAX_PATH_LEN;
if (argc != 3) {
print(screen, "USAGE: COPY <src path> <dst path>\n");
free(x);
return -1;
}
// Copy the source path and make sure it's absolute
strncpy(src_path, argv[1], MAX_PATH_LEN);
if (fsys_copy_path_absolute(src_path)) {
print(screen, "Unable to find the current working directory.\n");
free(x);
return -1;
}
// Copy the destination path and make sure it's absolute
strncpy(dst_path, argv[2], MAX_PATH_LEN);
if (fsys_copy_path_absolute(dst_path)) {
print(screen, "Unable to find the current working directory.\n");
free(x);
return -1;
}
// Find the last slash, so we can check the file name portion
src_solidus = strrchr(src_path, '/');
if (src_solidus) {
// Copy the file name field...
strncpy(src_pattern, src_solidus + 1, MAX_PATH_LEN);
if (strchr(src_pattern, '*') || strchr(src_pattern, '?')) {
// There is a pattern in the file name field... remove the pattern from the path
src_solidus[1] = 0;
result = fsys_copy_pattern(src_path, src_pattern, dst_path);
if (result) {
fsys_copy_error(screen, result);
free(x);
return -1;
}
} else {
// Just one file to copy...
// If the destination is a directory, add the source file name
if (is_directory(dst_path)) {
if (dst_path[strlen(dst_path)-1] == '/') {
sprintf(tmp_path, "%s%s", dst_path, src_pattern);
} else {
sprintf(tmp_path, "%s/%s", dst_path, src_pattern);
}
strcpy(dst_path, tmp_path);
}
// Attempt to make the copy
result = fsys_copy(src_path, dst_path);
if (result) {
char line[80];
fsys_copy_error(screen, result);
free(x);
return -1;
}
}
} else {
print(screen, "Unable to parse the source path.\n");
free(x);
return -1;
}
free(x);
return 0;
}

14
src/cli/dos_copy.h Normal file
View file

@ -0,0 +1,14 @@
/** @file: dos_copy.h
* Provide the various functions needed for the COPY command
*/
#ifndef __DOS_COPY_H
#define __DOS_COPY_H
/**
* The DOS COPY command itself:
* COPY <src path> <dst path>
*/
extern short cmd_copy(short screen, int argc, char * argv[]);
#endif

View file

@ -7,8 +7,12 @@
#include "simpleio.h"
#include "sys_general.h"
#include "syscalls.h"
#include "types.h"
#include "mem_cmds.h"
/* Pointer to a function taking void and returning void */
typedef void (*p_thunk)();
/*
* Print out the contents of a block of memory
*
@ -38,6 +42,27 @@ short mem_cmd_dump(short channel, int argc, const char * argv[]) {
}
}
void test_thunk() {
log(LOG_ERROR, "CALL is working.");
}
/*
* Command to start execution in supervisor mode at a location in memory:
*
* CALL <address>
*/
short mem_cmd_call(short channel, int argc, const char * argv[]) {
p_thunk thunk = 0;
TRACE ("mem_cmd_call");
thunk = (p_thunk)cli_eval_number(argv[1]);
if (thunk) {
thunk();
}
return 0;
}
short mem_cmd_dasm(short channel, int argc, const char * argv[]) {
unsigned long address = 0;
long count = 1000;

View file

@ -7,6 +7,13 @@
#include "dis68k.h"
/*
* Command to start execution in supervisor mode at a location in memory:
*
* CALL <address>
*/
extern short mem_cmd_call(short channel, int argc, const char * argv[]);
/*
* Print out the contents of a block of memory
*
@ -63,4 +70,11 @@ extern short mem_cmd_poke32(short channel, int argc, const char * argv[]);
*/
extern short mem_cmd_peek32(short channel, int argc, const char * argv[]);
/*
* Command to start execution in supervisor mode at a location in memory:
*
* CALL <address>
*/
extern short mem_cmd_call(short channel, int argc, const char * argv[]);
#endif

View file

@ -18,10 +18,15 @@
#include "interrupt.h"
#include "rtc_reg.h"
#include "dev/rtc.h"
#include "dev/text_screen_iii.h"
#include "dev/txt_screen.h"
#include "snd/codec.h"
#include "utilities.h"
#include "vicky_general.h"
#if MODEL == MODEL_FOENIX_A2560K
#include "dev/kbd_mo.h"
#endif
#define MAX_SETTING_NAME 64
#define MAX_SETTING_HELP 80
@ -138,8 +143,8 @@ p_setting cli_find_setting(const char * name) {
short cli_set_value(short channel, const char * name, const char * value) {
p_setting setting = cli_find_setting(name);
if (setting == 0) {
/* Setting not found... */
return ERR_NOT_FOUND;
/* Setting not found: set a system variable */
return sys_var_set(name, value);
} else {
/* Attempt to set the value, and return the results */
@ -161,8 +166,15 @@ short cli_set_value(short channel, const char * name, const char * value) {
short cli_get_value(short channel, const char * name, char * buffer, short size) {
p_setting setting = cli_find_setting(name);
if (setting == 0) {
/* Setting not found... */
/* Setting not found: try to get an environment variable */
const char * value = sys_var_get(name);
if (value) {
strncpy(buffer, value, size);
return 0;
} else {
return ERR_NOT_FOUND;
}
} else {
/* Attempt to set the value, and return the results */
@ -409,44 +421,92 @@ short cli_time_get(short channel, char * value, short size) {
return 0;
}
/*
* Font setter -- SET FONT <path>
*/
short cli_font_set(short screen, const char * value) {
/* Open the file */
short chan = fsys_open(value, 0x01);
if (chan > 0) {
int i;
for (i = 0; i < 8 * 256; i++) {
short b = sys_chan_read_b(chan);
if (b >= 0) {
VICKY_TXT_FONT_A[i] = (unsigned char)b;
} else {
short cli_set_font(short screen, const char * path) {
const unsigned long load_address = 0x10000;
unsigned long jump_address = 0;
char message[80];
t_file_info filinfo;
/* Reset the text screen */
text_init();
fsys_close(chan);
sprintf(message, "Unable to read font file: %d\n", b);
sys_chan_write(screen, message, strlen(message));
return -1;
}
}
fsys_close(chan);
short result = sys_fsys_stat(path, &filinfo);
if (result == 0) {
if (filinfo.size == 256 * 8) {
// It's a simple 8x8 font
result = sys_fsys_load(path, load_address, &jump_address);
if (result == 0) {
sys_txt_set_font(screen, 8, 8, (unsigned char *)load_address);
return 0;
} else {
print(screen, "Could not load font file.\n");
return -1;
return result;
}
} else {
// It's 8x16.. check to make sure this device can support that
p_txt_capabilities txt_caps = sys_txt_get_capabilities(screen);
if (txt_caps != 0) {
short supports_8x16 = 0;
int i;
for (i = 0; i < txt_caps->font_size_count; i++) {
p_extent font_size = &(txt_caps->font_sizes[i]);
if ((font_size->width == 8) && (font_size->height == 16)) {
// 8x16 is supported... load the font
result = sys_fsys_load(path, load_address, &jump_address);
if (result == 0) {
sys_txt_set_font(screen, 8, 16, (unsigned char *)load_address);
return 0;
} else {
return result;
}
}
}
/*
* Font setter -- GET FONT <path>
// 8x16 is not a supported font size
return ERR_NOT_SUPPORTED;
} else {
return -1;
}
}
} else {
return result;
}
}
/**
* Font@0 setter -- SET FONT@0 <path>
*
* Sets the font for the main screen (channel B)
*/
short cli_font_get(short channel, char * value, short size) {
/* We don't keep the font path */
*value = 0;
short cli_font0_set(short screen, const char * value) {
// Load the font into memory
short result = cli_set_font(0, value);
return result;
}
/**
* Font@0 getter -- GET FONT@0
*/
short cli_font0_get(short screen, char * value, short size) {
value[0] = 0;
return 0;
}
/**
* Font@1 setter -- SET FONT@1 <path>
*
* Sets the font for the secondary screen (channel A or EVID)
*/
short cli_font1_set(short screen, const char * value) {
// Load the font into memory
short result = cli_set_font(1, value);
return result;
}
/**
* Font@0 getter -- GET FONT@0
*/
short cli_font1_get(short screen, char * value, short size) {
value[0] = 0;
return 0;
}
@ -496,21 +556,114 @@ short cli_layout_set(short channel, const char * value) {
* Get the keyboard layout given a keyboard layout file -- GET LAYOUT
*/
short cli_layout_get(short channel, char * value, short size) {
value[0] = 0;
return 0;
}
#if MODEL == MODEL_FOENIX_A2560K
unsigned short kbd_mo_color = 0x0000;
short cli_keycolor_set(short channel, const char * value) {
kbd_mo_color = (unsigned short)cli_eval_number(value);
kbdmo_set_led_matrix_fill(kbd_mo_color);
return 0;
}
short cli_keycolor_get(short channel, char * value, short size) {
sprintf(value, "%04x", kbd_mo_color);
return 0;
}
#endif
/**
* Set the number of the text screen to use for interactions
*/
short cli_screen_set(short channel, const char * value) {
char message[80];
t_sys_info info;
short screen = (short)cli_eval_number(value);
sys_get_info(&info);
if (screen < info.screens) {
cli_txt_screen_set(screen);
} else {
sprintf(message, "Screen #%d not present.\n", screen);
print(channel, message);
}
return 0;
}
/**
* Get the number of the text screen to use for interactions
*/
short cli_screen_get(short channel, char * value, short size) {
sprintf(value, "%d", cli_txt_screen_get());
return 0;
}
/**
* Set the path to the command processor "CLI" for built-in command processor
*/
short cli_shell_set(short channel, const char * value) {
if (strcicmp(value, "cli") == 0) {
cli_command_set(0);
} else {
cli_command_set(value);
}
return 0;
}
/**
* Get the path to the command processor "CLI" for built-in command processor
*/
short cli_shell_get(short channel, char * value, short size) {
char tmp[255];
// Get the path...
cli_command_get(tmp);
// If it's empty... return that CLI is the current setting
if (strlen(tmp) == 0) {
strncpy(value, "cli", size);
} else {
strncpy(value, tmp, size);
}
return 0;
}
/*
* Initialize the settings tables
*/
void cli_set_init() {
t_sys_info info;
cli_first_setting = 0;
cli_last_setting = 0;
sys_get_info(&info);
cli_set_register("DATE", "DATE yyyy-mm-dd -- set the date in the realtime clock", cli_date_set, cli_date_get);
// cli_set_register("RTC", "RTC 1|0 -- Enable or disable the realtime clock interrupt", cli_rtc_set, cli_rtc_get);
// cli_set_register("SOF", "SOF 1|0 -- Enable or disable the Start of Frame interrupt", cli_sof_set, cli_sof_get);
cli_set_register("FONT", "FONT <path> -- set a font for the display", cli_font_set, cli_font_get);
cli_set_register("KEYBOARD", "KEYBOARD <path> -- set the keyboard layout", cli_layout_set, cli_layout_get);
cli_set_register("TIME", "TIME HH:MM:SS -- set the time in the realtime clock", cli_time_set, cli_time_get);
cli_set_register("VOLUME", "VOLUME <0 - 255> -- set the master volume", cli_volume_set, cli_volume_get);
if (info.screens == 1) {
cli_set_register("FONT", "FONT <path> -- set a font for the display", cli_font0_set, cli_font0_get);
} else {
cli_set_register("FONT@0", "FONT@0 <path> -- set a font for the display #0", cli_font0_set, cli_font0_get);
cli_set_register("FONT@1", "FONT@1 <path> -- set a font for the display #1", cli_font1_set, cli_font1_get);
}
cli_set_register("KEYBOARD", "KEYBOARD <path> -- set the keyboard layout", cli_layout_set, cli_layout_get);
if (info.model == MODEL_FOENIX_A2560K) {
cli_set_register("KEYCOLOR", "KEYCOLOR 0x0RGB -- set the keyboard color", cli_keycolor_set, cli_keycolor_get);
}
if (info.screens > 1) {
cli_set_register("SCREEN", "SCREEN <0 - 1> -- set the channel number to use for interactions", cli_screen_set, cli_screen_get);
}
cli_set_register("SHELL", "SHELL <path> -- set the path for the command processor shell", cli_shell_set, cli_shell_get);
cli_set_register("TIME", "TIME HH:MM:SS -- set the time in the realtime clock", cli_time_set, cli_time_get);
}

File diff suppressed because it is too large Load diff

View file

@ -10,15 +10,25 @@
*/
extern short psg_test(short channel, int argc, const char * argv[]);
/*
* Play a sound on the SID
*/
extern short sid_test(short channel, int argc, const char * argv[]);
/*
* Play a sound on the OPL3
*/
extern short opl3_test(short channel, int argc, const char * argv[]);
/*
* Test the OPL2
* Play a sound on the OPM
*/
extern short opl2_test(short channel, int argc, const char * argv[]);
extern short opm_test(short channel, int argc, const char * argv[]);
/*
* Play a sound on the OPN
*/
extern short opn_test(short channel, int argc, const char * argv[]);
/*
* Perform a transmit test on the MIDI ports

View file

@ -3,21 +3,25 @@
*/
#include <ctype.h>
#include <string.h>
#include <stdio.h>
#include <string.h>
#include "cli.h"
#include "cli/test_cmds.h"
#include "cli/sound_cmds.h"
#include "dev/block.h"
#include "dev/channel.h"
#include "dev/fdc.h"
#include "dev/fsys.h"
#include "dev/lpt.h"
#include "dev/rtc.h"
#include "dev/txt_screen.h"
#include "dev/uart.h"
#include "fatfs/ff.h"
#include "interrupt.h"
#include "log.h"
#include "fdc_reg.h"
#include "lpt_reg.h"
#include "dev/ps2.h"
#include "rtc_reg.h"
#include "simpleio.h"
@ -26,28 +30,9 @@
#include "uart_reg.h"
#include "vicky_general.h"
#define LPT_DATA_PORT ((volatile unsigned char *)0x00C02378)
#define LPT_STAT_PORT ((volatile unsigned char *)0x00C02379)
#define LPT_STAT_BUSY 0x80
#define LPT_STAT_ACK 0x40
#define LPT_STAT_PO 0x20
#define LPT_STAT_SELECT 0x10
#define LPT_STAT_ERROR 0x08
#define LPT_STAT_IRQ 0x04
#define LPT_CTRL_PORT ((volatile unsigned char *)0x00C0237A)
#define LPT_CTRL_STROBE 0x01
#define LPT_CTRL_AL 0x02
#define LPT_CTRL_INIT 0x04
#define LPT_CTRL_SELECT 0x08
#define LPT_CTRL_IRQE 0x10
#define LPT_CTRL_BI 0x20
#define LPT_INIT_ON 0x08 /* Start the printer initialization process */
#define LPT_INIT_OFF 0x0C /* Stop the printer initialization process */
#define LPT_STROBE_ON 0x0F /* Strobe the printer */
#define LPT_STROBE_OFF 0x0E /* Drop the strobe to the printer */
#if MODEL == MODEL_FOENIX_A2560K
#include "dev/kbd_mo.h"
#endif
typedef struct s_cli_test_feature {
const char * name;
@ -59,12 +44,142 @@ typedef struct s_cli_test_feature {
* Tests...
*/
/*
* Return true if the BREAK key has been pressed
*/
short kbd_break() {
/* Channel 0, CON_IOCTRL_BREAK */
return sys_chan_ioctrl(0, 5, 0, 0);
}
/*
* Test the PS/2 keyboard
*/
short cli_test_ps2(short channel, int argc, const char * argv[]) {
char message[80];
unsigned short scancode = 0;
sprintf(message, "Press keys on a PS/2 keyboard... CTRL-C to quit.\n");
sys_chan_write(channel, message, strlen(message));
do {
if (scancode != 0) {
sprintf(message, "Scan code: %04x\n", scancode);
sys_chan_write(channel, message, strlen(message));
}
} while (sys_chan_ioctrl(channel, 0x05, 0, 0) == 0);
return 0;
}
/*
* Test the joystick ports
*/
short cli_test_joystick(short channel, int argc, const char * argv[]) {
char message[80];
volatile unsigned int * joystick_port = (volatile unsigned int *)0xFEC00500;
volatile unsigned int * game_ctrl_port = (volatile unsigned int *)0xFEC00504;
unsigned int joy_state = 0, old_joy_state = 0xffffffff;
unsigned short scancode = 0;
sprintf(message, "Plug a joystick into either port 0 or port 1... ESC to quit.\n");
sys_chan_write(channel, message, strlen(message));
/* Make sure we're in Atari joystick mode */
*game_ctrl_port = 0;
do {
joy_state = *joystick_port;
if (joy_state != old_joy_state) {
old_joy_state = joy_state;
sprintf(message, "Joystick: %08X\n", joy_state);
sys_chan_write(channel, message, strlen(message));
}
scancode = sys_kbd_scancode();
} while (sys_chan_ioctrl(channel, 5, 0, 0) == 0);
return 0;
}
/*
* Test SNES gamepads
*/
short cli_test_gamepad(short channel, int argc, const char * argv[]) {
char message[80];
volatile unsigned int * game_ctrl_port = (volatile unsigned int *)0xFEC00504;
volatile unsigned int * game_0_0_port = (volatile unsigned int *)0xFEC00508;
volatile unsigned int * game_0_1_port = (volatile unsigned int *)0xFEC0050C;
volatile unsigned int * game_1_0_port = (volatile unsigned int *)0xFEC00510;
volatile unsigned int * game_1_1_port = (volatile unsigned int *)0xFEC00514;
unsigned int game_ctrl;
unsigned int game_status;
unsigned int game_state_0 = 0;
unsigned int game_state_1 = 0;
unsigned int old_game_state_0 = 0xffffffff;
unsigned int old_game_state_1 = 0xffffffff;
unsigned short scancode = 0;
unsigned short port = 0;
if (argc > 1) {
port = (unsigned short)(cli_eval_number(argv[1]) & 0x0000ffff);
if (port > 1) {
port = 1;
}
}
sprintf(message, "Testing SNES gamepad port %d... ESC to quit.\n", (short)port);
sys_chan_write(channel, message, strlen(message));
/* Make sure we're in SNES mode */
if (port == 0) {
/* Port #0 is SNES */
game_ctrl = 0x00000005;
} else {
/* Port #1 is SNES */
game_ctrl = 0x0000000A;
}
*game_ctrl_port = game_ctrl;
while (scancode != 0x01) {
/* Start transferring the data and wait for completion */
*game_ctrl_port = game_ctrl | 0x00000080;
do {
game_status = *game_ctrl_port;
} while ((game_status & 0x00000040) == 0) ;
if (port == 0) {
game_state_0 = *game_0_0_port;
game_state_1 = *game_0_1_port;
} else {
game_state_0 = *game_1_0_port;
game_state_1 = *game_1_1_port;
}
if ((game_state_0 != old_game_state_0) || (game_state_1 != old_game_state_1)) {
old_game_state_0 = game_state_0;
old_game_state_1 = game_state_1;
sprintf(message, "Gamepads: %08X %08X\n", game_state_0, game_state_1);
sys_chan_write(channel, message, strlen(message));
}
scancode = sys_kbd_scancode();
}
*game_ctrl_port = 0;
return 0;
}
short cli_test_bitmap(short channel, int argc, const char * argv[]) {
int i,m,p;
unsigned char j;
unsigned short k;
short scan_code;
// Switch to bitmap mode
sys_txt_set_mode(0, TXT_MODE_BITMAP);
*MasterControlReg_A = VKY3_MCR_BITMAP_EN | VKY3_MCR_GRAPH_EN; // Enable bitmap graphics
*BM0_Control_Reg = 0x00000001; // Enable BM0
*BM0_Addy_Pointer_Reg = 0x00000000; //Pointing to Starting of VRAM Bank A
// *BorderControlReg_L = 0x00000800; // Enable
@ -80,36 +195,77 @@ short cli_test_bitmap(short channel, int argc, const char * argv[]) {
VRAM_Bank0[i] = i & 0xff;
}
do {
scan_code = sys_kbd_scancode();
} while (scan_code != 0x01);
// Go back to text mode
sys_txt_set_mode(0, TXT_MODE_TEXT);
return 0;
}
/**
* Test for the serial ports
*
* TEST UART [1 | 2]
*/
short cli_test_uart(short channel, int argc, const char * argv[]) {
char c;
char c, c_out;
short scan_code;
char buffer[80];
short cdev = CDEV_COM1;
short uart = -1;
short uart_index = 0;
unsigned long uart_address = 0;
uart_init(0);
uart_setbps(0, UART_115200);
uart_setlcr(0, LCR_DATABITS_8 | LCR_STOPBIT_1 | LCR_PARITY_NONE);
sprintf(buffer, "COM1: 115200, no parity, 1 stop bit, 8 data bits\nPress ESC to finish (%d).\n", UART_115200);
sys_chan_write(0, buffer, strlen(buffer));
for (;;) {
c = kbd_getc();
if (c != 0) {
if (c == 0x1b) {
return 0;
if (argc > 1) {
// Get the COM port number
short port = (short)cli_eval_number(argv[1]);
if (port <= 1) cdev = CDEV_COM1;
if (port >= 2) cdev = CDEV_COM2;
}
uart_put(0, c);
} else if (uart_has_bytes(0)) {
c = uart_get(0);
uart_index = cdev - CDEV_COM1;
uart_address = (unsigned long)uart_get_base(uart_index);
sprintf(buffer, "Serial port loopback test of COM%d at 0x%08X...\n", cdev - CDEV_COM1 + 1, uart_address);
print(channel, buffer);
uart = sys_chan_open(cdev, "9600,8,1,NONE", 0);
if (uart >= 0) {
sprintf(buffer, "COM%d: 9600, no parity, 1 stop bit, 8 data bits\nPress ESC to finish.\n", cdev - CDEV_COM1 + 1);
print(channel, buffer);
c_out = ' ';
do {
sys_chan_write_b(uart, c_out++);
if (c_out > '}') {
c_out = ' ';
sys_chan_write_b(uart, '\r');
sys_chan_write_b(uart, '\n');
}
if (sys_chan_status(uart) & CDEV_STAT_READABLE) {
c = sys_chan_read_b(uart);
if (c != 0) {
sys_chan_write_b(channel, c);
}
}
scan_code = sys_kbd_scancode();
} while (scan_code != 0x01);
} else {
sprintf(buffer, "Unable to open the serial port: %d\n", uart);
print(channel, buffer);
}
return 0;
}
/**
* Do a simple test of a kernel panic using division by zero
*/
short cli_test_panic(short channel, int argc, const char * argv[]) {
volatile int x = 0;
return argc / x;
@ -149,55 +305,203 @@ short cli_test_rtc(short channel, int argc, const char * argv[]) {
/*
* Test the memory
* MEM [SYS|MERA]
*/
short cli_mem_test(short channel, int argc, const char * argv[]) {
volatile unsigned char * memory = 0x00000000;
t_sys_info sys_info;
const long mem_start = 0x00050000; /* TODO find out better where the kernel stop */
long mem_end;
unsigned long mem_start = 0x00010000;
unsigned long mem_end = sys_mem_get_ramtop();
char message[80];
long i;
unsigned long i;
sys_get_info(&sys_info);
mem_end = sys_info.system_ram_size;
#if MODEL == MODEL_FOENIX_A2560K
if (argc > 1) {
if ((strcmp(argv[1], "MERA") == 0) || (strcmp(argv[1], "mera") == 0)) {
mem_start = 0x02000000;
mem_end = 0x06000000;
sprintf(message, "\x1B[H\x1B[2JTesting memory...");
sys_chan_write(channel, message, strlen(message));
print(channel, "\x1B[H\x1B[2JTesting MERA memory...");
}
}
#endif
sprintf(message, "\x1B[H\x1B[2JTesting memory from 0x%08X to 0x%08X\n", (unsigned long)mem_start, (unsigned long)mem_end);
print(channel, message);
for (i = mem_start; i < mem_end; i++) {
memory[i] = 0x55; /* Every other bit starting with 1 */
if (memory[i] != 0x55) {
sprintf(message, "\x1B[1;2H\x1B[KFailed to write 0x55... read %02X at %p\n\n", memory[i], (void*)i);
sys_chan_write(channel, message, strlen(message));
print(channel, message);
return ERR_GENERAL;
}
memory[i] = 0xAA; /* Every other bit starting with 0 */
if (memory[i] != 0xAA) {
sprintf(message, "\x1B[1;2H\x1B[KFailed to write 0xAA... read %02X at %p\n\n", memory[i], (void*)i);
sys_chan_write(channel, message, strlen(message));
print(channel, message);
return ERR_GENERAL;
}
memory[i] = 0x00;
if (memory[i] != 0x00) {
sprintf(message, "\x1B[1;2H\x1B[KFailed to write 0x00... read %02X at %p\n\nX", memory[i], (void*)i);
sys_chan_write(channel, message, strlen(message));
print(channel, message);
return ERR_GENERAL;
}
if ((i % 1024) == 0) {
sprintf(message, "\x1B[H\x1B[0KMemory tested: %p", (void*)i);
sys_chan_write(channel, message, strlen(message));
sprintf(message, "\x1B[1;2H\x1B[0KMemory tested: %p", (void*)i);
print(channel, message);
}
}
sprintf(message, "\x1B[H\x1B[2JMemory passed basic tests.\n\n");
sys_chan_write(channel, message, strlen(message));
print(channel, "\x1B[1;3H\x1B[0KMemory passed basic tests.\n\n");
return 0;
}
#if MODEL == MODEL_FOENIX_A2560K
short cli_test_recalibrate(short screen, int argc, const char * argv[]) {
unsigned char buffer[512];
short i;
short result;
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_ON, 0, 0);
sprintf(buffer, "Recalibrating the floppy drive\n");
sys_chan_write(screen, buffer, strlen(buffer));
if (fdc_recalibrate() == 0) {
sprintf(buffer, "Success\n");
sys_chan_write(screen, buffer, strlen(buffer));
} else {
sprintf(buffer, "Failed\n");
sys_chan_write(screen, buffer, strlen(buffer));
}
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_OFF, 0, 0);
return 0;
}
short cli_test_seek(short screen, int argc, const char * argv[]) {
unsigned char buffer[512];
short i;
unsigned char cylinder;
short result;
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_ON, 0, 0);
cylinder = (unsigned char)cli_eval_number(argv[1]);
sprintf(buffer, "Seeking to %d\n", (short)cylinder);
sys_chan_write(screen, buffer, strlen(buffer));
if (fdc_seek(cylinder) == 0) {
sprintf(buffer, "Success\n");
sys_chan_write(screen, buffer, strlen(buffer));
} else {
sprintf(buffer, "Failed\n");
sys_chan_write(screen, buffer, strlen(buffer));
}
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_OFF, 0, 0);
return 0;
}
/*
* Test the FDC interface by reading the MBR
*
* TEST FDC DSKCHG | [<lba> [WRITE <data>]]
*/
short cli_test_fdc(short screen, int argc, const char * argv[]) {
unsigned char buffer[512];
char message[80];
unsigned long lba = 0;
short i;
short scancode;
short n = 0;
short result;
short is_write = 0;
short is_change_test = 0;
unsigned char data = 0xAA;
if (argc > 1) {
if ((strcmp(argv[1], "DSKCHG") == 0) || (strcmp(argv[1], "dskchg") == 0)) {
is_change_test = 1;
} else {
lba = (unsigned long)cli_eval_number(argv[1]);
if (argc > 2) {
print(screen, "Will attempt to write before reading...\n");
is_write = 1;
data = (unsigned long)cli_eval_number(argv[3]);
}
}
}
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_ON, 0, 0);
if (is_change_test) {
// long target_jiffies = sys_time_jiffies() + 240;
// while (target_jiffies > sys_time_jiffies()) ;
sprintf(message, "FDC_DIR: %02X\n", *FDC_DIR);
print(screen, message);
print(screen, "Recalibrating... ");
fdc_recalibrate();
fdc_seek(1);
print(screen, "done\n");
sprintf(message, "FDC_DIR: %02X\n", *FDC_DIR);
print(screen, message);
} else {
result = bdev_init(BDEV_FDC);
if (result != 0) {
sprintf(buffer, "Could not initialize FDC: %s\n", sys_err_message(result));
sys_chan_write(screen, buffer, strlen(buffer));
return result;
}
for (i = 0; i < 512; i++) {
buffer[i] = data;
}
if (is_write) {
n = bdev_write(BDEV_FDC, lba, buffer, 512);
if (n < 0) {
dump_buffer(screen, buffer, 512, 1);
sprintf(message, "Unable to write sector %d: %s\n", lba, err_message(n));
print(screen, message);
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_OFF, 0, 0);
return n;
}
}
for (i = 0; i < 512; i++) {
buffer[i] = 0xAA;
}
n = bdev_read(BDEV_FDC, lba, buffer, 512);
if (n < 0) {
dump_buffer(screen, buffer, 512, 1);
sprintf(message, "Unable to read sector %d: %s\n", lba, err_message(n));
print(screen, message);
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_OFF, 0, 0);
return n;
}
dump_buffer(screen, buffer, 512, 1);
print(screen, "\n\n");
}
bdev_ioctrl(BDEV_FDC, FDC_CTRL_MOTOR_OFF, 0, 0);
}
#endif
/*
* Test the IDE interface by reading the MBR
*/
@ -218,6 +522,8 @@ short cli_test_ide(short screen, int argc, const char * argv[]) {
print(screen, "\n\n");
return 0;
scancode = sys_kbd_scancode();
if (scancode == 0x01) {
break;
@ -261,49 +567,76 @@ short cli_test_lpt(short screen, int argc, const char * argv[]) {
char message[80];
unsigned char scancode;
sprintf(message, "Test parallel port:\nF1: DATA=00 F2: DATA=FF F3: STRB=1 F4: STRB=0\n");
sprintf(message, "Test parallel port:\nF1: DATA='B' F2: DATA='A' F3: STRB=1 F4: STRB=0\n");
sys_chan_write(screen, message, strlen(message));
sprintf(message, "F5: INIT=1 F6: INIT=0 F7: SEL=1 F8: SEL=0\nESC: Quit");
sprintf(message, "F5: INIT=1 F6: INIT=0 F7: SEL=1 F8: SEL=0\nESC: Quit\n");
sys_chan_write(screen, message, strlen(message));
unsigned char ctrl = 0;
*LPT_CTRL_PORT = ctrl;
while (1) {
scancode = sys_kbd_scancode();
switch (scancode) {
case 0x3B: /* F1 */
*LPT_DATA_PORT = 0;
print(0, "DATA = 'B'\n");
*LPT_DATA_PORT = 'B';
break;
case 0x3C: /* F2 */
*LPT_DATA_PORT = 0xff;
print(0, "DATA = 'A'\n");
*LPT_DATA_PORT = 'A';
break;
case 0x3D: /* F3 */
*LPT_CTRL_PORT = LPT_CTRL_STROBE;
ctrl |= LPT_CTRL_STROBE;
*LPT_CTRL_PORT = ctrl;
sprintf(message, "STROBE = TRUE [%02X]\n", ctrl);
print(0, message);
break;
case 0x3E: /* F4 */
*LPT_CTRL_PORT = 0;
ctrl &= ~LPT_CTRL_STROBE;
*LPT_CTRL_PORT = ctrl;
sprintf(message, "STROBE = FALSE [%02X]\n", ctrl);
print(0, message);
break;
case 0x3F: /* F5 */
*LPT_CTRL_PORT = 0;
ctrl |= LPT_CTRL_mINIT;
*LPT_CTRL_PORT = ctrl;
sprintf(message, "INIT = TRUE [%02X]\n", ctrl);
print(0, message);
break;
case 0x40: /* F6 */
*LPT_CTRL_PORT = LPT_CTRL_INIT;
ctrl &= ~LPT_CTRL_mINIT;
*LPT_CTRL_PORT = ctrl;
sprintf(message, "INIT = FALSE [%02X]\n", ctrl);
print(0, message);
break;
case 0x41: /* F7 */
*LPT_CTRL_PORT = LPT_CTRL_SELECT;
ctrl |= LPT_CTRL_SELECT;
*LPT_CTRL_PORT = ctrl;
sprintf(message, "SELECT = TRUE [%02X]\n", ctrl);
print(0, message);
break;
case 0x42: /* F8 */
*LPT_CTRL_PORT = 0;
ctrl &= ~LPT_CTRL_SELECT;
*LPT_CTRL_PORT = ctrl;
sprintf(message, "SELECT = FALSE [%02X]\n", ctrl);
print(0, message);
break;
case 0x1B: /* ESC */
case 0x01: /* ESC */
return 0;
case 0x02: /* 1 */
*LPT_DATA_PORT = '\r';
break;
default:
break;
}
@ -319,37 +652,156 @@ short cmd_test_print(short screen, int argc, const char * argv[]) {
char message[80];
unsigned short scancode = 0;
sprintf(message, "Initializing printer...\n");
sys_chan_write(screen, message, strlen(message));
print(screen, "Initializing printer...\n");
lpt_initialize();
sprintf(message, "Sending test patterns to printer (ESC to quit)...\n");
sys_chan_write(screen, message, strlen(message));
short lpt = sys_chan_open(CDEV_LPT, 0, 0);
if (lpt > 0) {
print(screen, "Sending test patterns to printer (ESC to quit)...\n");
while (scancode != 0x01) {
short result = sys_chan_write(lpt, test_pattern, strlen(test_pattern));
if (result != 0) {
sprintf(message, "Unable to print: %s\n", err_message(result));
print(screen, message);
sprintf(message, "Printer status: %02X\n", sys_chan_status(lpt));
print(screen, message);
break;
}
scancode = sys_kbd_scancode();
lpt_write(0, test_pattern, strlen(test_pattern));
}
sys_chan_close(lpt);
} else if (lpt == 0) {
print(screen, "Unable to print: got a bad channel number.\n");
} else {
sprintf(message, "Could not open channel to printer: %s\n", err_message(lpt));
print(screen, message);
}
#endif
return 0;
}
/**
* Test the ANSI escape codes
*/
short cmd_test_ansi(short screen, int argc, const char * argv[]) {
t_rect old_region, region;
char buffer[255];
// Clear the screen and home the cursor
print(screen, "\x1b[2J\x1b[H0_________1_________2_________3_________\n");
print(screen, "0123456789012345678901234567890123456789\n");
// Test some positioning
print(screen, "\x1b[21;3H20\x1b[50;1H\x1b[31m\x03\x1b[B\x1b[30m\x05\x1b[3D\x06\x1b[1B\x1b[31m\x04\n");
// Test color bars
for (int i = 0; i < 8; i++) {
char * color_name;
switch (i) {
case 0: color_name = "BLACK"; break;
case 1: color_name = "RED"; break;
case 2: color_name = "GREEN"; break;
case 3: color_name = "YELLOW"; break;
case 4: color_name = "BLUE"; break;
case 5: color_name = "ORANGE"; break;
case 6: color_name = "CYAN"; break;
case 7: color_name = "GREY"; break;
default: color_name = "???"; break;
}
sprintf(buffer, "\x1b[%dm%10s\x1b[37;44m \x1b[30;%dm%10s\x1b[37;44m", 30 + i, color_name, 40 + i, color_name);
sys_chan_write(screen, buffer, strlen(buffer));
sprintf(buffer, "\t\x1b[%dm%10s\x1b[37;44m \x1b[30;%dm%10s\x1b[37;44m\n", 90 + i, color_name, 100 + i, color_name);
sys_chan_write(screen, buffer, strlen(buffer));
}
print(screen, "\x1b[1;13H0123456789ABCDEF\x1b[6;13H\x1b[2@^^\x1b[20;13H<--2 characters inserted");
print(screen, "\x1b[1;14H0123456789ABCDEF\x1b[6;14H\x1b[2P\x1b[20;14H<--2 characters deleted");
print(screen, "\x1b[1;15H0123456789ABCDEF\x1b[8;15H\x1b[0K\x1b[20;15H<--2nd half of line deleted");
print(screen, "\x1b[1;16H0123456789ABCDEF\x1b[8;16H\x1b[1K\x1b[20;16H<--1st half of line deleted");
print(screen, "\x1b[1;17H0123456789ABCDEF\x1b[8;17H\x1b[2K\x1b[20;17H<-- Whole line deleted...\n");
print(screen, "\x1b[1;20HDelete 2nd Half\x1b[22;20HDelete 1st Half\x1b[43;20HDelete All");
txt_get_region(screen, &old_region);
region.origin.x = 0;
region.origin.y = 20;
region.size.width = 20;
region.size.height = 10;
txt_set_region(screen, &region);
txt_fill(screen, 'X');
region.origin.x = 1;
region.origin.y = 21;
region.size.width = 18;
region.size.height = 8;
txt_set_region(screen, &region);
print(screen, "\x1b[10;4H\x1b[0J");
region.origin.x = 21;
region.origin.y = 20;
region.size.width = 20;
region.size.height = 10;
txt_set_region(screen, &region);
txt_fill(screen, 'X');
region.origin.x = 22;
region.origin.y = 21;
region.size.width = 18;
region.size.height = 8;
txt_set_region(screen, &region);
print(screen, "\x1b[10;4H\x1b[1J");
region.origin.x = 42;
region.origin.y = 20;
region.size.width = 20;
region.size.height = 10;
txt_set_region(screen, &region);
txt_fill(screen, 'X');
region.origin.x = 43;
region.origin.y = 21;
region.size.width = 18;
region.size.height = 8;
txt_set_region(screen, &region);
print(screen, "\x1b[1;4H\x1b[2J");
txt_set_region(screen, &old_region);
print(screen, "\x1b[1;35H\x1b[0;44;37mDone!\n");
return 0;
}
const t_cli_test_feature cli_test_features[] = {
{"ANSI", "ANSI: test the ANSI escape codes", cmd_test_ansi},
{"BITMAP", "BITMAP: test the bitmap screen", cli_test_bitmap},
{"CREATE", "CREATE <path>: test creating a file", cli_test_create},
{"IDE", "IDE: test reading the MBR of the IDE drive", cli_test_ide},
{"PANIC", "PANIC: test the kernel panic mechanism", cli_test_panic},
#if MODEL == MODEL_FOENIX_A2560K
{"FDC", "FDC DSKCHG | [<lba> [WRITE <data>]]: test reading/writing the MBR from the floppy drive", cli_test_fdc},
{"GAMEPAD", "GAMEPAD [0 | 1]: test SNES gamepads", cli_test_gamepad},
{"JOY", "JOY: test the joystick", cli_test_joystick},
#endif
{"LPT", "LPT: test the parallel port", cli_test_lpt},
{"MEM", "MEM: test reading and writing memory", cli_mem_test},
{"MEM", "MEM [SYS|MERA]: test reading and writing of system or MERA memory", cli_mem_test},
{"MIDILOOP", "MIDILOOP: perform a loopback test on the MIDI ports", midi_loop_test},
{"MIDIRX", "MIDIRX: perform a receive test on the MIDI ports", midi_rx_test},
{"MIDITX", "MIDITX: send a note to a MIDI keyboard", midi_tx_test},
{"OPL2", "OPL2: test the OPL2 sound chip", opl2_test},
{"OPL3", "OPL3: test the OPL3 sound chip", opl3_test},
{"PSG", "PSG: test the PSG sound chip", psg_test},
{"OPN", "OPN [EXT|INT]: test the OPN sound chip", opn_test},
{"OPM", "OPM [EXT|INT]: test the OPM sound chip", opm_test},
{"PANIC", "PANIC: test the kernel panic mechanism", cli_test_panic},
{"PS2", "PS2: test the PS/2 keyboard", cli_test_ps2},
{"PSG", "PSG [EXT|INTL|INTR|INTS]: test the PSG sound chip", psg_test},
{"PRINT", "PRINT: sent text to the printer", cmd_test_print},
{"UART", "UART: test the serial port", cli_test_uart},
#if MODEL == MODEL_FOENIX_A2560K
{"RECALIBRATE", "RECALIBRATE: recalibrate the floppy drive", cli_test_recalibrate},
{"SEEK", "SEEK <track>: move the floppy drive head to a track", cli_test_seek},
{"SID", "SID [EXT|INT]: test the SID sound chips", sid_test},
#endif
{"UART","UART [1|2]: test the serial port",cli_test_uart},
{"END", "END", 0}
};

View file

@ -1,6 +1,8 @@
csources = $(wildcard *.c)
cobjects = $(subst .c,.o,$(csources))
cobjects = $(subst .c,.o,$(csources))
.PHONY: all
all: $(cobjects)
@ -10,4 +12,4 @@ all: $(cobjects)
.PHONY: clean
clean:
$(RM) $(aobjects) $(cobjects) *.asm
$(RM) *.o *.asm

View file

@ -6,8 +6,11 @@
* Examples include: console, serial port, an open file, etc.
*/
#include <string.h>
#include "dev/channel.h"
#include "errors.h"
#include "simpleio.h"
#include "types.h"
#include "log.h"
@ -80,8 +83,8 @@ p_channel chan_alloc(short dev) {
TRACE("chan_alloc");
if ((dev == CDEV_CONSOLE) || (dev == CDEV_EVID)) {
/* For CONSOLE and EVID, the channel is always the same number as the device */
if ((dev >= CDEV_CONSOLE) && (dev < CDEV_FILE)) {
/* For most devices (all but files): the channel is always the same number as the device */
g_channels[dev].number = dev;
g_channels[dev].dev = dev;
return &g_channels[dev];
@ -171,7 +174,11 @@ short cdev_init(short dev) {
if (dev < CDEV_DEVICES_MAX) {
p_dev_chan cdev = &g_channel_devs[dev];
if (cdev->number == dev) {
if (cdev->init) {
return cdev->init();
} else {
return 0;
}
} else {
return DEV_ERR_BADDEV;
}
@ -210,8 +217,12 @@ short chan_open(short dev, const uint8_t * path, short mode) {
if (chan == 0) {
return ERR_OUT_OF_HANDLES;
}
if (chan->dev != dev) {
return ERR_BADCHANNEL;
}
/* Open the channel */
if (cdev->open) {
result = cdev->open(chan, path, mode);
if (result == 0) {
/* Success: return the channel number */
@ -219,6 +230,10 @@ short chan_open(short dev, const uint8_t * path, short mode) {
} else {
return result;
}
} else {
// There's no actual open routine... just return the channel number
return chan->number;
}
} else {
return DEV_ERR_BADDEV;
}
@ -237,7 +252,9 @@ short chan_close(short channel) {
p_channel chan;
p_dev_chan cdev;
if (chan_get_records(channel, &chan, &cdev) == 0) {
if (cdev->close) {
cdev->close(chan);
}
chan_free(chan);
}
@ -265,7 +282,12 @@ short chan_read(short channel, uint8_t * buffer, short size) {
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
log2(LOG_DEBUG, "chan_read: ", cdev->name);
if (cdev->read) {
return cdev->read(chan, buffer, size);
} else {
return 0;
}
} else {
log_num(LOG_DEBUG, "Couldn't get channel: ", res);
return res;
@ -290,7 +312,11 @@ short chan_readline(short channel, uint8_t * buffer, short size) {
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
if (cdev->readline) {
return cdev->readline(chan, buffer, size);
} else {
return 0;
}
} else {
return res;
}
@ -313,7 +339,11 @@ short chan_read_b(short channel) {
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
if (cdev->read_b) {
return cdev->read_b(chan);
} else {
return 0;
}
} else {
return res;
}
@ -335,14 +365,17 @@ short chan_write(short channel, const uint8_t * buffer, short size) {
p_dev_chan cdev;
short res;
log_num(LOG_INFO, "chan_write: ", channel);
// log_num(LOG_INFO, "chan_write: ", channel);
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
if (cdev->write) {
return cdev->write(chan, buffer, size);
} else {
return 0;
}
} else {
log_num(LOG_ERROR, "chan_write error: ", res);
while (1) ;
return res;
}
}
@ -362,11 +395,15 @@ short chan_write_b(short channel, uint8_t b) {
p_dev_chan cdev;
short res;
TRACE("chan_write_b");
// TRACE("chan_write_b");
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
if (cdev->write_b) {
return cdev->write_b(chan, b);
} else {
return 0;
}
} else {
return res;
}
@ -389,7 +426,11 @@ short chan_status(short channel) {
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
if (cdev->status) {
return cdev->status(chan);
} else {
return 0;
}
} else {
return res;
}
@ -411,7 +452,11 @@ short chan_flush(short channel) {
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
if (cdev->flush) {
return cdev->flush(chan);
} else {
return 0;
}
} else {
return res;
}
@ -436,7 +481,11 @@ short chan_seek(short channel, long position, short base) {
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
if (cdev->seek) {
return cdev->seek(chan, position, base);
} else {
return 0;
}
} else {
return res;
}
@ -461,8 +510,71 @@ short chan_ioctrl(short channel, short command, uint8_t * buffer, short size) {
res = chan_get_records(channel, &chan, &cdev);
if (res == 0) {
if (cdev->ioctrl) {
return cdev->ioctrl(chan, command, buffer, size);
} else {
return 0;
}
} else {
return res;
}
}
/**
* Return the device associated with the channel
*
* @param channel the ID of the channel to query
* @return the ID of the device associated with the channel, negative number for error
*/
short chan_device(short channel) {
if (channel >= CHAN_MAX) {
// If either channel ID is bad...
return ERR_BADCHANNEL;
} else {
if (g_channels[channel].number != channel) {
// Channel is closed
return ERR_BADCHANNEL;
} else {
return g_channels[channel].dev;
}
}
}
/**
* Swap the channel ID assignments for two channels
*
* Before call: channel1 = "Channel A", channel2 = "Channel B"
* After call: channel1 = "Channel B", channel2 = "Channel A"
*
* @param channel1 the ID of one of the channels
* @param channel2 the ID of the other channel
* @return 0 on success, any other number is an error
*/
short chan_swap(short channel1, short channel2) {
if ((channel1 >= CHAN_MAX) || (channel2 >= CHAN_MAX)) {
// If either channel ID is bad...
return ERR_BADCHANNEL;
} else {
uint8_t tmp_data[CHAN_DATA_SIZE];
p_channel chan1 = 0, chan2 = 0;
short i = 0, tmp_dev = 0;
chan1 = &g_channels[channel1];
chan2 = &g_channels[channel2];
// Swap the devices
tmp_dev = chan1->dev;
chan1->dev = chan2->dev;
chan2->dev = tmp_dev;
// Swap the data blocks
memcpy(tmp_data, chan1->data, CHAN_DATA_SIZE);
memcpy(chan1->data, chan2->data, CHAN_DATA_SIZE);
memcpy(chan2->data, tmp_data, CHAN_DATA_SIZE);
return 0;
}
}

View file

@ -265,4 +265,24 @@ extern short chan_seek(short channel, long position, short base);
*/
extern short chan_ioctrl(short channel, short command, uint8_t * buffer, short size);
/**
* Return the device associated with the channel
*
* @param channel the ID of the channel to query
* @return the ID of the device associated with the channel, negative number for error
*/
extern short chan_device(short channel);
/**
* Swap the channel ID assignments for two channels
*
* Before call: channel1 = "Channel A", channel2 = "Channel B"
* After call: channel1 = "Channel B", channel2 = "Channel A"
*
* @param channel1 the ID of one of the channels
* @param channel2 the ID of the other channel
* @return 0 on success, any other number is an error
*/
extern short chan_swap(short channel1, short channel2);
#endif

View file

@ -14,15 +14,14 @@
#include "dev/console.h"
#include "dev/ps2.h"
#include "dev/kbd_mo.h"
#include "dev/text_screen_iii.h"
#include "dev/txt_screen.h"
#include "simpleio.h"
#define ANSI_BUFFER_SIZE 16
#define MAX_ANSI_ARGS 10
#define CON_CTRL_ANSI 0x80 /* Set to enable ANSI escape processing */
#define CON_IOCTRL_ANSI_ON 0x01 /* IOCTRL Command: turn on ANSI terminal codes */
#define CON_IOCTRL_ANSI_OFF 0x02 /* IOCTRL Command: turn off ANSI terminal codes */
#define CON_CTRL_ECHO 0x40 /* Set to enable echo of input characters */
typedef void (*ansi_handler)(p_channel, short, short[]);
@ -53,6 +52,7 @@ extern void ansi_cuf(p_channel chan, short arg_count, short args[]);
extern void ansi_cub(p_channel chan, short arg_count, short args[]);
extern void ansi_cud(p_channel chan, short arg_count, short args[]);
extern void ansi_cup(p_channel chan, short arg_count, short args[]);
extern void ansi_cha(p_channel chan, short arg_count, short args[]);
extern void ansi_ed(p_channel chan, short arg_count, short args[]);
extern void ansi_el(p_channel chan, short arg_count, short args[]);
extern void ansi_ich(p_channel chan, short arg_count, short args[]);
@ -73,6 +73,7 @@ const t_ansi_seq ansi_sequence[] = {
{ 'B', ansi_cud },
{ 'C', ansi_cuf },
{ 'D', ansi_cub },
{ 'G', ansi_cha },
{ 'J', ansi_ed },
{ 'K', ansi_el },
{ 'P', ansi_dch },
@ -164,7 +165,7 @@ void ansi_match_pattern(p_channel chan, p_console_data con_data) {
* Add a character to the ANSI buffer... and process when an escape sequence is found
*/
void ansi_process_c(p_channel chan, p_console_data con_data, char c) {
TRACE("ansi_process_c");
// TRACE("ansi_process_c");
if (c == '\x1B') {
/* Start the escape sequence */
@ -184,7 +185,7 @@ void ansi_process_c(p_channel chan, p_console_data con_data, char c) {
} else {
/* Not working on a sequence... so just print it */
text_put_raw(chan->dev, c);
txt_put(chan->dev, c);
}
}
@ -192,7 +193,7 @@ void ansi_process_c(p_channel chan, p_console_data con_data, char c) {
* ANSI Handler: cursor up
*/
void ansi_cuu(p_channel chan, short arg_count, short args[]) {
unsigned short x, y;
t_point position;
short delta = 1;
TRACE("ansi_cuu");
@ -203,16 +204,16 @@ void ansi_cuu(p_channel chan, short arg_count, short args[]) {
if (delta == 0) delta = 1;
text_get_xy(chan->dev, &x, &y);
y -= delta;
text_set_xy(chan->dev, x, y);
txt_get_xy(chan->dev, &position);
position.y -= delta;
txt_set_xy(chan->dev, position.x, position.y);
}
/*
* ANSI Handler: cursor forward
*/
void ansi_cuf(p_channel chan, short arg_count, short args[]) {
unsigned short x, y;
t_point position;
short delta = 1;
TRACE("ansi_cuf");
@ -223,16 +224,16 @@ void ansi_cuf(p_channel chan, short arg_count, short args[]) {
if (delta == 0) delta = 1;
text_get_xy(chan->dev, &x, &y);
x += delta;
text_set_xy(chan->dev, x, y);
txt_get_xy(chan->dev, &position);
position.x += delta;
txt_set_xy(chan->dev, position.x, position.y);
}
/*
* ANSI Handler: cursor back
*/
void ansi_cub(p_channel chan, short arg_count, short args[]) {
unsigned short x, y;
t_point position;
short delta = 1;
TRACE("ansi_cub");
@ -243,16 +244,16 @@ void ansi_cub(p_channel chan, short arg_count, short args[]) {
if (delta == 0) delta = 1;
text_get_xy(chan->dev, &x, &y);
x -= delta;
text_set_xy(chan->dev, x, y);
txt_get_xy(chan->dev, &position);
position.x -= delta;
txt_set_xy(chan->dev, position.x, position.y);
}
/*
* ANSI Handler: cursor down
*/
void ansi_cud(p_channel chan, short arg_count, short args[]) {
unsigned short x, y;
t_point position;
short delta = 1;
TRACE("ansi_cud");
@ -263,9 +264,9 @@ void ansi_cud(p_channel chan, short arg_count, short args[]) {
if (delta == 0) delta = 1;
text_get_xy(chan->dev, &x, &y);
y += delta;
text_set_xy(chan->dev, x, y);
txt_get_xy(chan->dev, &position);
position.y += delta;
txt_set_xy(chan->dev, position.x, position.y);
}
/*
@ -287,7 +288,26 @@ void ansi_cup(p_channel chan, short arg_count, short args[]) {
if (x == 0) x = 1;
if (y == 0) y = 1;
text_set_xy(chan->dev, x - 1, y - 1);
txt_set_xy(chan->dev, x - 1, y - 1);
}
/*
* ANSI Handler: cursor horizontal absolute
*/
void ansi_cha(p_channel chan, short arg_count, short args[]) {
t_point position;
short column = 1;
TRACE("ansi_cha");
if (arg_count > 0) {
column = args[0];
}
if (column == 0) column = 1;
txt_get_xy(chan->dev, &position);
txt_set_xy(chan->dev, column - 1, position.y);
}
/*
@ -302,7 +322,7 @@ void ansi_ed(p_channel chan, short arg_count, short args[]) {
n = args[0];
}
text_clear(chan->dev, n);
txt_clear(chan->dev, n);
}
/*
@ -317,7 +337,7 @@ void ansi_el(p_channel chan, short arg_count, short args[]) {
n = args[0];
}
text_clear_line(chan->dev, n);
txt_clear_line(chan->dev, n);
}
/*
@ -332,14 +352,14 @@ void ansi_ich(p_channel chan, short arg_count, short args[]) {
n = args[0];
}
text_insert(chan->dev, n);
txt_insert(chan->dev, n);
}
/*
* ANSI Handler: delete a character
*/
void ansi_dch(p_channel chan, short arg_count, short args[]) {
unsigned short n = 2;
unsigned short n = 1;
TRACE("ansi_dch");
@ -347,20 +367,22 @@ void ansi_dch(p_channel chan, short arg_count, short args[]) {
n = args[0];
}
text_delete(chan->dev, n);
if (n > 0) {
txt_delete(chan->dev, n);
}
}
/*
* Set Graphics Rendition
*/
void ansi_sgr(p_channel chan, short argc, short args[]) {
short foreground = 0, background = 0;
unsigned char foreground = 0, background = 0;
short i;
TRACE("ansi_sgr");
/* Get the current colors */
text_get_color(chan->dev, &foreground, &background);
txt_get_color(chan->dev, &foreground, &background);
/* Walk through each argument code... */
for (i = 0; i < argc; i++) {
@ -394,7 +416,7 @@ void ansi_sgr(p_channel chan, short argc, short args[]) {
}
/* Set the colors */
text_set_color(chan->dev, foreground, background);
txt_set_color(chan->dev, foreground, background);
}
//
@ -424,7 +446,7 @@ short con_open(p_channel chan, const uint8_t * path, short mode) {
/* Initialize the console data for this channel */
con_data = (p_console_data)&(chan->data);
con_data->control = CON_CTRL_ANSI;
con_data->control = CON_CTRL_ANSI | CON_CTRL_ECHO;
con_data->ansi_buffer_count = 0;
for (i = 0; i < ANSI_BUFFER_SIZE; i++) {
con_data->ansi_buffer[i] = 0;
@ -447,7 +469,7 @@ static short con_flush(p_channel chan) {
con_data = (p_console_data)&(chan->data);
if (con_data->control & CON_CTRL_ANSI) {
for (i = 0; i < con_data->ansi_buffer_count; i++) {
text_put_raw(chan->dev, con_data->ansi_buffer[i]);
txt_put(chan->dev, con_data->ansi_buffer[i]);
con_data->ansi_buffer[i] = 0;
}
}
@ -481,7 +503,7 @@ short con_write_b(p_channel chan, uint8_t b) {
} else {
/* Not processing ANSI codes... just pass it to the text driver */
text_put_raw(chan->dev, (char)b);
txt_put(chan->dev, (char)b);
}
return 0;
}
@ -505,7 +527,7 @@ short con_read_b(p_channel chan) {
#if MODEL == MODEL_FOENIX_A2560K
#ifdef KBD_POLLED
ps2_mouse_get_packet();
//ps2_mouse_get_packet();
c = kbdmo_getc_poll();
#else
c = kbdmo_getc();
@ -521,8 +543,10 @@ short con_read_b(p_channel chan) {
} while (c == 0);
if ((con_data->control & CON_CTRL_ECHO) != 0) {
// Echo the character to the screen
con_write_b(chan, c);
}
return (short)(c & 0x00ff);
}
@ -682,6 +706,17 @@ short con_seek(p_channel chan, long position, short base) {
return 0;
}
/**
* Show or hide the cursor
*
* @param chan
* @param is_visible boolean to indicate if the cursor should be seen (non-zero) or hidden (0)
*/
short con_set_cursor_visible(p_channel chan, short is_visible) {
txt_set_cursor_visible(chan->dev, is_visible);
return 0;
}
short con_ioctrl(p_channel chan, short command, uint8_t * buffer, short size) {
p_console_data con_data;
@ -695,10 +730,37 @@ short con_ioctrl(p_channel chan, short command, uint8_t * buffer, short size) {
return 0;
case CON_IOCTRL_ANSI_OFF:
/* Turn on ANSI interpreting */
/* Turn off ANSI interpreting */
con_data->control &= ~CON_CTRL_ANSI;
return 0;
case CON_IOCTRL_ECHO_ON:
/* Turn on echo interpreting */
con_data->control |= CON_CTRL_ECHO;
return 0;
case CON_IOCTRL_ECHO_OFF:
/* Turn off echo */
con_data->control &= ~CON_CTRL_ECHO;
return 0;
case CON_IOCTRL_BREAK:
/* Return the result of the BREAK key test */
#if MODEL == MODEL_FOENIX_A2560K
return kbdmo_break();
#else
/* TODO: flesh this out for the A2560U */
return 0;
#endif
case CON_IOCTRL_CURS_ON:
// Show the cursor
return con_set_cursor_visible(chan, 1);
case CON_IOCTRL_CURS_OFF:
// Hide the cursor
return con_set_cursor_visible(chan, 0);
default:
break;
}
@ -755,7 +817,10 @@ short con_install() {
/* Pre-open the console and EVID channels */
chan_open(CDEV_CONSOLE, 0, 0);
// chan_open(CDEV_EVID, 0, 0);
#if MODEL == MODEL_FOENIX_A2560K
chan_open(CDEV_EVID, 0, 0);
#endif
return result;
}

View file

@ -8,6 +8,14 @@
#ifndef __CONSOLE_H
#define __CONSOLE_H
#define CON_IOCTRL_ANSI_ON 0x01 /* IOCTRL Command: turn on ANSI terminal codes */
#define CON_IOCTRL_ANSI_OFF 0x02 /* IOCTRL Command: turn off ANSI terminal codes */
#define CON_IOCTRL_ECHO_ON 0x03 /* IOCTRL Command: turn on echo of input characters */
#define CON_IOCTRL_ECHO_OFF 0x04 /* IOCTRL Command: turn off echo of input characters */
#define CON_IOCTRL_BREAK 0x05 /* IOCTRL Command: return the status of the keyboard BREAK */
#define CON_IOCTRL_CURS_ON 0x06 /* IOCTRL Command: show the cursor */
#define CON_IOCTRL_CURS_OFF 0x07 /* IOCTRL Command: hide the cursor */
//
// Install the console device driver
//

File diff suppressed because it is too large Load diff

View file

@ -5,8 +5,6 @@
#ifndef __FDC_H
#define __FDC_H
#if MODEL == MODEL_FOENIX_A2560K
#include "types.h"
/*
@ -14,14 +12,33 @@
*/
#define FDC_SECTOR_SIZE 512 /* Size of a block on the FDC */
#define FDC_MAX_PARAMS 10 /* Maximum number of parameters/result bytes in a transaction */
#define FDC_DEFAULT_RETRIES 3 /* Default number of times we'll retry a transaction */
#define FDC_STAT_NOINIT 0x01 /* FDC has not been initialized */
#define FDC_STAT_PRESENT 0x02 /* FD is present */
#define FDC_STAT_PROTECTED 0x04 /* FD is write-protected */
#define FDC_STAT_MOTOR_ON 0x08 /* FDC spindle motor is on */
#define FDC_CTRL_MOTOR_ON 0x0100 /* IOCTRL command to start spinning the motor */
#define FDC_CTRL_MOTOR_OFF 0x0200 /* IOCTRL command to start spinning the motor */
#define FDC_CTRL_MOTOR_ON 0x0001 /* IOCTRL command to start spinning the motor */
#define FDC_CTRL_MOTOR_OFF 0x0002 /* IOCTRL command to start spinning the motor */
#define FDC_CTRL_CHECK_CHANGE 0x0003 /* IOCTRL command to check to see if the disk has changed */
/*
* Structure to keep track of the information about a transaction with the floppy drive
*/
typedef struct s_fdc_trans {
short retries; /* The number of retries that may be attempted on the transaction */
unsigned char command; /* The command code for the transaction */
unsigned char parameters[FDC_MAX_PARAMS]; /* The parameters to send as part of the transaction */
short parameter_count; /* The number of parameters to send as part of the command */
unsigned char results[FDC_MAX_PARAMS]; /* The parameters to send as part of the transaction */
short result_count; /* The number of parameters to send as part of the command */
unsigned char *data; /* Pointer to the data buffer to read or write to the FDC */
short data_count; /* Number of data bytes to transfer */
short direction; /* 0 = no data, 1 = data is written to the FDC, 2 = data is read from the FDC */
} t_fdc_trans, *p_fdc_trans;
/*
* Install the FDC driver
@ -36,6 +53,13 @@ extern short fdc_install();
*/
extern short fdc_init();
/**
* Set whether to use DMA or polled I/O for exchanging data
*
* @param dma 0 for polled I/O, anything else for DMA
*/
extern void fdc_set_dma(short dma);
/*
* Read a block from the FDC
*
@ -99,6 +123,14 @@ extern short fdc_flush();
*/
extern short fdc_ioctrl(short command, unsigned char * buffer, short size);
#endif
/*
* Move the read/write head to the indicated cylinder
*/
extern short fdc_seek(unsigned char cylinder);
/*
* Recalibrate the read/write head
*/
extern short fdc_recalibrate();
#endif

View file

@ -12,6 +12,7 @@
#include <string.h>
#include "dev/channel.h"
#include "dev/fdc.h"
#include "errors.h"
#include "elf.h"
#include "fsys.h"
@ -75,6 +76,38 @@ short fatfs_to_foenix(FRESULT r) {
}
}
/**
* Make sure the status of the drive is up to date for the given path
*
* @param path
*/
void fsys_update_stat(const char * path) {
char buffer[20];
int i;
if (path[0] != '/') {
// The root was not specified... get it from the current working directory
strncpy(buffer, g_current_directory, 20);
} else {
// The root was specified... work with the data in the path
strncpy(buffer, path, 20);
}
// Make sure the path is lower case
for (i = 0; i < strlen(buffer); i++) {
char c = buffer[i];
if ((c >= 'A') && (c <= 'Z')) {
buffer[i] = tolower(c);
}
}
if (strncmp(buffer, "/fd", 3) == 0) {
// If the drive is the floppy drive, force the drive to spin up and check for a disk change
// this will update the fdc_status, which will be seen by FatFS and treated appropriately
sys_bdev_ioctrl(BDEV_FDC, FDC_CTRL_CHECK_CHANGE, 0, 0);
}
}
/**
* Attempt to open a file given the path to the file and the mode.
*
@ -91,6 +124,10 @@ short fsys_open(const char * path, short mode) {
TRACE("fsys_open");
// If the file being opened is on the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
fsys_update_stat(path);
/* Allocate a file handle */
for (i = 0; i < MAX_FILES; i++) {
@ -175,9 +212,13 @@ short fsys_opendir(const char * path) {
short dir = -1;
FRESULT fres;
// Make sure our status is updated for the drive indicated by the path
fsys_update_stat(path);
/* Allocate a directory handle */
for (i = 0; i < MAX_DIRECTORIES; i++) {
if (g_dir_state[i] == 0) {
g_dir_state[i] = 1;
dir = i;
break;
}
@ -264,6 +305,71 @@ short fsys_readdir(short dir, p_file_info file) {
}
}
/**
* Check to see if the file is present.
* If it is not, return a file not found error.
* If it is, populate the file info record
*
* Inputs:
* path = the path to the file to check
* file = pointer to a file info record to fill in, if the file is found.
*/
short fsys_stat(const char * path, p_file_info file) {
FRESULT fres;
FILINFO finfo;
char match1[10], match2[10];
short i = 0;
// If the file being checked is on the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
fsys_update_stat(path);
// FatFS's f_stat function does not handle root directories so bodge this in...
// For each drive...
for (i = 0; i < 3; i++) {
// Compute two legitimate paths to it
strcpy(match1, "/");
strcat(match1, (char *)VolumeStr[i]);
strcpy(match2, match1);
strcat(match2, "/");
// Check to see if the path is the same (barring letter case)
if ((strcicmp(path, match1) == 0) || (strcicmp(path, match2) == 0)) {
// It's a match... return the record for it
file->size = 0;
file->date = 0;
file->time = 0;
file->attributes = FSYS_AM_DIR;
strcpy(file->name, (char *)VolumeStr[i]);
return 0;
}
}
fres = f_stat(path, &finfo);
if (fres == FR_OK) {
int i;
/* Copy file information into the kernel table */
file->size = finfo.fsize;
file->date = finfo.fdate;
file->time = finfo.ftime;
file->attributes = finfo.fattrib;
for (i = 0; i < MAX_PATH_LEN; i++) {
file->name[i] = finfo.fname[i];
if (file->name[i] == 0) {
break;
}
}
return 0;
} else {
/* There was an error... return it to the caller */
return fatfs_to_foenix(fres);
}
}
/**
* Open a directory given the path and search for the first file matching the pattern.
*
@ -277,13 +383,18 @@ short fsys_readdir(short dir, p_file_info file) {
*/
short fsys_findfirst(const char * path, const char * pattern, p_file_info file) {
FILINFO finfo;
FRESULT fres;
short dir;
short i;
FRESULT fres = -1;
short dir = 0;
short i = 0;
// If the path being queried is on the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
fsys_update_stat(path);
/* Allocate a directory handle */
for (i = 0; i < MAX_DIRECTORIES; i++) {
if (g_dir_state[i] == 0) {
g_dir_state[i] = 1;
dir = i;
break;
}
@ -293,6 +404,7 @@ short fsys_findfirst(const char * path, const char * pattern, p_file_info file)
return ERR_OUT_OF_HANDLES;
} else {
fres = f_findfirst(&g_directory[dir], &finfo, path, pattern);
if (fres != FR_OK) {
return fatfs_to_foenix(fres);
@ -373,6 +485,10 @@ short fsys_mkdir(const char * path) {
TRACE("fsys_mkdir");
// If the directory being created is on the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
fsys_update_stat(path);
result = f_mkdir(path);
if (result == FR_OK) {
return 0;
@ -394,6 +510,10 @@ short fsys_mkdir(const char * path) {
short fsys_delete(const char * path) {
FRESULT result;
// If the path being deleted is on the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
fsys_update_stat(path);
result = f_unlink(path);
if (result == FR_OK) {
return 0;
@ -416,6 +536,10 @@ short fsys_delete(const char * path) {
short fsys_rename(const char * old_path, const char * new_path) {
FRESULT fres;
// If the path being renamed is on the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
fsys_update_stat(old_path);
fres = f_rename(old_path, new_path);
if (fres != 0) {
return fatfs_to_foenix(fres);
@ -719,6 +843,10 @@ short fsys_mount(short bdev) {
short fsys_getlabel(char * path, char * label) {
TRACE("fsys_getlabel");
// If the drive being queried is the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
fsys_update_stat(path);
FRESULT fres = f_getlabel(path, label, 0);
if (fres != FR_OK) {
return fatfs_to_foenix(fres);
@ -738,6 +866,12 @@ short fsys_setlabel(short drive, const char * label) {
FRESULT fres;
char buffer[80];
// If the drive being labeled is on the floppy drive, make sure the FDC status
// is updated correctly for disk change by spinning up the motor and checking the DIR register
if (drive == BDEV_FDC) {
sys_bdev_ioctrl(BDEV_FDC, FDC_CTRL_CHECK_CHANGE, 0, 0);
}
sprintf(buffer, "%d:%s", drive, label);
fres = f_setlabel(buffer);
if (fres != FR_OK) {
@ -876,7 +1010,7 @@ short fsys_pgz_loader(short chan, long destination, long * start) {
short data_idx = 0; /* Expected offset for the first byte of the data */
short result = 0;
TRACE("fsys_pgx_loader");
TRACE("fsys_pgz_loader");
/* Allocate the buffer we'll use for reading the file */
chunk = malloc(DEFAULT_CHUNK_SIZE);
@ -1138,52 +1272,45 @@ short fsys_pgx_loader(short chan, long destination, long * start) {
return result;
}
/*
* Load a file into memory at the designated destination address.
*
* If destination = 0, the file must be in a recognized binary format
* that specifies its own loading address.
*
* Inputs:
* path = the path to the file to load
* destination = the destination address (0 for use file's address)
* start = pointer to the long variable to fill with the starting address
* (0 if not an executable, any other number if file is executable
* with a known starting address)
*
* Returns:
* 0 on success, negative number on error
*/
short fsys_load(const char * path, long destination, long * start) {
static bool loader_exists(const char * extension) {
int i;
char extension[MAX_EXT];
short chan = -1;
p_file_loader loader = 0;
TRACE("fsys_load");
/* Clear out the extension */
for (i = 0; i <= MAX_EXT; i++) {
extension[i] = 0;
for (i = 0; i < MAX_LOADERS; i++) {
if (g_file_loader[i].status) {
if (strcmp(g_file_loader[i].extension, extension) == 0) {
return 1;
}
}
}
return 0;
}
if (destination == 0) {
/* Find the extension */
static int get_app_ext(const char * path, char * extension) {
char * point = strrchr(path, '.');
extension[0] = 0;
if (point != 0) {
point++;
for (i = 0; i < MAX_EXT; i++) {
for (int i = 0; i < MAX_EXT; i++) {
char c = *point++;
if (c) {
extension[i] = toupper(c);
} else {
break;
extension[i] = 0;
return 1;
}
}
} else {
return 0;
}
}
log2(LOG_VERBOSE, "fsys_load ext: ", extension);
static short fsys_load_ext(const char * path, const char * extension, long destination, long * start) {
int i;
short chan = -1;
p_file_loader loader = 0;
TRACE("fsys_load_ext");
log2(LOG_VERBOSE, "fsys_load_ext ext: ", extension);
if (extension[0] == 0) {
if (destination != 0) {
@ -1207,7 +1334,7 @@ short fsys_load(const char * path, long destination, long * start) {
}
}
TRACE("fsys_load: loader search");
TRACE("fsys_load_ext: loader search");
if (loader == 0) {
if (destination != 0) {
@ -1247,6 +1374,77 @@ short fsys_load(const char * path, long destination, long * start) {
}
}
/*
* Load a file into memory at the designated destination address.
*
* If destination = 0, the file must be in a recognized binary format
* that specifies its own loading address.
*
* Inputs:
* path = the path to the file to load
* destination = the destination address (0 for use file's address)
* start = pointer to the long variable to fill with the starting address
* (0 if not an executable, any other number if file is executable
* with a known starting address)
*
* Returns:
* 0 on success, negative number on error
*/
short fsys_load(const char * path, long destination, long * start) {
int i;
char extension[MAX_EXT];
char spath[MAX_PATH_LEN];
short chan = -1;
p_file_loader loader = 0;
int found_extension = 0;
int found_loader = 0;
FRESULT fr; /* Return value */
DIR dj; /* Directory object */
FILINFO fno; /* File information */
TRACE("fsys_load");
/* Clear out the extension */
for (i = 0; i <= MAX_EXT; i++) {
extension[i] = 0;
}
found_extension = get_app_ext(path, extension);
if (found_extension || destination != 0) {
// extension provided, pass to loader
fsys_load_ext(path, extension, destination, start);
} else {
// extension not provided, search for a matching file.
strcpy(spath, path);
strcat(spath, ".*");
// TODO: Iterate through path, and replace "".
fr = f_findfirst(&dj, &fno, "", spath); /* Start to search for executables */
while (fr == FR_OK && fno.fname[0]) { /* Repeat while an item is found */
get_app_ext(fno.fname, extension);
if (loader_exists(extension)) {
strcpy(spath, fno.fname);
found_loader = 1;
break;
}
fr = f_findnext(&dj, &fno); /* Search for next item */
}
f_closedir(&dj);
if(found_loader) {
// Found path with valid loader
fsys_load_ext(spath, extension, destination, start);
} else {
log(LOG_ERROR, "Command not found.");
return ERR_NOT_FOUND;
}
}
return 0;
}
/*
* Register a file loading routine
*
@ -1296,6 +1494,8 @@ short fsys_register_loader(const char * extension, p_file_loader loader) {
short fsys_init() {
int i, j;
TRACE("fsys_init");
/* Set the default working directory.
* TODO: set this based on the boot drive.
*/

View file

@ -5,9 +5,9 @@
#ifndef __FSYS_H
#define __FSYS_H
#include "constants.h"
#include "types.h"
#define MAX_PATH_LEN 256
#define DEFAULT_CHUNK_SIZE 256
/**
@ -125,6 +125,17 @@ extern short fsys_findfirst(const char * path, const char * pattern, p_file_info
*/
extern short fsys_findnext(short dir, p_file_info file);
/**
* Check to see if the file is present.
* If it is not, return a file not found error.
* If it is, populate the file info record
*
* Inputs:
* path = the path to the file to check
* file = pointer to a file info record to fill in, if the file is found.
*/
extern short fsys_stat(const char * path, p_file_info file);
/*
* Get the label for the drive holding the path
*

View file

@ -2,6 +2,7 @@
* Declarations for Mo, the built-in keyboard of the A2560K
*/
#include <ctype.h>
#include "sys_general.h"
#if MODEL == MODEL_FOENIX_A2560K
@ -11,9 +12,12 @@
#include "kbd_mo.h"
#include "ring_buffer.h"
#include "gabe_reg.h"
#include "simpleio.h"
#define KBD_MO_DATA ((volatile unsigned short *)0x00C00040) /* Data register for the keyboard (scan codes will be here) */
#define KBD_MO_STAT ((volatile unsigned short *)0x00C00042) /* Status register for the keyboard */
#define KBD_MO_LEDMATRIX ((volatile unsigned short *)0xFEC01000) /* 6x16 array of 16-bit words: ARGB */
#define KBD_MO_LED_ROWS 6
#define KBD_MO_LED_COLUMNS 16
#define KBD_MO_DATA ((volatile unsigned int *)0xFEC00040) /* Data register for the keyboard (scan codes will be here) */
#define KBD_MO_EMPTY 0x8000 /* Status flag that will be set if the keyboard buffer is empty */
#define KBD_MO_FULL 0x4000 /* Status flag that will be set if the keyboard buffer is full */
@ -25,11 +29,16 @@
#define KBD_LOCK_NUM 0x02
#define KBD_LOCK_CAPS 0x04
#define KBD_MOD_SHIFT 0x08
#define KBD_MOD_CTRL 0x10
#define KBD_MOD_ALT 0x20
#define KBD_MOD_ALT 0x10
#define KBD_MOD_CTRL 0x20
#define KBD_MOD_OS 0x40
#define KBD_MOD_MENU 0x80
/*
* Status codes
*/
#define KBD_STAT_BREAK 0x80 /* BREAK has been pressed recently */
/*
* Structure to track the keyboard input
*/
@ -42,12 +51,13 @@ struct s_kdbmo_kbd {
/* Scan code to character lookup tables */
char * keys_unmodified;
char * keys_shift;
char * keys_control;
char * keys_control_shift;
char * keys_caps;
char * keys_caps_shift;
char keys_unmodified[128];
char keys_shift[128];
char keys_control[128];
char keys_control_shift[128];
char keys_caps[128];
char keys_caps_shift[128];
char keys_alt[128];
};
/*
@ -56,12 +66,46 @@ struct s_kdbmo_kbd {
struct s_kdbmo_kbd g_kbdmo_control;
static short kbdmo_leds = 0;
static unsigned char g_kbdmo_break_sc = 0x2E; // Scancode for the BREAK key (must be pressed with CTRL)
/*
* Mapping of "codepoints" 0x80 - 0x98 (function keys, etc)
* to ANSI escape codes
*/
const char * ansi_keys[] = {
"1", /* HOME */
"2", /* INS */
"3", /* DELETE */
"4", /* END */
"5", /* PgUp */
"6", /* PgDn */
"A", /* Up */
"B", /* Left */
"C", /* Right */
"D", /* Down */
"11", /* F1 */
"12", /* F2 */
"13", /* F3 */
"14", /* F4 */
"15", /* F5 */
"17", /* F6 */
"18", /* F7 */
"19", /* F8 */
"20", /* F9 */
"21", /* F10 */
"23", /* F11 */
"24", /* F12 */
"30", /* MONITOR */
"31", /* CTX SWITCH */
"32" /* MENU HELP */
};
/*
* US keyboard layout scancode translation tables
*/
static char g_us_sc_unmodified[] = {
const char g_us_kbdmo_layout[] = {
// Unmodified
0x00, 0x1B, '1', '2', '3', '4', '5', '6', /* 0x00 - 0x07 */
'7', '8', '9', '0', '-', '=', 0x08, 0x09, /* 0x08 - 0x0F */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 0x10 - 0x17 */
@ -72,15 +116,14 @@ static char g_us_sc_unmodified[] = {
0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */
0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */
0x87, 0x85, 0x81, 0x82, 0x00, 0x00, 0x00, 0x94, /* 0x50 - 0x57 */
0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x78 - 0x7F */
};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */
static char g_us_sc_shift[] = {
// Shifted
0x00, 0x1B, '!', '@', '#', '$', '%', '^', /* 0x00 - 0x07 */
'&', '*', '(', ')', '_', '+', 0x08, 0x09, /* 0x08 - 0x0F */
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 0x10 - 0x17 */
@ -91,15 +134,14 @@ static char g_us_sc_shift[] = {
0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */
0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */
0x87, 0x85, 0x81, 0x82, 0x00, 0x00, 0x00, 0x94, /* 0x50 - 0x57 */
0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x78 - 0x7F */
};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */
static char g_us_sc_ctrl[] = {
// Control
0x00, 0x1B, '1', '2', '3', '4', '5', 0x1E, /* 0x00 - 0x07 */
'7', '8', '9', '0', 0x1F, '=', 0x08, 0x09, /* 0x08 - 0x0F */
0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* 0x10 - 0x17 */
@ -110,53 +152,15 @@ static char g_us_sc_ctrl[] = {
0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */
0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */
0x87, 0x85, 0x81, 0x82, 0x00, 0x00, 0x00, 0x94, /* 0x50 - 0x57 */
0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x78 - 0x7F */
};
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */
static char g_us_sc_lock[] = {
0x00, 0x1B, '1', '2', '3', '4', '5', '6', /* 0x00 - 0x07 */
'7', '8', '9', '0', '-', '=', 0x08, 0x09, /* 0x08 - 0x0F */
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 0x10 - 0x17 */
'O', 'P', '[', ']', 0x0D, 0x00, 'A', 'S', /* 0x18 - 0x1F */
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', /* 0x20 - 0x27 */
0x27, '`', 0x00, '\\', 'Z', 'X', 'C', 'V', /* 0x28 - 0x2F */
'B', 'N', 'M', ',', '.', '/', 0x00, 0x00, /* 0x30 - 0x37 */
0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, '7', /* 0x40 - 0x47 */
'8', '9', '-', '4', '5', '6', '+', '1', /* 0x48 - 0x4F */
'2', '3', '0', '.', 0x00, 0x00, 0x00, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x78 - 0x7F */
};
static char g_us_sc_lock_shift[] = {
0x00, 0x1B, '!', '@', '#', '$', '%', '^', /* 0x00 - 0x07 */
'&', '*', '(', ')', '_', '+', 0x08, 0x09, /* 0x08 - 0x0F */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 0x10 - 0x17 */
'o', 'p', '{', '}', 0x0A, 0x00, 'a', 's', /* 0x18 - 0x1F */
'd', 'f', 'g', 'h', 'j', 'k', 'l', ':', /* 0x20 - 0x27 */
0x22, '~', 0x00, '|', 'z', 'x', 'c', 'v', /* 0x28 - 0x2F */
'b', 'n', 'm', '<', '>', '?', 0x00, 0x00, /* 0x30 - 0x37 */
0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, '7', /* 0x40 - 0x47 */
'8', '9', '-', '4', '5', '6', '+', '1', /* 0x48 - 0x4F */
'2', '3', '0', '.', 0x00, 0x00, 0x00, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x78 - 0x7F */
};
static char g_us_sc_ctrl_shift[] = {
// Control-Shift
0x00, 0x1B, '!', '@', '#', '$', '%', '^', /* 0x00 - 0x07 */
'&', '*', '(', ')', '_', '+', 0x08, 0x09, /* 0x08 - 0x0F */
0x11, 0x17, 0x05, 0x12, 0x14, 0x19, 0x15, 0x09, /* 0x10 - 0x17 */
@ -167,24 +171,124 @@ static char g_us_sc_ctrl_shift[] = {
0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */
0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */
0x87, 0x85, 0x81, 0x82, 0x00, 0x00, 0x00, 0x94, /* 0x50 - 0x57 */
0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* 0x78 - 0x7F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */
// Capslock
0x00, 0x1B, '1', '2', '3', '4', '5', '6', /* 0x00 - 0x07 */
'7', '8', '9', '0', '-', '=', 0x08, 0x09, /* 0x08 - 0x0F */
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', /* 0x10 - 0x17 */
'O', 'P', '[', ']', 0x0D, 0x00, 'A', 'S', /* 0x18 - 0x1F */
'D', 'F', 'G', 'H', 'J', 'K', 'L', ';', /* 0x20 - 0x27 */
0x27, '`', 0x00, '\\', 'Z', 'X', 'C', 'V', /* 0x28 - 0x2F */
'B', 'N', 'M', ',', '.', '/', 0x00, 0x00, /* 0x30 - 0x37 */
0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, '7', /* 0x40 - 0x47 */
'8', '9', '-', '4', '5', '6', '+', '1', /* 0x48 - 0x4F */
'2', '3', '0', '.', 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */
// Caps-Shift
0x00, 0x1B, '!', '@', '#', '$', '%', '^', /* 0x00 - 0x07 */
'&', '*', '(', ')', '_', '+', 0x08, 0x09, /* 0x08 - 0x0F */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 0x10 - 0x17 */
'o', 'p', '{', '}', 0x0A, 0x00, 'a', 's', /* 0x18 - 0x1F */
'd', 'f', 'g', 'h', 'j', 'k', 'l', ':', /* 0x20 - 0x27 */
0x22, '~', 0x00, '|', 'z', 'x', 'c', 'v', /* 0x28 - 0x2F */
'b', 'n', 'm', '<', '>', '?', 0x00, 0x00, /* 0x30 - 0x37 */
0x00, ' ', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, '7', /* 0x40 - 0x47 */
'8', '9', '-', '4', '5', '6', '+', '1', /* 0x48 - 0x4F */
'2', '3', '0', '.', 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */
// ALT
0x00, 0x1B, '1', '2', '3', '4', '5', '6', /* 0x00 - 0x07 */
'7', '8', '9', '0', '-', '=', 0x08, 0x09, /* 0x08 - 0x0F */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', /* 0x10 - 0x17 */
'o', 'p', '[', ']', 0x0D, 0x00, 'a', 's', /* 0x18 - 0x1F */
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 0x20 - 0x27 */
0x27, '`', 0x00, '\\', 'z', 'x', 'c', 'v', /* 0x28 - 0x2F */
'b', 'n', 'm', ',', '.', '/', 0x00, '*', /* 0x30 - 0x37 */
0x00, ' ', 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, /* 0x38 - 0x3F */
0x8F, 0x90, 0x91, 0x92, 0x93, 0x00, 0x00, 0x80, /* 0x40 - 0x47 */
0x86, 0x84, '-', 0x89, '5', 0x88, '+', 0x83, /* 0x48 - 0x4F */
0x87, 0x85, 0x81, 0x82, 0x96, 0x97, 0x98, 0x94, /* 0x50 - 0x57 */
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58 - 0x5F */
0x00, 0x00, 0x81, 0x80, 0x84, 0x82, 0x83, 0x85, /* 0x60 - 0x67 */
0x86, 0x89, 0x87, 0x88, '/', 0x0D, 0x00, 0x00, /* 0x68 - 0x6F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 - 0x77 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78 - 0x7F */
};
/**
* Set the color of the A2560K keyboard LED matrix
*
* @param row the number of the row to set (0 - 5)
* @param color the color for the LEDs: ARGB
*/
void kbdmo_set_led_matrix_row(unsigned char row, unsigned short color) {
int column;
for (column = 0; column < KBD_MO_LED_COLUMNS; column++) {
KBD_MO_LEDMATRIX[row * KBD_MO_LED_COLUMNS + column] = color;
}
}
/**
* Set all the LEDs to the same color
*
* @param color the color for the LEDs: ARGB
*/
void kbdmo_set_led_matrix_fill(unsigned short color) {
unsigned char row;
for (row = 0; row < KBD_MO_LED_ROWS; row++) {
kbdmo_set_led_matrix_row(row, color);
}
}
/*
* Make sure everything is removed from Mo's input buffer
*/
void kbdmo_flush_out() {
long data;
TRACE("kbdmo_flush_out");
/* While there is data in the buffer ... */
while ((*KBD_MO_STAT & 0x00ff) != 0) {
/* Read and throw out the scan codes */
unsigned short dummy = *KBD_MO_DATA;
do {
data = *KBD_MO_DATA;
} while ((data & 0x00ff0000) != 0);
}
/*
* Check to see if a BREAK code has been pressed recently
* If so, return 1 and reset the internal flag.
*
* BREAK will be F-ESC on the A2560K
*
* Returns:
* 1 if a BREAK has been pressed since the last check
*/
short kbdmo_break() {
if (g_kbdmo_control.status & KBD_STAT_BREAK) {
/* BREAK was pressed: clear the flag and return a 1 */
g_kbdmo_control.status &= ~KBD_STAT_BREAK;
return 1;
} else {
/* BREAK was not pressed: return a 0 */
return 0;
}
}
@ -200,19 +304,16 @@ short kbdmo_init() {
int_disable(INT_KBD_A2560K);
/* Turn off the LEDs */
kbdmo_set_led_matrix_fill(0);
/* Set up the ring buffers */
rb_word_init(&g_kbdmo_control.sc_buf); /* Scan-code ring buffer is empty */
rb_word_init(&g_kbdmo_control.char_buf); /* Character ring buffer is empty */
/* Set the default keyboard layout to US */
g_kbdmo_control.keys_unmodified = g_us_sc_unmodified;
g_kbdmo_control.keys_shift = g_us_sc_shift;
g_kbdmo_control.keys_control = g_us_sc_ctrl;
g_kbdmo_control.keys_control_shift = g_us_sc_ctrl_shift;
g_kbdmo_control.keys_caps = g_us_sc_lock;
g_kbdmo_control.keys_caps_shift = g_us_sc_lock_shift;
kbdmo_layout(g_us_kbdmo_layout);
g_kbdmo_control.status = 0;
g_kbdmo_control.modifiers = 0;
@ -275,9 +376,22 @@ void kbdmo_enqueue_scan(unsigned char scan_code) {
if ((scan_code != 0) && (scan_code != 0x80)) {
unsigned char is_break = scan_code & 0x80;
// If CTRL-C pressed, treat it as a break
if ((scan_code == g_kbdmo_break_sc) & ((g_kbdmo_control.modifiers & KBD_MOD_CTRL) != 0)) {
g_kbdmo_control.status |= KBD_STAT_BREAK;
}
// Check the scan code to see if it's a modifier key or a lock key
// update the modifier and lock variables accordingly...
switch (scan_code & 0x7f) {
case 0x01:
/* ESC key pressed... check to see if it's a press with the Foenix key */
if (((g_kbdmo_control.modifiers & KBD_MOD_OS) != 0) && (is_break == 0)) {
/* ESC pressed with Foenix key... flag a BREAK. */
g_kbdmo_control.status |= KBD_STAT_BREAK;
}
break;
case 0x2A:
case 0x36:
kbdmo_makebreak_modifier(KBD_MOD_SHIFT, is_break);
@ -325,23 +439,26 @@ void kbdmo_enqueue_scan(unsigned char scan_code) {
* IRQ handler for the keyboard... read a scan code and queue it
*/
void kbdmo_handle_irq() {
unsigned long data;
/* We got an interrupt for MO.
* While there is data in the input queue...
*/
int_clear(INT_KBD_A2560K);
while ((*KBD_MO_STAT & 0x00ff) != 0) {
/* Get a scan code from the input buffer */
unsigned short scan_code = *KBD_MO_DATA;
/* While there is data in the buffer ... */
do {
data = *KBD_MO_DATA;
/* Read and throw out the scan codes */
unsigned short scan_code = data & 0xffff;
if ((scan_code & 0x7fff) != 0) {
/* TODO: beep if the input was full or the ring buffer is full */
/* Process it and enqueue it */
kbdmo_enqueue_scan((unsigned char)(scan_code & 0x00ff));
}
}
} while ((data & 0x00ff0000) != 0);
}
@ -352,21 +469,90 @@ void kbdmo_handle_irq() {
* The next scancode to be processed, 0 if nothing.
*/
unsigned short kbdmo_get_scancode() {
unsigned long data;
unsigned short scan_code = rb_word_get(&g_kbdmo_control.sc_buf);
if (scan_code != 0) {
/* Got a result... return it */
return scan_code;
} else {
/* Nothing in the queue... let's make sure we haven't lost an interrupt */
if ((*KBD_MO_STAT & 0x00ff) != 0) {
/* Something is pending, process it as if an interrupt occurred */
kbdmo_handle_irq();
return rb_word_get(&g_kbdmo_control.sc_buf);
} else {
return 0;
}
}
/*
* Catch special keys and convert them to their ANSI terminal codes
*
* Characters 0x80 - 0x98 are reserved for function keys, arrow keys, etc.
* This function maps them to the ANSI escape codes
*
* Inputs:
* modifiers = the current modifier bit flags (ALT, CTRL, META, etc)
* c = the character found from the scan code.
*/
static unsigned char kbd_to_ansi(unsigned char modifiers, unsigned char c) {
if ((c >= 0x80) && (c <= 0x98)) {
/* The key is a function key or a special control key */
const char * ansi_key = ansi_keys[c - 0x80];
const char * sequence;
short modifiers_after = 0;
// Figure out if the modifiers come before or after the sequence code
if (isdigit(ansi_key[0])) {
// Sequence is numeric, modifiers come after
modifiers_after = 1;
}
// After ESC, all sequences have [
rb_word_put(&g_kbdmo_control.char_buf, '[');
if (modifiers_after) {
// Sequence is numberic, get the expanded sequence and put it in the queue
for (sequence = ansi_keys[c - 0x80]; *sequence != 0; sequence++) {
rb_word_put(&g_kbdmo_control.char_buf, *sequence);
}
}
// Check to see if we need to send a modifier sequence
if (modifiers & (KBD_MOD_SHIFT | KBD_MOD_CTRL | KBD_MOD_ALT | KBD_MOD_OS)) {
unsigned char code_bcd;
short modifier_code = 0;
short i;
if (modifiers_after) {
// Sequence is numeric, so put modifiers after the sequence and a semicolon
rb_word_put(&g_kbdmo_control.char_buf, ';');
}
modifier_code = ((modifiers >> 3) & 0x1F) + 1;
code_bcd = i_to_bcd(modifier_code);
if (code_bcd & 0xF0) {
rb_word_put(&g_kbdmo_control.char_buf, ((code_bcd & 0xF0) >> 4) + '0');
}
rb_word_put(&g_kbdmo_control.char_buf, (code_bcd & 0x0F) + '0');
}
if (!modifiers_after) {
// Sequence is a letter code
rb_word_put(&g_kbdmo_control.char_buf, ansi_key[0]);
} else {
// Sequence is numeric, close it with a tilda
rb_word_put(&g_kbdmo_control.char_buf, '~');
}
return 0x1B; /* Start the sequence with an escape */
} else if (c == 0x1B) {
/* ESC should be doubled, to distinguish from the start of an escape sequence */
rb_word_put(&g_kbdmo_control.char_buf, 0x1B);
return c;
} else {
/* Not a special key: return the character unmodified */
return c;
}
}
/*
@ -375,7 +561,7 @@ unsigned short kbdmo_get_scancode() {
* Returns:
* the next character to be read from the keyboard (0 if none available)
*/
char kbdmo_getc() {
unsigned char kbdmo_getc() {
if (!rb_word_empty(&g_kbdmo_control.char_buf)) {
// If there is a character waiting in the character buffer, return it...
return (char)rb_word_get(&g_kbdmo_control.char_buf);
@ -391,37 +577,39 @@ char kbdmo_getc() {
// Check the modifiers to see what we should lookup...
if ((modifiers & (KBD_MOD_SHIFT | KBD_MOD_CTRL | KBD_LOCK_CAPS)) == 0) {
if ((modifiers & (KBD_MOD_ALT | KBD_MOD_SHIFT | KBD_MOD_CTRL | KBD_LOCK_CAPS)) == 0) {
// No modifiers... just return the base character
return g_kbdmo_control.keys_unmodified[scan_code];
return kbd_to_ansi(modifiers, g_kbdmo_control.keys_unmodified[scan_code]);
} else if (modifiers & KBD_MOD_ALT) {
return kbd_to_ansi(modifiers, g_kbdmo_control.keys_alt[scan_code]);
} else if (modifiers & KBD_MOD_CTRL) {
// If CTRL is pressed...
if (modifiers & KBD_MOD_SHIFT) {
// If SHIFT is also pressed, return CTRL-SHIFT form
return g_kbdmo_control.keys_control_shift[scan_code];
return kbd_to_ansi(modifiers, g_kbdmo_control.keys_control_shift[scan_code]);
} else {
// Otherwise, return just CTRL form
return g_kbdmo_control.keys_control[scan_code];
return kbd_to_ansi(modifiers, g_kbdmo_control.keys_control[scan_code]);
}
} else if (modifiers & KBD_LOCK_CAPS) {
// If CAPS is locked...
if (modifiers & KBD_MOD_SHIFT) {
// If SHIFT is also pressed, return CAPS-SHIFT form
return g_kbdmo_control.keys_caps_shift[scan_code];
return kbd_to_ansi(modifiers, g_kbdmo_control.keys_caps_shift[scan_code]);
} else {
// Otherwise, return just CAPS form
return g_kbdmo_control.keys_caps[scan_code];
return kbd_to_ansi(modifiers, g_kbdmo_control.keys_caps[scan_code]);
}
} else {
// SHIFT is pressed, return SHIFT form
return g_kbdmo_control.keys_shift[scan_code];
return kbd_to_ansi(modifiers, g_kbdmo_control.keys_shift[scan_code]);
}
}
// If we reach this point, it wasn't a useful scan-code...
@ -494,4 +682,46 @@ void kbdmo_set_hdc_led(short colors) {
*GABE_MO_LEDS = kbdmo_leds;
}
/*
* Set the keyboard translation tables
*
* The translation tables provided to the keyboard consist of eight
* consecutive tables of 128 characters each. Each table maps from
* the MAKE scan code of a key to its appropriate 8-bit character code.
*
* The tables included must include, in order:
* - UNMODIFIED: Used when no modifier keys are pressed or active
* - SHIFT: Used when the SHIFT modifier is pressed
* - CTRL: Used when the CTRL modifier is pressed
* - CTRL-SHIFT: Used when both CTRL and SHIFT are pressed
* - CAPSLOCK: Used when CAPSLOCK is down but SHIFT is not pressed
* - CAPSLOCK-SHIFT: Used when CAPSLOCK is down and SHIFT is pressed
* - ALT: Used when only ALT is presse
* - ALT-SHIFT: Used when ALT is pressed and either CAPSLOCK is down
* or SHIFT is pressed (but not both)
*
* Inputs:
* tables = pointer to the keyboard translation tables
*/
short kbdmo_layout(const char * tables) {
short i;
for (i = 0; i < 128; i++) {
g_kbdmo_control.keys_unmodified[i] = tables[i];
g_kbdmo_control.keys_shift[i] = tables[i + 128];
g_kbdmo_control.keys_control[i] = tables[i + 256];
if (g_kbdmo_control.keys_control[i] == 0x03) {
// We have set the scan code for CTRL-C?
g_kbdmo_break_sc = i;
}
// Check for CTRL-C
g_kbdmo_control.keys_control_shift[i] = tables[i + 384];
g_kbdmo_control.keys_caps[i] = tables[i + 512];
g_kbdmo_control.keys_caps_shift[i] = tables[i + 640];
g_kbdmo_control.keys_alt[i] = tables[i + 768];
}
return 0;
}
#endif

View file

@ -18,6 +18,32 @@
*/
extern short kbdmo_init();
/**
* Set the color of the A2560K keyboard LED matrix
*
* @param row the number of the row to set (0 - 5)
* @param color the color for the LEDs: ARGB
*/
void kbdmo_set_led_matrix_row(unsigned char row, unsigned short color);
/**
* Set all the LEDs to the same color
*
* @param color the color for the LEDs: ARGB
*/
void kbdmo_set_led_matrix_fill(unsigned short color);
/*
* Check to see if a BREAK code has been pressed recently
* If so, return 1 and reset the internal flag.
*
* BREAK will be F-ESC on the A2560K
*
* Returns:
* 1 if a BREAK has been pressed since the last check
*/
extern short kbdmo_break();
/*
* Try to retrieve the next scancode from the keyboard.
*
@ -32,7 +58,7 @@ extern unsigned short kbdmo_get_scancode();
* Returns:
* the next character to be read from the keyboard (0 if none available)
*/
extern char kbdmo_getc();
extern unsigned char kbdmo_getc();
/*
* Use polling to fetch a key
@ -78,6 +104,29 @@ extern void kbdmo_set_sdc_led(short colors);
*/
extern void kbdmo_set_hdc_led(short colors);
/*
* Set the keyboard translation tables
*
* The translation tables provided to the keyboard consist of eight
* consecutive tables of 128 characters each. Each table maps from
* the MAKE scan code of a key to its appropriate 8-bit character code.
*
* The tables included must include, in order:
* - UNMODIFIED: Used when no modifier keys are pressed or active
* - SHIFT: Used when the SHIFT modifier is pressed
* - CTRL: Used when the CTRL modifier is pressed
* - CTRL-SHIFT: Used when both CTRL and SHIFT are pressed
* - CAPSLOCK: Used when CAPSLOCK is down but SHIFT is not pressed
* - CAPSLOCK-SHIFT: Used when CAPSLOCK is down and SHIFT is pressed
* - ALT: Used when only ALT is presse
* - ALT-SHIFT: Used when ALT is pressed and either CAPSLOCK is down
* or SHIFT is pressed (but not both)
*
* Inputs:
* tables = pointer to the keyboard translation tables
*/
extern short kbdmo_layout(const char * tables);
#endif
#endif

View file

@ -2,137 +2,123 @@
* Parallel port printer driver
*/
#include "errors.h"
#include "log.h"
#include "lpt_reg.h"
#include "dev/lpt.h"
#include "dev/text_screen_iii.h"
#include "dev/txt_screen.h"
#include "simpleio.h"
#include "sys_general.h"
#include "syscalls.h"
#if MODEL == MODEL_FOENIX_A2560K
#define LPT_DATA_PORT ((volatile unsigned char *)0x00C02378)
#define MAX_LPT_JIFFIES 600
#define LPT_STAT_PORT ((volatile unsigned char *)0x00C02379)
#define LPT_STAT_BUSY 0x80
#define LPT_STAT_ACK 0x40
#define LPT_STAT_PO 0x20
#define LPT_STAT_SELECT 0x10
#define LPT_STAT_ERROR 0x08
#define LPT_STAT_IRQ 0x04
#define LPT_CTRL_PORT ((volatile unsigned char *)0x00C0237A)
#define LPT_CTRL_STROBE 0x01
#define LPT_CTRL_AL 0x02
#define LPT_CTRL_INIT 0x04
#define LPT_CTRL_SELECT 0x08
#define LPT_CTRL_IRQE 0x10
#define LPT_CTRL_BI 0x20
#define LPT_INIT_ON 0x08 /* Start the printer initialization process */
#define LPT_INIT_OFF 0x0C /* Stop the printer initialization process */
#define LPT_STROBE_ON 0x0F /* Strobe the printer */
#define LPT_STROBE_OFF 0x0E /* Drop the strobe to the printer */
short lpt_delay() {
int i;
short x;
for (i = 0, x = 0; i < 10; i++) {
x++;
}
return x;
}
/*
* Install the LPT driver
/**
* Wait a little bit...
*/
short lpt_install() {
return 0;
void lpt_delay() {
long target_jiffies = sys_time_jiffies() + 1;
while (target_jiffies > sys_time_jiffies()) ;
}
void lpt_initialize() {
/**
* Initialize the printer... assert the INIT pin to trigger a reset on the printer
*/
short lpt_initialize() {
int i;
/* Set the outputs to start the initialization process */
*LPT_CTRL_PORT = LPT_INIT_ON;
/* Wait 50 micro seconds */
*LPT_CTRL_PORT = LPT_CTRL_SELECT;
lpt_delay();
/* Set the outputs to stop the initialization process */
*LPT_CTRL_PORT = LPT_INIT_OFF;
lpt_delay();
}
short lpt_wait_busy() {
unsigned char stat = 0;
do {
stat = *LPT_STAT_PORT;
if ((stat & LPT_STAT_ERROR) == 0) {
// There was an error...
DEBUG("LPT: lpt_wait_busy error");
return -1;
} else if (stat & LPT_STAT_PO) {
// Out of paper
DEBUG("LPT: lpt_wait_busy out of paper");
return -1;
}
} while ((stat & LPT_STAT_BUSY) == 0);
*LPT_CTRL_PORT = LPT_CTRL_mINIT | LPT_CTRL_SELECT;
return 0;
}
short lpt_wait_ack() {
unsigned char stat = 0;
short counter = 0;
/**
* Open a connection to the printer... all we do is assert the SELECT pin
*/
short lpt_open(t_channel * chan, const uint8_t * path, short mode) {
lpt_initialize();
do {
stat = *LPT_STAT_PORT;
} while ((counter++ < 32000) && ((stat & LPT_STAT_ACK) != 0));
*LPT_CTRL_PORT = LPT_CTRL_mINIT | LPT_CTRL_SELECT;
// Write a dummy character to kick everything off
lpt_write_b(0, "\x00", 0);
return 0;
}
/*
/**
* Close the connection to the printer... all we do is deassert the SELECT pin
*/
short lpt_close(t_channel * chan) {
*LPT_CTRL_PORT = LPT_CTRL_mINIT;
return 0;
}
/**
* Write a character to the parallel port
*/
short lpt_write_b(p_channel chan, unsigned char b) {
/* This write routine is polled I/O. */
/* TODO: convert it to interrupt driven */
long target_jiffies = 0;
/* Wait until the printer is not busy */
if (lpt_wait_busy()) {
// If we got an error, return an error
DEBUG("LPT: Error writing");
return -1;
}
*LPT_DATA_PORT = b; /* Send the byte */
*LPT_CTRL_PORT = LPT_STROBE_ON; /* Strobe the interface */
target_jiffies = sys_time_jiffies() + MAX_LPT_JIFFIES;
while ((*LPT_STAT_PORT & LPT_STAT_nBUSY) != LPT_STAT_nBUSY) {
lpt_delay();
/* Wait for the printer to acknowledge */
if (lpt_wait_ack()) {
// If we got an error, return an error
*LPT_CTRL_PORT = LPT_STROBE_OFF; /* Drop the strobe */
return -1;
if (target_jiffies < sys_time_jiffies()) {
return DEV_TIMEOUT;
}
}
*LPT_CTRL_PORT = LPT_STROBE_OFF; /* Drop the strobe */
/* Send the byte */
*LPT_DATA_PORT = b;
return 0; /* Return success */
/* Strobe the interface */
*LPT_CTRL_PORT = LPT_CTRL_mINIT | LPT_CTRL_SELECT;
lpt_delay();
*LPT_CTRL_PORT = LPT_CTRL_mINIT | LPT_CTRL_SELECT | LPT_CTRL_STROBE;
/* Wait until the printer is not busy */
target_jiffies = sys_time_jiffies() + MAX_LPT_JIFFIES;
while ((*LPT_STAT_PORT & LPT_STAT_nBUSY) != LPT_STAT_nBUSY) {
lpt_delay();
if (target_jiffies < sys_time_jiffies()) {
return DEV_TIMEOUT;
}
}
unsigned char status = *LPT_STAT_PORT;
if ((status & (LPT_STAT_nERROR | LPT_STAT_PO)) != LPT_STAT_nERROR ) {
// Online, there's paper, not busy, and not in error
if (status & LPT_STAT_PO) {
return DEV_NOMEDIA;
} else {
return ERR_GENERAL;
}
} else {
return 0;
}
return 0;
}
/*
* Write a buffer of bytes to the parallel port
*/
short lpt_write(p_channel chan, unsigned char * buffer, short size) {
short lpt_write(p_channel chan, const uint8_t * buffer, short size) {
int i;
short result;
for (i = 0; i < size; i++) {
result = lpt_write_b(chan, buffer[i]);
if (result < 0) {
if (result) {
return result;
}
}
@ -140,4 +126,49 @@ short lpt_write(p_channel chan, unsigned char * buffer, short size) {
return 0;
}
/**
* Return the status of the printer
*/
short lpt_status(p_channel chan) {
short result = 0;
// Get the status
unsigned char stat = *LPT_STAT_PORT;
// Conver the status bits to be consistent with channels
if ((stat & LPT_STAT_nERROR) == 0) result |= LPT_STATUS_ERROR;
if (stat & LPT_STAT_PO) result |= LPT_STATUS_PAPER;
if (stat & LPT_STAT_SELECT) result |= LPT_STATUS_ONLINE;
if ((stat & (LPT_STAT_nERROR | LPT_STAT_PO | LPT_STAT_nBUSY | LPT_STAT_SELECT)) == LPT_STAT_nERROR | LPT_STAT_nBUSY | LPT_STAT_SELECT) {
// Online, there's paper, not busy, and not in error
result |= LPT_STATUS_WRITABLE;
}
return result;
}
/**
* Install the LPT driver
*/
short lpt_install() {
t_dev_chan dev;
dev.name = "LPT";
dev.number = CDEV_LPT;
dev.init = 0;
dev.open = lpt_open;
dev.close = lpt_close;
dev.read = 0;
dev.readline = 0;
dev.read_b = 0;
dev.write = lpt_write;
dev.write_b = lpt_write_b;
dev.flush = 0;
dev.seek = 0;
dev.status = lpt_status;
dev.ioctrl = 0;
return cdev_register(&dev);
}
#endif

View file

@ -7,21 +7,14 @@
#include "dev/channel.h"
#define LPT_STATUS_ERROR 0x02 /** The printer has encountered some error */
#define LPT_STATUS_WRITABLE 0x08 /** The printer can accept data (online, no error, has paper, not busy) */
#define LPT_STATUS_PAPER 0x10 /** The printer is out of paper */
#define LPT_STATUS_ONLINE 0x20 /** The printer is selected/online */
/*
* Install the LPT driver
*/
extern short lpt_install();
extern void lpt_initialize();
/*
* Write a character to the parallel port
*/
extern short lpt_write_b(p_channel chan, unsigned char b);
/*
* Write a buffer of bytes to the parallel port
*/
extern short lpt_write(p_channel chan, unsigned char * buffer, short size);
#endif

View file

@ -3,80 +3,222 @@
*/
#include "midi_reg.h"
#include "dev/channel.h"
#include "dev/midi.h"
#include "errors.h"
#include "simpleio.h"
#include "sys_general.h"
#include "timers.h"
#if MODEL == MODEL_FOENIX_A2560K
/*
* Return true if there is data waiting to be read
/** Timeout for waiting on the MIDI interface */
const long midi_timeout = 60;
/**
* Wait for data to be ready to read...
*
* @return 1 on success, 0 if there is a timeout
*/
short midi_input_not_ready() {
return (*MIDI_STAT & MIDI_STAT_RX_EMPTY);
short midi_can_read() {
long target = timers_jiffies() + midi_timeout;
do {
if ((*MIDI_STAT & MIDI_STAT_RX_EMPTY) == 0) {
// There is data waiting
return 1;
}
} while (target > timers_jiffies());
// We have waited too long
return 0;
}
/*
* Return true if there is data waiting to be read
/**
* Wait for the MIDI transmiter to be empty...
*
* @return 1 on success, 0 if there is a timeout
*/
short midi_output_busy() {
return (*MIDI_STAT & MIDI_STAT_RX_EMPTY);
short midi_can_write() {
long target = timers_jiffies() + midi_timeout;
do {
if ((*MIDI_STAT & MIDI_STAT_TX_BUSY) != 0) {
// The transmit buffer is empty
return 1;
}
} while (target > timers_jiffies());
// We have waited too long
return 0;
}
/**
* Send a command to the MPU-401
*
* @param cmd the command byte
* @return 0 on success, any other number is an error
*/
short midi_command(unsigned char cmd) {
/* Send the byte */
*MIDI_CMD = cmd;
return 0;
}
/*
/**
* Initilialize the MIDI port
*
* @return 0 on success, any other number is an error
*/
short midi_init() {
unsigned char dummy;
short result;
while (midi_output_busy()) ;
*MIDI_CMD = 0xFF; /* Reset the MIDI port */
/* Wait for the ACK */
for (dummy = 0; dummy != 0xFE; ) {
while (midi_input_not_ready()) ;
dummy = *MIDI_DATA;
result = midi_command(0xFF); /* Reset the MIDI port */
if (result != 0) {
return result;
}
while (midi_output_busy()) ;
*MIDI_CMD = 0x3F; /* Switch the MIDI port into UART mode */
result = midi_command(0x3F); /* Switch the MIDI port into UART mode */
if (result != 0) {
return result;
}
/* Wait for the ACK */
for (dummy = 0; dummy != 0xFE; ) {
while (midi_input_not_ready()) ;
do {
if (midi_can_read()) {
dummy = *MIDI_DATA;
} else {
// There was a timeout
return DEV_TIMEOUT;
}
} while (dummy != 0xFE);
return 0;
}
/*
/**
* Send a byte to the MIDI port
*
* Inputs:
* b = the byte to send
* @param b the byte to send
* @return 0 on success, any other number is an error
*/
short midi_put(unsigned char b) {
while (midi_output_busy()) ;
short midi_write_b(p_channel chan, const unsigned char b) {
if (midi_can_write()) {
/* Send the byte */
*MIDI_DATA = b;
return 0;
} else {
// There was a timeout
return DEV_TIMEOUT;
}
}
/**
* Write a buffer's worth of bytes to the MIDI port
*
* @param chan the channel record (ignored)
* @param buffer the array of bytes to send
* @param size the number of bytes to send
*/
short midi_write(p_channel chan, const unsigned char * buffer, short size) {
short i = 0;
short result = 0;
for (i = 0; i < size; i++) {
result = midi_write_b(chan, buffer[i]);
if (result) {
return result;
}
}
return 0;
}
/*
/**
* Get a byte from the MIDI port
*
* Returns:
* b = the byte to send
* @param chan the channel record (ignored)
* @return the byte read, negative on error
*/
unsigned char midi_get_poll() {
while (midi_input_not_ready()) ;
return *MIDI_DATA;
short midi_read_b(p_channel chan) {
if (midi_can_read()) {
return ((short)*MIDI_DATA & 0x00ff);
} else {
// There was a timeout
return DEV_TIMEOUT;
}
}
/**
* Read a number of bytes from the MIDI port into the buffer
*
* @param chan the channel record (ignored)
* @param buffer the byte buffer into which to store the read data
* @size the number of bytes to read
*/
short midi_read(p_channel chan, unsigned char * buffer, short size) {
short i = 0;
short result = 0;
for (i = 0; i < size; i++) {
result = midi_read_b(chan);
if (result < 0) {
return result;
} else {
buffer[i] = (unsigned char)(result & 0xff);
}
}
return size;
}
/**
* Return the status of the MIDI port
*
* @param chan the channel record (ignored)
* @return the channel status flags
*/
short midi_status(p_channel chan) {
short status = 0;
unsigned char midi_stat_value = *MIDI_STAT;
if ((midi_stat_value & MIDI_STAT_TX_BUSY) != 0) {
status |= CDEV_STAT_WRITABLE;
}
if ((midi_stat_value & MIDI_STAT_RX_EMPTY) == 0) {
status |= CDEV_STAT_READABLE;
}
return status;
}
short midi_open(p_channel chan, const char * path, short mode) {
return midi_init();
}
/**
* Install the driver for the MIDI port
*/
short midi_install() {
short result;
t_dev_chan dev;
dev.name = "MIDI";
dev.number = CDEV_MIDI;
dev.init = midi_init;
dev.open = midi_open;
dev.close = 0;
dev.read = midi_read;
dev.readline = 0;
dev.read_b = midi_read_b;
dev.write = midi_write;
dev.write_b = midi_write_b;
dev.flush = 0;
dev.seek = 0;
dev.status = midi_status;
dev.ioctrl = 0;
return cdev_register(&dev);
}
#endif

View file

@ -5,25 +5,9 @@
#ifndef __MIDI_H
#define __MIDI_H
/*
* Initilialize the MIDI port
/**
* Install the driver for the MIDI port
*/
extern short midi_init();
/*
* Send a byte to the MIDI port
*
* Inputs:
* b = the byte to send
*/
extern short midi_put(unsigned char b);
/*
* Get a byte from the MIDI port
*
* Returns:
* b = the byte to send
*/
extern unsigned char midi_get_poll();
extern short midi_install();
#endif

View file

@ -4,9 +4,11 @@
#include "constants.h"
#include "vicky_general.h"
#include "text_screen_iii.h"
#include "dev/txt_screen.h"
#include "simpleio.h"
#include "sys_general.h"
#include "rsrc/font/MSX_CP437_8x8.h"
#include "rsrc/font/BM437_IBM_Model3_Alt4.h"
#define MAX_TEXT_CHANNELS 2
@ -15,6 +17,7 @@
*/
typedef struct s_text_channel {
unsigned char current_color;
unsigned char * font_ptr;
volatile unsigned long * master_control;
volatile char * text_cells;
@ -22,11 +25,14 @@ typedef struct s_text_channel {
volatile unsigned long * cursor_settings;
volatile unsigned long * cursor_position;
volatile unsigned long * border_control;
volatile unsigned long * font_size_ctrl;
volatile unsigned long * font_count_ctrl;
short columns_max;
short rows_max;
short columns_visible;
short rows_visible;
short font_size; /* 0 = 8x8, 1 = 8x16 */
short x;
short y;
@ -80,9 +86,16 @@ const unsigned short bg_color_lut [32] = {
* Initialize the text screen driver
*/
int text_init() {
short need_hires = 0;
short need_hires = 1;
int i, x;
p_text_channel chan_a = &text_channel[0];
unsigned long border_color = 0;
#if MODEL == MODEL_FOENIX_A2560K
border_color = 0x00004000; /* Dark blue border for the K */
#elif MODEL == MODEL_FOENIX_A2560U || MODEL == MODEL_FOENIX_A2560U_PLUS
border_color = 0x00008080; /* Dark blue border for the K */
#endif
#if MODEL == MODEL_FOENIX_A2560K
p_text_channel chan_b = &text_channel[1];
@ -108,19 +121,27 @@ int text_init() {
text_channel[i].y = 0;
}
#if MODEL == MODEL_FOENIX_A2560K
// Init CLUT for the Color Memory
for (i = 0; i < 16; i++) {
unsigned long fg_color = fg_color_lut[2*i + 1] << 16 | fg_color_lut[2*i];
unsigned long bg_color = bg_color_lut[2*i + 1] << 16 | bg_color_lut[2*i];
FG_CLUT_A[i] = fg_color;
BG_CLUT_A[i] = bg_color;
FG_CLUT_B[i] = fg_color;
BG_CLUT_B[i] = bg_color;
}
#else
// Init CLUT for the Color Memory
for (i = 0; i<32; i++) {
FG_CLUT_A[i] = fg_color_lut[i];
BG_CLUT_A[i] = bg_color_lut[i];
#if MODEL == MODEL_FOENIX_A2560K
FG_CLUT_B[i] = fg_color_lut[i];
BG_CLUT_B[i] = bg_color_lut[i];
#endif
}
#endif
/* Initialize everything... only do a screen if it's present */
need_hires = ((*VKY3_DIP_REG & VKY3_DIP_HIRES) == 0) ? 1 : 0;
// need_hires = ((*VKY3_DIP_REG & VKY3_DIP_HIRES) == 0) ? 1 : 0;
chan_a->master_control = MasterControlReg_A;
chan_a->text_cells = ScreenText_A;
@ -129,29 +150,68 @@ int text_init() {
chan_a->cursor_position = CursorControlReg_H_A;
chan_a->border_control = BorderControlReg_L_A;
#if MODEL == MODEL_FOENIX_A2560K
/* A2560K has support for 8x16 characters and therefore font sizes */
chan_a->font_size_ctrl = FONT_Size_Ctrl_A;
chan_a->font_count_ctrl = FONT_Count_Ctrl_A;
need_hires = 0;
if (need_hires) {
*chan_a->master_control = VKY3_MCRA_1024x768 | VKY3_MCR_TEXT_EN; /* Set to text only mode: 800x600 */
} else {
*chan_a->master_control = VKY3_MCR_800x600 | VKY3_MCR_TEXT_EN; /* Set to text only mode: 800x600 */
}
#else
/* All other models do not have this feature */
chan_a->font_size_ctrl = 0;
chan_a->font_count_ctrl = 0;
if (need_hires) {
*chan_a->master_control = VKY3_MCR_800x600 | VKY3_MCR_TEXT_EN; /* Set to text only mode: 800x600 */
} else {
*chan_a->master_control = VKY3_MCR_640x480 | VKY3_MCR_TEXT_EN; /* Set to text only mode: 640x480 */
}
#endif
chan_a->border_control[0] = 0x00102001; // Enable
chan_a->border_control[1] = 0x00000040; //Dark Blue
if (chan_a->font_size_ctrl) {
*chan_a->font_size_ctrl = 0x08080808; /* Font and container are 8x8 */
*chan_a->font_count_ctrl = 0x00004B64; /* 75 rows and 100 columns */
chan_a->font_size = 0; /* Set 8x16 */
/* Set the font for channel A */
for (i = 0; i < 0x800; i++) {
unsigned char b = MSX_CP437_8x8_bin[i];
VICKY_TXT_FONT_A[i] = b;
} else {
chan_a->font_size = 0;
}
text_set_border(0, 1, 0x20, 0x10, 0x00008080);
text_set_border(0, 1, 0x10, 0x10, border_color);
text_setsizes(0);
text_set_color(0, 0xf, 4);
text_set_cursor(0, 0xF3, 0x7F, 1, 1);
text_set_xy(0, 0, 0);
text_clear(0, 2);
/* Set the font for channel A */
if (chan_a->font_size == 1) {
/* Load the 8x16 font */
for (i = 0; i < 0x1000; i++) {
unsigned char b = BM437_IBM_Model3_Alt4[i];
VICKY_TXT_FONT_A[i] = b;
}
/* Cursor for this font */
text_set_cursor(0, 0xF3, 0xB0, 1, 1);
} else {
/* Load the 8x8 font */
for (i = 0; i < 0x800; i++) {
unsigned char b = MSX_CP437_8x8_bin[i];
VICKY_TXT_FONT_A[i] = b;
}
/* Cursor for this font */
text_set_border(0, 1, 0x20, 0x10, border_color);
}
#if MODEL == MODEL_FOENIX_A2560K
chan_b->master_control = MasterControlReg_B;
@ -160,6 +220,8 @@ int text_init() {
chan_b->cursor_settings = CursorControlReg_L_B;
chan_b->cursor_position = CursorControlReg_H_B;
chan_b->border_control = BorderControlReg_L_B;
chan_b->font_size_ctrl = 0;
chan_b->font_count_ctrl = 0;
if (need_hires) {
*chan_b->master_control = VKY3_MCR_800x600 | VKY3_MCR_TEXT_EN; /* Set to text only mode: 800x600 */
@ -167,11 +229,9 @@ int text_init() {
*chan_b->master_control = VKY3_MCR_640x480 | VKY3_MCR_TEXT_EN; /* Set to text only mode: 640x480 */
}
chan_b->border_control[0] = 0x00102000; // Enable
chan_b->border_control[1] = 0x00400000; //Dark Red
text_set_border(1, 1, 0x20, 0x10, border_color);
text_setsizes(1);
text_set_color(1, 4, 3);
text_set_color(1, 0x0f, 0x04);
text_clear(1, 2);
text_set_cursor(1, 0xF3, 0x7F, 1, 1);
text_set_xy(1, 0, 0);
@ -333,6 +393,10 @@ void text_setsizes(short screen) {
chan->rows_max /= 2;
}
if (chan->font_size == 1) {
chan->rows_max /= 2;
}
/* Calculate visible rows and columns assuming no border */
chan->rows_visible = chan->rows_max;
chan->columns_visible = chan->columns_max;
@ -350,6 +414,10 @@ void text_setsizes(short screen) {
rows_reduction /= 2;
}
if (chan->font_size == 1) {
rows_reduction /= 2;
}
chan->columns_visible -= columns_reduction;
chan->rows_visible -= rows_reduction;
}
@ -538,6 +606,30 @@ void text_scroll(short screen) {
short row, column;
p_text_channel chan = &text_channel[screen];
#if MODEL == MODEL_FOENIX_A2560K
for (row = 0; row < chan->rows_visible - 1; row++) {
short offset1 = row * chan->columns_max;
short offset2 = (row + 1) * chan->columns_max;
volatile unsigned char * text_dest = &chan->text_cells[offset1];
volatile unsigned char * color_dest = &chan->color_cells[offset1];
volatile unsigned char * text_src = &chan->text_cells[offset2];
volatile unsigned char * color_src = &chan->color_cells[offset2];
for (column = 0; column < chan->columns_max; column++) {
*text_dest++ = *text_src++;
*color_dest++ = *color_src++;
}
}
short offset3 = (chan->rows_visible - 1) * chan->columns_max;
volatile unsigned char * text_dest = &chan->text_cells[offset3];
volatile unsigned char * color_dest = &chan->color_cells[offset3];
uint8_t color = chan->current_color;
for (column = 0; column < chan->columns_max; column++) {
*text_dest++ = ' ';
*color_dest++ = color;
}
#else
for (row = 0; row < chan->rows_visible - 1; row++) {
short offset1 = row * chan->columns_max;
short offset2 = (row + 1) * chan->columns_max;
@ -560,6 +652,7 @@ void text_scroll(short screen) {
*text_dest++ = ' ';
*color_dest++ = color << 8 | color;
}
#endif
}
}
@ -605,3 +698,21 @@ void text_put_raw(short screen, char c) {
}
}
}
/*
* Gets the size of the test screen in rows and columns
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* columns = pointer to a short in which to store the number of columns
* rows = pointer to a short in which to store the number of rows
*/
void text_getsize(short screen, short * columns, short * rows) {
if (screen < MAX_TEXT_CHANNELS) {
short x, y;
p_text_channel chan = &text_channel[screen];
*columns = chan->columns_visible;
*rows = chan->rows_visible;
}
}

View file

@ -142,4 +142,14 @@ extern void text_delete(short screen, short count);
*/
extern void text_scroll(short screen);
/*
* Gets the size of the test screen in rows and columns
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* columns = pointer to a short in which to store the number of columns
* rows = pointer to a short in which to store the number of rows
*/
extern void text_getsize(short screen, short * columns, short * rows);
#endif

View file

@ -9,7 +9,7 @@
#include "indicators.h"
#include "dev/block.h"
#include "dev/pata.h"
#include "dev/text_screen_iii.h"
#include "dev/txt_screen.h"
#include "dev/rtc.h"
#include "pata_reg.h"
@ -39,8 +39,8 @@ short g_pata_status = PATA_STAT_NOINIT; // Status of the PATA interface
//
short pata_wait_not_busy() {
long target_ticks;
long ticks;
char status;
long ticks = 0;
char status = 0;
TRACE("pata_wait_not_busy");
@ -68,8 +68,8 @@ short pata_wait_not_busy() {
//
short pata_wait_ready() {
long target_ticks;
long ticks;
char status;
long ticks = 0;
char status = 0;
TRACE("pata_wait_ready");
@ -94,9 +94,9 @@ short pata_wait_ready() {
// 0 on success (PATA drive is ready and not busy), DEV_TIMEOUT on timeout
//
short pata_wait_ready_not_busy() {
long target_ticks;
long ticks;
char status;
long target_ticks = 0;
long ticks = 0;
char status = 0;
TRACE("pata_wait_ready_not_busy");
@ -115,6 +115,7 @@ short pata_wait_ready_not_busy() {
log(LOG_ERROR, "pata_wait_ready_not_busy: timeout");
log_num(LOG_ERROR, "target_ticks: ", (int)target_ticks);
log_num(LOG_ERROR, "ticks: ", (int)ticks);
return DEV_TIMEOUT;
} else {
return 0;
@ -128,9 +129,9 @@ short pata_wait_ready_not_busy() {
// 0 on success (PATA drive is ready to transfer data), DEV_TIMEOUT on timeout
//
short pata_wait_data_request() {
long target_ticks;
long ticks;
char status;
long target_ticks = 0;
long ticks = 0;
char status = 0;
TRACE("pata_wait_data_request");
@ -266,11 +267,11 @@ short pata_read(long lba, unsigned char * buffer, short size) {
log_num(LOG_VERBOSE, "pata_read lba: ", lba);
/* Turn on the HDD LED */
// ind_set(IND_HDC, IND_ON);
ind_set(IND_HDC, IND_ON);
if (pata_wait_ready_not_busy()) {
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
return DEV_TIMEOUT;
}
@ -278,7 +279,7 @@ short pata_read(long lba, unsigned char * buffer, short size) {
*PATA_HEAD = ((lba >> 24) & 0x07) | 0xe0; // Upper 3 bits of LBA, Drive 0, LBA mode.
if (pata_wait_ready_not_busy()) {
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
return DEV_TIMEOUT;
}
@ -294,14 +295,14 @@ short pata_read(long lba, unsigned char * buffer, short size) {
if (pata_wait_ready_not_busy()) {
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
return DEV_TIMEOUT;
}
if (pata_wait_data_request()) {
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
return DEV_TIMEOUT;
}
@ -312,7 +313,7 @@ short pata_read(long lba, unsigned char * buffer, short size) {
}
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
return i;
}
@ -385,12 +386,12 @@ short pata_write(long lba, const unsigned char * buffer, short size) {
TRACE("pata_write");
/* Turn on the HDD LED */
// ind_set(IND_HDC, IND_ON);
ind_set(IND_HDC, IND_ON);
if (pata_wait_ready_not_busy()) {
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
log(LOG_ERROR, "pata_write: pata_wait_ready_not_busy timeout 1");
return DEV_TIMEOUT;
}
@ -398,8 +399,8 @@ short pata_write(long lba, const unsigned char * buffer, short size) {
if (pata_wait_ready_not_busy()) {
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
log(LOG_ERROR, "pata_write: pata_wait_ready_not_busy timeout 2");
return DEV_TIMEOUT;
}
@ -416,8 +417,8 @@ short pata_write(long lba, const unsigned char * buffer, short size) {
if (pata_wait_ready_not_busy()) {
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
log(LOG_ERROR, "pata_write: pata_wait_ready_not_busy timeout 3");
return DEV_TIMEOUT;
}
@ -426,25 +427,25 @@ short pata_write(long lba, const unsigned char * buffer, short size) {
*PATA_DATA_16 = *wptr++;
}
// Give the controller some time...
for (i = 0; i < 32000; i++) ;
// // Give the controller some time...
// for (i = 0; i < 32000; i++) ;
if (pata_wait_ready_not_busy()) {
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
log(LOG_ERROR, "pata_write: pata_wait_ready_not_busy timeout 4");
return DEV_TIMEOUT;
}
// Give the controller some time...
for (i = 0; i < 32000; i++) ;
// for (i = 0; i < 32000; i++) ;
status = *PATA_CMD_STAT;
if ((status & PATA_STAT_DF) != 0){
log(LOG_ERROR, "pata_write: device fault");
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
return -1;
}
@ -453,13 +454,13 @@ short pata_write(long lba, const unsigned char * buffer, short size) {
log(LOG_ERROR, "pata_write: error");
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
return -1;
}
/* Turn off the HDD LED */
// ind_set(IND_HDC, IND_OFF);
ind_set(IND_HDC, IND_OFF);
return size;
}

View file

@ -14,7 +14,7 @@
#include "vicky_general.h"
#include "dev/ps2.h"
#include "dev/rtc.h"
#include "dev/text_screen_iii.h"
#include "dev/txt_screen.h"
#include "rsrc/bitmaps/mouse_pointer.h"
#define PS2_TIMEOUT_JF 10 /* Timeout in jiffies: 1/60 second units */
@ -98,7 +98,7 @@ short g_mouse_state = 0; /* Mouse packet state machine's state */
* Mapping of "codepoints" 0x80 - 0x95 (function keys, etc)
* to ANSI escape codes
*/
const char * ansi_keys[] = {
static const char * ansi_keys[] = {
"1~", /* HOME */
"2~", /* INS */
"3~", /* DELETE */
@ -334,7 +334,7 @@ const char g_us_sc_alt_shift[] = {
short ps2_wait_out() {
long target_ticks;
log(LOG_TRACE, "ps2_wait_out");
// log(LOG_TRACE, "ps2_wait_out");
target_ticks = rtc_get_jiffies() + PS2_TIMEOUT_JF;
while ((*PS2_STATUS & PS2_STAT_OBF) == 0) {
@ -355,7 +355,7 @@ short ps2_wait_out() {
short ps2_wait_in() {
long target_ticks;
log(LOG_TRACE, "ps2_wait_in");
// log(LOG_TRACE, "ps2_wait_in");
target_ticks = rtc_get_jiffies() + PS2_TIMEOUT_JF;
while ((*PS2_STATUS & PS2_STAT_IBF) != 0) {
@ -729,7 +729,7 @@ void kbd_handle_irq() {
* modifiers = the current modifier bit flags (ALT, CTRL, META, etc)
* c = the character found from the scan code.
*/
char kbd_to_ansi(unsigned char modifiers, unsigned char c) {
static char kbd_to_ansi(unsigned char modifiers, unsigned char c) {
if ((c >= 0x80) && (c <= 0x95)) {
/* The key is a function key or a special control key */
const char * sequence;
@ -857,6 +857,12 @@ char kbd_getc() {
}
}
char kbd_getc_poll() {
kbd_handle_irq();
return kbd_getc();
}
/*
* Handle an interrupt from the PS/2 mouse port
*/

View file

@ -44,6 +44,8 @@ extern unsigned short kbd_get_scancode();
*/
extern char kbd_getc();
extern char kbd_getc_poll();
/*
* Set the keyboard translation tables
*

View file

@ -19,6 +19,7 @@ void rtc_handle_int() {
unsigned char flags;
/* Periodic interrupt: increment the ticks counter */
flags = *RTC_FLAGS;
rtc_ticks++;
}
@ -45,13 +46,14 @@ void rtc_init() {
// /* Set the periodic interrupt to 15 millisecs */
// *RTC_RATES = RTC_RATE_15ms;
//
// int_register(INT_RTC, rtc_handle_int);
/* Enable the periodic interrupt */
//
// /* Enable the periodic interrupt */
// flags = *RTC_FLAGS;
// *RTC_ENABLES = RTC_PIE;
// rtc_ticks = 0;
//
// int_enable(INT_RTC);
}
@ -69,6 +71,29 @@ void rtc_enable_ticks() {
int_enable(INT_RTC);
}
/**
* Register a function to be called periodically
*
* @param rate the rate at which the function should be called using the bq4802LY periodic rate values (0 to disable)
* @param handler a pointer to a function from void to void to be called
* @return 0 on success, any other number is an error
*/
short rtc_register_periodic(short rate, FUNC_V_2_V handler) {
if (rate == 0) {
int_disable(INT_RTC);
*RTC_RATES = 0;
*RTC_ENABLES &= ~RTC_PIE;
} else {
int_register(INT_RTC, handler);
*RTC_RATES = rate;
unsigned char flags = *RTC_FLAGS;
*RTC_ENABLES = RTC_PIE;
int_enable(INT_RTC);
}
}
/*
* Set the time on the RTC
*

View file

@ -5,6 +5,8 @@
#ifndef __RTC_H
#define __RTC_H
#include "types.h"
typedef struct s_time {
short year;
short month;
@ -54,4 +56,13 @@ extern void rtc_get_time(p_time time);
*/
extern long rtc_get_jiffies();
/**
* Register a function to be called periodically
*
* @param rate the rate at which the function should be called using the bq4802LY periodic rate values (0 to disable)
* @param handler a pointer to a function from void to void to be called
* @return 0 on success, any other number is an error
*/
extern short rtc_register_periodic(short rate, FUNC_V_2_V handler);
#endif

View file

@ -7,11 +7,11 @@
#include "errors.h"
#include "gabe_reg.h"
#include "indicators.h"
#include "interrupt.h"
#include "dev/block.h"
#include "sdc_reg.h"
#include "dev/rtc.h"
#include "dev/sdc.h"
#include "dev/text_screen_iii.h"
//
// Constants
@ -22,6 +22,14 @@
unsigned char g_sdc_status = SDC_STAT_NOINIT;
unsigned char g_sdc_error = 0;
/*
* Handle insertion of an SD card
*/
void sdc_handler() {
/* Very simple... just flag it as uninitialized */
g_sdc_status = SDC_STAT_NOINIT;
}
//
// Attempt to reset the SD controller
//
@ -40,16 +48,14 @@ void sdc_reset() {
// Return true if there is an SD card in the slot
//
short sdc_detected() {
return 1;
// return (*SDCARD_STAT & SDC_DETECTED) != SDC_DETECTED;
return (*GABE_SDC_REG & GABE_SDC_PRESENT) != GABE_SDC_PRESENT;
}
//
// Return true if there is an SD card is protected
//
short sdc_protected() {
return 0;
// return (*SDCARD_STAT & SDC_WRITEPROT) != SDC_WRITEPROT;
return (*GABE_SDC_REG & GABE_SDC_WPROT) == GABE_SDC_WPROT;
}
//
@ -406,6 +412,10 @@ short sdc_install() {
TRACE("sdc_install");
/* Install an interrupt handler to catch insertion of a card */
int_register(INT_SDC_INS, sdc_handler);
int_enable(INT_SDC_INS);
sdc_reset();
dev.number = BDEV_SDC;

670
src/dev/txt_a2560k_a.c Normal file
View file

@ -0,0 +1,670 @@
/** @file txt_a2560k_a.c
*
* Text screen driver for A2560K Channel A
*/
#include <string.h>
#include <stdio.h>
#include "constants.h"
#include "log.h"
#include "utilities.h"
#include "A2560K/vky_chan_a.h"
#include "A2560K/vky_chan_b.h"
#include "dev/txt_screen.h"
#include "dev/txt_a2560k_a.h"
extern const unsigned char MSX_CP437_8x8_bin[];
/* Default text color lookup table values (AARRGGBB) */
const unsigned long a2560k_a_lut[VKY3_A_LUT_SIZE] = {
0xFF000000, // Black (transparent)
0xFF800000, // Mid-Tone Red
0xFF008000, // Mid-Tone Green
0xFF808000, // Mid-Tone Yellow
0xFF000080, // Mid-Tone Blue
0xFFAA5500, // Mid-Tone Orange
0xFF008080, // Mid-Tone Cian
0xFF808080, // 50% Grey
0xFF555555, // Dark Grey
0xFFFF0000, // Bright Red
0xFF55FF55, // Bright Green
0xFFFFFF55, // Bright Yellow
0xFF5555FF, // Bright Blue
0xFFFF7FFF, // Bright Orange
0xFF55FFFF, // Bright Cyan
0xFFFFFFFF // White
};
/*
* Driver level variables for the screen
*/
unsigned char a2560k_a_enable_set_sizes; /* Flag to enable set_sizes to actually do its computation */
t_txt_capabilities a2560k_a_caps; /* The capabilities of Channel A */
t_extent a2560k_a_resolutions[2]; /* The list of display resolutions */
t_extent a2560k_a_fonts[2]; /* The list of font resolutions */
t_rect a2560k_a_region; /* The current region */
t_point a2560k_a_cursor; /* The current cursor position */
t_extent a2560k_a_resolution; /* The current display resolution */
t_extent a2560k_a_font_size; /* The current font size */
t_extent a2560k_a_max_size; /* The size of the screen in characters (without border removed) */
t_extent a2560k_a_visible_size; /* The size of the visible screen in characters (with border removed) */
short a2560k_a_border_width; /* Width of the border on one side */
short a2560k_a_border_height; /* Height of the border on one side */
unsigned char a2560k_a_color; /* The current color */
unsigned long msr_shadow; /* A shadow register for the Master Control Register */
/**
* Gets the description of a screen's capabilities
*
* @return a pointer to the read-only description (0 on error)
*/
const p_txt_capabilities txt_a2560k_a_get_capabilities() {
return &a2560k_a_caps;
}
/**
* Calculate the size of the text screen in rows and columns so that
* the kernel printing routines can work correctly.
*
* NOTE: this should be called whenever the VKY3 Channel A registers are changed
*/
void txt_a2560k_a_set_sizes() {
if (a2560k_a_enable_set_sizes) {
/* Only recalculate after initialization is mostly completed */
/*
* Calculate the maximum number of characters visible on the screen
* This controls text layout in memory
*/
a2560k_a_max_size.width = a2560k_a_resolution.width / a2560k_a_font_size.width;
a2560k_a_max_size.height = a2560k_a_resolution.height / a2560k_a_font_size.height;
// /* Set the font manager register */
*VKY3_A_FM1 = (a2560k_a_max_size.height & 0xff) << 8 | (a2560k_a_max_size.width & 0xff);
/*
* Calculate the characters that are visible in whole or in part
*/
if ((a2560k_a_border_width != 0) && (a2560k_a_border_height != 0)) {
short border_width = (2 * a2560k_a_border_width) / a2560k_a_font_size.width;
short border_height = (2 * a2560k_a_border_height) / a2560k_a_font_size.height;
a2560k_a_visible_size.width = a2560k_a_max_size.width - border_width;
a2560k_a_visible_size.height = a2560k_a_max_size.height - border_height;
} else {
a2560k_a_visible_size.width = a2560k_a_max_size.width;
a2560k_a_visible_size.height = a2560k_a_max_size.height;
}
}
}
/**
* Get the display resolutions
*
* @param text_size the size of the screen in visible characters (may be null)
* @param pixel_size the size of the screen in pixels (may be null)
*/
void txt_a2560k_a_get_sizes(p_extent text_size, p_extent pixel_size) {
if (text_size) {
text_size->width = a2560k_a_visible_size.width;
text_size->height = a2560k_a_visible_size.height;
}
if (pixel_size) {
pixel_size->width = a2560k_a_resolution.width;
pixel_size->height = a2560k_a_resolution.height;
}
}
/**
* Set the display mode for the screen
*
* @param mode a bitfield of desired display mode options
*
* @return 0 on success, any other number means the mode is invalid for the screen
*/
short txt_a2560k_a_set_mode(short mode) {
/* Turn off anything not set */
msr_shadow &= ~(TXT_MODE_SLEEP | TXT_MODE_TEXT);
if (mode & TXT_MODE_SLEEP) {
/* Put the monitor to sleep */
msr_shadow |= VKY3_A_MCR_SLEEP;
*VKY3_A_MCR = msr_shadow;
return 0;
} else if (mode & TXT_MODE_TEXT) {
/* Put on text mode */
msr_shadow |= VKY3_A_MCR_TEXT;
*VKY3_A_MCR = msr_shadow;
return 0;
} else {
/* Unsupported mode */
return -1;
}
}
/**
* Set the display resolution of the screen
*
* @param width the desired horizontal resolution in pixels
* @param height the desired veritical resolution in pixels
*
* @return 0 on success, any other number means the resolution is unsupported
*/
short txt_a2560k_a_set_resolution(short width, short height) {
// If no size specified, set it based on the DIP switch
if ((width == 0) || (height == 0)) {
if ((*VKY3_A_MCR & VKY3_A_HIRES) == 0) {
width = 1024;
height = 768;
} else {
width = 800;
height = 600;
}
}
// Kick the PLL
// If VICKY is generating a 40MHz signal, we need to switch the bit to go to 40MHz before
// clearing it to go back to 25MHz.
if (*VKY3_A_MCR & VKY3_A_CLK40) {
*VKY3_A_MCR |= VKY3_A_1024x768;
*VKY3_A_MCR &= ~(VKY3_A_1024x768);
}
/* Turn off resolution bits */
msr_shadow &= ~(VKY3_A_1024x768);
if ((width == 800) && (height == 600)) {
a2560k_a_resolution.width = width;
a2560k_a_resolution.height = height;
// Recalculate the size of the screen
txt_a2560k_a_set_sizes();
*VKY3_A_MCR = msr_shadow;
return 0;
} else if ((width == 1024) && (height == 768)) {
msr_shadow |= VKY3_A_1024x768;
a2560k_a_resolution.width = width;
a2560k_a_resolution.height = height;
// Recalculate the size of the screen
txt_a2560k_a_set_sizes();
*VKY3_A_MCR = msr_shadow;
return 0;
} else {
/* Unsupported resolution */
return -1;
}
}
/**
* Set the size of the border of the screen (if supported)
*
* @param width the horizontal size of one side of the border (0 - 32 pixels)
* @param height the vertical size of one side of the border (0 - 32 pixels)
*/
void txt_a2560k_a_set_border(short width, short height) {
if ((width > 0) || (height > 0)) {
a2560k_a_border_width = width;
a2560k_a_border_height = height;
*VKY3_A_BCR = (height & 0x3f) << 16 | (width & 0x3f) << 8 | VKY3_A_BCR_ENABLE;
// Recalculate the size of the screen
txt_a2560k_a_set_sizes();
} else {
a2560k_a_border_width = 0;
a2560k_a_border_height = 0;
*VKY3_A_BCR = 0;
// Recalculate the size of the screen
txt_a2560k_a_set_sizes();
}
}
/**
* Set the size of the border of the screen (if supported)
*
* @param red the red component of the color (0 - 255)
* @param green the green component of the color (0 - 255)
* @param blue the blue component of the color (0 - 255)
*/
void txt_a2560k_a_set_border_color(unsigned char red, unsigned char green, unsigned char blue) {
*VKY3_A_BRDCOLOR = (unsigned long)(((red & 0xff) << 16) | ((green & 0xff) << 8) | (blue & 0xff));
}
/**
* Load a font as the current font for the screen
*
* @param width width of a character in pixels
* @param height of a character in pixels
* @param data pointer to the raw font data to be loaded
*/
short txt_a2560k_a_set_font(short width, short height, const unsigned char * data) {
if (((width == 8) && (height == 8)) || ((width == 8) && (height == 16))) {
int i;
/* The size is valid... set the font */
a2560k_a_font_size.width = width;
a2560k_a_font_size.height = height;
/* Set the size of the character and container */
*VKY3_A_FM0 = ((height & 0xff) << 24) | ((width & 0xff) << 16) | ((height & 0xff) << 8) | (width & 0xff);
/* Copy the font data... this assumes a width of one byte! */
/* TODO: generalize this for all possible font sizes */
for (i = 0; i < 256 * height; i++) {
VKY3_A_FONT_MEMORY[i] = data[i];
}
// Recalculate the size of the screen
txt_a2560k_a_set_sizes();
return 0;
} else {
return -1;
}
}
/**
* Set the appearance of the cursor
*
* @param enable 0 to hide, any other number to make visible
* @param rate the blink rate for the cursor (0=1s, 1=0.5s, 2=0.25s, 3=1/5s)
* @param c the character in the current font to use as a cursor
*/
void txt_a2560k_a_set_cursor(short enable, short rate, char c) {
*VKY3_A_CCR = ((a2560k_a_color & 0xff) << 24) | ((c & 0xff) << 16) | ((rate & 0x03) << 1) | (enable & 0x01);
}
/**
* Set if the cursor is visible or not
*
* @param enable 0 to hide, any other number to make visible
*/
void txt_a2560k_a_set_cursor_visible(short enable) {
if (enable) {
*VKY3_A_CCR |= 0x01;
} else {
*VKY3_A_CCR &= ~0x01;
}
}
/**
* get the current region
*
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
short txt_a2560k_a_get_region(p_rect region) {
region->origin.x = a2560k_a_region.origin.x;
region->origin.y = a2560k_a_region.origin.y;
region->size.width = a2560k_a_region.size.width;
region->size.height = a2560k_a_region.size.height;
return 0;
}
/**
* Set a region to restrict further character display, scrolling, etc.
* Note that a region of zero size will reset the region to the full size of the screen.
*
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
short txt_a2560k_a_set_region(p_rect region) {
if ((region->size.width == 0) || (region->size.height == 0)) {
/* Set the region to the default (full screen) */
a2560k_a_region.origin.x = 0;
a2560k_a_region.origin.y = 0;
a2560k_a_region.size.width = a2560k_a_visible_size.width;
a2560k_a_region.size.height = a2560k_a_visible_size.height;
} else {
a2560k_a_region.origin.x = region->origin.x;
a2560k_a_region.origin.y = region->origin.y;
a2560k_a_region.size.width = region->size.width;
a2560k_a_region.size.height = region->size.height;
}
return 0;
}
/**
* Get the default foreground and background colors for printing
*
* @param pointer to the foreground the Text LUT index of the new current foreground color (0 - 15)
* @param pointer to the background the Text LUT index of the new current background color (0 - 15)
*/
short txt_a2560k_a_get_color(unsigned char * foreground, unsigned char * background) {
*foreground = (a2560k_a_color & 0xf0) >> 4;
*background = a2560k_a_color & 0x0f;
return 0;
}
/**
* Set the default foreground and background colors for printing
*
* @param foreground the Text LUT index of the new current foreground color (0 - 15)
* @param background the Text LUT index of the new current background color (0 - 15)
*/
short txt_a2560k_a_set_color(unsigned char foreground, unsigned char background) {
a2560k_a_color = ((foreground & 0x0f) << 4) + (background & 0x0f);
return 0;
}
/**
* Scroll the text in the current region
*
* @param screen the number of the text device
* @param horizontal the number of columns to scroll (negative is left, positive is right)
* @param vertical the number of rows to scroll (negative is down, positive is up)
*/
void txt_a2560k_a_scroll(short horizontal, short vertical) {
short x, x0, x1, x2, x3, dx;
short y, y0, y1, y2, y3, dy;
/*
* Determine limits of rectangles to move and fill and directions of loops
* x0 and y0 are the positions of the first cell to be over-written
* x1 and y1 are the positions of the first cell to be copyed... TEXT[x0,y0] := TEXT[x1,y1]
* x2 and y2 are the position of the last cell to be over-written
* x3 and y3 are the position of the last cell to be copied... TEXT[x2,y2] := TEXT[x3,y3]
*
* When blanking, the rectangles (x2,y0) - (x3,y3) and (x0,y2) - (x2,y3) are cleared
*/
// Determine the row limits
if (vertical >= 0) {
y0 = a2560k_a_region.origin.y;
y1 = y0 + vertical;
y3 = a2560k_a_region.origin.y + a2560k_a_region.size.height;
y2 = y3 - vertical;
dy = 1;
} else {
y0 = a2560k_a_region.origin.y + a2560k_a_region.size.height - 1;
y1 = y0 + vertical;
y3 = a2560k_a_region.origin.y - 1;
y2 = y3 - vertical;
dy = -1;
}
// Determine the column limits
if (horizontal >= 0) {
x0 = a2560k_a_region.origin.x;
x1 = x0 + horizontal;
x3 = a2560k_a_region.origin.x + a2560k_a_region.size.width;
x2 = x3 - horizontal;
dx = 1;
} else {
x0 = a2560k_a_region.origin.x + a2560k_a_region.size.width - 1;
x1 = x0 + horizontal;
x3 = a2560k_a_region.origin.x - 1;
x2 = x3 - horizontal;
dx = -1;
}
/* Copy the rectangle */
for (y = y0; y != y2; y += dy) {
int row_dst = y * a2560k_a_max_size.width;
int row_src = (y + vertical) * a2560k_a_max_size.width;
for (x = x0; x != x2; x += dx) {
int offset_dst = row_dst + x;
int offset_src = row_src + x + horizontal;
VKY3_A_TEXT_MATRIX[offset_dst] = VKY3_A_TEXT_MATRIX[offset_src];
VKY3_A_COLOR_MATRIX[offset_dst] = VKY3_A_COLOR_MATRIX[offset_src];
}
}
/* Clear the rectangles */
if (horizontal != 0) {
for (y = y0; y != y3; y += dy) {
int row_dst = y * a2560k_a_max_size.width;
for (x = x2; x != x3; x += dx) {
VKY3_A_TEXT_MATRIX[row_dst + x] = ' ';
VKY3_A_COLOR_MATRIX[row_dst + x] = a2560k_a_color;
}
}
}
if (vertical != 0) {
for (y = y2; y != y3; y += dy) {
int row_dst = y * a2560k_a_max_size.width;
for (x = x0; x != x3; x += dx) {
VKY3_A_TEXT_MATRIX[row_dst + x] = ' ';
VKY3_A_COLOR_MATRIX[row_dst + x] = a2560k_a_color;
}
}
}
}
/**
* Fill the current region with a character in the current color
*
* @param screen the number of the text device
* @param c the character to fill the region with
*/
void txt_a2560k_a_fill(char c) {
int x;
int y;
for (y = 0; y < a2560k_a_region.size.height; y++) {
int offset_row = (a2560k_a_region.origin.y + y) * a2560k_a_max_size.width;
for (x = 0; x < a2560k_a_region.size.width; x++) {
int offset = offset_row + a2560k_a_region.origin.x + x;
VKY3_A_TEXT_MATRIX[offset] = c;
VKY3_A_COLOR_MATRIX[offset] = a2560k_a_color;
}
}
}
/**
* Set the position of the cursor to (x, y) relative to the current region
* If the (x, y) coordinate is outside the region, it will be clipped to the region.
* If y is greater than the height of the region, the region will scroll until that relative
* position would be within view.
*
* @param x the column for the cursor
* @param y the row for the cursor
*/
void txt_a2560k_a_set_xy(short x, short y) {
/* Make sure X is within range for the current region... "print" a newline if not */
if (x < 0) {
x = 0;
} else if (x >= a2560k_a_region.size.width) {
x = 0;
y++;
}
/* Make sure Y is within range for the current region... scroll if not */
if (y < 0) {
y = 0;
} else if (y >= a2560k_a_region.size.height) {
txt_a2560k_a_scroll(0, y - a2560k_a_region.size.height + 1);
y = a2560k_a_region.size.height - 1;
}
a2560k_a_cursor.x = x;
a2560k_a_cursor.y = y;
/* Set register */
*VKY3_A_CPR = (((a2560k_a_region.origin.y + y) & 0xffff) << 16) | ((a2560k_a_region.origin.x + x) & 0xffff);
}
/**
* Get the position of the cursor (x, y) relative to the current region
*
* @param screen the number of the text device
* @param position pointer to a t_point record to fill out
*/
void txt_a2560k_a_get_xy(p_point position) {
position->x = a2560k_a_cursor.x;
position->y = a2560k_a_cursor.y;
}
/**
* Print a character to the current cursor position in the current color
*
* @param screen the number of the text device
* @param c the character to print
*/
void txt_a2560k_a_put(char c) {
short x;
short y;
unsigned int offset;
x = a2560k_a_region.origin.x + a2560k_a_cursor.x;
y = a2560k_a_region.origin.y + a2560k_a_cursor.y;
offset = y * a2560k_a_max_size.width + x;
VKY3_A_TEXT_MATRIX[offset] = c;
VKY3_A_COLOR_MATRIX[offset] = a2560k_a_color;
txt_a2560k_a_set_xy(a2560k_a_cursor.x + 1, a2560k_a_cursor.y);
}
/**
* Initialize the screen
*/
void txt_a2560k_a_init() {
char buffer[255];
t_rect region;
int i;
// Kick the PLL
// If VICKY is generating a 40MHz signal, we need to switch the bit to go to 40MHz before
// clearing it to go back to 25MHz.
if (*VKY3_A_MCR & VKY3_A_CLK40) {
*VKY3_A_MCR |= VKY3_A_1024x768;
*VKY3_A_MCR &= ~(VKY3_A_1024x768);
}
a2560k_a_resolution.width = 0;
a2560k_a_resolution.height = 0;
a2560k_a_font_size.width = 0;
a2560k_a_font_size.height = 0;
/* Disable the set_sizes call for now */
a2560k_a_enable_set_sizes = 0;
/* Start with nothing on */
msr_shadow = 0;
/* Define the capabilities */
/* Specify the screen number */
a2560k_a_caps.number = TXT_SCREEN_A2560K_A;
/* This screen can be text or can be put to sleep */
a2560k_a_caps.supported_modes = TXT_MODE_TEXT | TXT_MODE_SLEEP;
/* Resolutions supported: 800x600, 1024x768 */
a2560k_a_resolutions[0].width = 800;
a2560k_a_resolutions[0].height = 600;
a2560k_a_resolutions[1].width = 1024;
a2560k_a_resolutions[1].height = 768;
a2560k_a_caps.resolution_count = 2;
a2560k_a_caps.resolutions = a2560k_a_resolutions;
/* At the moment, support only 8x8 and 8x16 fonts */
/* TODO: add support for all possible font sizes */
a2560k_a_fonts[0].width = 8;
a2560k_a_fonts[0].height = 8;
a2560k_a_fonts[1].width = 8;
a2560k_a_fonts[1].height = 16;
a2560k_a_caps.font_size_count = 2;
a2560k_a_caps.font_sizes = a2560k_a_fonts;
/* Initialze the color lookup tables */
for (i = 0; i < VKY3_A_LUT_SIZE; i++) {
VKY3_A_TEXT_LUT_FG[i] = a2560k_a_lut[i];
VKY3_A_TEXT_LUT_BG[i] = a2560k_a_lut[i];
}
/* Set the mode to text */
txt_a2560k_a_set_mode(TXT_MODE_TEXT);
/* Set the resolution */
txt_a2560k_a_set_resolution(800, 600); /* Default resolution is 800x600 */
/* Set the default color: light grey on blue */
txt_a2560k_a_set_color(0x07, 0x04);
/* Set the font */
txt_a2560k_a_set_font(8, 8, MSX_CP437_8x8_bin); /* Use 8x8 font */
/* Set the cursor */
txt_a2560k_a_set_cursor(1, 0, 0xB1);
/* Set the border */
txt_a2560k_a_set_border(16, 16); /* Set up the border */
txt_a2560k_a_set_border_color(0, 0, 0x3f);
/*
* Enable set_sizes, now that everything is set up initially
* And calculate the size of the screen
*/
a2560k_a_enable_set_sizes = 1;
txt_a2560k_a_set_sizes();
/* Set region to default */
region.origin.x = 0;
region.origin.y = 0;
region.size.width = 0;
region.size.height = 0;
txt_a2560k_a_set_region(&region);
/* Home the cursor */
txt_a2560k_a_set_xy(0, 0);
/* Clear the screen */
txt_a2560k_a_fill(' ');
}
/**
* Initialize and install the driver
*
* @return 0 on success, any other number is an error
*/
short txt_a2560k_a_install() {
t_txt_device device;
device.number = TXT_SCREEN_A2560K_A;
device.name = "SCREEN A";
device.init = txt_a2560k_a_init;
device.get_capabilities = txt_a2560k_a_get_capabilities;
device.set_mode = txt_a2560k_a_set_mode;
device.set_sizes = txt_a2560k_a_set_sizes;
device.set_resolution = txt_a2560k_a_set_resolution;
device.set_border = txt_a2560k_a_set_border;
device.set_border_color = txt_a2560k_a_set_border_color;
device.set_font = txt_a2560k_a_set_font;
device.set_cursor = txt_a2560k_a_set_cursor;
device.set_cursor_visible = txt_a2560k_a_set_cursor_visible;
device.get_region = txt_a2560k_a_get_region;
device.set_region = txt_a2560k_a_set_region;
device.get_color = txt_a2560k_a_get_color;
device.set_color = txt_a2560k_a_set_color;
device.set_xy = txt_a2560k_a_set_xy;
device.get_xy = txt_a2560k_a_get_xy;
device.put = txt_a2560k_a_put;
device.scroll = txt_a2560k_a_scroll;
device.fill = txt_a2560k_a_fill;
device.get_sizes = txt_a2560k_a_get_sizes;
return txt_register(&device);
}

21
src/dev/txt_a2560k_a.h Normal file
View file

@ -0,0 +1,21 @@
/** @file txt_a2560k_a.h
*
* Text screen driver for A2560K Channel A
*/
#ifndef __TXT_A2560K_A_H
#define __TXT_A2560K_A_H
/* Channel A is assigned to screen #1, it will be considered a secondary channel */
#define TXT_SCREEN_A2560K_A 1
/**
* Initialize and install the driver
*
* @return 0 on success, any other number is an error
*/
extern short txt_a2560k_a_install();
extern t_extent a2560k_a_max_size;
#endif

704
src/dev/txt_a2560k_b.c Normal file
View file

@ -0,0 +1,704 @@
/** @file txt_a2560k_B.c
*
* Text screen driver for A2560K Channel B
*/
#include <string.h>
#include <stdio.h>
#include "log.h"
#include "utilities.h"
#include "A2560K/vky_chan_a.h"
#include "A2560K/vky_chan_b.h"
#include "dev/txt_screen.h"
#include "dev/txt_a2560k_b.h"
extern const unsigned char MSX_CP437_8x8_bin[];
/* Default text color lookup table values (AARRGGBB) */
const unsigned long a2560k_b_lut[VKY3_B_LUT_SIZE] = {
0xFF000000, // Black (transparent)
0xFF800000, // Mid-Tone Red
0xFF008000, // Mid-Tone Green
0xFF808000, // Mid-Tone Yellow
0xFF000080, // Mid-Tone Blue
0xFFAA5500, // Mid-Tone Orange
0xFF008080, // Mid-Tone Cian
0xFF808080, // 50% Grey
0xFF555555, // Dark Grey
0xFFFF0000, // Bright Red
0xFF55FF55, // Bright Green
0xFFFFFF55, // Bright Yellow
0xFF5555FF, // Bright Blue
0xFFFF7FFF, // Bright Orange
0xFF55FFFF, // Bright Cyan
0xFFFFFFFF // White
};
/*
* Driver level variables for the screen
*/
unsigned char a2560k_b_enable_set_sizes; /* Flag to enable set_sizes to actually do its computation */
t_txt_capabilities a2560k_b_caps; /* The capabilities of Channel B */
t_extent a2560k_b_resolutions[6]; /* The list of display resolutions */
t_extent a2560k_b_fonts[1]; /* The list of font resolutions */
t_rect a2560k_b_region; /* The current region */
t_point a2560k_b_cursor; /* The current cursor position */
t_extent a2560k_b_resolution; /* The current display resolution */
t_extent a2560k_b_font_size; /* The current font size */
t_extent a2560k_b_max_size; /* The size of the screen in characters (without border removed) */
t_extent a2560k_b_visible_size; /* The size of the visible screen in characters (with border removed) */
short a2560k_b_border_width; /* Width of the border on one side */
short a2560k_b_border_height; /* Height of the border on one side */
unsigned char a2560k_b_color; /* The current color */
unsigned long msr_shadow_b; /* A shadow register for the Master Control Register */
/**
* Gets the description of a screen's capabilities
*
* @return a pointer to the read-only description (0 on error)
*/
const p_txt_capabilities txt_a2560k_b_get_capabilities() {
return &a2560k_b_caps;
}
/**
* Calculate the size of the text screen in rows and columns so that
* the kernel printing routines can work correctly.
*
* NOTE: this should be called whenever the VKY3 Channel B registers are changed
*/
void txt_a2560k_b_set_sizes() {
if (a2560k_b_enable_set_sizes) {
/* Only recalculate after initialization is mostly completed */
/*
* Calculate the maximum number of characters visible on the screen
* This controls text layout in memory
*/
a2560k_b_max_size.width = a2560k_b_resolution.width / a2560k_b_font_size.width;
a2560k_b_max_size.height = a2560k_b_resolution.height / a2560k_b_font_size.height;
/*
* Calculate the characters that are visible in whole or in part
*/
short border_width = (2 * a2560k_b_border_width) / a2560k_b_font_size.width;
short border_height = (2 * a2560k_b_border_height) / a2560k_b_font_size.height;
a2560k_b_visible_size.width = a2560k_b_max_size.width - border_width;
a2560k_b_visible_size.height = a2560k_b_max_size.height - border_height;
}
}
/**
* Get the display resolutions
*
* @param text_size the size of the screen in visible characters (may be null)
* @param pixel_size the size of the screen in pixels (may be null)
*/
void txt_a2560k_b_get_sizes(p_extent text_size, p_extent pixel_size) {
if (text_size) {
text_size->width = a2560k_b_visible_size.width;
text_size->height = a2560k_b_visible_size.height;
}
if (pixel_size) {
pixel_size->width = a2560k_b_resolution.width;
pixel_size->height = a2560k_b_resolution.height;
}
}
/**
* Set the display mode for the screen
*
* @param mode a bitfield of desired display mode options
*
* @return 0 on success, any other number means the mode is invalid for the screen
*/
short txt_a2560k_b_set_mode(short mode) {
/* Turn off anything not set */
msr_shadow_b &= ~(VKY3_B_MCR_TEXT | VKY3_B_MCR_TXT_OVR | VKY3_B_MCR_GRAPHICS | VKY3_B_MCR_BITMAP | VKY3_B_MCR_TILE | VKY3_B_MCR_SPRITE);
if (mode & TXT_MODE_SLEEP) {
/* Put the monitor to sleep: overrides all other option bits */
msr_shadow_b |= VKY3_B_MCR_SLEEP;
*VKY3_B_MCR = msr_shadow_b;
return 0;
} else {
if (mode & ~(TXT_MODE_TEXT | TXT_MODE_BITMAP | TXT_MODE_SPRITE | TXT_MODE_TILE)) {
/* A mode bit was set beside one of the supported ones... */
return -1;
} else {
if (mode & TXT_MODE_TEXT) {
msr_shadow_b |= VKY3_B_MCR_TEXT;
}
if (mode & TXT_MODE_BITMAP) {
msr_shadow_b |= VKY3_B_MCR_GRAPHICS | VKY3_B_MCR_BITMAP;
}
if (mode & TXT_MODE_SPRITE) {
msr_shadow_b |= VKY3_B_MCR_GRAPHICS | VKY3_B_MCR_SPRITE;
}
if (mode & TXT_MODE_TILE) {
msr_shadow_b |= VKY3_B_MCR_GRAPHICS | VKY3_B_MCR_TILE;
}
if ((msr_shadow_b & (VKY3_B_MCR_GRAPHICS | VKY3_B_MCR_TEXT)) == (VKY3_B_MCR_GRAPHICS | VKY3_B_MCR_TEXT)) {
msr_shadow_b |= VKY3_B_MCR_TXT_OVR;
}
*VKY3_B_MCR = msr_shadow_b;
return 0;
}
}
}
/**
* Set the display resolution of the screen
*
* @param width the desired horizontal resolution in pixels
* @param height the desired veritical resolution in pixels
*
* @return 0 on success, any other number means the resolution is unsupported
*/
short txt_a2560k_b_set_resolution(short width, short height) {
int i;
// If no size specified, set it based on the DIP switch
if ((width == 0) || (height == 0)) {
if ((*VKY3_B_MCR & VKY3_B_HIRES) == 0) {
width = 800;
height = 600;
} else {
width = 640;
height = 480;
}
}
// Kick the PLL
// If VICKY is generating a 40MHz signal, we need to switch the bit to go to 40MHz before
// clearing it to go back to 25MHz.
if (*VKY3_B_MCR & VKY3_B_CLK40) {
*VKY3_B_MCR |= VKY3_B_PLL | VKY3_B_MODE1;
*VKY3_B_MCR &= ~(VKY3_B_PLL | VKY3_B_MODE1);
}
for (i = 0; i < a2560k_b_caps.resolution_count; i++) {
if ((a2560k_b_caps.resolutions[i].width == width) && (a2560k_b_caps.resolutions[i].height == height)) {
msr_shadow_b &= ~(VKY3_B_DOUBLE | VKY3_B_MODE0 | VKY3_B_MODE1);
if (height < 400) {
/* We're in pixel doubling range */
msr_shadow_b |= VKY3_B_DOUBLE;
/* Figure out what the base resolution is */
height *= 2;
}
// Use the height to determine the resolution we should set
switch (height) {
case 400: // 640x400 or 320x200 (mode = 11)
msr_shadow_b |= VKY3_B_MODE0;
break;
case 480: // 640x480 or 320x240 (mode = 00)
break;
case 600: // 800x600 or 400x300 (mode = 01)
msr_shadow_b |= VKY3_B_PLL | VKY3_B_MODE1;
break;
default:
// Shouldn't get here... bad resolution
return -1;
}
// Update the kernel variables
a2560k_b_resolution.width = width;
a2560k_b_resolution.height = height;
// Recalculate the size of the screen
txt_a2560k_b_set_sizes();
// Kick the PLL
if (*VKY3_B_MCR & VKY3_B_PLL) {
*VKY3_B_MCR &= ~(VKY3_B_PLL | VKY3_B_MODE0 | VKY3_B_MODE1);
*VKY3_B_MCR |= (VKY3_B_PLL | VKY3_B_MODE1);
}
*VKY3_B_MCR &= ~(VKY3_B_PLL | VKY3_B_MODE0 | VKY3_B_MODE1);
// Update the register
*VKY3_B_MCR = msr_shadow_b;
return 0;
}
}
return -1;
}
/**
* Set the size of the border of the screen (if supported)
*
* @param width the horizontal size of one side of the border (0 - 32 pixels)
* @param height the vertical size of one side of the border (0 - 32 pixels)
*/
void txt_a2560k_b_set_border(short width, short height) {
if ((width > 0) || (height > 0)) {
a2560k_b_border_width = width;
a2560k_b_border_height = height;
*VKY3_B_BCR = (height & 0x3f) << 16 | (width & 0x3f) << 8 | VKY3_B_BCR_ENABLE;
// Recalculate the size of the screen
txt_a2560k_b_set_sizes();
} else {
a2560k_b_border_width = 0;
a2560k_b_border_height = 0;
*VKY3_B_BCR = 0;
// Recalculate the size of the screen
txt_a2560k_b_set_sizes();
}
}
/**
* Set the size of the border of the screen (if supported)
*
* @param red the red component of the color (0 - 255)
* @param green the green component of the color (0 - 255)
* @param blue the blue component of the color (0 - 255)
*/
void txt_a2560k_b_set_border_color(unsigned char red, unsigned char green, unsigned char blue) {
*VKY3_B_BRDCOLOR = (unsigned long)(((red & 0xff) << 16) | ((green & 0xff) << 8) | (blue & 0xff));
}
/**
* Load a font as the current font for the screen
*
* @param width width of a character in pixels
* @param height of a character in pixels
* @param data pointer to the raw font data to be loaded
*/
short txt_a2560k_b_set_font(short width, short height, const unsigned char * data) {
if ((width == 8) && (height == 8)) {
int i;
/* The size is valid... set the font */
a2560k_b_font_size.width = width;
a2560k_b_font_size.height = height;
/* Copy the font data... this assumes a width of one byte! */
for (i = 0; i < 256 * height; i++) {
VKY3_B_FONT_MEMORY[i] = data[i];
}
return 0;
} else {
return -1;
}
}
/**
* Set the appearance of the cursor
*
* @param enable 0 to hide, any other number to make visible
* @param rate the blink rate for the cursor (0=1s, 1=0.5s, 2=0.25s, 3=1/5s)
* @param c the character in the current font to use as a cursor
*/
void txt_a2560k_b_set_cursor(short enable, short rate, char c) {
*VKY3_B_CCR = ((a2560k_b_color & 0xff) << 24) | ((c & 0xff) << 16) | ((rate & 0x03) << 1) | (enable & 0x01);
}
/**
* Set if the cursor is visible or not
*
* @param enable 0 to hide, any other number to make visible
*/
void txt_a2560k_b_set_cursor_visible(short enable) {
if (enable) {
*VKY3_B_CCR |= 0x01;
} else {
*VKY3_B_CCR &= ~0x01;
}
}
/**
* Set a region to restrict further character display, scrolling, etc.
* Note that a null region pointer and a region of zero size will reset the region to the full size of the screen.
*
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
short txt_a2560k_b_set_region(p_rect region) {
if ((region->size.width == 0) || (region->size.height == 0)) {
/* Set the region to the default (full screen) */
a2560k_b_region.origin.x = 0;
a2560k_b_region.origin.y = 0;
a2560k_b_region.size.width = a2560k_b_visible_size.width;
a2560k_b_region.size.height = a2560k_b_visible_size.height;
} else {
a2560k_b_region.origin.x = region->origin.x;
a2560k_b_region.origin.y = region->origin.y;
a2560k_b_region.size.width = region->size.width;
a2560k_b_region.size.height = region->size.height;
}
return 0;
}
/**
* get the current region
*
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
short txt_a2560k_b_get_region(p_rect region) {
region->origin.x = a2560k_b_region.origin.x;
region->origin.y = a2560k_b_region.origin.y;
region->size.width = a2560k_b_region.size.width;
region->size.height = a2560k_b_region.size.height;
return 0;
}
/**
* Set the default foreground and background colors for printing
*
* @param foreground the Text LUT index of the new current foreground color (0 - 15)
* @param background the Text LUT index of the new current background color (0 - 15)
*/
short txt_a2560k_b_set_color(unsigned char foreground, unsigned char background) {
a2560k_b_color = ((foreground & 0x0f) << 4) | (background & 0x0f);
return 0;
}
/**
* Get the default foreground and background colors for printing
*
* @param pointer to the foreground the Text LUT index of the new current foreground color (0 - 15)
* @param pointer to the background the Text LUT index of the new current background color (0 - 15)
*/
short txt_a2560k_b_get_color(unsigned char * foreground, unsigned char * background) {
*foreground = (a2560k_b_color & 0xf0) >> 4;
*background = a2560k_b_color & 0x0f;
return 0;
}
/**
* Scroll the text in the current region
*
* @param screen the number of the text device
* @param horizontal the number of columns to scroll (negative is left, positive is right)
* @param vertical the number of rows to scroll (negative is down, positive is up)
*/
void txt_a2560k_b_scroll(short horizontal, short vertical) {
short x, x0, x1, x2, x3, dx;
short y, y0, y1, y2, y3, dy;
/*
* Determine limits of rectangles to move and fill and directions of loops
* x0 and y0 are the positions of the first cell to be over-written
* x1 and y1 are the positions of the first cell to be copyed... TEXT[x0,y0] := TEXT[x1,y1]
* x2 and y2 are the position of the last cell to be over-written
* x3 and y3 are the position of the last cell to be copied... TEXT[x2,y2] := TEXT[x3,y3]
*
* When blanking, the rectangles (x2,y0) - (x3,y3) and (x0,y2) - (x2,y3) are cleared
*/
// Determine the row limits
if (vertical >= 0) {
y0 = a2560k_b_region.origin.y;
y1 = y0 + vertical;
y3 = a2560k_b_region.origin.y + a2560k_b_region.size.height;
y2 = y3 - vertical;
dy = 1;
} else {
y0 = a2560k_b_region.origin.y + a2560k_b_region.size.height - 1;
y1 = y0 + vertical;
y3 = a2560k_b_region.origin.y - 1;
y2 = y3 - vertical;
dy = -1;
}
// Determine the column limits
if (horizontal >= 0) {
x0 = a2560k_b_region.origin.x;
x1 = x0 + horizontal;
x3 = a2560k_b_region.origin.x + a2560k_b_region.size.width;
x2 = x3 - horizontal;
dx = 1;
} else {
x0 = a2560k_b_region.origin.x + a2560k_b_region.size.width - 1;
x1 = x0 + horizontal;
x3 = a2560k_b_region.origin.x - 1;
x2 = x3 - horizontal;
dx = -1;
}
/* Copy the rectangle */
for (y = y0; y != y2; y += dy) {
int row_dst = y * a2560k_b_max_size.width;
int row_src = (y + vertical) * a2560k_b_max_size.width;
for (x = x0; x != x2; x += dx) {
int offset_dst = row_dst + x;
int offset_src = row_src + x + horizontal;
VKY3_B_TEXT_MATRIX[offset_dst] = VKY3_B_TEXT_MATRIX[offset_src];
VKY3_B_COLOR_MATRIX[offset_dst] = VKY3_B_COLOR_MATRIX[offset_src];
}
}
/* Clear the rectangles */
if (horizontal != 0) {
for (y = y0; y != y3; y += dy) {
int row_dst = y * a2560k_b_max_size.width;
for (x = x2; x != x3; x += dx) {
VKY3_B_TEXT_MATRIX[row_dst + x] = ' ';
VKY3_B_COLOR_MATRIX[row_dst + x] = a2560k_b_color;
}
}
}
if (vertical != 0) {
for (y = y2; y != y3; y += dy) {
int row_dst = y * a2560k_b_max_size.width;
for (x = x0; x != x3; x += dx) {
VKY3_B_TEXT_MATRIX[row_dst + x] = ' ';
VKY3_B_COLOR_MATRIX[row_dst + x] = a2560k_b_color;
}
}
}
}
/**
* Fill the current region with a character in the current color
*
* @param screen the number of the text device
* @param c the character to fill the region with
*/
void txt_a2560k_b_fill(char c) {
int x;
int y;
for (y = 0; y < a2560k_b_region.size.height; y++) {
int offset_row = (a2560k_b_region.origin.y + y) * a2560k_b_max_size.width;
for (x = 0; x < a2560k_b_region.size.width; x++) {
int offset = offset_row + a2560k_b_region.origin.x + x;
VKY3_B_TEXT_MATRIX[offset] = c;
VKY3_B_COLOR_MATRIX[offset] = a2560k_b_color;
}
}
}
/**
* Set the position of the cursor to (x, y) relative to the current region
* If the (x, y) coordinate is outside the region, it will be clipped to the region.
* If y is greater than the height of the region, the region will scroll until that relative
* position would be within view.
*
* @param x the column for the cursor
* @param y the row for the cursor
*/
void txt_a2560k_b_set_xy(short x, short y) {
/* Make sure X is within range for the current region... "print" a newline if not */
if (x < 0) {
x = 0;
} else if (x >= a2560k_b_region.size.width) {
x = 0;
y++;
}
/* Make sure Y is within range for the current region... scroll if not */
if (y < 0) {
y = 0;
} else if (y >= a2560k_b_region.size.height) {
txt_a2560k_b_scroll(0, y - a2560k_b_region.size.height + 1);
y = a2560k_b_region.size.height - 1;
}
a2560k_b_cursor.x = x;
a2560k_b_cursor.y = y;
/* Set register */
*VKY3_B_CPR = (((a2560k_b_region.origin.y + y) & 0xffff) << 16) | ((a2560k_b_region.origin.x + x) & 0xffff);
}
/**
* Get the position of the cursor (x, y) relative to the current region
*
* @param screen the number of the text device
* @param position pointer to a t_point record to fill out
*/
void txt_a2560k_b_get_xy(p_point position) {
position->x = a2560k_b_cursor.x;
position->y = a2560k_b_cursor.y;
}
/**
* Print a character to the current cursor position in the current color
*
* @param screen the number of the text device
* @param c the character to print
*/
void txt_a2560k_b_put(char c) {
short x;
short y;
unsigned int offset;
x = a2560k_b_region.origin.x + a2560k_b_cursor.x;
y = a2560k_b_region.origin.y + a2560k_b_cursor.y;
offset = y * a2560k_b_max_size.width + x;
VKY3_B_TEXT_MATRIX[offset] = c;
VKY3_B_COLOR_MATRIX[offset] = a2560k_b_color;
txt_a2560k_b_set_xy(a2560k_b_cursor.x + 1, a2560k_b_cursor.y);
}
/**
* Initialize the screen
*/
void txt_a2560k_b_init() {
char buffer[255];
t_rect region;
int i;
// Kick the PLL
// If VICKY is generating a 40MHz signal, we need to switch the bit to go to 40MHz before
// clearing it to go back to 25MHz.
if (*VKY3_B_MCR & VKY3_B_CLK40) {
*VKY3_B_MCR |= VKY3_B_PLL | VKY3_B_MODE1;
*VKY3_B_MCR &= ~(VKY3_B_PLL | VKY3_B_MODE1);
}
a2560k_b_resolution.width = 0;
a2560k_b_resolution.height = 0;
a2560k_b_font_size.width = 0;
a2560k_b_font_size.height = 0;
/* Disable the set_sizes call for now */
a2560k_b_enable_set_sizes = 0;
/* Start with nothing on */
msr_shadow_b = 0;
/* Define the capabilities */
/* Specify the screen number */
a2560k_b_caps.number = TXT_SCREEN_A2560K_B;
/* This screen can be nothing, sleep, or any combination of text, sprite, bitmap, and tile */
a2560k_b_caps.supported_modes = TXT_MODE_TEXT | TXT_MODE_SPRITE | TXT_MODE_BITMAP | TXT_MODE_TILE | TXT_MODE_SLEEP;
/* Resolutions supported: 320x200, 320x240, 400x300, 640x400, 640x480, 800x600 */
a2560k_b_resolutions[0].width = 320;
a2560k_b_resolutions[0].height = 200;
a2560k_b_resolutions[1].width = 320;
a2560k_b_resolutions[1].height = 240;
a2560k_b_resolutions[2].width = 400;
a2560k_b_resolutions[2].height = 300;
a2560k_b_resolutions[3].width = 640;
a2560k_b_resolutions[3].height = 400;
a2560k_b_resolutions[4].width = 640;
a2560k_b_resolutions[4].height = 480;
a2560k_b_resolutions[5].width = 800;
a2560k_b_resolutions[5].height = 600;
a2560k_b_caps.resolution_count = 6;
a2560k_b_caps.resolutions = a2560k_b_resolutions;
/* Channel B supports 8x8 fonts ONLY */
a2560k_b_fonts[0].width = 8;
a2560k_b_fonts[0].height = 8;
a2560k_b_caps.font_size_count = 1;
a2560k_b_caps.font_sizes = a2560k_b_fonts;
/* Initialze the color lookup tables */
for (i = 0; i < VKY3_B_LUT_SIZE; i++) {
VKY3_B_TEXT_LUT_FG[i] = a2560k_b_lut[i];
VKY3_B_TEXT_LUT_BG[i] = a2560k_b_lut[i];
}
/* Set the mode to text */
txt_a2560k_b_set_mode(TXT_MODE_TEXT);
/* Set the resolution */
txt_a2560k_b_set_resolution(640, 480); /* Default resolution is 640x480 */
/* Set the default color: light grey on blue */
txt_a2560k_b_set_color(0x07, 0x04);
/* Set the font */
txt_a2560k_b_set_font(8, 8, MSX_CP437_8x8_bin); /* Use 8x8 font */
/* Set the cursor */
txt_a2560k_b_set_cursor(1, 0, 0xB1);
/* Set the border */
txt_a2560k_b_set_border(16, 16); /* Set up the border */
txt_a2560k_b_set_border_color(0, 0, 0x3f);
/*
* Enable set_sizes, now that everything is set up initially
* And calculate the size of the screen
*/
a2560k_b_enable_set_sizes = 1;
txt_a2560k_b_set_sizes();
/* Set region to default */
region.origin.x = 0;
region.origin.y = 0;
region.size.width = 0;
region.size.height = 0;
txt_a2560k_b_set_region(&region);
/* Home the cursor */
txt_a2560k_b_set_xy(0, 0);
/* Clear the screen */
txt_a2560k_b_fill(' ');
}
/**
* Initialize and install the driver
*
* @return 0 on success, any other number is an error
*/
short txt_a2560k_b_install() {
t_txt_device device;
device.number = TXT_SCREEN_A2560K_B;
device.name = "SCREEN B";
device.init = txt_a2560k_b_init;
device.get_capabilities = txt_a2560k_b_get_capabilities;
device.set_mode = txt_a2560k_b_set_mode;
device.set_sizes = txt_a2560k_b_set_sizes;
device.set_resolution = txt_a2560k_b_set_resolution;
device.set_border = txt_a2560k_b_set_border;
device.set_border_color = txt_a2560k_b_set_border_color;
device.set_font = txt_a2560k_b_set_font;
device.set_cursor = txt_a2560k_b_set_cursor;
device.set_cursor_visible = txt_a2560k_b_set_cursor_visible;
device.set_region = txt_a2560k_b_set_region;
device.get_region = txt_a2560k_b_get_region;
device.set_color = txt_a2560k_b_set_color;
device.get_color = txt_a2560k_b_get_color;
device.set_xy = txt_a2560k_b_set_xy;
device.get_xy = txt_a2560k_b_get_xy;
device.put = txt_a2560k_b_put;
device.scroll = txt_a2560k_b_scroll;
device.fill = txt_a2560k_b_fill;
device.get_sizes = txt_a2560k_b_get_sizes;
return txt_register(&device);
}

19
src/dev/txt_a2560k_b.h Normal file
View file

@ -0,0 +1,19 @@
/** @file txt_a2560k_b.h
*
* Text screen driver for A2560K Channel B
*/
#ifndef __TXT_A2560K_B_H
#define __TXT_A2560K_B_H
/* Channel B is assigned to screen #0, it will be considered the primary channel */
#define TXT_SCREEN_A2560K_B 0
/**
* Initialize and install the driver
*
* @return 0 on success, any other number is an error
*/
extern short txt_a2560k_b_install();
#endif

714
src/dev/txt_screen.c Normal file
View file

@ -0,0 +1,714 @@
/**
* @file txt_screen.c
*
* Uniform routines to manage the text screens
*
* The console code will call this layer, which will dispatch those calls
* to the low level drivers (e.g. txt_a2560k_a) registered with it.
*/
#include "constants.h"
#include "log.h"
#include "dev/txt_screen.h"
/**
* The array of device drivers.
*
* If the number of the driver record is 0, no driver is registered for that device
*/
static t_txt_device txt_device_driver[TXT_CNT_SCREENS];
/**
* Initialize the text system.
*/
void txt_init() {
int i;
/* Initialize all the drivers to blank... */
for (i = 0; i < TXT_CNT_SCREENS; i++) {
txt_device_driver[i].number = 0;
txt_device_driver[i].name = 0;
txt_device_driver[i].init = 0;
txt_device_driver[i].get_capabilities = 0;
txt_device_driver[i].set_mode = 0;
txt_device_driver[i].set_sizes = 0;
txt_device_driver[i].set_resolution = 0;
txt_device_driver[i].set_border = 0;
txt_device_driver[i].set_border_color = 0;
txt_device_driver[i].set_font = 0;
txt_device_driver[i].set_cursor = 0;
txt_device_driver[i].set_cursor_visible = 0;
txt_device_driver[i].get_region = 0;
txt_device_driver[i].set_region = 0;
txt_device_driver[i].get_color = 0;
txt_device_driver[i].set_color = 0;
txt_device_driver[i].set_xy = 0;
txt_device_driver[i].get_xy = 0;
txt_device_driver[i].put = 0;
txt_device_driver[i].scroll = 0;
txt_device_driver[i].fill = 0;
txt_device_driver[i].get_sizes = 0;
}
}
/**
* Register a device driver for a text screen
*
* The data in the provided structure will be copied to the kernel's
* internal structures. Also, the driver data provided will over-write
* any previous driver data for the device number, if one was previously
* registered.
*
* @param device the pointer to the device driver
*
* @return 0 on success, any other number is an error
*/
short txt_register(p_txt_device device) {
if (device->number < TXT_CNT_SCREENS) {
int i = device->number;
txt_device_driver[i].number = device->number;
txt_device_driver[i].name = device->name;
txt_device_driver[i].init = device->init;
txt_device_driver[i].get_capabilities = device->get_capabilities;
txt_device_driver[i].set_mode = device->set_mode;
txt_device_driver[i].set_sizes = device->set_sizes;
txt_device_driver[i].set_resolution = device->set_resolution;
txt_device_driver[i].set_border = device->set_border;
txt_device_driver[i].set_border_color = device->set_border_color;
txt_device_driver[i].set_font = device->set_font;
txt_device_driver[i].set_cursor = device->set_cursor;
txt_device_driver[i].set_cursor_visible = device->set_cursor_visible;
txt_device_driver[i].get_region = device->get_region;
txt_device_driver[i].set_region = device->set_region;
txt_device_driver[i].get_color = device->get_color;
txt_device_driver[i].set_color = device->set_color;
txt_device_driver[i].set_xy = device->set_xy;
txt_device_driver[i].get_xy = device->get_xy;
txt_device_driver[i].put = device->put;
txt_device_driver[i].scroll = device->scroll;
txt_device_driver[i].fill = device->fill;
txt_device_driver[i].get_sizes = device->get_sizes;
return 0;
} else {
return -1;
}
}
/**
* Find the device driver for the screen, if installed
*
* @param device the pointer to the device driver
*
* @return pointer to the device driver structure, 0 if invalid or not found
*/
p_txt_device txt_get_device(short screen) {
if (screen < TXT_CNT_SCREENS) {
p_txt_device device = &(txt_device_driver[screen]);
if (device->number == screen) {
return device;
} else {
log_num(LOG_ERROR, "txt_get_device: number mismatch ", screen);
}
}
return 0;
}
/**
* Initialize a screen
*
* @param screen the number of the text device
*/
void txt_init_screen(short screen) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->init) {
device->init();
}
} else {
log_num(LOG_ERROR, "Could not find screen ", screen);
}
}
/**
* Gets the description of a screen's capabilities
*
* @param screen the number of the text device
*
* @return a pointer to the read-only description (0 on error)
*/
const p_txt_capabilities txt_get_capabilities(short screen) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->get_capabilities) {
return device->get_capabilities();
}
}
return 0;
}
/**
* Set the display mode for the screen
*
* @param mode a bitfield of desired display mode options
*
* @return 0 on success, any other number means the mode is invalid for the screen
*/
short txt_set_mode(short screen, short mode) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_mode) {
return device->set_mode(mode);
}
}
return -1;
}
/**
* Recalculate the size of the text screen
*
* @return 0 on success, any other number means the mode is invalid for the screen
*/
short txt_setsizes(short screen) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_sizes) {
device->set_sizes();
return 0;
}
}
return -1;
}
/**
* Set the display resolution of the screen
*
* @param screen the number of the text device
* @param width the desired horizontal resolution in pixels
* @param height the desired veritical resolution in pixels
*
* @return 0 on success, any other number means the resolution is unsupported
*/
short txt_set_resolution(short screen, short width, short height) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_resolution) {
return device->set_resolution(width, height);
}
}
return -1;
}
/**
* Set the size of the border of the screen (if supported)
*
* @param screen the number of the text device
* @param width the horizontal size of one side of the border (0 - 32 pixels)
* @param height the vertical size of one side of the border (0 - 32 pixels)
*/
void txt_set_border(short screen, short width, short height) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_border) {
device->set_border(width, height);
}
}
}
/**
* Set the size of the border of the screen (if supported)
*
* @param screen the number of the text device
* @param red the red component of the color (0 - 255)
* @param green the green component of the color (0 - 255)
* @param blue the blue component of the color (0 - 255)
*/
void txt_set_border_color(short screen, unsigned char red, unsigned char green, unsigned char blue) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_border_color) {
device->set_border_color(red, green, blue);
}
}
}
/**
* Load a font as the current font for the screen
*
* @param screen the number of the text device
* @param width width of a character in pixels
* @param height of a character in pixels
* @param data pointer to the raw font data to be loaded
*/
short txt_set_font(short screen, short width, short height, const unsigned char * data) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_font) {
return device->set_font(width, height, data);
}
}
return -1;
}
/**
* Set the appearance of the cursor
*
* @param screen the number of the text device
* @param enable 0 to hide, any other number to make visible
* @param rate the blink rate for the cursor (0=1s, 1=0.5s, 2=0.25s, 3=1/5s)
* @param c the character in the current font to use as a cursor
*/
void txt_set_cursor(short screen, short enable, short rate, char c) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_cursor) {
device->set_cursor(enable, rate, c);
}
}
}
/**
* Set the appearance of the cursor
*
* @param screen the number of the text device
* @param enable 0 to hide, any other number to make visible
*/
void txt_set_cursor_visible(short screen, short enable) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_cursor_visible) {
device->set_cursor_visible(enable);
}
}
}
/**
* Get the current region.
*
* @param screen the number of the text device
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
short txt_get_region(short screen, p_rect region) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->get_region) {
return device->get_region(region);
}
}
return -1;
}
/**
* Set a region to restrict further character display, scrolling, etc.
* Note that a region of zero size will reset the region to the full size of the screen.
*
* @param screen the number of the text device
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
short txt_set_region(short screen, p_rect region) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_region) {
return device->set_region(region);
}
}
return -1;
}
/**
* Set the default foreground and background colors for printing
*
* @param screen the number of the text device
* @param foreground the Text LUT index of the new current foreground color (0 - 15)
* @param background the Text LUT index of the new current background color (0 - 15)
*/
short txt_set_color(short screen, unsigned char foreground, unsigned char background) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_color) {
return device->set_color(foreground, background);
}
}
return -1;
}
/*
* Get the foreground and background color for printing
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* foreground = pointer to the foreground color number
* background = pointer to the background color number
*/
void txt_get_color(short screen, unsigned char * foreground, unsigned char * background) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->get_color) {
device->get_color(foreground, background);
}
}
}
/**
* Set the position of the cursor to (x, y) relative to the current region
* If the (x, y) coordinate is outside the region, it will be clipped to the region.
* If y is greater than the height of the region, the region will scroll until that relative
* position would be within view.
*
* @param screen the number of the text device
* @param x the column for the cursor
* @param y the row for the cursor
*/
void txt_set_xy(short screen, short x, short y) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->set_xy) {
device->set_xy(x, y);
}
}
}
/**
* Get the position of the cursor (x, y) relative to the current region
*
* @param screen the number of the text device
* @param position pointer to a t_point record to fill out
*/
void txt_get_xy(short screen, p_point position) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->get_xy) {
device->get_xy(position);
}
}
}
/**
* Print a character to the current cursor position in the current color
*
* Most character codes will result in a glyph being displayed at the current
* cursor position, advancing the cursor one spot. There are some exceptions that
* will be treated as control codes:
*
* 0x08 - BS - Move the cursor back one position, erasing the character underneath
* 0x09 - HT - Move forward to the next TAB stop
* 0x0A - LF - Move the cursor down one line (line feed)
* 0x0D - CR - Move the cursor to column 0 (carriage return)
*
* @param screen the number of the text device
* @param c the character to print
*/
void txt_put(short screen, char c) {
t_point cursor;
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->put) {
switch (c) {
case CHAR_BS:
/* Backspace */
txt_get_xy(screen, &cursor);
if (cursor.x > 0) {
txt_set_xy(screen, cursor.x - 1, cursor.y);
device->put(' ');
txt_set_xy(screen, cursor.x - 1, cursor.y);
}
break;
case CHAR_TAB:
/* horizontal tab */
txt_get_xy(screen, &cursor);
txt_set_xy(screen, ((cursor.x >> 3) + 1) << 3, cursor.y);
break;
case CHAR_NL:
/* line feed */
txt_get_xy(screen, &cursor);
txt_set_xy(screen, 0, cursor.y + 1);
break;
case CHAR_CR:
/* carriage return */
break;
default:
device->put(c);
break;
}
}
}
}
/*
* Send a character to the screen without any escape code interpretation
*
* Deprecated legacy function
*
* @param screen the screen number 0 for channel A, 1 for channel B
* @param c the character to print
*/
void text_put_raw(short screen, char c) {
txt_put(screen, c);
}
/**
* Print an ASCII Z string to the screen
*
* @param screen the number of the text device
* @param c the ASCII Z string to print
*/
void txt_print(short screen, const char * message) {
const char * x = message;
while (*x) {
txt_put(screen, *x++);
}
}
/**
* Scroll the text in the current region
*
* @param screen the number of the text device
* @param horizontal the number of columns to scroll (negative is left, positive is right)
* @param vertical the number of rows to scroll (negative is down, positive is up)
*/
void txt_scroll(short screen, short horizontal, short vertical) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->scroll) {
device->scroll(horizontal, vertical);
}
}
}
/**
* Fill the current region with a character in the current color
*
* @param screen the number of the text device
* @param c the character to fill the region with
*/
void txt_fill(short screen, char c) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->fill) {
device->fill(c);
}
}
}
/*
* Clear the screen of data
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* mode = 0: erase from the cursor to the end of the screen,
1: erase from start of the screen to the cursor,
2: erase entire screen
*/
void txt_clear(short screen, short mode) {
t_point cursor;
t_rect old_region, region;
txt_get_xy(screen, &cursor);
txt_get_region(screen, &old_region);
switch (mode) {
case 0:
// Erase from cursor to end of region
// Clear the end of the line
region.origin.x = old_region.origin.x + cursor.x;
region.origin.y = old_region.origin.y + cursor.y;
region.size.width = old_region.size.width - cursor.x;
region.size.height = 1;
txt_set_region(screen, &region);
txt_fill(screen, ' ');
// Clear the region after the cursor
region.origin.x = old_region.origin.x;
region.origin.y = old_region.origin.y + cursor.y + 1;
region.size.width = old_region.size.width;
region.size.height = old_region.size.height - cursor.y - 1;
txt_set_region(screen, &region);
txt_fill(screen, ' ');
// Restore the original region
txt_set_region(screen, &old_region);
break;
case 1:
// Erase from start of region to cursor
// Clear the region to the cursor line
region.origin.x = old_region.origin.x;
region.origin.y = old_region.origin.y;
region.size.width = old_region.size.width;
region.size.height = cursor.y;
txt_set_region(screen, &region);
txt_fill(screen, ' ');
// Clear the end of the line
region.origin.x = old_region.origin.x;
region.origin.y = old_region.origin.y + cursor.y;
region.size.width = cursor.x + 1;
region.size.height = 1;
txt_set_region(screen, &region);
txt_fill(screen, ' ');
// Restore the original region
txt_set_region(screen, &old_region);
break;
case 2:
// Erase entire region
txt_fill(screen, ' ');
break;
default:
break;
}
}
/*
* Clear part or all of the current line
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* mode = 0: erase from the start of the line to the cursor,
* 1: erase from cursor to end of the line,
* 2: erase entire line
*/
void txt_clear_line(short screen, short mode) {
t_point cursor;
t_rect old_region, region;
txt_get_xy(screen, &cursor);
txt_get_region(screen, &old_region);
switch (mode) {
case 0:
// Erase from cursor to end of line
// Clear the end of the line
region.origin.x = old_region.origin.x + cursor.x;
region.origin.y = old_region.origin.y + cursor.y;
region.size.width = old_region.size.width - cursor.x;
region.size.height = 1;
txt_set_region(screen, &region);
txt_fill(screen, ' ');
// Restore the original region
txt_set_region(screen, &old_region);
break;
case 1:
// Erase from start of line to cursor
// Clear the end of the line
region.origin.x =old_region.origin.x;
region.origin.y = old_region.origin.y + cursor.y;
region.size.width = cursor.x;
region.size.height = 1;
txt_set_region(screen, &region);
txt_fill(screen, ' ');
// Restore the original region
txt_set_region(screen, &old_region);
break;
case 2:
// Clear the line
region.origin.x = old_region.origin.x;
region.origin.y = old_region.origin.y + cursor.y;
region.size.width = old_region.size.width;
region.size.height = 1;
txt_set_region(screen, &region);
txt_fill(screen, ' ');
// Restore the original region
txt_set_region(screen, &old_region);
break;
default:
break;
}
}
/*
* Insert a number of characters at the cursor position
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* count = the number of characters to insert
*/
void txt_insert(short screen, short count) {
t_point cursor;
t_rect old_region, region;
if (count > 0) {
txt_get_xy(screen, &cursor);
txt_get_region(screen, &old_region);
region.origin.x = old_region.origin.x + cursor.x;
region.origin.y = old_region.origin.y + cursor.y;
region.size.width = old_region.size.width - cursor.x;
region.size.height = 1;
txt_set_region(screen, &region);
txt_scroll(screen, 0 - count, 0);
txt_set_region(screen, &old_region);
}
}
/*
* Delete a number of characters at the cursor position
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* count = the number of characters to delete
*/
void txt_delete(short screen, short count) {
t_point cursor;
t_rect old_region, region;
short left;
if (count > 0) {
txt_get_xy(screen, &cursor);
txt_get_region(screen, &old_region);
if (count > cursor.x) {
count = cursor.x;
}
region.origin.x = old_region.origin.x + cursor.x;
region.origin.y = old_region.origin.y + cursor.y;
region.size.width = old_region.size.width - cursor.x;
region.size.height = 1;
txt_set_region(screen, &region);
txt_scroll(screen, count, 0);
txt_set_region(screen, &old_region);
}
}
/**
* Get the display resolutions
*
* @param screen the screen number 0 for channel A, 1 for channel B
* @param text_size the size of the screen in visible characters (may be null)
* @param pixel_size the size of the screen in pixels (may be null)
*/
void txt_get_sizes(short screen, p_extent text_size, p_extent pixel_size) {
p_txt_device device = txt_get_device(screen);
if (device) {
if (device->get_sizes) {
device->get_sizes(text_size, pixel_size);
}
}
}

354
src/dev/txt_screen.h Normal file
View file

@ -0,0 +1,354 @@
/**
* @file txt_screen.h
*
* Uniform routines to manage the text screens
*/
#ifndef __TXT_SCREEN_H
#define __TXT_SCREEN_H
#include "types.h"
#define TXT_CNT_SCREENS 5 /**< The maximum number of screens supported */
#define TXT_MODE_TEXT 0x0001 /**< The bit to enable text mode */
#define TXT_MODE_BITMAP 0x0002 /**< The bit to enable bitmap graphics mode */
#define TXT_MODE_SPRITE 0x0004 /**< The bit to enable sprite graphics mode */
#define TXT_MODE_TILE 0x0008 /**< The bit to enable tile graphics mode */
#define TXT_MODE_SLEEP 0x0010 /**< The bit to put the monitor to sleep by disabling sync */
/**
* @struct s_txt_capabilities
*
* A description of a screen's capabilities
*/
typedef struct s_txt_capabilities {
short number; /**< The unique ID of the screen */
short supported_modes; /**< The display modes supported on this screen */
short font_size_count; /**< The number of supported font sizes */
p_extent font_sizes; /**< Pointer to a list of t_extent listing all supported font sizes */
short resolution_count; /**< The number of supported display resolutions */
p_extent resolutions; /**< Pointer to a list of t_extent listing all supported display resolutions (in pixels) */
} t_txt_capabilities, *p_txt_capabilities;
typedef void (*p_init)();
typedef const p_txt_capabilities (*p_get_capabilities)();
typedef short (*p_set_mode)(short mode);
typedef void (*p_setsizes)();
typedef short (*p_set_resolution)(short width, short height);
typedef void (*p_set_border)(short width, short height);
typedef void (*p_set_border_color)(unsigned char red, unsigned char green, unsigned char blue);
typedef short (*p_set_font)(short width, short height, const unsigned char * data);
typedef void (*p_set_cursor)(short enable, short rate, char c);
typedef void (*p_set_cursor_visible)(short enable);
typedef short (*p_set_region)(p_rect region);
typedef short (*p_set_color)(unsigned char foreground, unsigned char background);
typedef short (*p_get_color)(unsigned char * foreground, unsigned char * background);
typedef void (*p_set_xy)(short x, short y);
typedef void (*p_get_xy)(p_point position);
typedef void (*p_put)(char c);
typedef void (*p_scroll)(short horizontal, short vertical);
typedef void (*p_fill)(char c);
typedef void (*p_get_sizes)(p_extent text_size, p_extent pixel_size);
/**
* @struct s_txt_device
*
* A device driver for a text screen
*
* The driver contains basic information about the device and pointers
* to all the functions that implement actions the driver can take.
*/
typedef struct s_txt_device {
short number; /**< The unique ID of the screen */
const char * name; /**< A human-readable (mostly) name for the screen */
p_init init; /**< Pointer to the device's init function */
p_get_capabilities get_capabilities; /**< Pointer to the device's get_capabilities function */
p_set_mode set_mode; /**< Pointer to the device's set_mode function */
p_setsizes set_sizes; /**< Pointer to the device's set_sizes function */
p_set_resolution set_resolution; /**< Pointer to the device's set_resolution function */
p_set_border set_border; /**< Pointer to the device's set_border function */
p_set_border_color set_border_color; /**< Pointer to the device's set_border function */
p_set_font set_font; /**< Pointer to the device's set_font function */
p_set_region get_region; /**< Pointer to the device's get_region function */
p_set_region set_region; /**< Pointer to the device's set_region function */
p_get_color get_color; /**< Pointer to the device's get_color function */
p_set_color set_color; /**< Pointer to the device's set_color function */
p_set_cursor set_cursor; /**< Pointer to the device's set_cursor function */
p_set_cursor_visible set_cursor_visible; /**< Pointer to the device's set_cursor_visible function */
p_set_xy set_xy; /**< Pointer to the device's set_xy function */
p_get_xy get_xy; /**< Pointer to the device's get_xy function */
p_put put; /**< Pointer to the device's put function */
p_scroll scroll; /**< Pointer to the device's scroll function */
p_fill fill; /**< Pointer to the device's fill function */
p_get_sizes get_sizes; /**< Pointer to the device's get_sizes function */
} t_txt_device, *p_txt_device;
/**
* Initialize the text system.
*/
extern void txt_init();
/**
* Register a device driver for a text screen
*
* @param device the pointer to the device driver (all will be copied into the kernel's internal storage)
*
* @return 0 on success, any other number is an error
*/
extern short txt_register(p_txt_device device);
/**
* Initialize a screen
*
* @param screen the number of the text device
*/
extern void txt_init_screen(short screen);
/**
* Gets the description of a screen's capabilities
*
* @param screen the number of the text device
*
* @return a pointer to the read-only description (0 on error)
*/
extern const p_txt_capabilities txt_get_capabilities(short screen);
/**
* Set the display mode for the screen
*
* @param screen the number of the text device
* @param mode a bitfield of desired display mode options
*
* @return 0 on success, any other number means the mode is invalid for the screen
*/
extern short txt_set_mode(short screen, short mode);
/**
* Recalculate the size of the text screen
*
* @return 0 on success, any other number means the mode is invalid for the screen
*/
extern short txt_setsizes(short screen);
/**
* Set the display resolution of the screen
*
* @param screen the number of the text device
* @param width the desired horizontal resolution in pixels
* @param height the desired veritical resolution in pixels
*
* @return 0 on success, any other number means the resolution is unsupported
*/
extern short txt_set_resolution(short screen, short width, short height);
/**
* Set the size of the border of the screen (if supported)
*
* @param screen the number of the text device
* @param width the horizontal size of one side of the border (0 - 32 pixels)
* @param height the vertical size of one side of the border (0 - 32 pixels)
*/
extern void txt_set_border(short screen, short width, short height);
/**
* Set the size of the border of the screen (if supported)
*
* @param screen the number of the text device
* @param red the red component of the color (0 - 255)
* @param green the green component of the color (0 - 255)
* @param blue the blue component of the color (0 - 255)
*/
extern void txt_set_border_color(short screen, unsigned char red, unsigned char green, unsigned char blue);
/**
* Load a font as the current font for the screen
*
* @param screen the number of the text device
* @param width width of a character in pixels
* @param height of a character in pixels
* @param data pointer to the raw font data to be loaded
*/
extern short txt_set_font(short screen, short width, short height, const unsigned char * data);
/**
* Set the appearance of the cursor
*
* @param screen the number of the text device
* @param enable 0 to hide, any other number to make visible
* @param rate the blink rate for the cursor (0=1s, 1=0.5s, 2=0.25s, 3=1/5s)
* @param c the character in the current font to use as a cursor
*/
extern void txt_set_cursor(short screen, short enable, short rate, char c);
/**
* Set the appearance of the cursor
*
* @param screen the number of the text device
* @param enable 0 to hide, any other number to make visible
*/
extern void txt_set_cursor_visible(short screen, short enable);
/**
* Get the current region.
*
* @param screen the number of the text device
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
extern short txt_get_region(short screen, p_rect region);
/**
* Set a region to restrict further character display, scrolling, etc.
* Note that a region of zero size will reset the region to the full size of the screen.
*
* @param screen the number of the text device
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
extern short txt_set_region(short screen, p_rect region);
/**
* Set the default foreground and background colors for printing
*
* @param screen the number of the text device
* @param foreground the Text LUT index of the new current foreground color (0 - 15)
* @param background the Text LUT index of the new current background color (0 - 15)
*/
extern short txt_set_color(short screen, unsigned char foreground, unsigned char background);
/*
* Get the foreground and background color for printing
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* foreground = pointer to the foreground color number
* background = pointer to the background color number
*/
extern void txt_get_color(short screen, unsigned char * foreground, unsigned char * background);
/**
* Set the position of the cursor to (x, y) relative to the current region
* If the (x, y) coordinate is outside the region, it will be clipped to the region.
* If y is greater than the height of the region, the region will scroll until that relative
* position would be within view.
*
* @param screen the number of the text device
* @param x the column for the cursor
* @param y the row for the cursor
*/
extern void txt_set_xy(short screen, short x, short y);
/**
* Get the position of the cursor (x, y) relative to the current region
*
* @param screen the number of the text device
* @param position pointer to a t_point record to fill out
*/
extern void txt_get_xy(short screen, p_point position);
/**
* Print a character to the current cursor position in the current color
*
* Most character codes will result in a glyph being displayed at the current
* cursor position, advancing the cursor one spot. There are some exceptions that
* will be treated as control codes:
*
* 0x08 - BS - Move the cursor back one position, erasing the character underneath
* 0x09 - HT - Move forward to the next TAB stop
* 0x0A - LF - Move the cursor down one line (line feed)
* 0x0D - CR - Move the cursor to column 0 (carriage return)
*
* @param screen the number of the text device
* @param c the character to print
*/
extern void txt_put(short screen, char c);
/*
* Send a character to the screen without any escape code interpretation
*
* Deprecated legacy function
*
* @param screen the screen number 0 for channel A, 1 for channel B
* @param c the character to print
*/
extern void text_put_raw(short screen, char c);
/**
* Print an ASCII Z string to the screen
*
* @param screen the number of the text device
* @param c the ASCII Z string to print
*/
extern void txt_print(short screen, const char * message);
/**
* Scroll the text in the current region
*
* @param screen the number of the text device
* @param horizontal the number of columns to scroll (negative is left, positive is right)
* @param vertical the number of rows to scroll (negative is down, positive is up)
*/
extern void txt_scroll(short screen, short horiztonal, short vertical);
/**
* Fill the current region with a character in the current color
*
* @param screen the number of the text device
* @param c the character to fill the region with
*/
extern void txt_fill(short screen, char c);
/*
* Clear the screen of data
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* mode = 0: erase from the cursor to the end of the screen,
1: erase from start of the screen to the cursor,
2: erase entire screen
*/
extern void txt_clear(short screen, short mode);
/*
* Clear part or all of the current line
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* mode = 0: erase from the start of the line to the cursor,
* 1: erase from cursor to end of the line,
* 2: erase entire line
*/
extern void txt_clear_line(short screen, short mode);
/*
* Insert a number of characters at the cursor position
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* count = the number of characters to insert
*/
extern void txt_insert(short screen, short count);
/*
* Delete a number of characters at the cursor position
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* count = the number of characters to delete
*/
extern void txt_delete(short screen, short count);
/**
* Get the display resolutions
*
* @param screen the screen number 0 for channel A, 1 for channel B
* @param text_size the size of the screen in visible characters (may be null)
* @param pixel_size the size of the screen in pixels (may be null)
*/
extern void txt_get_sizes(short screen, p_extent text_size, p_extent pixel_size);
#endif

View file

@ -2,9 +2,23 @@
* Definitions of the UART routines
*/
#include <stdlib.h>
#include <string.h>
#include "errors.h"
#include "log.h"
#include "uart_reg.h"
#include "dev/channel.h"
#include "dev/uart.h"
#include "simpleio.h"
#include "utilities.h"
/**
* Return the UART index for the given channel device
*/
short cdev_to_uart(short dev) {
return dev - CDEV_COM1;
}
volatile unsigned char * uart_get_base(short uart) {
if (uart == 0) {
@ -23,7 +37,7 @@ volatile unsigned char * uart_get_base(short uart) {
*/
void uart_setbps(short uart, unsigned short bps_code) {
volatile unsigned char * uart_base = uart_get_base(uart);
unsigned char lcr;
if (uart_base) {
/* Enable divisor latch */
uart_base[UART_LCR] = uart_base[UART_LCR] | 0x80;
@ -46,13 +60,13 @@ void uart_setbps(short uart, unsigned short bps_code) {
*/
void uart_setlcr(short uart, unsigned char lcr_bits) {
volatile unsigned char * uart_base = uart_get_base(uart);
DEBUG("uart_setlcr");
//if (uart_base) {
if (uart_base) {
uart_base[UART_LCR] = lcr_bits; /* Set the LCR bits (without the DLL bit) */
if (uart_base[UART_LCR] != lcr_bits) {
DEBUG("LCR mismatched!");
}
//}
}
}
/*
@ -63,7 +77,7 @@ void uart_setlcr(short uart, unsigned char lcr_bits) {
*/
void uart_init(short uart) {
volatile unsigned char * uart_base = uart_get_base(uart);
DEBUG("uart_init");
if (uart_base) {
/* Default to 9600 bps */
uart_setbps(uart, UART_9600);
@ -87,6 +101,7 @@ void uart_init(short uart) {
*/
short uart_has_bytes(short uart) {
volatile unsigned char * uart_base = uart_get_base(uart);
if (uart_base) {
if (uart_base[UART_LSR] & LSR_DATA_AVAIL) {
return 1;
@ -98,6 +113,26 @@ short uart_has_bytes(short uart) {
}
}
/**
* Return true (non-zero) if the UART transmit FIFO is not full
*
* @param uart the number of the UART: 0 for COM1, 1 for COM2
* @return non-zero if the FIFO can accept a byte, 0 if it is full
*/
short uart_can_send(short uart) {
volatile unsigned char * uart_base = uart_get_base(uart);
if (uart_base) {
if (uart_base[UART_LSR] & LSR_XMIT_EMPTY) {
return 1;
} else {
return 0;
}
} else {
return 0;
}
}
/*
* Send a byte to the UART. Blocks until the FIFO is ready to recieve a byte.
*
@ -107,6 +142,7 @@ short uart_has_bytes(short uart) {
*/
void uart_put(short uart, unsigned char b) {
volatile unsigned char * uart_base = uart_get_base(uart);
if (uart_base) {
unsigned char status = 0;
@ -131,6 +167,7 @@ void uart_put(short uart, unsigned char b) {
*/
unsigned char uart_get(short uart) {
volatile unsigned char * uart_base = uart_get_base(uart);
if (uart_base) {
unsigned char status = 0;
@ -143,3 +180,304 @@ unsigned char uart_get(short uart) {
return uart_base[UART_TRHB];
}
}
/**
* Return the status of the UART
*
* @param channel the descriptor for the channel
* @return the status of the device
*/
short uart_status(p_channel chan) {
short status = 0;
// Check if there is data to be read
if (uart_has_bytes(cdev_to_uart(chan->dev))) {
status |= CDEV_STAT_READABLE;
}
// Check if the FIFO is full
if (uart_can_send(cdev_to_uart(chan->dev))) {
status |= CDEV_STAT_WRITABLE;
}
// TODO: reflect error bits?
return status;
}
/**
* Open a serial connection... allow specification for bps, data size, etc.
*
* The specification provided to open is a string of four comma separated values:
* 1. Bits-per-second: 300, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200
* 2. Number of data bits: 5, 6, 7, 8
* 3. Stop bits: 1, or 2
* 4. Parity: NONE, ODD, EVEN, MARK, or SPACE
*
* @param chan the channel descriptor to open
* @param spec a string describing the connection to open: <bps>,<data bits>,<stop bits>,<parity Y/N>
* @param mode an unused parameter
* @return 0 on success, any other number is an error
*/
short uart_open(p_channel chan, const char * spec, short mode) {
unsigned short bps = 0, lcr = 0;
char * saveptr;
char spec_copy[80];
char *token = 0;
short i = 0;
short bps_code = 0;
short lcr_code = 0;
/* Do some basic initialization of the UART */
uart_init(cdev_to_uart(chan->dev));
// Make a local copy of the specification so we can tokenize it
strncpy(spec_copy, spec, 80);
// Get the first token
saveptr = spec_copy;
token = strtok_r(spec_copy, ",", &saveptr);
if (token) {
// Parse the bit rate token
i = atoi(token);
switch (i) {
case 300:
bps_code = UART_300;
break;
case 1200:
bps_code = UART_1200;
break;
case 2400:
bps_code = UART_2400;
break;
case 4800:
bps_code = UART_4800;
break;
case 9600:
bps_code = UART_9600;
break;
case 19200:
bps_code = UART_19200;
break;
case 38400:
bps_code = UART_38400;
break;
case 57600:
bps_code = UART_57600;
break;
case 115200:
bps_code = UART_115200;
break;
default:
return ERR_BAD_ARGUMENT;
}
uart_setbps(cdev_to_uart(chan->dev), bps_code);
// Get the next token
token = strtok_r(spec_copy, ",", &saveptr);
if (token) {
// Parse the data bit count
i = atoi(token);
switch (i) {
case 5:
lcr_code = LCR_DATABITS_5;
break;
case 6:
lcr_code = LCR_DATABITS_6;
break;
case 7:
lcr_code = LCR_DATABITS_7;
break;
case 8:
lcr_code = LCR_DATABITS_8;
break;
default:
log(LOG_ERROR, "uart_open: Bad data word length");
return ERR_BAD_ARGUMENT;
}
// Get the next token
token = strtok_r(spec_copy, ",", &saveptr);
if (token) {
// Parse the stop bit count (1 or 2)
i = atoi(token);
if (i == 1) {
lcr_code |= LCR_STOPBIT_1;
} else if (i == 2) {
lcr_code |= LCR_STOPBIT_2;
} else {
log(LOG_ERROR, "uart_open: Bad stop bits");
return ERR_BAD_ARGUMENT;
}
// Get the next token
token = strtok_r(spec_copy, ",", &saveptr);
if (token) {
// NONE, ODD, EVEN, MARK, or SPACE
if (strcmp(token, "NONE") == 0) {
lcr_code |= LCR_PARITY_NONE;
} else if (strcmp(token, "ODD") == 0) {
lcr_code |= LCR_PARITY_ODD;
} else if (strcmp(token, "EVEN") == 0) {
lcr_code |= LCR_PARITY_EVEN;
} else if (strcmp(token, "MARK") == 0) {
lcr_code |= LCR_PARITY_MARK;
} else if (strcmp(token, "SPACE") == 0) {
lcr_code |= LCR_PARITY_SPACE;
} else {
log(LOG_ERROR, "uart_open: Bad parity");
return ERR_BAD_ARGUMENT;
}
// Set word length, stop bit size, and parity
uart_setlcr(cdev_to_uart(chan->dev), lcr_code);
return 0;
} else {
log(LOG_ERROR, "uart_open: no parity token");
return ERR_BAD_ARGUMENT;
}
} else {
log(LOG_ERROR, "uart_open: no stop bit token");
return ERR_BAD_ARGUMENT;
}
} else {
log(LOG_ERROR, "uart_open: no data length token");
return ERR_BAD_ARGUMENT;
}
} else {
log(LOG_ERROR, "uart_open: no BPS token");
return ERR_BAD_ARGUMENT;
}
return 0;
}
/*
* Read a single char from the UART
*
* @param channel the number of the channel
* @return the value read (if negative, error)
*/
short uart_read_b(p_channel chan) {
return uart_get(cdev_to_uart(chan->dev));
}
/**
* Read bytes from the UART
*
* @param channel the number of the channel
* @param buffer the buffer into which to copy the channel data
* @param size the size of the buffer.
* @return number of bytes read, any negative number is an error code
*/
short uart_read(p_channel chan, char * buffer, short size) {
short i = 0, count = 0;
for (i = 0; i < size; i++) {
buffer[i] = uart_get(cdev_to_uart(chan->dev));
count++;
}
return count;
}
/**
* Read a line from the UART
*
* @param channel the number of the channel
* @param buffer the buffer into which to copy the channel data
* @param size the size of the buffer.
* @returns number of bytes read, any negative number is an error code
*/
short uart_readline(p_channel chan, char * buffer, short size) {
short i = 0, count = 0;
for (i = 0; i < size; i++) {
char c = uart_get(cdev_to_uart(chan->dev));
if ((c == '\n') || (c == '\r')) {
break;
}
buffer[i] = c;
count++;
}
return count;
}
/**
* Write a single unsigned char to the UART
*
* @param channel the number of the channel
* @param b the unsigned char to write
* @return 0 on success, a negative value on error
*/
short uart_write_b(p_channel chan, unsigned char c) {
uart_put(cdev_to_uart(chan->dev), c);
return 0;
}
/**
* Write a bytes to the UART
*
* @param channel the number of the channel
* @param buffer the buffer containing the data to write
* @param size the size of the buffer.
* @return number of bytes written, any negative number is an error code
*/
short uart_write(p_channel chan, const char * buffer, short size) {
int i;
for (i = 0; i < size; i++) {
uart_put(cdev_to_uart(chan->dev), buffer[i]);
}
return 0;
}
/**
* Install the UART driver
*/
short uart_install() {
t_dev_chan dev;
short result = 0;
dev.name = "COM1";
dev.number = CDEV_COM1;
dev.init = 0;
dev.open = uart_open;
dev.close = 0;
dev.read = uart_read;
dev.readline = uart_readline;
dev.read_b = uart_read_b;
dev.write = uart_write;
dev.write_b = uart_write_b;
dev.flush = 0;
dev.seek = 0;
dev.status = uart_status;
dev.ioctrl = 0;
result = cdev_register(&dev);
if (result) {
return result;
}
dev.name = "COM2";
dev.number = CDEV_COM2;
result = cdev_register(&dev);
if (result) {
return result;
}
}

View file

@ -5,6 +5,13 @@
#ifndef __UART_H
#define __UART_H
/**
* Returns the address of the first register in the given UART
*
* @param uart the number of the UART 0 = COM1, 1 = COM2
*/
extern volatile unsigned char * uart_get_base(short uart);
/*
* Set the data transfer speed
*
@ -61,4 +68,10 @@ extern void uart_put(short uart, unsigned char b);
* the byte read from the UART
*/
extern unsigned char uart_get(short uart);
/**
* Install the UART driver
*/
extern short uart_install();
#endif

View file

@ -9,7 +9,6 @@
#include "log.h"
#include "dev/block.h"
#include "dev/text_screen_iii.h"
#include "ff.h" /* Obtains integer types */
#include "diskio.h" /* Declarations of disk functions */
#include "simpleio.h"
@ -33,7 +32,8 @@ DSTATUS disk_status (
TRACE("disk_status");
return bdev_status(pdrv);
stat = bdev_status(pdrv);
return stat;
}
@ -77,7 +77,13 @@ DRESULT disk_read (
result = bdev_read(pdrv, sector, buff, 512);
if (result < 0) {
log_num(LOG_ERROR, "disk_read error: ", result);
if (result == ERR_MEDIA_CHANGE) {
log(LOG_ERROR, "disk changed.");
return RES_NOTRDY;
} else {
log(LOG_ERROR, "gerneral error");
return RES_PARERR;
}
} else {
sector++;
}

View file

@ -19,27 +19,36 @@
#include "syscalls.h"
#include "timers.h"
#include "boot.h"
#include "memory.h"
#include "dev/block.h"
#include "dev/channel.h"
#include "dev/console.h"
#include "dev/fdc.h"
#include "dev/text_screen_iii.h"
#include "dev/lpt.h"
#include "dev/midi.h"
#include "dev/pata.h"
#include "dev/ps2.h"
#include "dev/rtc.h"
#include "dev/sdc.h"
#include "dev/txt_screen.h"
#include "dev/txt_a2560k_a.h"
#include "dev/txt_a2560k_b.h"
#include "dev/uart.h"
#include "vicky_general.h"
#include "snd/codec.h"
#include "snd/psg.h"
#include "snd/sid.h"
#include "snd/yamaha.h"
#include "variables.h"
#include "vicky_general.h"
#include "fatfs/ff.h"
#include "cli/cli.h"
// #include "rsrc/bitmaps/splash_a2560k.h"
#include "rsrc/bitmaps/splash_a2560u.h"
#include "rsrc/font/MSX_CP437_8x8.h"
const char* VolumeStr[FF_VOLUMES] = { "sd", "fd", "hd" };
extern unsigned long __memory_start;
#if MODEL == MODEL_FOENIX_A2560K
/*
* Initialize the SuperIO registers
@ -62,7 +71,7 @@ const char* VolumeStr[FF_VOLUMES] = { "sd", "fd", "hd" };
*GP30_REG = 0x01;
*GP31_REG = 0x01;
*GP32_REG = 0x01;
*GP33_REG = 0x01;
*GP33_REG = 0x04; // FAN1 GPIO Config
*GP34_REG = 0x01;
*GP35_REG = 0x01;
*GP36_REG = 0x01;
@ -92,54 +101,13 @@ const char* VolumeStr[FF_VOLUMES] = { "sd", "fd", "hd" };
*LED1_REG = 0x01;
*LED2_REG = 0x02;
*FAN1_REG = 0xE0; // <= Value to change to Get the Fan running.
// See doc for more options, need to set $80 to get it started and use other bits to change the PWN...
*FAN_CTRL_REG = 0x01;
}
#endif
/*
* Load and display the splash screen
*/
void load_splashscreen() {
long target_ticks;
int i;
unsigned char * pixels;
volatile unsigned char * vram = VRAM_Bank0;
/* Turn off the screen */
*MasterControlReg_A = VKY3_MCR_BLANK_EN;
for (i = 0; i < 256; i++) {
LUT_0[4*i] = splashscreen_lut[4*i];
LUT_0[4*i+1] = splashscreen_lut[4*i+1];
LUT_0[4*i+2] = splashscreen_lut[4*i+2];
LUT_0[4*i+3] = splashscreen_lut[4*i+3];
}
/* Copy the bitmap to video RAM */
for (pixels = splashscreen_pix; *pixels != 0;) {
unsigned char count = *pixels++;
unsigned char pixel = *pixels++;
for (i = 0; i < count; i++) {
*vram++ = pixel;
}
}
/* Set up the bitmap */
*BM0_Addy_Pointer_Reg = 0;
*BM0_Control_Reg = 1;
/* Turn off the border */
*BorderControlReg_L_A = 0;
/* Set a background color for the bitmap mode */
*BackGroundControlReg_A = 0x00800000;
/* Display the splashscreen: 640x480 */
*MasterControlReg_A = VKY3_MCR_GRAPH_EN | VKY3_MCR_BITMAP_EN;
/* Play the SID test bong on the Gideon SID implementation */
sid_test_internal();
}
void print_error(short channel, char * message, short code) {
print(channel, message);
print(channel, ": ");
@ -156,17 +124,28 @@ void initialize() {
short res;
/* Set the logging level */
log_setlevel(LOG_ERROR);
log_setlevel(LOG_FATAL);
/* Initialize the memory system */
mem_init(0x3d0000);
// /* Hide the mouse */
mouse_set_visible(0);
/* Initialize the text channels */
text_init();
/* Initialize the variable system */
var_init();
/* Initialize the indicators, and turn on the power indicator */
/* Initialize the text channels */
txt_init();
txt_a2560k_a_install();
txt_a2560k_b_install();
txt_init_screen(1);
txt_init_screen(0);
log(LOG_INFO, "Text system initialized");
/* Initialize the indicators */
ind_init();
ind_set(IND_POWER, IND_ON);
log(LOG_INFO, "Indicators initialized");
/* Initialize the interrupt system */
int_init();
@ -179,12 +158,15 @@ void initialize() {
/* Mute the PSG */
psg_mute_all();
/* Initialize and mute the SID chips */
sid_init_all();
/* Initialize the Yamaha sound chips (well, turn their volume down at least) */
ym_init();
/* Initialize the CODEC */
init_codec();
/* Initialize the SID chips */
sid_init_all();
cdev_init_system(); // Initialize the channel device system
log(LOG_INFO, "Channel device system ready.");
@ -204,12 +186,14 @@ void initialize() {
rtc_init();
target_jiffies = sys_time_jiffies() + 300; /* 5 seconds minimum */
log_num(LOG_DEBUG, "target_jiffies assigned: ", target_jiffies);
/* Enable all interrupts */
int_enable_all();
log(LOG_TRACE, "Interrupts enabled");
/* Display the splash screen */
load_splashscreen();
/* Play the SID test bong on the Gideon SID implementation */
sid_test_internal();
if (res = pata_install()) {
log_num(LOG_ERROR, "FAILED: PATA driver installation", res);
@ -223,12 +207,20 @@ void initialize() {
log(LOG_INFO, "SDC driver installed.");
}
#if MODEL == MODEL_FOENIX_A2560K
if (res = fdc_install()) {
log_num(LOG_ERROR, "FAILED: Floppy drive initialization", res);
} else {
log(LOG_INFO, "Floppy drive initialized.");
}
#endif
// At this point, we should be able to call into to console to print to the screens
if (res = ps2_init()) {
print_error(0, "FAILED: PS/2 keyboard initialization", res);
} else {
DEBUG("PS/2 keyboard initialized.");
log(LOG_INFO, "PS/2 keyboard initialized.");
}
#if MODEL == MODEL_FOENIX_A2560K
@ -237,8 +229,28 @@ void initialize() {
} else {
log(LOG_INFO, "A2560K built-in keyboard initialized.");
}
if (res = lpt_install()) {
log_num(LOG_ERROR, "FAILED: LPT installation", res);
} else {
log(LOG_INFO, "LPT installed.");
}
if (res = midi_install()) {
log_num(LOG_ERROR, "FAILED: MIDI installation", res);
} else {
log(LOG_INFO, "MIDI installed.");
}
#endif
if (res = uart_install()) {
log_num(LOG_ERROR, "FAILED: serial port initialization", res);
} else {
log(LOG_INFO, "Serial ports initialized.");
}
if (res = cli_init()) {
log_num(LOG_ERROR, "FAILED: CLI initialization", res);
} else {
@ -250,68 +262,24 @@ void initialize() {
} else {
log(LOG_INFO, "File system initialized.");
}
/* Wait until the target duration has been reached _or_ the user presses a key */
while (target_jiffies > sys_time_jiffies()) {
short scan_code = sys_kbd_scancode();
if (scan_code != 0) {
break;
}
}
/* Go back to text mode */
text_init();
}
#define BOOT_DEFAULT -1 // User chose default, or the time to over-ride has passed
int main(int argc, char * argv[]) {
const char * color_bars = "\x1b[31m\x0b\x0c\x1b[35m\x0b\x0c\x1b[33m\x0b\x0c\x1b[32m\x0b\x0c\x1b[36m\x0b\x0c";
#if MODEL == MODEL_FOENIX_A2560U
const char * title_1 = "\x1b[37m A 2222 55555 666 000 U U";
const char * title_2 = "\x1b[37m A A 2 5 6 0 0 U U";
const char * title_3 = "\x1b[37m AAAAA 222 555 6666 0 0 U U";
const char * title_4 = "\x1b[37m A A 2 5 6 6 0 0 U U";
const char * title_5 = "\x1b[37m A A 22222 5555 666 000 UUU";
#elif MODEL == MODEL_FOENIX_A2560U_PLUS
const char * title_1 = "\x1b[37m A 2222 55555 666 000 U U +";
const char * title_2 = "\x1b[37m A A 2 5 6 0 0 U U +";
const char * title_3 = "\x1b[37m AAAAA 222 555 6666 0 0 U U +++++";
const char * title_4 = "\x1b[37m A A 2 5 6 6 0 0 U U +";
const char * title_5 = "\x1b[37m A A 22222 5555 666 000 UUU +";
#elif MODEL == MODEL_FOENIX_A2560K
const char * title_1 = "\x1b[37m A 2222 55555 666 000 K K";
const char * title_2 = "\x1b[37m A A 2 5 6 0 0 K K";
const char * title_3 = "\x1b[37m AAAAA 222 555 6666 0 0 KKK";
const char * title_4 = "\x1b[37m A A 2 5 6 6 0 0 K K";
const char * title_5 = "\x1b[37m A A 22222 5555 666 000 K K";
#else
const char * title_1 = "\x1b[37m FFFFF OOO EEEEE N N IIIII X X";
const char * title_2 = "\x1b[37m F O O E NN N I X X";
const char * title_3 = "\x1b[37m FFF O O EEE N N N I X";
const char * title_4 = "\x1b[37m F O O E N NN I X X";
const char * title_5 = "\x1b[37m F OOO EEEEE N N IIIII X X";
#endif
char welcome[255];
short result;
short i;
initialize();
sprintf(welcome, " %s%s\n %s %s\n %s %s\n %s %s\n%s %s\n\n", color_bars, title_1, color_bars, title_2, color_bars, title_3, color_bars, title_4, color_bars, title_5);
sys_chan_write(0, welcome, strlen(welcome));
// Make sure the command path is set to the default before we get started
cli_command_set("");
sprintf(welcome, "Foenix/MCP v%02d.%02d-alpha+%04d\n\nType \"HELP\" or \"?\" for command summary.", VER_MAJOR, VER_MINOR, VER_BUILD);
sys_chan_write(0, welcome, strlen(welcome));
// Display the splash screen and wait for user input
short boot_dev = boot_screen();
// #if MODEL == MODEL_FOENIX_A2560K
// fdc_init();
// if (fdc_ioctrl(FDC_CTRL_MOTOR_ON, 0, 0)) {
// log(LOG_ERROR, "Could not turn on the floppy drive motor.");
// }
// #endif
cli_repl(0);
// Start the boot process
boot_from_bdev(boot_dev);
log(LOG_INFO, "Stopping.");

View file

@ -9,117 +9,122 @@
* Screen Channel A
*/
#define MasterControlReg_A ((volatile uint32_t *)0x00C40000)
#define MasterControlReg_A ((volatile unsigned long *)0xFEC40000)
#define VKY3_MCR_TEXT_EN 0x00000001 /* Text Mode Enable */
#define VKY3_MCR_TEXT_OVRLY 0x00000002 /* Text Mode overlay */
#define VKY3_MCR_GRAPH_EN 0x00000004 /* Graphic Mode Enable */
#define VKY3_MCR_BITMAP_EN 0x00000008 /* Bitmap Engine Enable */
#define VKY3_MCR_VIDEO_DISABLE 0x00000080 /* Disable the video engine and VRAM access by Vicky */
#define VKY3_MCR_RESOLUTION_MASK 0x00000300 /* Resolution - 00: 640x480, 01:800x600, 10: 1024x768, 11: 640x400 */
#define VKY3_MCR_640x480 0x00000000
#define VKY3_MCR_800x600 0x00000100
#define VKY3_MCR_1024x768 0x00000200
#define VKY3_MCR_640x400 0x00000300
#define VKY3_MCRA_1024x768 0x00000800
#define VKY3_MCR_DOUBLE_EN 0x00000400 /* Doubling Pixel */
#define VKY3_MCR_GAMMA_EN 0x00010000 /* GAMMA Enable */
#define VKY3_MCR_MANUAL_GAMMA_EN 0x00020000 /* Enable Manual GAMMA Enable */
#define VKY3_MCR_BLANK_EN 0x00040000 /* Turn OFF sync (to monitor in sleep mode) */
#define VKY3_MCR_DISABLE_SYNC 0x00040000 /* Turn OFF sync (to monitor in sleep mode) */
/* Access to DIP switch information (read only) */
#define VKY3_DIP_REG ((volatile unsigned short *)0x00C40002)
#define VKY3_DIP_REG ((volatile unsigned short *)0xFEC40002)
/* Bits 0 - 12: Master Control Register data */
#define VKY3_DIP_GAMMA 0x2000 /* DIP switch indication for Gamma correction */
#define VKY3_DIP_HIRES 0x4000 /* DIP switch for high resolution mode */
#define VKY3_PLL_ACTIVE_CLK 0x8000 /* Active Clock --- 0: 25.175Mhz, 1: 40Mhz */
#define BorderControlReg_L_A ((volatile uint32_t *)0x00C40004)
#define BorderControlReg_L_A ((volatile unsigned long *)0xFEC40004)
#define VKY3_BRDR_EN 0x00000001 /* Border Enable */
#define VKY3_X_SCROLL_MASK 0x00000070 /* X Scroll */
#define VKY3_X_SIZE_MASK 0x00003f00 /* X Size */
#define VKY3_Y_SIZE_MASK 0x003f0000 /* Y Size */
#define BorderControlReg_H_A ((volatile uint32_t *)0x00C40008)
#define BackGroundControlReg_A ((volatile uint32_t *)0x00C4000C)
#define CursorControlReg_L_A ((volatile uint32_t *)0x00C40010)
#define CursorControlReg_H_A ((volatile uint32_t *)0x00C40014)
#define BorderControlReg_H_A ((volatile unsigned long *)0xFEC40008)
#define BackGroundControlReg_A ((volatile unsigned long *)0xFEC4000C)
#define CursorControlReg_L_A ((volatile unsigned long *)0xFEC40010)
#define CursorControlReg_H_A ((volatile unsigned long *)0xFEC40014)
#define LineInterrupt0_A ((volatile uint16_t *)0x00C40018)
#define LineInterrupt1_A ((volatile uint16_t *)0x00C4001A)
#define LineInterrupt2_A ((volatile uint16_t *)0x00C4001C)
#define LineInterrupt3_A ((volatile uint16_t *)0x00C4001E)
#define LineInterrupt0_A ((volatile unsigned long *)0xFEC40018)
#define LineInterrupt1_A ((volatile unsigned long *)0xFEC4001A)
#define LineInterrupt2_A ((volatile unsigned long *)0xFEC4001C)
#define LineInterrupt3_A ((volatile unsigned long *)0xFEC4001E)
#define MousePointer_Mem_A ((volatile uint16_t *)0x00C40400)
#define MousePtr_A_CTRL_Reg ((volatile uint16_t *)0x00C40C00)
#define FONT_Size_Ctrl_A ((volatile unsigned long *)0xFEC40020)
#define FONT_Count_Ctrl_A ((volatile unsigned long *)0xFEC40024)
#define MousePointer_Mem_A ((volatile unsigned long *)0xFEC40400)
#define MousePtr_A_CTRL_Reg ((volatile unsigned long *)0xFEC40C00)
#define MousePtr_En 0x0001
#define MousePtr_A_X_Pos ((volatile uint16_t *)0x00C40C02)
#define MousePtr_A_Y_Pos ((volatile uint16_t *)0x00C40C04)
#define MousePtr_A_Mouse0 ((volatile uint16_t *)0x00C40C0A)
#define MousePtr_A_Mouse1 ((volatile uint16_t *)0x00C40C0C)
#define MousePtr_A_Mouse2 ((volatile uint16_t *)0x00C40C0E)
#define MousePtr_A_X_Pos ((volatile unsigned long *)0xFEC40C02)
#define MousePtr_A_Y_Pos ((volatile unsigned long *)0xFEC40C04)
#define MousePtr_A_Mouse0 ((volatile unsigned long *)0xFEC40C0A)
#define MousePtr_A_Mouse1 ((volatile unsigned long *)0xFEC40C0C)
#define MousePtr_A_Mouse2 ((volatile unsigned long *)0xFEC40C0E)
#define ScreenText_A ((volatile char *)0x00C60000) /* Text matrix */
#define ColorText_A ((volatile uint8_t *)0x00C68000) /* Color matrix */
#define FG_CLUT_A ((volatile uint16_t *)0x00C6C400) /* Foreground LUT */
#define BG_CLUT_A ((volatile uint16_t *)0x00C6C440) /* Background LUT */
#define ScreenText_A ((volatile char *)0xFEC60000) /* Text matrix */
#define ColorText_A ((volatile uint8_t *)0xFEC68000) /* Color matrix */
#define FG_CLUT_A ((volatile unsigned long *)0xFEC6C400) /* Foreground LUT */
#define BG_CLUT_A ((volatile unsigned long *)0xFEC6C440) /* Background LUT */
/*
* Screen Channel B
*/
#define MasterControlReg_B ((volatile uint32_t *)0x00C80000)
#define BorderControlReg_L_B ((volatile uint32_t *)0x00C80004)
#define BorderControlReg_H_B ((volatile uint32_t *)0x00C80008)
#define BackGroundControlReg_B ((volatile uint32_t *)0x00C8000C)
#define CursorControlReg_L_B ((volatile uint32_t *)0x00C80010)
#define CursorControlReg_H_B ((volatile uint32_t *)0x00C80014)
#define MasterControlReg_B ((volatile unsigned long *)0xFEC80000)
#define BorderControlReg_L_B ((volatile unsigned long *)0xFEC80004)
#define BorderControlReg_H_B ((volatile unsigned long *)0xFEC80008)
#define BackGroundControlReg_B ((volatile unsigned long *)0xFEC8000C)
#define CursorControlReg_L_B ((volatile unsigned long *)0xFEC80010)
#define CursorControlReg_H_B ((volatile unsigned long *)0xFEC80014)
#define LineInterrupt0_B ((volatile uint16_t *)0x00C80018)
#define LineInterrupt1_B ((volatile uint16_t *)0x00C8001A)
#define LineInterrupt2_B ((volatile uint16_t *)0x00C8001C)
#define LineInterrupt3_B ((volatile uint16_t *)0x00C8001E)
#define LineInterrupt0_B ((volatile unsigned long *)0xFEC80018)
#define LineInterrupt1_B ((volatile unsigned long *)0xFEC8001A)
#define LineInterrupt2_B ((volatile unsigned long *)0xFEC8001C)
#define LineInterrupt3_B ((volatile unsigned long *)0xFEC8001E)
#define MousePointer_Mem_B ((volatile uint16_t *)0x00C80400)
#define MousePtr_B_CTRL_Reg ((volatile uint16_t *)0x00C80C00)
#define MousePointer_Mem_B ((volatile unsigned long *)0xFEC80400)
#define MousePtr_B_CTRL_Reg ((volatile unsigned long *)0xFEC80C00)
#define MousePtr_B_X_Pos ((volatile uint16_t *)0x00C80C02)
#define MousePtr_B_Y_Pos ((volatile uint16_t *)0x00C80C04)
#define MousePtr_B_Mouse0 ((volatile uint16_t *)0x00C80C0A)
#define MousePtr_B_Mouse1 ((volatile uint16_t *)0x00C80C0C)
#define MousePtr_B_Mouse2 ((volatile uint16_t *)0x00C80C0E)
#define MousePtr_B_X_Pos ((volatile unsigned long *)0xFEC80C02)
#define MousePtr_B_Y_Pos ((volatile unsigned long *)0xFEC80C04)
#define MousePtr_B_Mouse0 ((volatile unsigned long *)0xFEC80C0A)
#define MousePtr_B_Mouse1 ((volatile unsigned long *)0xFEC80C0C)
#define MousePtr_B_Mouse2 ((volatile unsigned long *)0xFEC80C0E)
#define ScreenText_B ((volatile char *)0x00CA0000) /* Text matrix */
#define ColorText_B ((volatile uint8_t *)0x00CA8000) /* Color matrix */
#define FG_CLUT_B ((volatile uint16_t *)0x00CAC400) /* Foreground LUT */
#define BG_CLUT_B ((volatile uint16_t *)0x00CAC440) /* Background LUT */
#define ScreenText_B ((volatile char *)0xFECA0000) /* Text matrix */
#define ColorText_B ((volatile uint8_t *)0xFECA8000) /* Color matrix */
#define FG_CLUT_B ((volatile unsigned long *)0xFECAC400) /* Foreground LUT */
#define BG_CLUT_B ((volatile unsigned long *)0xFECAC440) /* Background LUT */
#define BM0_Control_Reg ((volatile uint16_t *)0x00C80100)
#define BM0_Addy_Pointer_Reg ((volatile uint16_t *)0x00C80104)
#define BM0_Control_Reg ((volatile unsigned long *)0xFEC80100)
#define BM0_Addy_Pointer_Reg ((volatile unsigned long *)0xFEC80104)
#define Sprite_0_CTRL ((volatile uint16_t *)0x00C81000)
#define Sprite_0_ADDY_HI ((volatile uint16_t *)0x00C81002)
#define Sprite_0_POS_X ((volatile uint16_t *)0x00C81004)
#define Sprite_0_POS_Y ((volatile uint16_t *)0x00C81006)
#define Sprite_0_CTRL ((volatile unsigned long *)0xFEC81000)
#define Sprite_0_ADDY_HI ((volatile unsigned long *)0xFEC81002)
#define Sprite_0_POS_X ((volatile unsigned long *)0xFEC81004)
#define Sprite_0_POS_Y ((volatile unsigned long *)0xFEC81006)
/*
* Color lookup tables
*/
#define LUT_0 ((volatile uint8_t *)0x00C82000)
#define LUT_1 ((volatile uint8_t *)0x00C82400)
#define LUT_2 ((volatile uint8_t *)0x00C82800)
#define LUT_3 ((volatile uint8_t *)0x00C82C00)
#define LUT_4 ((volatile uint8_t *)0x00C83000)
#define LUT_5 ((volatile uint8_t *)0x00C83400)
#define LUT_6 ((volatile uint8_t *)0x00C83800)
#define LUT_7 ((volatile uint8_t *)0x00C83C00)
#define LUT_0 ((volatile uint8_t *)0xFEC82000)
#define LUT_1 ((volatile uint8_t *)0xFEC82400)
#define LUT_2 ((volatile uint8_t *)0xFEC82800)
#define LUT_3 ((volatile uint8_t *)0xFEC82C00)
#define LUT_4 ((volatile uint8_t *)0xFEC83000)
#define LUT_5 ((volatile uint8_t *)0xFEC83400)
#define LUT_6 ((volatile uint8_t *)0xFEC83800)
#define LUT_7 ((volatile uint8_t *)0xFEC83C00)
/*
* Text mode font memory
*/
#define VICKY_TXT_FONT_A ((volatile unsigned char *)0x00C48000) /* $00C48000..$00C48FFF - FONT MEMORY Channel A */
#define VICKY_TXT_FONT_B ((volatile unsigned char *)0x00C88000) /* $00C88000..$00C88FFF - FONT MEMORY Channel B */
#define VICKY_TXT_FONT_A ((volatile unsigned char *)0xFEC48000) /* $00C48000..$00C48FFF - FONT MEMORY Channel A */
#define VICKY_TXT_FONT_B ((volatile unsigned char *)0xFEC88000) /* $00C88000..$00C88FFF - FONT MEMORY Channel B */
/*
* Location of VRAM

496
src/include/A2560K/YM2151.h Normal file
View file

@ -0,0 +1,496 @@
#ifndef YM2151_H_ /* Include guard */
#define YM2151_H_
//;--------------------------------------------------------------------------------------
//;--------------------------------------------------------------------------------------
//;--------------------------------------------------------------------------------------
// External OPM
unsigned char * EXT_OPM_01_TEST = (void *) 0xFEC20601;
unsigned char * EXT_OPM_08_KEY_ON_OFF = (void *) 0xFEC20608;
unsigned char * EXT_OPM_0F_NE_NFREQ = (void *) 0xFEC2060F;
unsigned char * EXT_OPM_10_CLK_A1 = (void *) 0xFEC20610;
unsigned char * EXT_OPM_11_CLK_A2 = (void *) 0xFEC20611;
unsigned char * EXT_OPM_12_CLK_B = (void *) 0xFEC20612;
unsigned char * EXT_OPM_14_CMS_FLAG_RST_IRQEN_LD = (void *) 0xFEC20614;
unsigned char * EXT_OPM_18_LFRQ = (void *) 0xFEC20618;
unsigned char * EXT_OPM_19_PMD_AMD = (void *) 0xFEC20619;
unsigned char * EXT_OPM_1B_CT_W = (void *) 0xFEC2061B;
unsigned char * EXT_OPM_20_A_RL_FR_CONNECT = (void *) 0xFEC20620;
unsigned char * EXT_OPM_21_B_RL_FR_CONNECT = (void *) 0xFEC20621;
unsigned char * EXT_OPM_22_C_RL_FR_CONNECT = (void *) 0xFEC20622;
unsigned char * EXT_OPM_23_D_RL_FR_CONNECT = (void *) 0xFEC20623;
unsigned char * EXT_OPM_24_E_RL_FR_CONNECT = (void *) 0xFEC20624;
unsigned char * EXT_OPM_25_F_RL_FR_CONNECT = (void *) 0xFEC20625;
unsigned char * EXT_OPM_26_G_RL_FR_CONNECT = (void *) 0xFEC20626;
unsigned char * EXT_OPM_27_H_RL_FR_CONNECT = (void *) 0xFEC20627;
unsigned char * EXT_OPM_28_A_KC = (void *) 0xFEC20628;
unsigned char * EXT_OPM_29_B_KC = (void *) 0xFEC20629;
unsigned char * EXT_OPM_2A_C_KC = (void *) 0xFEC2062A;
unsigned char * EXT_OPM_2B_D_KC = (void *) 0xFEC2062B;
unsigned char * EXT_OPM_2C_E_KC = (void *) 0xFEC2062C;
unsigned char * EXT_OPM_2D_F_KC = (void *) 0xFEC2062D;
unsigned char * EXT_OPM_2E_G_KC = (void *) 0xFEC2062E;
unsigned char * EXT_OPM_2F_H_KC = (void *) 0xFEC2062F;
unsigned char * EXT_OPM_30_A_KF = (void *) 0xFEC20630;
unsigned char * EXT_OPM_31_B_KF = (void *) 0xFEC20631;
unsigned char * EXT_OPM_32_C_KF = (void *) 0xFEC20632;
unsigned char * EXT_OPM_33_D_KF = (void *) 0xFEC20633;
unsigned char * EXT_OPM_34_E_KF = (void *) 0xFEC20634;
unsigned char * EXT_OPM_35_F_KF = (void *) 0xFEC20635;
unsigned char * EXT_OPM_36_G_KF = (void *) 0xFEC20636;
unsigned char * EXT_OPM_37_H_KF = (void *) 0xFEC20637;
unsigned char * EXT_OPM_38_A_PMS_AMS = (void *) 0xFEC20638;
unsigned char * EXT_OPM_39_B_PMS_AMS = (void *) 0xFEC20639;
unsigned char * EXT_OPM_3A_C_PMS_AMS = (void *) 0xFEC2063A;
unsigned char * EXT_OPM_3B_D_PMS_AMS = (void *) 0xFEC2063B;
unsigned char * EXT_OPM_3C_E_PMS_AMS = (void *) 0xFEC2063C;
unsigned char * EXT_OPM_3D_F_PMS_AMS = (void *) 0xFEC2063D;
unsigned char * EXT_OPM_3E_G_PMS_AMS = (void *) 0xFEC2063E;
unsigned char * EXT_OPM_3F_H_PMS_AMS = (void *) 0xFEC2063F;
unsigned char * EXT_OPM_40_A_M1_DT1_MUL = (void *) 0xFEC20640;
unsigned char * EXT_OPM_41_B_M1_DT1_MUL = (void *) 0xFEC20641;
unsigned char * EXT_OPM_42_C_M1_DT1_MUL = (void *) 0xFEC20642;
unsigned char * EXT_OPM_43_D_M1_DT1_MUL = (void *) 0xFEC20643;
unsigned char * EXT_OPM_44_E_M1_DT1_MUL = (void *) 0xFEC20644;
unsigned char * EXT_OPM_45_F_M1_DT1_MUL = (void *) 0xFEC20645;
unsigned char * EXT_OPM_46_G_M1_DT1_MUL = (void *) 0xFEC20646;
unsigned char * EXT_OPM_47_H_M1_DT1_MUL = (void *) 0xFEC20647;
unsigned char * EXT_OPM_48_A_M2_DT1_MUL = (void *) 0xFEC20648;
unsigned char * EXT_OPM_49_B_M2_DT1_MUL = (void *) 0xFEC20649;
unsigned char * EXT_OPM_4A_C_M2_DT1_MUL = (void *) 0xFEC2064A;
unsigned char * EXT_OPM_4B_D_M2_DT1_MUL = (void *) 0xFEC2064B;
unsigned char * EXT_OPM_4C_E_M2_DT1_MUL = (void *) 0xFEC2064C;
unsigned char * EXT_OPM_4D_F_M2_DT1_MUL = (void *) 0xFEC2064D;
unsigned char * EXT_OPM_4E_G_M2_DT1_MUL = (void *) 0xFEC2064E;
unsigned char * EXT_OPM_4F_H_M2_DT1_MUL = (void *) 0xFEC2064F;
unsigned char * EXT_OPM_50_A_C1_DT1_MUL = (void *) 0xFEC20650;
unsigned char * EXT_OPM_51_B_C1_DT1_MUL = (void *) 0xFEC20651;
unsigned char * EXT_OPM_52_C_C1_DT1_MUL = (void *) 0xFEC20652;
unsigned char * EXT_OPM_53_D_C1_DT1_MUL = (void *) 0xFEC20653;
unsigned char * EXT_OPM_54_E_C1_DT1_MUL = (void *) 0xFEC20654;
unsigned char * EXT_OPM_55_F_C1_DT1_MUL = (void *) 0xFEC20655;
unsigned char * EXT_OPM_56_G_C1_DT1_MUL = (void *) 0xFEC20656;
unsigned char * EXT_OPM_57_H_C1_DT1_MUL = (void *) 0xFEC20657;
unsigned char * EXT_OPM_58_A_C2_DT1_MUL = (void *) 0xFEC20658;
unsigned char * EXT_OPM_59_B_C2_DT1_MUL = (void *) 0xFEC20659;
unsigned char * EXT_OPM_5A_C_C2_DT1_MUL = (void *) 0xFEC2065A;
unsigned char * EXT_OPM_5B_D_C2_DT1_MUL = (void *) 0xFEC2065B;
unsigned char * EXT_OPM_5C_E_C2_DT1_MUL = (void *) 0xFEC2065C;
unsigned char * EXT_OPM_5D_F_C2_DT1_MUL = (void *) 0xFEC2065D;
unsigned char * EXT_OPM_5E_G_C2_DT1_MUL = (void *) 0xFEC2065E;
unsigned char * EXT_OPM_5F_H_C2_DT1_MUL = (void *) 0xFEC2065F;
unsigned char * EXT_OPM_60_A_M1_TL = (void *) 0xFEC20660;
unsigned char * EXT_OPM_61_B_M1_TL = (void *) 0xFEC20661;
unsigned char * EXT_OPM_62_C_M1_TL = (void *) 0xFEC20662;
unsigned char * EXT_OPM_63_D_M1_TL = (void *) 0xFEC20663;
unsigned char * EXT_OPM_64_E_M1_TL = (void *) 0xFEC20664;
unsigned char * EXT_OPM_65_F_M1_TL = (void *) 0xFEC20665;
unsigned char * EXT_OPM_66_G_M1_TL = (void *) 0xFEC20666;
unsigned char * EXT_OPM_67_H_M1_TL = (void *) 0xFEC20667;
unsigned char * EXT_OPM_68_A_M2_TL = (void *) 0xFEC20668;
unsigned char * EXT_OPM_69_B_M2_TL = (void *) 0xFEC20669;
unsigned char * EXT_OPM_6A_C_M2_TL = (void *) 0xFEC2066A;
unsigned char * EXT_OPM_6B_D_M2_TL = (void *) 0xFEC2066B;
unsigned char * EXT_OPM_6C_E_M2_TL = (void *) 0xFEC2066C;
unsigned char * EXT_OPM_6D_F_M2_TL = (void *) 0xFEC2066D;
unsigned char * EXT_OPM_6E_G_M2_TL = (void *) 0xFEC2066E;
unsigned char * EXT_OPM_6F_H_M2_TL = (void *) 0xFEC2066F;
unsigned char * EXT_OPM_70_A_C1_TL = (void *) 0xFEC20670;
unsigned char * EXT_OPM_71_B_C1_TL = (void *) 0xFEC20671;
unsigned char * EXT_OPM_72_C_C1_TL = (void *) 0xFEC20672;
unsigned char * EXT_OPM_73_D_C1_TL = (void *) 0xFEC20673;
unsigned char * EXT_OPM_74_E_C1_TL = (void *) 0xFEC20674;
unsigned char * EXT_OPM_75_F_C1_TL = (void *) 0xFEC20675;
unsigned char * EXT_OPM_76_G_C1_TL = (void *) 0xFEC20676;
unsigned char * EXT_OPM_77_H_C1_TL = (void *) 0xFEC20677;
unsigned char * EXT_OPM_78_A_C2_TL = (void *) 0xFEC20678;
unsigned char * EXT_OPM_79_B_C2_TL = (void *) 0xFEC20679;
unsigned char * EXT_OPM_7A_C_C2_TL = (void *) 0xFEC2067A;
unsigned char * EXT_OPM_7B_D_C2_TL = (void *) 0xFEC2067B;
unsigned char * EXT_OPM_7C_E_C2_TL = (void *) 0xFEC2067C;
unsigned char * EXT_OPM_7D_F_C2_TL = (void *) 0xFEC2067D;
unsigned char * EXT_OPM_7E_G_C2_TL = (void *) 0xFEC2067E;
unsigned char * EXT_OPM_7F_H_C2_TL = (void *) 0xFEC2067F;
unsigned char * EXT_OPM_80_A_M1_KS_AR = (void *) 0xFEC20680;
unsigned char * EXT_OPM_81_B_M1_KS_AR = (void *) 0xFEC20681;
unsigned char * EXT_OPM_82_C_M1_KS_AR = (void *) 0xFEC20682;
unsigned char * EXT_OPM_83_D_M1_KS_AR = (void *) 0xFEC20683;
unsigned char * EXT_OPM_84_E_M1_KS_AR = (void *) 0xFEC20684;
unsigned char * EXT_OPM_85_F_M1_KS_AR = (void *) 0xFEC20685;
unsigned char * EXT_OPM_86_G_M1_KS_AR = (void *) 0xFEC20686;
unsigned char * EXT_OPM_87_H_M1_KS_AR = (void *) 0xFEC20687;
unsigned char * EXT_OPM_88_A_M2_KS_AR = (void *) 0xFEC20688;
unsigned char * EXT_OPM_89_B_M2_KS_AR = (void *) 0xFEC20689;
unsigned char * EXT_OPM_8A_C_M2_KS_AR = (void *) 0xFEC2068A;
unsigned char * EXT_OPM_8B_D_M2_KS_AR = (void *) 0xFEC2068B;
unsigned char * EXT_OPM_8C_E_M2_KS_AR = (void *) 0xFEC2068C;
unsigned char * EXT_OPM_8D_F_M2_KS_AR = (void *) 0xFEC2068D;
unsigned char * EXT_OPM_8E_G_M2_KS_AR = (void *) 0xFEC2068E;
unsigned char * EXT_OPM_8F_H_M2_KS_AR = (void *) 0xFEC2068F;
unsigned char * EXT_OPM_90_A_C1_KS_AR = (void *) 0xFEC20690;
unsigned char * EXT_OPM_91_B_C1_KS_AR = (void *) 0xFEC20691;
unsigned char * EXT_OPM_92_C_C1_KS_AR = (void *) 0xFEC20692;
unsigned char * EXT_OPM_93_D_C1_KS_AR = (void *) 0xFEC20693;
unsigned char * EXT_OPM_94_E_C1_KS_AR = (void *) 0xFEC20694;
unsigned char * EXT_OPM_95_F_C1_KS_AR = (void *) 0xFEC20695;
unsigned char * EXT_OPM_96_G_C1_KS_AR = (void *) 0xFEC20696;
unsigned char * EXT_OPM_97_H_C1_KS_AR = (void *) 0xFEC20697;
unsigned char * EXT_OPM_98_A_C2_KS_AR = (void *) 0xFEC20698;
unsigned char * EXT_OPM_99_B_C2_KS_AR = (void *) 0xFEC20699;
unsigned char * EXT_OPM_9A_C_C2_KS_AR = (void *) 0xFEC2069A;
unsigned char * EXT_OPM_9B_D_C2_KS_AR = (void *) 0xFEC2069B;
unsigned char * EXT_OPM_9C_E_C2_KS_AR = (void *) 0xFEC2069C;
unsigned char * EXT_OPM_9D_F_C2_KS_AR = (void *) 0xFEC2069D;
unsigned char * EXT_OPM_9E_G_C2_KS_AR = (void *) 0xFEC2069E;
unsigned char * EXT_OPM_9F_H_C2_KS_AR = (void *) 0xFEC2069F;
unsigned char * EXT_OPM_A0_A_M1_AMS_EN_D1R = (void *) 0xFEC206A0;
unsigned char * EXT_OPM_A1_B_M1_AMS_EN_D1R = (void *) 0xFEC206A1;
unsigned char * EXT_OPM_A2_C_M1_AMS_EN_D1R = (void *) 0xFEC206A2;
unsigned char * EXT_OPM_A3_D_M1_AMS_EN_D1R = (void *) 0xFEC206A3;
unsigned char * EXT_OPM_A4_E_M1_AMS_EN_D1R = (void *) 0xFEC206A4;
unsigned char * EXT_OPM_A5_F_M1_AMS_EN_D1R = (void *) 0xFEC206A5;
unsigned char * EXT_OPM_A6_G_M1_AMS_EN_D1R = (void *) 0xFEC206A6;
unsigned char * EXT_OPM_A7_H_M1_AMS_EN_D1R = (void *) 0xFEC206A7;
unsigned char * EXT_OPM_A8_A_M2_AMS_EN_D1R = (void *) 0xFEC206A8;
unsigned char * EXT_OPM_A9_B_M2_AMS_EN_D1R = (void *) 0xFEC206A9;
unsigned char * EXT_OPM_AA_C_M2_AMS_EN_D1R = (void *) 0xFEC206AA;
unsigned char * EXT_OPM_AB_D_M2_AMS_EN_D1R = (void *) 0xFEC206AB;
unsigned char * EXT_OPM_AC_E_M2_AMS_EN_D1R = (void *) 0xFEC206AC;
unsigned char * EXT_OPM_AD_F_M2_AMS_EN_D1R = (void *) 0xFEC206AD;
unsigned char * EXT_OPM_AE_G_M2_AMS_EN_D1R = (void *) 0xFEC206AE;
unsigned char * EXT_OPM_AF_H_M2_AMS_EN_D1R = (void *) 0xFEC206AF;
unsigned char * EXT_OPM_B0_A_C1_AMS_EN_D1R = (void *) 0xFEC206B0;
unsigned char * EXT_OPM_B1_B_C1_AMS_EN_D1R = (void *) 0xFEC206B1;
unsigned char * EXT_OPM_B2_C_C1_AMS_EN_D1R = (void *) 0xFEC206B2;
unsigned char * EXT_OPM_B3_D_C1_AMS_EN_D1R = (void *) 0xFEC206B3;
unsigned char * EXT_OPM_B4_E_C1_AMS_EN_D1R = (void *) 0xFEC206B4;
unsigned char * EXT_OPM_B5_F_C1_AMS_EN_D1R = (void *) 0xFEC206B5;
unsigned char * EXT_OPM_B6_G_C1_AMS_EN_D1R = (void *) 0xFEC206B6;
unsigned char * EXT_OPM_B7_H_C1_AMS_EN_D1R = (void *) 0xFEC206B7;
unsigned char * EXT_OPM_B8_A_C2_AMS_EN_D1R = (void *) 0xFEC206B8;
unsigned char * EXT_OPM_B9_B_C2_AMS_EN_D1R = (void *) 0xFEC206B9;
unsigned char * EXT_OPM_BA_C_C2_AMS_EN_D1R = (void *) 0xFEC206BA;
unsigned char * EXT_OPM_BB_D_C2_AMS_EN_D1R = (void *) 0xFEC206BB;
unsigned char * EXT_OPM_BC_E_C2_AMS_EN_D1R = (void *) 0xFEC206BC;
unsigned char * EXT_OPM_BD_F_C2_AMS_EN_D1R = (void *) 0xFEC206BD;
unsigned char * EXT_OPM_BE_G_C2_AMS_EN_D1R = (void *) 0xFEC206BE;
unsigned char * EXT_OPM_BF_H_C2_AMS_EN_D1R = (void *) 0xFEC206BF;
unsigned char * EXT_OPM_C0_A_M1_DT2_D2R = (void *) 0xFEC206C0;
unsigned char * EXT_OPM_C1_B_M1_DT2_D2R = (void *) 0xFEC206C1;
unsigned char * EXT_OPM_C2_C_M1_DT2_D2R = (void *) 0xFEC206C2;
unsigned char * EXT_OPM_C3_D_M1_DT2_D2R = (void *) 0xFEC206C3;
unsigned char * EXT_OPM_C4_E_M1_DT2_D2R = (void *) 0xFEC206C4;
unsigned char * EXT_OPM_C5_F_M1_DT2_D2R = (void *) 0xFEC206C5;
unsigned char * EXT_OPM_C6_G_M1_DT2_D2R = (void *) 0xFEC206C6;
unsigned char * EXT_OPM_C7_H_M1_DT2_D2R = (void *) 0xFEC206C7;
unsigned char * EXT_OPM_C8_A_M2_DT2_D2R = (void *) 0xFEC206C8;
unsigned char * EXT_OPM_C9_B_M2_DT2_D2R = (void *) 0xFEC206C9;
unsigned char * EXT_OPM_CA_C_M2_DT2_D2R = (void *) 0xFEC206CA;
unsigned char * EXT_OPM_CB_D_M2_DT2_D2R = (void *) 0xFEC206CB;
unsigned char * EXT_OPM_CC_E_M2_DT2_D2R = (void *) 0xFEC206CC;
unsigned char * EXT_OPM_CD_F_M2_DT2_D2R = (void *) 0xFEC206CD;
unsigned char * EXT_OPM_CE_G_M2_DT2_D2R = (void *) 0xFEC206CE;
unsigned char * EXT_OPM_CF_H_M2_DT2_D2R = (void *) 0xFEC206CF;
unsigned char * EXT_OPM_D0_A_C1_DT2_D2R = (void *) 0xFEC206D0;
unsigned char * EXT_OPM_D1_B_C1_DT2_D2R = (void *) 0xFEC206D1;
unsigned char * EXT_OPM_D2_C_C1_DT2_D2R = (void *) 0xFEC206D2;
unsigned char * EXT_OPM_D3_D_C1_DT2_D2R = (void *) 0xFEC206D3;
unsigned char * EXT_OPM_D4_E_C1_DT2_D2R = (void *) 0xFEC206D4;
unsigned char * EXT_OPM_D5_F_C1_DT2_D2R = (void *) 0xFEC206D5;
unsigned char * EXT_OPM_D6_G_C1_DT2_D2R = (void *) 0xFEC206D6;
unsigned char * EXT_OPM_D7_H_C1_DT2_D2R = (void *) 0xFEC206D7;
unsigned char * EXT_OPM_D8_A_C2_DT2_D2R = (void *) 0xFEC206D8;
unsigned char * EXT_OPM_D9_B_C2_DT2_D2R = (void *) 0xFEC206D9;
unsigned char * EXT_OPM_DA_C_C2_DT2_D2R = (void *) 0xFEC206DA;
unsigned char * EXT_OPM_DB_D_C2_DT2_D2R = (void *) 0xFEC206DB;
unsigned char * EXT_OPM_DC_E_C2_DT2_D2R = (void *) 0xFEC206DC;
unsigned char * EXT_OPM_DD_F_C2_DT2_D2R = (void *) 0xFEC206DD;
unsigned char * EXT_OPM_DE_G_C2_DT2_D2R = (void *) 0xFEC206DE;
unsigned char * EXT_OPM_DF_H_C2_DT2_D2R = (void *) 0xFEC206DF;
unsigned char * EXT_OPM_E0_A_M1_D1L_RR = (void *) 0xFEC206E0;
unsigned char * EXT_OPM_E1_B_M1_D1L_RR = (void *) 0xFEC206E1;
unsigned char * EXT_OPM_E2_C_M1_D1L_RR = (void *) 0xFEC206E2;
unsigned char * EXT_OPM_E3_D_M1_D1L_RR = (void *) 0xFEC206E3;
unsigned char * EXT_OPM_E4_E_M1_D1L_RR = (void *) 0xFEC206E4;
unsigned char * EXT_OPM_E5_F_M1_D1L_RR = (void *) 0xFEC206E5;
unsigned char * EXT_OPM_E6_G_M1_D1L_RR = (void *) 0xFEC206E6;
unsigned char * EXT_OPM_E7_H_M1_D1L_RR = (void *) 0xFEC206E7;
unsigned char * EXT_OPM_E8_A_M2_D1L_RR = (void *) 0xFEC206E8;
unsigned char * EXT_OPM_E9_B_M2_D1L_RR = (void *) 0xFEC206E9;
unsigned char * EXT_OPM_EA_C_M2_D1L_RR = (void *) 0xFEC206EA;
unsigned char * EXT_OPM_EB_D_M2_D1L_RR = (void *) 0xFEC206EB;
unsigned char * EXT_OPM_EC_E_M2_D1L_RR = (void *) 0xFEC206EC;
unsigned char * EXT_OPM_ED_F_M2_D1L_RR = (void *) 0xFEC206ED;
unsigned char * EXT_OPM_EE_G_M2_D1L_RR = (void *) 0xFEC206EE;
unsigned char * EXT_OPM_EF_H_M2_D1L_RR = (void *) 0xFEC206EF;
unsigned char * EXT_OPM_F0_A_C1_D1L_RR = (void *) 0xFEC206F0;
unsigned char * EXT_OPM_F1_B_C1_D1L_RR = (void *) 0xFEC206F1;
unsigned char * EXT_OPM_F2_C_C1_D1L_RR = (void *) 0xFEC206F2;
unsigned char * EXT_OPM_F3_D_C1_D1L_RR = (void *) 0xFEC206F3;
unsigned char * EXT_OPM_F4_E_C1_D1L_RR = (void *) 0xFEC206F4;
unsigned char * EXT_OPM_F5_F_C1_D1L_RR = (void *) 0xFEC206F5;
unsigned char * EXT_OPM_F6_G_C1_D1L_RR = (void *) 0xFEC206F6;
unsigned char * EXT_OPM_F7_H_C1_D1L_RR = (void *) 0xFEC206F7;
unsigned char * EXT_OPM_F8_A_C2_D1L_RR = (void *) 0xFEC206F8;
unsigned char * EXT_OPM_F9_B_C2_D1L_RR = (void *) 0xFEC206F9;
unsigned char * EXT_OPM_FA_C_C2_D1L_RR = (void *) 0xFEC206FA;
unsigned char * EXT_OPM_FB_D_C2_D1L_RR = (void *) 0xFEC206FB;
unsigned char * EXT_OPM_FC_E_C2_D1L_RR = (void *) 0xFEC206FC;
unsigned char * EXT_OPM_FD_F_C2_D1L_RR = (void *) 0xFEC206FD;
unsigned char * EXT_OPM_FE_G_C2_D1L_RR = (void *) 0xFEC206FE;
unsigned char * EXT_OPM_FF_H_C2_D1L_RR = (void *) 0xFEC206FF;
///////////////////////////////////////////////////
// Internal OPM 0xFEC20C00
unsigned char * INT_OPM_01_TEST = (void *) 0xFEC20C01;
unsigned char * INT_OPM_08_KEY_ON_OFF = (void *) 0xFEC20C08;
unsigned char * INT_OPM_0F_NE_NFREQ = (void *) 0xFEC20C0F;
unsigned char * INT_OPM_10_CLK_A1 = (void *) 0xFEC20C10;
unsigned char * INT_OPM_11_CLK_A2 = (void *) 0xFEC20C11;
unsigned char * INT_OPM_12_CLK_B = (void *) 0xFEC20C12;
unsigned char * INT_OPM_14_CMS_FLAG_RST_IRQEN_LD = (void *) 0xFEC20C14;
unsigned char * INT_OPM_18_LFRQ = (void *) 0xFEC20C18;
unsigned char * INT_OPM_19_PMD_AMD = (void *) 0xFEC20C19;
unsigned char * INT_OPM_1B_CT_W = (void *) 0xFEC20C1B;
unsigned char * INT_OPM_20_A_RL_FR_CONNECT = (void *) 0xFEC20C20;
unsigned char * INT_OPM_21_B_RL_FR_CONNECT = (void *) 0xFEC20C21;
unsigned char * INT_OPM_22_C_RL_FR_CONNECT = (void *) 0xFEC20C22;
unsigned char * INT_OPM_23_D_RL_FR_CONNECT = (void *) 0xFEC20C23;
unsigned char * INT_OPM_24_E_RL_FR_CONNECT = (void *) 0xFEC20C24;
unsigned char * INT_OPM_25_F_RL_FR_CONNECT = (void *) 0xFEC20C25;
unsigned char * INT_OPM_26_G_RL_FR_CONNECT = (void *) 0xFEC20C26;
unsigned char * INT_OPM_27_H_RL_FR_CONNECT = (void *) 0xFEC20C27;
unsigned char * INT_OPM_28_A_KC = (void *) 0xFEC20C28;
unsigned char * INT_OPM_29_B_KC = (void *) 0xFEC20C29;
unsigned char * INT_OPM_2A_C_KC = (void *) 0xFEC20C2A;
unsigned char * INT_OPM_2B_D_KC = (void *) 0xFEC20C2B;
unsigned char * INT_OPM_2C_E_KC = (void *) 0xFEC20C2C;
unsigned char * INT_OPM_2D_F_KC = (void *) 0xFEC20C2D;
unsigned char * INT_OPM_2E_G_KC = (void *) 0xFEC20C2E;
unsigned char * INT_OPM_2F_H_KC = (void *) 0xFEC20C2F;
unsigned char * INT_OPM_30_A_KF = (void *) 0xFEC20C30;
unsigned char * INT_OPM_31_B_KF = (void *) 0xFEC20C31;
unsigned char * INT_OPM_32_C_KF = (void *) 0xFEC20C32;
unsigned char * INT_OPM_33_D_KF = (void *) 0xFEC20C33;
unsigned char * INT_OPM_34_E_KF = (void *) 0xFEC20C34;
unsigned char * INT_OPM_35_F_KF = (void *) 0xFEC20C35;
unsigned char * INT_OPM_36_G_KF = (void *) 0xFEC20C36;
unsigned char * INT_OPM_37_H_KF = (void *) 0xFEC20C37;
unsigned char * INT_OPM_38_A_PMS_AMS = (void *) 0xFEC20C38;
unsigned char * INT_OPM_39_B_PMS_AMS = (void *) 0xFEC20C39;
unsigned char * INT_OPM_3A_C_PMS_AMS = (void *) 0xFEC20C3A;
unsigned char * INT_OPM_3B_D_PMS_AMS = (void *) 0xFEC20C3B;
unsigned char * INT_OPM_3C_E_PMS_AMS = (void *) 0xFEC20C3C;
unsigned char * INT_OPM_3D_F_PMS_AMS = (void *) 0xFEC20C3D;
unsigned char * INT_OPM_3E_G_PMS_AMS = (void *) 0xFEC20C3E;
unsigned char * INT_OPM_3F_H_PMS_AMS = (void *) 0xFEC20C3F;
unsigned char * INT_OPM_40_A_M1_DT1_MUL = (void *) 0xFEC20C40;
unsigned char * INT_OPM_41_B_M1_DT1_MUL = (void *) 0xFEC20C41;
unsigned char * INT_OPM_42_C_M1_DT1_MUL = (void *) 0xFEC20C42;
unsigned char * INT_OPM_43_D_M1_DT1_MUL = (void *) 0xFEC20C43;
unsigned char * INT_OPM_44_E_M1_DT1_MUL = (void *) 0xFEC20C44;
unsigned char * INT_OPM_45_F_M1_DT1_MUL = (void *) 0xFEC20C45;
unsigned char * INT_OPM_46_G_M1_DT1_MUL = (void *) 0xFEC20C46;
unsigned char * INT_OPM_47_H_M1_DT1_MUL = (void *) 0xFEC20C47;
unsigned char * INT_OPM_48_A_M2_DT1_MUL = (void *) 0xFEC20C48;
unsigned char * INT_OPM_49_B_M2_DT1_MUL = (void *) 0xFEC20C49;
unsigned char * INT_OPM_4A_C_M2_DT1_MUL = (void *) 0xFEC20C4A;
unsigned char * INT_OPM_4B_D_M2_DT1_MUL = (void *) 0xFEC20C4B;
unsigned char * INT_OPM_4C_E_M2_DT1_MUL = (void *) 0xFEC20C4C;
unsigned char * INT_OPM_4D_F_M2_DT1_MUL = (void *) 0xFEC20C4D;
unsigned char * INT_OPM_4E_G_M2_DT1_MUL = (void *) 0xFEC20C4E;
unsigned char * INT_OPM_4F_H_M2_DT1_MUL = (void *) 0xFEC20C4F;
unsigned char * INT_OPM_50_A_C1_DT1_MUL = (void *) 0xFEC20C50;
unsigned char * INT_OPM_51_B_C1_DT1_MUL = (void *) 0xFEC20C51;
unsigned char * INT_OPM_52_C_C1_DT1_MUL = (void *) 0xFEC20C52;
unsigned char * INT_OPM_53_D_C1_DT1_MUL = (void *) 0xFEC20C53;
unsigned char * INT_OPM_54_E_C1_DT1_MUL = (void *) 0xFEC20C54;
unsigned char * INT_OPM_55_F_C1_DT1_MUL = (void *) 0xFEC20C55;
unsigned char * INT_OPM_56_G_C1_DT1_MUL = (void *) 0xFEC20C56;
unsigned char * INT_OPM_57_H_C1_DT1_MUL = (void *) 0xFEC20C57;
unsigned char * INT_OPM_58_A_C2_DT1_MUL = (void *) 0xFEC20C58;
unsigned char * INT_OPM_59_B_C2_DT1_MUL = (void *) 0xFEC20C59;
unsigned char * INT_OPM_5A_C_C2_DT1_MUL = (void *) 0xFEC20C5A;
unsigned char * INT_OPM_5B_D_C2_DT1_MUL = (void *) 0xFEC20C5B;
unsigned char * INT_OPM_5C_E_C2_DT1_MUL = (void *) 0xFEC20C5C;
unsigned char * INT_OPM_5D_F_C2_DT1_MUL = (void *) 0xFEC20C5D;
unsigned char * INT_OPM_5E_G_C2_DT1_MUL = (void *) 0xFEC20C5E;
unsigned char * INT_OPM_5F_H_C2_DT1_MUL = (void *) 0xFEC20C5F;
unsigned char * INT_OPM_60_A_M1_TL = (void *) 0xFEC20C60;
unsigned char * INT_OPM_61_B_M1_TL = (void *) 0xFEC20C61;
unsigned char * INT_OPM_62_C_M1_TL = (void *) 0xFEC20C62;
unsigned char * INT_OPM_63_D_M1_TL = (void *) 0xFEC20C63;
unsigned char * INT_OPM_64_E_M1_TL = (void *) 0xFEC20C64;
unsigned char * INT_OPM_65_F_M1_TL = (void *) 0xFEC20C65;
unsigned char * INT_OPM_66_G_M1_TL = (void *) 0xFEC20C66;
unsigned char * INT_OPM_67_H_M1_TL = (void *) 0xFEC20C67;
unsigned char * INT_OPM_68_A_M2_TL = (void *) 0xFEC20C68;
unsigned char * INT_OPM_69_B_M2_TL = (void *) 0xFEC20C69;
unsigned char * INT_OPM_6A_C_M2_TL = (void *) 0xFEC20C6A;
unsigned char * INT_OPM_6B_D_M2_TL = (void *) 0xFEC20C6B;
unsigned char * INT_OPM_6C_E_M2_TL = (void *) 0xFEC20C6C;
unsigned char * INT_OPM_6D_F_M2_TL = (void *) 0xFEC20C6D;
unsigned char * INT_OPM_6E_G_M2_TL = (void *) 0xFEC20C6E;
unsigned char * INT_OPM_6F_H_M2_TL = (void *) 0xFEC20C6F;
unsigned char * INT_OPM_70_A_C1_TL = (void *) 0xFEC20C70;
unsigned char * INT_OPM_71_B_C1_TL = (void *) 0xFEC20C71;
unsigned char * INT_OPM_72_C_C1_TL = (void *) 0xFEC20C72;
unsigned char * INT_OPM_73_D_C1_TL = (void *) 0xFEC20C73;
unsigned char * INT_OPM_74_E_C1_TL = (void *) 0xFEC20C74;
unsigned char * INT_OPM_75_F_C1_TL = (void *) 0xFEC20C75;
unsigned char * INT_OPM_76_G_C1_TL = (void *) 0xFEC20C76;
unsigned char * INT_OPM_77_H_C1_TL = (void *) 0xFEC20C77;
unsigned char * INT_OPM_78_A_C2_TL = (void *) 0xFEC20C78;
unsigned char * INT_OPM_79_B_C2_TL = (void *) 0xFEC20C79;
unsigned char * INT_OPM_7A_C_C2_TL = (void *) 0xFEC20C7A;
unsigned char * INT_OPM_7B_D_C2_TL = (void *) 0xFEC20C7B;
unsigned char * INT_OPM_7C_E_C2_TL = (void *) 0xFEC20C7C;
unsigned char * INT_OPM_7D_F_C2_TL = (void *) 0xFEC20C7D;
unsigned char * INT_OPM_7E_G_C2_TL = (void *) 0xFEC20C7E;
unsigned char * INT_OPM_7F_H_C2_TL = (void *) 0xFEC20C7F;
unsigned char * INT_OPM_80_A_M1_KS_AR = (void *) 0xFEC20C80;
unsigned char * INT_OPM_81_B_M1_KS_AR = (void *) 0xFEC20C81;
unsigned char * INT_OPM_82_C_M1_KS_AR = (void *) 0xFEC20C82;
unsigned char * INT_OPM_83_D_M1_KS_AR = (void *) 0xFEC20C83;
unsigned char * INT_OPM_84_E_M1_KS_AR = (void *) 0xFEC20C84;
unsigned char * INT_OPM_85_F_M1_KS_AR = (void *) 0xFEC20C85;
unsigned char * INT_OPM_86_G_M1_KS_AR = (void *) 0xFEC20C86;
unsigned char * INT_OPM_87_H_M1_KS_AR = (void *) 0xFEC20C87;
unsigned char * INT_OPM_88_A_M2_KS_AR = (void *) 0xFEC20C88;
unsigned char * INT_OPM_89_B_M2_KS_AR = (void *) 0xFEC20C89;
unsigned char * INT_OPM_8A_C_M2_KS_AR = (void *) 0xFEC20C8A;
unsigned char * INT_OPM_8B_D_M2_KS_AR = (void *) 0xFEC20C8B;
unsigned char * INT_OPM_8C_E_M2_KS_AR = (void *) 0xFEC20C8C;
unsigned char * INT_OPM_8D_F_M2_KS_AR = (void *) 0xFEC20C8D;
unsigned char * INT_OPM_8E_G_M2_KS_AR = (void *) 0xFEC20C8E;
unsigned char * INT_OPM_8F_H_M2_KS_AR = (void *) 0xFEC20C8F;
unsigned char * INT_OPM_90_A_C1_KS_AR = (void *) 0xFEC20C90;
unsigned char * INT_OPM_91_B_C1_KS_AR = (void *) 0xFEC20C91;
unsigned char * INT_OPM_92_C_C1_KS_AR = (void *) 0xFEC20C92;
unsigned char * INT_OPM_93_D_C1_KS_AR = (void *) 0xFEC20C93;
unsigned char * INT_OPM_94_E_C1_KS_AR = (void *) 0xFEC20C94;
unsigned char * INT_OPM_95_F_C1_KS_AR = (void *) 0xFEC20C95;
unsigned char * INT_OPM_96_G_C1_KS_AR = (void *) 0xFEC20C96;
unsigned char * INT_OPM_97_H_C1_KS_AR = (void *) 0xFEC20C97;
unsigned char * INT_OPM_98_A_C2_KS_AR = (void *) 0xFEC20C98;
unsigned char * INT_OPM_99_B_C2_KS_AR = (void *) 0xFEC20C99;
unsigned char * INT_OPM_9A_C_C2_KS_AR = (void *) 0xFEC20C9A;
unsigned char * INT_OPM_9B_D_C2_KS_AR = (void *) 0xFEC20C9B;
unsigned char * INT_OPM_9C_E_C2_KS_AR = (void *) 0xFEC20C9C;
unsigned char * INT_OPM_9D_F_C2_KS_AR = (void *) 0xFEC20C9D;
unsigned char * INT_OPM_9E_G_C2_KS_AR = (void *) 0xFEC20C9E;
unsigned char * INT_OPM_9F_H_C2_KS_AR = (void *) 0xFEC20C9F;
unsigned char * INT_OPM_A0_A_M1_AMS_EN_D1R = (void *) 0xFEC20CA0;
unsigned char * INT_OPM_A1_B_M1_AMS_EN_D1R = (void *) 0xFEC20CA1;
unsigned char * INT_OPM_A2_C_M1_AMS_EN_D1R = (void *) 0xFEC20CA2;
unsigned char * INT_OPM_A3_D_M1_AMS_EN_D1R = (void *) 0xFEC20CA3;
unsigned char * INT_OPM_A4_E_M1_AMS_EN_D1R = (void *) 0xFEC20CA4;
unsigned char * INT_OPM_A5_F_M1_AMS_EN_D1R = (void *) 0xFEC20CA5;
unsigned char * INT_OPM_A6_G_M1_AMS_EN_D1R = (void *) 0xFEC20CA6;
unsigned char * INT_OPM_A7_H_M1_AMS_EN_D1R = (void *) 0xFEC20CA7;
unsigned char * INT_OPM_A8_A_M2_AMS_EN_D1R = (void *) 0xFEC20CA8;
unsigned char * INT_OPM_A9_B_M2_AMS_EN_D1R = (void *) 0xFEC20CA9;
unsigned char * INT_OPM_AA_C_M2_AMS_EN_D1R = (void *) 0xFEC20CAA;
unsigned char * INT_OPM_AB_D_M2_AMS_EN_D1R = (void *) 0xFEC20CAB;
unsigned char * INT_OPM_AC_E_M2_AMS_EN_D1R = (void *) 0xFEC20CAC;
unsigned char * INT_OPM_AD_F_M2_AMS_EN_D1R = (void *) 0xFEC20CAD;
unsigned char * INT_OPM_AE_G_M2_AMS_EN_D1R = (void *) 0xFEC20CAE;
unsigned char * INT_OPM_AF_H_M2_AMS_EN_D1R = (void *) 0xFEC20CAF;
unsigned char * INT_OPM_B0_A_C1_AMS_EN_D1R = (void *) 0xFEC20CB0;
unsigned char * INT_OPM_B1_B_C1_AMS_EN_D1R = (void *) 0xFEC20CB1;
unsigned char * INT_OPM_B2_C_C1_AMS_EN_D1R = (void *) 0xFEC20CB2;
unsigned char * INT_OPM_B3_D_C1_AMS_EN_D1R = (void *) 0xFEC20CB3;
unsigned char * INT_OPM_B4_E_C1_AMS_EN_D1R = (void *) 0xFEC20CB4;
unsigned char * INT_OPM_B5_F_C1_AMS_EN_D1R = (void *) 0xFEC20CB5;
unsigned char * INT_OPM_B6_G_C1_AMS_EN_D1R = (void *) 0xFEC20CB6;
unsigned char * INT_OPM_B7_H_C1_AMS_EN_D1R = (void *) 0xFEC20CB7;
unsigned char * INT_OPM_B8_A_C2_AMS_EN_D1R = (void *) 0xFEC20CB8;
unsigned char * INT_OPM_B9_B_C2_AMS_EN_D1R = (void *) 0xFEC20CB9;
unsigned char * INT_OPM_BA_C_C2_AMS_EN_D1R = (void *) 0xFEC20CBA;
unsigned char * INT_OPM_BB_D_C2_AMS_EN_D1R = (void *) 0xFEC20CBB;
unsigned char * INT_OPM_BC_E_C2_AMS_EN_D1R = (void *) 0xFEC20CBC;
unsigned char * INT_OPM_BD_F_C2_AMS_EN_D1R = (void *) 0xFEC20CBD;
unsigned char * INT_OPM_BE_G_C2_AMS_EN_D1R = (void *) 0xFEC20CBE;
unsigned char * INT_OPM_BF_H_C2_AMS_EN_D1R = (void *) 0xFEC20CBF;
unsigned char * INT_OPM_C0_A_M1_DT2_D2R = (void *) 0xFEC20CC0;
unsigned char * INT_OPM_C1_B_M1_DT2_D2R = (void *) 0xFEC20CC1;
unsigned char * INT_OPM_C2_C_M1_DT2_D2R = (void *) 0xFEC20CC2;
unsigned char * INT_OPM_C3_D_M1_DT2_D2R = (void *) 0xFEC20CC3;
unsigned char * INT_OPM_C4_E_M1_DT2_D2R = (void *) 0xFEC20CC4;
unsigned char * INT_OPM_C5_F_M1_DT2_D2R = (void *) 0xFEC20CC5;
unsigned char * INT_OPM_C6_G_M1_DT2_D2R = (void *) 0xFEC20CC6;
unsigned char * INT_OPM_C7_H_M1_DT2_D2R = (void *) 0xFEC20CC7;
unsigned char * INT_OPM_C8_A_M2_DT2_D2R = (void *) 0xFEC20CC8;
unsigned char * INT_OPM_C9_B_M2_DT2_D2R = (void *) 0xFEC20CC9;
unsigned char * INT_OPM_CA_C_M2_DT2_D2R = (void *) 0xFEC20CCA;
unsigned char * INT_OPM_CB_D_M2_DT2_D2R = (void *) 0xFEC20CCB;
unsigned char * INT_OPM_CC_E_M2_DT2_D2R = (void *) 0xFEC20CCC;
unsigned char * INT_OPM_CD_F_M2_DT2_D2R = (void *) 0xFEC20CCD;
unsigned char * INT_OPM_CE_G_M2_DT2_D2R = (void *) 0xFEC20CCE;
unsigned char * INT_OPM_CF_H_M2_DT2_D2R = (void *) 0xFEC20CCF;
unsigned char * INT_OPM_D0_A_C1_DT2_D2R = (void *) 0xFEC20CD0;
unsigned char * INT_OPM_D1_B_C1_DT2_D2R = (void *) 0xFEC20CD1;
unsigned char * INT_OPM_D2_C_C1_DT2_D2R = (void *) 0xFEC20CD2;
unsigned char * INT_OPM_D3_D_C1_DT2_D2R = (void *) 0xFEC20CD3;
unsigned char * INT_OPM_D4_E_C1_DT2_D2R = (void *) 0xFEC20CD4;
unsigned char * INT_OPM_D5_F_C1_DT2_D2R = (void *) 0xFEC20CD5;
unsigned char * INT_OPM_D6_G_C1_DT2_D2R = (void *) 0xFEC20CD6;
unsigned char * INT_OPM_D7_H_C1_DT2_D2R = (void *) 0xFEC20CD7;
unsigned char * INT_OPM_D8_A_C2_DT2_D2R = (void *) 0xFEC20CD8;
unsigned char * INT_OPM_D9_B_C2_DT2_D2R = (void *) 0xFEC20CD9;
unsigned char * INT_OPM_DA_C_C2_DT2_D2R = (void *) 0xFEC20CDA;
unsigned char * INT_OPM_DB_D_C2_DT2_D2R = (void *) 0xFEC20CDB;
unsigned char * INT_OPM_DC_E_C2_DT2_D2R = (void *) 0xFEC20CDC;
unsigned char * INT_OPM_DD_F_C2_DT2_D2R = (void *) 0xFEC20CDD;
unsigned char * INT_OPM_DE_G_C2_DT2_D2R = (void *) 0xFEC20CDE;
unsigned char * INT_OPM_DF_H_C2_DT2_D2R = (void *) 0xFEC20CDF;
unsigned char * INT_OPM_E0_A_M1_D1L_RR = (void *) 0xFEC20CE0;
unsigned char * INT_OPM_E1_B_M1_D1L_RR = (void *) 0xFEC20CE1;
unsigned char * INT_OPM_E2_C_M1_D1L_RR = (void *) 0xFEC20CE2;
unsigned char * INT_OPM_E3_D_M1_D1L_RR = (void *) 0xFEC20CE3;
unsigned char * INT_OPM_E4_E_M1_D1L_RR = (void *) 0xFEC20CE4;
unsigned char * INT_OPM_E5_F_M1_D1L_RR = (void *) 0xFEC20CE5;
unsigned char * INT_OPM_E6_G_M1_D1L_RR = (void *) 0xFEC20CE6;
unsigned char * INT_OPM_E7_H_M1_D1L_RR = (void *) 0xFEC20CE7;
unsigned char * INT_OPM_E8_A_M2_D1L_RR = (void *) 0xFEC20CE8;
unsigned char * INT_OPM_E9_B_M2_D1L_RR = (void *) 0xFEC20CE9;
unsigned char * INT_OPM_EA_C_M2_D1L_RR = (void *) 0xFEC20CEA;
unsigned char * INT_OPM_EB_D_M2_D1L_RR = (void *) 0xFEC20CEB;
unsigned char * INT_OPM_EC_E_M2_D1L_RR = (void *) 0xFEC20CEC;
unsigned char * INT_OPM_ED_F_M2_D1L_RR = (void *) 0xFEC20CED;
unsigned char * INT_OPM_EE_G_M2_D1L_RR = (void *) 0xFEC20CEE;
unsigned char * INT_OPM_EF_H_M2_D1L_RR = (void *) 0xFEC20CEF;
unsigned char * INT_OPM_F0_A_C1_D1L_RR = (void *) 0xFEC20CF0;
unsigned char * INT_OPM_F1_B_C1_D1L_RR = (void *) 0xFEC20CF1;
unsigned char * INT_OPM_F2_C_C1_D1L_RR = (void *) 0xFEC20CF2;
unsigned char * INT_OPM_F3_D_C1_D1L_RR = (void *) 0xFEC20CF3;
unsigned char * INT_OPM_F4_E_C1_D1L_RR = (void *) 0xFEC20CF4;
unsigned char * INT_OPM_F5_F_C1_D1L_RR = (void *) 0xFEC20CF5;
unsigned char * INT_OPM_F6_G_C1_D1L_RR = (void *) 0xFEC20CF6;
unsigned char * INT_OPM_F7_H_C1_D1L_RR = (void *) 0xFEC20CF7;
unsigned char * INT_OPM_F8_A_C2_D1L_RR = (void *) 0xFEC20CF8;
unsigned char * INT_OPM_F9_B_C2_D1L_RR = (void *) 0xFEC20CF9;
unsigned char * INT_OPM_FA_C_C2_D1L_RR = (void *) 0xFEC20CFA;
unsigned char * INT_OPM_FB_D_C2_D1L_RR = (void *) 0xFEC20CFB;
unsigned char * INT_OPM_FC_E_C2_D1L_RR = (void *) 0xFEC20CFC;
unsigned char * INT_OPM_FD_F_C2_D1L_RR = (void *) 0xFEC20CFD;
unsigned char * INT_OPM_FE_G_C2_D1L_RR = (void *) 0xFEC20CFE;
unsigned char * INT_OPM_FF_H_C2_D1L_RR = (void *) 0xFEC20CFF;
#endif

View file

@ -0,0 +1,297 @@
#ifndef YM2612_Ext_H_
#define YM2612_Ext_H_
// External Registers $00C20400..$00C20BFF
unsigned char * EXT_OPN2_22_LFO = (void *)0xFEC20422; // LFO enable | LFO frequency
unsigned char * EXT_OPN2_23_TIMER_A_H = (void *)0xFEC20423; // Timer A MSBs
unsigned char * EXT_OPN2_24_TIMER_A_L = (void *)0xFEC20424; // Timer A LSBs
unsigned char * EXT_OPN2_25_TIMER_B = (void *)0xFEC20425; // Timer B
unsigned char * EXT_OPN2_27_CHANEL_3_MODE = (void *)0xFEC20427; // Ch3 mode Reset B Reset A Enable B Enable A Load B Load A
unsigned char * EXT_OPN2_27_TIMER_CONF = (void *)0xFEC20427; // Ch3 mode Reset B Reset A Enable B Enable A Load B Load A
unsigned char * EXT_OPN2_28_KEY_ON_OFF = (void *)0xFEC20428; // Operator Channel
unsigned char * EXT_OPN2_29 = (void *)0xFEC20429;
unsigned char * EXT_OPN2_2A_ADC = (void *)0xFEC2042A; // DAC
unsigned char * EXT_OPN2_2B_ADC_EN = (void *)0xFEC2042B; // DAC en
//;--------------------------------------------------------------------------------------
//;------------------- DT1 (detune) and MUL (multiple) ----------------------------------
//;--------------------------------------------------------------------------------------
//;
//; MUL ranges from 0 to 15 (decimal), and multiplies the overall frequency, with the
//; exception that 0 results in multiplication by 1/2. That is, MUL=0 to 15 gives ×1/2,
//; ×1, ×2, ... ×15.
//;
//; DT1 gives small variations from the overall frequency × MUL. The MSB of DT1 is a
//; primitive sign bit, and the two LSBs are magnitude bits. See the next page for a
//; diagram.
//;
//;--------------------------------------------------------------------------------------
unsigned char * EXT_OPN2_30_ADSR__DT1_MUL__CH1_OP1 = (void *) 0xFEC20430;
unsigned char * EXT_OPN2_31_ADSR__DT1_MUL__CH2_OP1 = (void *) 0xFEC20431;
unsigned char * EXT_OPN2_32_ADSR__DT1_MUL__CH3_OP1 = (void *) 0xFEC20432;
unsigned char * EXT_OPN2_34_ADSR__DT1_MUL__CH1_OP2 = (void *) 0xFEC20434;
unsigned char * EXT_OPN2_35_ADSR__DT1_MUL__CH2_OP2 = (void *) 0xFEC20435;
unsigned char * EXT_OPN2_36_ADSR__DT1_MUL__CH3_OP2 = (void *) 0xFEC20436;
unsigned char * EXT_OPN2_38_ADSR__DT1_MUL__CH1_OP3 = (void *) 0xFEC20438;
unsigned char * EXT_OPN2_39_ADSR__DT1_MUL__CH2_OP3 = (void *) 0xFEC20439;
unsigned char * EXT_OPN2_3A_ADSR__DT1_MUL__CH3_OP3 = (void *) 0xFEC2043A;
unsigned char * EXT_OPN2_3C_ADSR__DT1_MUL__CH1_OP4 = (void *) 0xFEC2043C;
unsigned char * EXT_OPN2_3D_ADSR__DT1_MUL__CH2_OP4 = (void *) 0xFEC2043D;
unsigned char * EXT_OPN2_3E_ADSR__DT1_MUL__CH3_OP4 = (void *) 0xFEC2043E;
unsigned char * EXT_OPN2_30_ADSR__DT1_MUL__CH1_OP5 = (void *) 0xFEC20530;
unsigned char * EXT_OPN2_31_ADSR__DT1_MUL__CH2_OP5 = (void *) 0xFEC20531;
unsigned char * EXT_OPN2_32_ADSR__DT1_MUL__CH3_OP5 = (void *) 0xFEC20532;
unsigned char * EXT_OPN2_34_ADSR__DT1_MUL__CH1_OP6 = (void *) 0xFEC20534;
unsigned char * EXT_OPN2_35_ADSR__DT1_MUL__CH2_OP6 = (void *) 0xFEC20535;
unsigned char * EXT_OPN2_36_ADSR__DT1_MUL__CH3_OP6 = (void *) 0xFEC20536;
unsigned char * EXT_OPN2_38_ADSR__DT1_MUL__CH1_OP7 = (void *) 0xFEC20538;
unsigned char * EXT_OPN2_39_ADSR__DT1_MUL__CH2_OP7 = (void *) 0xFEC20539;
unsigned char * EXT_OPN2_3A_ADSR__DT1_MUL__CH3_OP7 = (void *) 0xFEC2053A;
unsigned char * EXT_OPN2_3C_ADSR__DT1_MUL__CH1_OP8 = (void *) 0xFEC2053C;
unsigned char * EXT_OPN2_3D_ADSR__DT1_MUL__CH2_OP8 = (void *) 0xFEC2053D;
unsigned char * EXT_OPN2_3E_ADSR__DT1_MUL__CH3_OP8 = (void *) 0xFEC2053E;
//;--------------------------------------------------------------------------------------
//;---------------------------------- TL (total level) ----------------------------------
//;--------------------------------------------------------------------------------------
//;
//; TL (total level) represents the envelopes highest amplitude, with 0 being the largest
//; and 127 (decimal) the smallest. A change of one unit is about 0.75 dB.
//;
//; To make a note softer, only change the TL of the slots (the output operators).
//; Changing the other operators will affect the flavor of the note.
//;
//;--------------------------------------------------------------------------------------
unsigned char * EXT_OPN2_40_ADSR__LT__CH1_OP1 = (void *) 0xFEC20440;
unsigned char * EXT_OPN2_41_ADSR__LT__CH2_OP1 = (void *) 0xFEC20441;
unsigned char * EXT_OPN2_42_ADSR__LT__CH3_OP1 = (void *) 0xFEC20442;
unsigned char * EXT_OPN2_44_ADSR__LT__CH1_OP2 = (void *) 0xFEC20444;
unsigned char * EXT_OPN2_45_ADSR__LT__CH2_OP2 = (void *) 0xFEC20445;
unsigned char * EXT_OPN2_46_ADSR__LT__CH3_OP2 = (void *) 0xFEC20446;
unsigned char * EXT_OPN2_48_ADSR__LT__CH1_OP3 = (void *) 0xFEC20448;
unsigned char * EXT_OPN2_49_ADSR__LT__CH2_OP3 = (void *) 0xFEC20449;
unsigned char * EXT_OPN2_4A_ADSR__LT__CH3_OP3 = (void *) 0xFEC2044A;
unsigned char * EXT_OPN2_4C_ADSR__LT__CH1_OP4 = (void *) 0xFEC2044C;
unsigned char * EXT_OPN2_4D_ADSR__LT__CH2_OP4 = (void *) 0xFEC2044D;
unsigned char * EXT_OPN2_4E_ADSR__LT__CH3_OP4 = (void *) 0xFEC2044E;
unsigned char * EXT_OPN2_40_ADSR__LT__CH1_OP5 = (void *) 0xFEC20540;
unsigned char * EXT_OPN2_41_ADSR__LT__CH2_OP5 = (void *) 0xFEC20541;
unsigned char * EXT_OPN2_42_ADSR__LT__CH3_OP5 = (void *) 0xFEC20542;
unsigned char * EXT_OPN2_44_ADSR__LT__CH1_OP6 = (void *) 0xFEC20544;
unsigned char * EXT_OPN2_45_ADSR__LT__CH2_OP6 = (void *) 0xFEC20545;
unsigned char * EXT_OPN2_46_ADSR__LT__CH3_OP6 = (void *) 0xFEC20546;
unsigned char * EXT_OPN2_48_ADSR__LT__CH1_OP7 = (void *) 0xFEC20548;
unsigned char * EXT_OPN2_49_ADSR__LT__CH2_OP7 = (void *) 0xFEC20549;
unsigned char * EXT_OPN2_4A_ADSR__LT__CH3_OP7 = (void *) 0xFEC2054A;
unsigned char * EXT_OPN2_4C_ADSR__LT__CH1_OP8 = (void *) 0xFEC2054C;
unsigned char * EXT_OPN2_4D_ADSR__LT__CH2_OP8 = (void *) 0xFEC2054D;
unsigned char * EXT_OPN2_4E_ADSR__LT__CH3_OP8 = (void *) 0xFEC2054E;
//;--------------------------------------------------------------------------------------
//;------------------- RS (rate scaling) and AR (attack rate) ---------------------------
//;--------------------------------------------------------------------------------------
//;
//; AR is the steepness of the initial amplitude rise, shown on page 5.
//;
//; RS affects AR, D1R, D2R and RR in the same way. RS is the degree to which the envelope
//; becomes narrower as the frequency becomes higher.
//;
//;--------------------------------------------------------------------------------------
unsigned char * EXT_OPN2_50_ADSR__SR_AR__CH1_OP1 = (void *) 0xFEC20450;
unsigned char * EXT_OPN2_51_ADSR__SR_AR__CH2_OP1 = (void *) 0xFEC20451;
unsigned char * EXT_OPN2_52_ADSR__SR_AR__CH3_OP1 = (void *) 0xFEC20452;
unsigned char * EXT_OPN2_54_ADSR__SR_AR__CH1_OP2 = (void *) 0xFEC20454;
unsigned char * EXT_OPN2_55_ADSR__SR_AR__CH2_OP2 = (void *) 0xFEC20455;
unsigned char * EXT_OPN2_56_ADSR__SR_AR__CH3_OP2 = (void *) 0xFEC20456;
unsigned char * EXT_OPN2_58_ADSR__SR_AR__CH1_OP3 = (void *) 0xFEC20458;
unsigned char * EXT_OPN2_59_ADSR__SR_AR__CH2_OP3 = (void *) 0xFEC20459;
unsigned char * EXT_OPN2_5A_ADSR__SR_AR__CH3_OP3 = (void *) 0xFEC2045A;
unsigned char * EXT_OPN2_5C_ADSR__SR_AR__CH1_OP4 = (void *) 0xFEC2045C;
unsigned char * EXT_OPN2_5D_ADSR__SR_AR__CH2_OP4 = (void *) 0xFEC2045D;
unsigned char * EXT_OPN2_5E_ADSR__SR_AR__CH3_OP4 = (void *) 0xFEC2045E;
unsigned char * EXT_OPN2_50_ADSR__SR_AR__CH1_OP5 = (void *) 0xFEC20550;
unsigned char * EXT_OPN2_51_ADSR__SR_AR__CH2_OP5 = (void *) 0xFEC20551;
unsigned char * EXT_OPN2_52_ADSR__SR_AR__CH3_OP5 = (void *) 0xFEC20552;
unsigned char * EXT_OPN2_54_ADSR__SR_AR__CH1_OP6 = (void *) 0xFEC20554;
unsigned char * EXT_OPN2_55_ADSR__SR_AR__CH2_OP6 = (void *) 0xFEC20555;
unsigned char * EXT_OPN2_56_ADSR__SR_AR__CH3_OP6 = (void *) 0xFEC20556;
unsigned char * EXT_OPN2_58_ADSR__SR_AR__CH1_OP7 = (void *) 0xFEC20558;
unsigned char * EXT_OPN2_59_ADSR__SR_AR__CH2_OP7 = (void *) 0xFEC20559;
unsigned char * EXT_OPN2_5A_ADSR__SR_AR__CH3_OP7 = (void *) 0xFEC2055A;
unsigned char * EXT_OPN2_5C_ADSR__SR_AR__CH1_OP8 = (void *) 0xFEC2055C;
unsigned char * EXT_OPN2_5D_ADSR__SR_AR__CH2_OP8 = (void *) 0xFEC2055D;
unsigned char * EXT_OPN2_5E_ADSR__SR_AR__CH3_OP8 = (void *) 0xFEC2055E;
//;--------------------------------------------------------------------------------------
//;-------------- AM modulation enable amd D1R (first decay rate) -----------------------
//;--------------------------------------------------------------------------------------
//;
//; D1R (first decay rate) is the initial steep amplitude decay rate (see page 4). It is,
//; like all rates, 0-31 in value and affected by RS.
//;
//; AM is the amplitude modulation enable, whether of not this operator will be subject to
//; amplitude modulation by the LFO. This bit is not relevant unless both the LFO is
//; enabled and register B4s AMS (amplitude modulation sensitivity) is non-zero.
//;
//;--------------------------------------------------------------------------------------
unsigned char * EXT_OPN2_60_ADSR__AM_D1R__CH1_OP1 = (void *) 0xFEC20460;
unsigned char * EXT_OPN2_61_ADSR__AM_D1R__CH2_OP1 = (void *) 0xFEC20461;
unsigned char * EXT_OPN2_62_ADSR__AM_D1R__CH3_OP1 = (void *) 0xFEC20462;
unsigned char * EXT_OPN2_64_ADSR__AM_D1R__CH1_OP2 = (void *) 0xFEC20464;
unsigned char * EXT_OPN2_65_ADSR__AM_D1R__CH2_OP2 = (void *) 0xFEC20465;
unsigned char * EXT_OPN2_66_ADSR__AM_D1R__CH3_OP2 = (void *) 0xFEC20466;
unsigned char * EXT_OPN2_68_ADSR__AM_D1R__CH1_OP3 = (void *) 0xFEC20468;
unsigned char * EXT_OPN2_69_ADSR__AM_D1R__CH2_OP3 = (void *) 0xFEC20469;
unsigned char * EXT_OPN2_6A_ADSR__AM_D1R__CH3_OP3 = (void *) 0xFEC2046A;
unsigned char * EXT_OPN2_6C_ADSR__AM_D1R__CH1_OP4 = (void *) 0xFEC2046C;
unsigned char * EXT_OPN2_6D_ADSR__AM_D1R__CH2_OP4 = (void *) 0xFEC2046D;
unsigned char * EXT_OPN2_6E_ADSR__AM_D1R__CH3_OP4 = (void *) 0xFEC2046E;
unsigned char * EXT_OPN2_60_ADSR__AM_D1R__CH1_OP5 = (void *) 0xFEC20560;
unsigned char * EXT_OPN2_61_ADSR__AM_D1R__CH2_OP5 = (void *) 0xFEC20561;
unsigned char * EXT_OPN2_62_ADSR__AM_D1R__CH3_OP5 = (void *) 0xFEC20562;
unsigned char * EXT_OPN2_64_ADSR__AM_D1R__CH1_OP6 = (void *) 0xFEC20564;
unsigned char * EXT_OPN2_65_ADSR__AM_D1R__CH2_OP6 = (void *) 0xFEC20565;
unsigned char * EXT_OPN2_66_ADSR__AM_D1R__CH3_OP6 = (void *) 0xFEC20566;
unsigned char * EXT_OPN2_68_ADSR__AM_D1R__CH1_OP7 = (void *) 0xFEC20568;
unsigned char * EXT_OPN2_69_ADSR__AM_D1R__CH2_OP7 = (void *) 0xFEC20569;
unsigned char * EXT_OPN2_6A_ADSR__AM_D1R__CH3_OP7 = (void *) 0xFEC2056A;
unsigned char * EXT_OPN2_6C_ADSR__AM_D1R__CH1_OP8 = (void *) 0xFEC2056C;
unsigned char * EXT_OPN2_6D_ADSR__AM_D1R__CH2_OP8 = (void *) 0xFEC2056D;
unsigned char * EXT_OPN2_6E_ADSR__AM_D1R__CH3_OP8 = (void *) 0xFEC2056E;
//;--------------------------------------------------------------------------------------
//;-------------------------- D2R (secondary decay rate) --------------------------------
//;--------------------------------------------------------------------------------------
//;
//; D2R (secondary decay rate) is the long tail off of the sound that continues as long
//; as the key is depressed.
//;
//;--------------------------------------------------------------------------------------
unsigned char * EXT_OPN2_70_ADSR__D2R__CH1_OP1 = (void *) 0xFEC20470;
unsigned char * EXT_OPN2_71_ADSR__D2R__CH2_OP1 = (void *) 0xFEC20471;
unsigned char * EXT_OPN2_72_ADSR__D2R__CH3_OP1 = (void *) 0xFEC20472;
unsigned char * EXT_OPN2_74_ADSR__D2R__CH1_OP2 = (void *) 0xFEC20474;
unsigned char * EXT_OPN2_75_ADSR__D2R__CH2_OP2 = (void *) 0xFEC20475;
unsigned char * EXT_OPN2_76_ADSR__D2R__CH3_OP2 = (void *) 0xFEC20476;
unsigned char * EXT_OPN2_78_ADSR__D2R__CH1_OP3 = (void *) 0xFEC20478;
unsigned char * EXT_OPN2_79_ADSR__D2R__CH2_OP3 = (void *) 0xFEC20479;
unsigned char * EXT_OPN2_7A_ADSR__D2R__CH3_OP3 = (void *) 0xFEC2047A;
unsigned char * EXT_OPN2_7C_ADSR__D2R__CH1_OP4 = (void *) 0xFEC2047C;
unsigned char * EXT_OPN2_7D_ADSR__D2R__CH2_OP4 = (void *) 0xFEC2047D;
unsigned char * EXT_OPN2_7E_ADSR__D2R__CH3_OP4 = (void *) 0xFEC2047E;
unsigned char * EXT_OPN2_70_ADSR__D2R__CH1_OP5 = (void *) 0xFEC20570;
unsigned char * EXT_OPN2_71_ADSR__D2R__CH2_OP5 = (void *) 0xFEC20571;
unsigned char * EXT_OPN2_72_ADSR__D2R__CH3_OP5 = (void *) 0xFEC20572;
unsigned char * EXT_OPN2_74_ADSR__D2R__CH1_OP6 = (void *) 0xFEC20574;
unsigned char * EXT_OPN2_75_ADSR__D2R__CH2_OP6 = (void *) 0xFEC20575;
unsigned char * EXT_OPN2_76_ADSR__D2R__CH3_OP6 = (void *) 0xFEC20576;
unsigned char * EXT_OPN2_78_ADSR__D2R__CH1_OP7 = (void *) 0xFEC20578;
unsigned char * EXT_OPN2_79_ADSR__D2R__CH2_OP7 = (void *) 0xFEC20579;
unsigned char * EXT_OPN2_7A_ADSR__D2R__CH3_OP7 = (void *) 0xFEC2057A;
unsigned char * EXT_OPN2_7C_ADSR__D2R__CH1_OP8 = (void *) 0xFEC2057C;
unsigned char * EXT_OPN2_7D_ADSR__D2R__CH2_OP8 = (void *) 0xFEC2057D;
unsigned char * EXT_OPN2_7E_ADSR__D2R__CH3_OP8 = (void *) 0xFEC2057E;
//;--------------------------------------------------------------------------------------
//;-------------------------- D2R (secondary decay rate) --------------------------------
//;--------------------------------------------------------------------------------------
//;
//; D2R (secondary decay rate) is the long tail off of the sound that continues as long
//; as the key is depressed.
//;
//;--------------------------------------------------------------------------------------
unsigned char * EXT_OPN2_80_ADSR__D1L_RR__CH1_OP1 = (void *) 0xFEC20480;
unsigned char * EXT_OPN2_81_ADSR__D1L_RR__CH2_OP1 = (void *) 0xFEC20481;
unsigned char * EXT_OPN2_82_ADSR__D1L_RR__CH3_OP1 = (void *) 0xFEC20482;
unsigned char * EXT_OPN2_84_ADSR__D1L_RR__CH1_OP2 = (void *) 0xFEC20484;
unsigned char * EXT_OPN2_85_ADSR__D1L_RR__CH2_OP2 = (void *) 0xFEC20485;
unsigned char * EXT_OPN2_86_ADSR__D1L_RR__CH3_OP2 = (void *) 0xFEC20486;
unsigned char * EXT_OPN2_88_ADSR__D1L_RR__CH1_OP3 = (void *) 0xFEC20488;
unsigned char * EXT_OPN2_89_ADSR__D1L_RR__CH2_OP3 = (void *) 0xFEC20489;
unsigned char * EXT_OPN2_8A_ADSR__D1L_RR__CH3_OP3 = (void *) 0xFEC2048A;
unsigned char * EXT_OPN2_8C_ADSR__D1L_RR__CH1_OP4 = (void *) 0xFEC2048C;
unsigned char * EXT_OPN2_8D_ADSR__D1L_RR__CH2_OP4 = (void *) 0xFEC2048D;
unsigned char * EXT_OPN2_8E_ADSR__D1L_RR__CH3_OP4 = (void *) 0xFEC2048E;
unsigned char * EXT_OPN2_80_ADSR__D1L_RR__CH1_OP5 = (void *) 0xFEC20580;
unsigned char * EXT_OPN2_81_ADSR__D1L_RR__CH2_OP5 = (void *) 0xFEC20581;
unsigned char * EXT_OPN2_82_ADSR__D1L_RR__CH3_OP5 = (void *) 0xFEC20582;
unsigned char * EXT_OPN2_84_ADSR__D1L_RR__CH1_OP6 = (void *) 0xFEC20584;
unsigned char * EXT_OPN2_85_ADSR__D1L_RR__CH2_OP6 = (void *) 0xFEC20585;
unsigned char * EXT_OPN2_86_ADSR__D1L_RR__CH3_OP6 = (void *) 0xFEC20586;
unsigned char * EXT_OPN2_88_ADSR__D1L_RR__CH1_OP7 = (void *) 0xFEC20588;
unsigned char * EXT_OPN2_89_ADSR__D1L_RR__CH2_OP7 = (void *) 0xFEC20589;
unsigned char * EXT_OPN2_8A_ADSR__D1L_RR__CH3_OP7 = (void *) 0xFEC2058A;
unsigned char * EXT_OPN2_8C_ADSR__D1L_RR__CH1_OP8 = (void *) 0xFEC2058C;
unsigned char * EXT_OPN2_8D_ADSR__D1L_RR__CH2_OP8 = (void *) 0xFEC2058D;
unsigned char * EXT_OPN2_8E_ADSR__D1L_RR__CH3_OP8 = (void *) 0xFEC2058E;
//;--------------------------------------------------------------------------------------
//;------------------------------------ SSG-EG ------------------------------------------
//;--------------------------------------------------------------------------------------
//;
//; This register is proprietary and should be set to zero.
//;
//;--------------------------------------------------------------------------------------
unsigned char * EXT_OPN2_90_ADSR__D1L_RR__CH1_OP1 = (void *) 0xFEC20490;
unsigned char * EXT_OPN2_91_ADSR__D1L_RR__CH2_OP1 = (void *) 0xFEC20491;
unsigned char * EXT_OPN2_92_ADSR__D1L_RR__CH3_OP1 = (void *) 0xFEC20492;
unsigned char * EXT_OPN2_94_ADSR__D1L_RR__CH1_OP2 = (void *) 0xFEC20494;
unsigned char * EXT_OPN2_95_ADSR__D1L_RR__CH2_OP2 = (void *) 0xFEC20495;
unsigned char * EXT_OPN2_96_ADSR__D1L_RR__CH3_OP2 = (void *) 0xFEC20496;
unsigned char * EXT_OPN2_98_ADSR__D1L_RR__CH1_OP3 = (void *) 0xFEC20498;
unsigned char * EXT_OPN2_99_ADSR__D1L_RR__CH2_OP3 = (void *) 0xFEC20499;
unsigned char * EXT_OPN2_9A_ADSR__D1L_RR__CH3_OP3 = (void *) 0xFEC2049A;
unsigned char * EXT_OPN2_9C_ADSR__D1L_RR__CH1_OP4 = (void *) 0xFEC2049C;
unsigned char * EXT_OPN2_9D_ADSR__D1L_RR__CH2_OP4 = (void *) 0xFEC2049D;
unsigned char * EXT_OPN2_9E_ADSR__D1L_RR__CH3_OP4 = (void *) 0xFEC2049E;
unsigned char * EXT_OPN2_90_ADSR__D1L_RR__CH4_OP1 = (void *) 0xFEC20590;
unsigned char * EXT_OPN2_91_ADSR__D1L_RR__CH5_OP1 = (void *) 0xFEC20591;
unsigned char * EXT_OPN2_92_ADSR__D1L_RR__CH6_OP1 = (void *) 0xFEC20592;
unsigned char * EXT_OPN2_94_ADSR__D1L_RR__CH4_OP2 = (void *) 0xFEC20594;
unsigned char * EXT_OPN2_95_ADSR__D1L_RR__CH5_OP2 = (void *) 0xFEC20595;
unsigned char * EXT_OPN2_96_ADSR__D1L_RR__CH6_OP2 = (void *) 0xFEC20596;
unsigned char * EXT_OPN2_98_ADSR__D1L_RR__CH4_OP3 = (void *) 0xFEC20598;
unsigned char * EXT_OPN2_99_ADSR__D1L_RR__CH5_OP3 = (void *) 0xFEC20599;
unsigned char * EXT_OPN2_9A_ADSR__D1L_RR__CH6_OP3 = (void *) 0xFEC2059A;
unsigned char * EXT_OPN2_9C_ADSR__D1L_RR__CH4_OP4 = (void *) 0xFEC2059C;
unsigned char * EXT_OPN2_9D_ADSR__D1L_RR__CH5_OP4 = (void *) 0xFEC2059D;
unsigned char * EXT_OPN2_9E_ADSR__D1L_RR__CH6_OP4 = (void *) 0xFEC2059E;
//;--------------------------------------------------------------------------------------
unsigned char * EXT_OPN2_A0_CH1_FREQ_L = (void *) 0xFEC204A0; //Frequency number LSB
unsigned char * EXT_OPN2_A1_CH2_FREQ_L = (void *) 0xFEC204A1; //Frequency number LSB
unsigned char * EXT_OPN2_A2_CH3_FREQ_L = (void *) 0xFEC204A2; //Frequency number LSB
unsigned char * EXT_OPN2_A2_CH3_FREQ_OP1_L = (void *) 0xFEC204A2; //Frequency number LSB Chanel 3 Operator 1 if special mode
unsigned char * EXT_OPN2_A8_CH3_FREQ_OP2_L = (void *) 0xFEC204A8; //Frequency number LSB Chanel 3 Operator 2 if special mode
unsigned char * EXT_OPN2_A9_CH3_FREQ_OP3_L = (void *) 0xFEC204A9; //Frequency number LSB Chanel 3 Operator 3 if special mode
unsigned char * EXT_OPN2_AA_CH3_FREQ_OP4_L = (void *) 0xFEC204AA; //Frequency number LSB Chanel 3 Operator 4 if special mode
unsigned char * EXT_OPN2_A0_CH4_FREQ_L = (void *) 0xFEC205A0; //Frequency number LSB
unsigned char * EXT_OPN2_A1_CH5_FREQ_L = (void *) 0xFEC205A1; //Frequency number LSB
unsigned char * EXT_OPN2_A2_CH6_FREQ_L = (void *) 0xFEC205A2; //Frequency number LSB
unsigned char * EXT_OPN2_A4_CH1_OCTAVE_FREQ_H = (void *) 0xFEC204A4; //OCTAVE and Frequency number MSB
unsigned char * EXT_OPN2_A5_CH2_OCTAVE_FREQ_H = (void *) 0xFEC204A5; //OCTAVE and Frequency number MSB
unsigned char * EXT_OPN2_A6_CH3_OCTAVE_FREQ_H = (void *) 0xFEC204A6; //OCTAVE and Frequency number MSB
unsigned char * EXT_OPN2_A6_CH3_OCTAVE_FREQ_OP1_H = (void *) 0xFEC204A6; //OCTAVE and Frequency number MSB Chanel 3 Operator 1 if special mode
unsigned char * EXT_OPN2_AC_CH3_OCTAVE_FREQ_OP2_H = (void *) 0xFEC204AC; //OCTAVE and Frequency number MSB Chanel 3 Operator 2 if special mode
unsigned char * EXT_OPN2_AD_CH3_OCTAVE_FREQ_OP3_H = (void *) 0xFEC204AD; //OCTAVE and Frequency number MSB Chanel 3 Operator 3 if special mode
unsigned char * EXT_OPN2_AE_CH3_OCTAVE_FREQ_OP4_H = (void *) 0xFEC204AE; //OCTAVE and Frequency number MSB Chanel 3 Operator 4 if special mode
unsigned char * EXT_OPN2_A4_CH4_OCTAVE_FREQ_H = (void *) 0xFEC205A4; //OCTAVE and Frequency number MSB
unsigned char * EXT_OPN2_A5_CH5_OCTAVE_FREQ_H = (void *) 0xFEC205A5; //OCTAVE and Frequency number MSB
unsigned char * EXT_OPN2_A6_CH6_OCTAVE_FREQ_H = (void *) 0xFEC205A6; //OCTAVE and Frequency number MSB
//; Feedback is the degree to which operator 1 feeds back into itself.
//; The algorithm is the type of inter-operator connection used
unsigned char * EXT_OPN2_B0_CH1_FEEDBACK_ALGO = (void *)0xFEC204B0;
unsigned char * EXT_OPN2_B1_CH2_FEEDBACK_ALGO = (void *)0xFEC204B1;
unsigned char * EXT_OPN2_B2_CH3_FEEDBACK_ALGO = (void *)0xFEC204B2;
unsigned char * EXT_OPN2_B0_CH4_FEEDBACK_ALGO = (void *)0xFEC205B0;
unsigned char * EXT_OPN2_B1_CH5_FEEDBACK_ALGO = (void *)0xFEC205B1;
unsigned char * EXT_OPN2_B2_CH6_FEEDBACK_ALGO = (void *)0xFEC205B2;
//; Register B4H contains stereo output control and LFO sensitivity control.
unsigned char * EXT_OPN2_B4_CH1_L_R_AMS_FMS = (void *)0xFEC204B0;
unsigned char * EXT_OPN2_B5_CH2_L_R_AMS_FMS = (void *)0xFEC204B1;
unsigned char * EXT_OPN2_B6_CH3_L_R_AMS_FMS = (void *)0xFEC204B2;
unsigned char * EXT_OPN2_B4_CH4_L_R_AMS_FMS = (void *)0xFEC205B0;
unsigned char * EXT_OPN2_B5_CH5_L_R_AMS_FMS = (void *)0xFEC205B1;
unsigned char * EXT_OPN2_B6_CH6_L_R_AMS_FMS = (void *)0xFEC205B2;
#endif

View file

@ -5,8 +5,8 @@
#ifndef __FDC_A2560K_H
#define __FDC_A2560K_H
#define FDC_BASE ((volatile unsigned char *)0x00C023F0)
#define FDC_DOR ((volatile unsigned char *)0x00C023F2) /* Read/Write - Digital Output Register */
#define FDC_BASE ((volatile unsigned char *)0xFEC023F0)
#define FDC_DOR ((volatile unsigned char *)0xFEC023F2) /* Read/Write - Digital Output Register */
// FDC_DOR_DSEL0 = $01 ; Drive 0 Select
// FDC_DOR_DSEL1 = $02 ; Drive 1 Select
// FDC_DOR_NRESET = $04 ; Reset the FDC
@ -16,7 +16,7 @@
// FDC_DOR_MOT2 = $40 ; Turn on motor 2
// FDC_DOR_MOT3 = $80 ; Turn on motor 3
#define FDC_MSR ((volatile unsigned char *)0x00C023F4) /* Read - Main Status Register */
#define FDC_MSR ((volatile unsigned char *)0xFEC023F4) /* Read - Main Status Register */
// FDC_MSR_DRV0BSY = $01 ; Indicates if drive 0 is busy
// FDC_MSR_DRV1BSY = $02 ; Indicates if drive 1 is busy
// FDC_MSR_CMDBSY = $10 ; Indicates if a command is in progress
@ -24,20 +24,20 @@
// FDC_MSR_DIO = $40 ; Data direction: 1 = read, 0 = write
// FDC_MSR_RQM = $80 ; 1 = host can transfer data, 0 = host must wait
#define FDC_DSR ((volatile unsigned char *)0x00C023F4) /* Write - Data Select Register */
#define FDC_DSR ((volatile unsigned char *)0xFEC023F4) /* Write - Data Select Register */
// ; Bit[0..1] = data rate
// ; Bit[2..4] = precompensation select
// FDC_DSR_LOPWR = $40 ; Turn on low power mode
// FDC_DSR_RESET = $80 ; Software reset of the FDC
#define FDC_DATA ((volatile unsigned char *)0x00C023F5) /* Read/Write - Data - FIFO */
#define FDC_DATA ((volatile unsigned char *)0xFEC023F5) /* Read/Write - Data - FIFO */
#define FDC_RSV ((volatile unsigned char *)0x00C023F6) /* Reserved */
#define FDC_RSV ((volatile unsigned char *)0xFEC023F6) /* Reserved */
#define FDC_DIR ((volatile unsigned char *)0x00C023F7) /* Read - Digital Input Register */
#define FDC_DIR ((volatile unsigned char *)0xFEC023F7) /* Read - Digital Input Register */
// FDC_DIR_DSKCHG = $80 ; Indicates if the disk has changed
#define FDC_CCR ((volatile unsigned char *)0x00C023F7) /* Write - Configuration Control Register */
#define FDC_CCR ((volatile unsigned char *)0xFEC023F7) /* Write - Configuration Control Register */
// ; Bit[0..1] = Data rate
#endif

View file

@ -0,0 +1,53 @@
/**
* @file gabe_a2560k.h
*
* Define miscellaneous GABE registers
*/
#ifndef __GABE_A2560K_H
#define __GABE_A2560K_H
#define GABE_CTRL_REG ((volatile unsigned int *)0xFEC00000)
#define POWER_ON_LED 0x00000001
#define SDCARD_LED 0x00000002
#define BUZZER_CONTROL 0x00000010
#define MANUAL_RESET 0x00008000 // Make sure the word "DEAD" is written in GABE_RESET_ID
#define GABE_LFSR_REG0 ((volatile unsigned int *)0xFEC00004)
#define RGB_LED ((volatile unsigned int *)0xFEC00008) // Writing Only - A2560K Only - 0x__RRGGBB
#define GABE_LFSR_STATDATA ((volatile unsigned int *)0xFEC00008) // Read Only
#define GABE_SUBVER_ID ((volatile unsigned int *)0xFEC0000C) // Subversion[31:16], Machine ID[3:2] - Read Only
#define GABE_CPU_ID_MASK 0x0000FF00
#define GABE_CPU_SPD_MASK 0x000000E0
#define GABE_ID_MASK 0x0000000C
#define GABE_CHIP_SV_MASK 0xFFFF0000
#define GABE_CHIP_VERSION ((volatile unsigned int *)0xFEC00010) // Number[31:16], Version[15:0]
#define GABE_CHIP_V_MASK 0x0000FFFF
#define GABE_CHIP_N_MASK 0xFFFF0000
#define GABE_DIP_REG ((volatile unsigned int *)0xFEC00518)
#define GABE_DIP_BOOT_MASK 0x00000003 /* Mask for the boot mode: */
#define GABE_DIP_USER_MASK 0x00000700 /* Mask for the user switches: */
/*
* 16-bit register controlling the key of the A2560K built-in keyboard
*/
#define GABE_MO_LEDS ((volatile unsigned long *)0xFEC0000C)
#define GABE_MO_LED_0_B 0x00000001 /* LED 0 (Close to DEL key) -- Blue ON */
#define GABE_MO_LED_0_G 0x00000002 /* LED 0 (Close to DEL key) -- Green ON */
#define GABE_MO_LED_0_R 0x00000004 /* LED 0 (Close to DEL key) -- Red ON */
#define GABE_MO_LED_1_B 0x00000008 /* LED 1 (Below #0) -- Blue ON */
#define GABE_MO_LED_1_G 0x00000010 /* LED 1 (Below #0) -- Green ON */
#define GABE_MO_LED_1_R 0x00000020 /* LED 1 (Below #0) -- Red ON */
#define GABE_MO_LED_2_B 0x00000040 /* LED 2 (above arrow) -- Blue ON */
#define GABE_MO_LED_2_G 0x00000080 /* LED 2 (above arrow) -- Green ON */
#define GABE_MO_LED_2_R 0x00000100 /* LED 2 (above arrow) -- Red ON */
#define GABE_MO_LED_3_B 0x00000200 /* LED 2 (caps lock, Rev C) -- Blue ON */
#define GABE_MO_LED_3_G 0x00000400 /* LED 2 (caps lock, Rev C) -- Green ON */
#define GABE_MO_LED_3_R 0x00000800 /* LED 2 (caps lock, Rev C) -- Red ON */
#endif

View file

@ -5,14 +5,14 @@
#ifndef __PATA_A2560K_H
#define __PATA_A2560K_H
#define PATA_DATA_16 ((volatile unsigned short *)0x00C00400)
#define PATA_DATA_8 ((volatile unsigned char *)0x00C00400)
#define PATA_ERROR ((volatile unsigned char *)0x00C00402)
#define PATA_SECT_CNT ((volatile unsigned char *)0x00C00404)
#define PATA_SECT_SRT ((volatile unsigned char *)0x00C00406)
#define PATA_CLDR_LO ((volatile unsigned char *)0x00C00408)
#define PATA_CLDR_HI ((volatile unsigned char *)0x00C0040A)
#define PATA_HEAD ((volatile unsigned char *)0x00C0040C)
#define PATA_CMD_STAT ((volatile unsigned char *)0x00C0040E)
#define PATA_DATA_16 ((volatile unsigned short *)0xFEC00400)
#define PATA_DATA_8 ((volatile unsigned char *)0xFEC00400)
#define PATA_ERROR ((volatile unsigned char *)0xFEC00402)
#define PATA_SECT_CNT ((volatile unsigned char *)0xFEC00404)
#define PATA_SECT_SRT ((volatile unsigned char *)0xFEC00406)
#define PATA_CLDR_LO ((volatile unsigned char *)0xFEC00408)
#define PATA_CLDR_HI ((volatile unsigned char *)0xFEC0040A)
#define PATA_HEAD ((volatile unsigned char *)0xFEC0040C)
#define PATA_CMD_STAT ((volatile unsigned char *)0xFEC0040E)
#endif

View file

@ -5,10 +5,10 @@
* Ports for the PS/2 keyboard and mouse on the A2560K
*/
#define PS2_STATUS ((unsigned char *)0x00C02064)
#define PS2_CMD_BUF ((unsigned char *)0x00C02064)
#define PS2_OUT_BUF ((unsigned char *)0x00C02060)
#define PS2_INPT_BUF ((unsigned char *)0x00C02060)
#define PS2_DATA_BUF ((unsigned char *)0x00C02060)
#define PS2_STATUS ((unsigned char *)0xFEC02064)
#define PS2_CMD_BUF ((unsigned char *)0xFEC02064)
#define PS2_OUT_BUF ((unsigned char *)0xFEC02060)
#define PS2_INPT_BUF ((unsigned char *)0xFEC02060)
#define PS2_DATA_BUF ((unsigned char *)0xFEC02060)
#endif

View file

@ -5,31 +5,35 @@
#ifndef __SDC_A2560K_H
#define __SDC_A2560K_H
#define GABE_SDC_REG ((volatile unsigned short *)0x00C0051A)
#define GABE_SDC_PRESENT 0x0010 /* Is an SD card present? --- 0:Yes, 1:No */
#define GABE_SDC_WPROT 0x0020 /* Is the SD card write protected? --- 0:Yes, 1:No */
#define GABE_SDC_REG ((volatile unsigned int *)0xFEC00518)
#define GABE_SDC_PRESENT 0x01000000 /* Is an SD card present? --- 0:Yes, 1:No */
#define GABE_SDC_WPROT 0x02000000 /* Is the SD card write protected? --- 0:Yes, 1:No */
#define GABE_BOOTMODE_0 0x00000001 /* DIP switch: boot mode 0 */
#define GABE_BOOTMODE_1 0x00000002 /* DIP switch: boot mode 1 */
#define GABE_DIP_USER_0 0x00000100 /* DIP switch: User 0 */
#define GABE_DIP_USER_1 0x00000200 /* DIP switch: User 1 */
#define SDC_VERSION_REG ((unsigned char *)0x00C00300)
#define SDC_CONTROL_REG ((unsigned char *)0x00C00301)
#define SDC_TRANS_TYPE_REG ((unsigned char *)0x00C00302)
#define SDC_VERSION_REG ((unsigned char *)0xFEC00300)
#define SDC_CONTROL_REG ((unsigned char *)0xFEC00301)
#define SDC_TRANS_TYPE_REG ((unsigned char *)0xFEC00302)
#define SDC_TRANS_CONTROL_REG ((unsigned char *)0x00C00303)
#define SDC_TRANS_STATUS_REG ((unsigned char *)0x00C00304)
#define SDC_TRANS_ERROR_REG ((unsigned char *)0x00C00305)
#define SDC_DIRECT_ACCESS_REG ((unsigned char *)0x00C00306)
#define SDC_SD_ADDR_7_0_REG ((unsigned char *)0x00C00307)
#define SDC_SD_ADDR_15_8_REG ((unsigned char *)0x00C00308)
#define SDC_SD_ADDR_23_16_REG ((unsigned char *)0x00C00309)
#define SDC_SD_ADDR_31_24_REG ((unsigned char *)0x00C0030A)
#define SDC_TRANS_CONTROL_REG ((unsigned char *)0xFEC00303)
#define SDC_TRANS_STATUS_REG ((unsigned char *)0xFEC00304)
#define SDC_TRANS_ERROR_REG ((unsigned char *)0xFEC00305)
#define SDC_DIRECT_ACCESS_REG ((unsigned char *)0xFEC00306)
#define SDC_SD_ADDR_7_0_REG ((unsigned char *)0xFEC00307)
#define SDC_SD_ADDR_15_8_REG ((unsigned char *)0xFEC00308)
#define SDC_SD_ADDR_23_16_REG ((unsigned char *)0xFEC00309)
#define SDC_SD_ADDR_31_24_REG ((unsigned char *)0xFEC0030A)
#define SDC_SPI_CLK_DEL_REG ((unsigned char *)0x00C0030B)
#define SDC_SPI_CLK_DEL_REG ((unsigned char *)0xFEC0030B)
#define SDC_RX_FIFO_DATA_REG ((unsigned char *)0x00C00310)
#define SDC_RX_FIFO_DATA_CNT_HI ((unsigned char *)0x00C00312)
#define SDC_RX_FIFO_DATA_CNT_LO ((unsigned char *)0x00C00313)
#define SDC_RX_FIFO_CTRL_REG ((unsigned char *)0x00C00314)
#define SDC_RX_FIFO_DATA_REG ((unsigned char *)0xFEC00310)
#define SDC_RX_FIFO_DATA_CNT_HI ((unsigned char *)0xFEC00312)
#define SDC_RX_FIFO_DATA_CNT_LO ((unsigned char *)0xFEC00313)
#define SDC_RX_FIFO_CTRL_REG ((unsigned char *)0xFEC00314)
#define SDC_TX_FIFO_DATA_REG ((unsigned char *)0x00C00320)
#define SDC_TX_FIFO_CTRL_REG ((unsigned char *)0x00C00324)
#define SDC_TX_FIFO_DATA_REG ((unsigned char *)0xFEC00320)
#define SDC_TX_FIFO_CTRL_REG ((unsigned char *)0xFEC00324)
#endif

View file

@ -5,13 +5,16 @@
#ifndef __SOUND_A2560K_H
#define __SOUND_A2560K_H
#define PSG_PORT ((volatile unsigned char *)0x00C20100) /* Control register for the SN76489 */
#define OPL3_PORT ((volatile unsigned char *)0x00C20200) /* Access port for the OPL3 */
#define OPM_EXT_BASE ((volatile unsigned char *)0x00C20600) /* External OPM base address */
#define OPN2_EXT_BASE ((volatile unsigned char *)0x00C20400) /* External OPN2 base address */
#define OPM_INT_BASE ((volatile unsigned char *)0x00C20C00) /* Internal OPM base address */
#define OPN2_INT_BASE ((volatile unsigned char *)0x00C20A00) /* Internal OPN2 base address */
#define CODEC ((volatile unsigned short *)0x00C20E00) /* Control register for the CODEC */
#define PSG_PORT ((volatile unsigned char *)0xFEC20100) /* Control register for the SN76489 */
#define PSG_INT_L_PORT ((volatile unsigned char *)0xFEC20110) /* Control register for the SN76489 */
#define PSG_INT_R_PORT ((volatile unsigned char *)0xFEC20120) /* Control register for the SN76489 */
#define PSG_INT_S_PORT ((volatile unsigned char *)0xFEC20130) /* Control register for the SN76489 */
#define OPL3_PORT ((volatile unsigned char *)0xFEC20200) /* Access port for the OPL3 */
#define OPM_EXT_BASE ((volatile unsigned char *)0xFEC20600) /* External OPM base address */
#define OPN2_EXT_BASE ((volatile unsigned char *)0xFEC20400) /* External OPN2 base address */
#define OPM_INT_BASE ((volatile unsigned char *)0xFEC20C00) /* Internal OPM base address */
#define OPN2_INT_BASE ((volatile unsigned char *)0xFEC20A00) /* Internal OPN2 base address */
#define CODEC ((volatile unsigned short *)0xFEC20E00) /* Control register for the CODEC */
/*
* A2560K supports two external, physical SID chips.
@ -28,185 +31,185 @@
* External SID Left Channel
*/
#define SID_EXT_L_V1_FREQ_LO ((unsigned char *)0x00C20800)
#define SID_EXT_L_V1_FREQ_HI ((unsigned char *)0x00C20801)
#define SID_EXT_L_V1_PW_LO ((unsigned char *)0x00C20802)
#define SID_EXT_L_V1_PW_HI ((unsigned char *)0x00C20803)
#define SID_EXT_L_V1_CTRL ((unsigned char *)0x00C20804)
#define SID_EXT_L_V1_ATCK_DECY ((unsigned char *)0x00C20805)
#define SID_EXT_L_V1_SSTN_RLSE ((unsigned char *)0x00C20806)
#define SID_EXT_L_V2_FREQ_LO ((unsigned char *)0x00C20807)
#define SID_EXT_L_V2_FREQ_HI ((unsigned char *)0x00C20808)
#define SID_EXT_L_V2_PW_LO ((unsigned char *)0x00C20809)
#define SID_EXT_L_V2_PW_HI ((unsigned char *)0x00C2080A)
#define SID_EXT_L_V2_CTRL ((unsigned char *)0x00C2080B)
#define SID_EXT_L_V2_ATCK_DECY ((unsigned char *)0x00C2080C)
#define SID_EXT_L_V2_SSTN_RLSE ((unsigned char *)0x00C2080D)
#define SID_EXT_L_V3_FREQ_LO ((unsigned char *)0x00C2080E)
#define SID_EXT_L_V3_FREQ_HI ((unsigned char *)0x00C2080F)
#define SID_EXT_L_V3_PW_LO ((unsigned char *)0x00C20810)
#define SID_EXT_L_V3_PW_HI ((unsigned char *)0x00C20811)
#define SID_EXT_L_V3_CTRL ((unsigned char *)0x00C20812)
#define SID_EXT_L_V3_ATCK_DECY ((unsigned char *)0x00C20813)
#define SID_EXT_L_V3_SSTN_RLSE ((unsigned char *)0x00C20814)
#define SID_EXT_L_FC_LO ((unsigned char *)0x00C20815)
#define SID_EXT_L_FC_HI ((unsigned char *)0x00C20816)
#define SID_EXT_L_RES_FILT ((unsigned char *)0x00C20817)
#define SID_EXT_L_MODE_VOL ((unsigned char *)0x00C20818)
#define SID_EXT_L_POT_X ((unsigned char *)0x00C20819)
#define SID_EXT_L_POT_Y ((unsigned char *)0x00C2081A)
#define SID_EXT_L_OSC3_RND ((unsigned char *)0x00C2081B)
#define SID_EXT_L_ENV3 ((unsigned char *)0x00C2081C)
#define SID_EXT_L_NOT_USED0 ((unsigned char *)0x00C2081D)
#define SID_EXT_L_NOT_USED1 ((unsigned char *)0x00C2081E)
#define SID_EXT_L_NOT_USED2 ((unsigned char *)0x00C2081F)
#define SID_EXT_L_V1_FREQ_LO ((unsigned char *)0xFEC20800)
#define SID_EXT_L_V1_FREQ_HI ((unsigned char *)0xFEC20801)
#define SID_EXT_L_V1_PW_LO ((unsigned char *)0xFEC20802)
#define SID_EXT_L_V1_PW_HI ((unsigned char *)0xFEC20803)
#define SID_EXT_L_V1_CTRL ((unsigned char *)0xFEC20804)
#define SID_EXT_L_V1_ATCK_DECY ((unsigned char *)0xFEC20805)
#define SID_EXT_L_V1_SSTN_RLSE ((unsigned char *)0xFEC20806)
#define SID_EXT_L_V2_FREQ_LO ((unsigned char *)0xFEC20807)
#define SID_EXT_L_V2_FREQ_HI ((unsigned char *)0xFEC20808)
#define SID_EXT_L_V2_PW_LO ((unsigned char *)0xFEC20809)
#define SID_EXT_L_V2_PW_HI ((unsigned char *)0xFEC2080A)
#define SID_EXT_L_V2_CTRL ((unsigned char *)0xFEC2080B)
#define SID_EXT_L_V2_ATCK_DECY ((unsigned char *)0xFEC2080C)
#define SID_EXT_L_V2_SSTN_RLSE ((unsigned char *)0xFEC2080D)
#define SID_EXT_L_V3_FREQ_LO ((unsigned char *)0xFEC2080E)
#define SID_EXT_L_V3_FREQ_HI ((unsigned char *)0xFEC2080F)
#define SID_EXT_L_V3_PW_LO ((unsigned char *)0xFEC20810)
#define SID_EXT_L_V3_PW_HI ((unsigned char *)0xFEC20811)
#define SID_EXT_L_V3_CTRL ((unsigned char *)0xFEC20812)
#define SID_EXT_L_V3_ATCK_DECY ((unsigned char *)0xFEC20813)
#define SID_EXT_L_V3_SSTN_RLSE ((unsigned char *)0xFEC20814)
#define SID_EXT_L_FC_LO ((unsigned char *)0xFEC20815)
#define SID_EXT_L_FC_HI ((unsigned char *)0xFEC20816)
#define SID_EXT_L_RES_FILT ((unsigned char *)0xFEC20817)
#define SID_EXT_L_MODE_VOL ((unsigned char *)0xFEC20818)
#define SID_EXT_L_POT_X ((unsigned char *)0xFEC20819)
#define SID_EXT_L_POT_Y ((unsigned char *)0xFEC2081A)
#define SID_EXT_L_OSC3_RND ((unsigned char *)0xFEC2081B)
#define SID_EXT_L_ENV3 ((unsigned char *)0xFEC2081C)
#define SID_EXT_L_NOT_USED0 ((unsigned char *)0xFEC2081D)
#define SID_EXT_L_NOT_USED1 ((unsigned char *)0xFEC2081E)
#define SID_EXT_L_NOT_USED2 ((unsigned char *)0xFEC2081F)
/*
* External SID Right Channel
*/
#define SID_EXT_R_V1_FREQ_LO ((unsigned char *)0x00C20900)
#define SID_EXT_R_V1_FREQ_HI ((unsigned char *)0x00C20901)
#define SID_EXT_R_V1_PW_LO ((unsigned char *)0x00C20902)
#define SID_EXT_R_V1_PW_HI ((unsigned char *)0x00C20903)
#define SID_EXT_R_V1_CTRL ((unsigned char *)0x00C20904)
#define SID_EXT_R_V1_ATCK_DECY ((unsigned char *)0x00C20905)
#define SID_EXT_R_V1_SSTN_RLSE ((unsigned char *)0x00C20906)
#define SID_EXT_R_V2_FREQ_LO ((unsigned char *)0x00C20907)
#define SID_EXT_R_V2_FREQ_HI ((unsigned char *)0x00C20908)
#define SID_EXT_R_V2_PW_LO ((unsigned char *)0x00C20909)
#define SID_EXT_R_V2_PW_HI ((unsigned char *)0x00C2090A)
#define SID_EXT_R_V2_CTRL ((unsigned char *)0x00C2090B)
#define SID_EXT_R_V2_ATCK_DECY ((unsigned char *)0x00C2090C)
#define SID_EXT_R_V2_SSTN_RLSE ((unsigned char *)0x00C2090D)
#define SID_EXT_R_V3_FREQ_LO ((unsigned char *)0x00C2090E)
#define SID_EXT_R_V3_FREQ_HI ((unsigned char *)0x00C2090F)
#define SID_EXT_R_V3_PW_LO ((unsigned char *)0x00C20910)
#define SID_EXT_R_V3_PW_HI ((unsigned char *)0x00C20911)
#define SID_EXT_R_V3_CTRL ((unsigned char *)0x00C20912)
#define SID_EXT_R_V3_ATCK_DECY ((unsigned char *)0x00C20913)
#define SID_EXT_R_V3_SSTN_RLSE ((unsigned char *)0x00C20914)
#define SID_EXT_R_FC_LO ((unsigned char *)0x00C20915)
#define SID_EXT_R_FC_HI ((unsigned char *)0x00C20916)
#define SID_EXT_R_RES_FILT ((unsigned char *)0x00C20917)
#define SID_EXT_R_MODE_VOL ((unsigned char *)0x00C20918)
#define SID_EXT_R_POT_X ((unsigned char *)0x00C20919)
#define SID_EXT_R_POT_Y ((unsigned char *)0x00C2091A)
#define SID_EXT_R_OSC3_RND ((unsigned char *)0x00C2091B)
#define SID_EXT_R_ENV3 ((unsigned char *)0x00C2091C)
#define SID_EXT_R_NOT_USED0 ((unsigned char *)0x00C2091D)
#define SID_EXT_R_NOT_USED1 ((unsigned char *)0x00C2091E)
#define SID_EXT_R_NOT_USED2 ((unsigned char *)0x00C2091F)
#define SID_EXT_R_V1_FREQ_LO ((unsigned char *)0xFEC20900)
#define SID_EXT_R_V1_FREQ_HI ((unsigned char *)0xFEC20901)
#define SID_EXT_R_V1_PW_LO ((unsigned char *)0xFEC20902)
#define SID_EXT_R_V1_PW_HI ((unsigned char *)0xFEC20903)
#define SID_EXT_R_V1_CTRL ((unsigned char *)0xFEC20904)
#define SID_EXT_R_V1_ATCK_DECY ((unsigned char *)0xFEC20905)
#define SID_EXT_R_V1_SSTN_RLSE ((unsigned char *)0xFEC20906)
#define SID_EXT_R_V2_FREQ_LO ((unsigned char *)0xFEC20907)
#define SID_EXT_R_V2_FREQ_HI ((unsigned char *)0xFEC20908)
#define SID_EXT_R_V2_PW_LO ((unsigned char *)0xFEC20909)
#define SID_EXT_R_V2_PW_HI ((unsigned char *)0xFEC2090A)
#define SID_EXT_R_V2_CTRL ((unsigned char *)0xFEC2090B)
#define SID_EXT_R_V2_ATCK_DECY ((unsigned char *)0xFEC2090C)
#define SID_EXT_R_V2_SSTN_RLSE ((unsigned char *)0xFEC2090D)
#define SID_EXT_R_V3_FREQ_LO ((unsigned char *)0xFEC2090E)
#define SID_EXT_R_V3_FREQ_HI ((unsigned char *)0xFEC2090F)
#define SID_EXT_R_V3_PW_LO ((unsigned char *)0xFEC20910)
#define SID_EXT_R_V3_PW_HI ((unsigned char *)0xFEC20911)
#define SID_EXT_R_V3_CTRL ((unsigned char *)0xFEC20912)
#define SID_EXT_R_V3_ATCK_DECY ((unsigned char *)0xFEC20913)
#define SID_EXT_R_V3_SSTN_RLSE ((unsigned char *)0xFEC20914)
#define SID_EXT_R_FC_LO ((unsigned char *)0xFEC20915)
#define SID_EXT_R_FC_HI ((unsigned char *)0xFEC20916)
#define SID_EXT_R_RES_FILT ((unsigned char *)0xFEC20917)
#define SID_EXT_R_MODE_VOL ((unsigned char *)0xFEC20918)
#define SID_EXT_R_POT_X ((unsigned char *)0xFEC20919)
#define SID_EXT_R_POT_Y ((unsigned char *)0xFEC2091A)
#define SID_EXT_R_OSC3_RND ((unsigned char *)0xFEC2091B)
#define SID_EXT_R_ENV3 ((unsigned char *)0xFEC2091C)
#define SID_EXT_R_NOT_USED0 ((unsigned char *)0xFEC2091D)
#define SID_EXT_R_NOT_USED1 ((unsigned char *)0xFEC2091E)
#define SID_EXT_R_NOT_USED2 ((unsigned char *)0xFEC2091F)
/*
* Internal SID Left Channel
*/
#define SID_INT_L_V1_FREQ_LO ((unsigned char *)0x00C21000)
#define SID_INT_L_V1_FREQ_HI ((unsigned char *)0x00C21001)
#define SID_INT_L_V1_PW_LO ((unsigned char *)0x00C21002)
#define SID_INT_L_V1_PW_HI ((unsigned char *)0x00C21003)
#define SID_INT_L_V1_CTRL ((unsigned char *)0x00C21004)
#define SID_INT_L_V1_ATCK_DECY ((unsigned char *)0x00C21005)
#define SID_INT_L_V1_SSTN_RLSE ((unsigned char *)0x00C21006)
#define SID_INT_L_V2_FREQ_LO ((unsigned char *)0x00C21007)
#define SID_INT_L_V2_FREQ_HI ((unsigned char *)0x00C21008)
#define SID_INT_L_V2_PW_LO ((unsigned char *)0x00C21009)
#define SID_INT_L_V2_PW_HI ((unsigned char *)0x00C2100A)
#define SID_INT_L_V2_CTRL ((unsigned char *)0x00C2100B)
#define SID_INT_L_V2_ATCK_DECY ((unsigned char *)0x00C2100C)
#define SID_INT_L_V2_SSTN_RLSE ((unsigned char *)0x00C2100D)
#define SID_INT_L_V3_FREQ_LO ((unsigned char *)0x00C2100E)
#define SID_INT_L_V3_FREQ_HI ((unsigned char *)0x00C2100F)
#define SID_INT_L_V3_PW_LO ((unsigned char *)0x00C21010)
#define SID_INT_L_V3_PW_HI ((unsigned char *)0x00C21011)
#define SID_INT_L_V3_CTRL ((unsigned char *)0x00C21012)
#define SID_INT_L_V3_ATCK_DECY ((unsigned char *)0x00C21013)
#define SID_INT_L_V3_SSTN_RLSE ((unsigned char *)0x00C21014)
#define SID_INT_L_FC_LO ((unsigned char *)0x00C21015)
#define SID_INT_L_FC_HI ((unsigned char *)0x00C21016)
#define SID_INT_L_RES_FILT ((unsigned char *)0x00C21017)
#define SID_INT_L_MODE_VOL ((unsigned char *)0x00C21018)
#define SID_INT_L_POT_X ((unsigned char *)0x00C21019)
#define SID_INT_L_POT_Y ((unsigned char *)0x00C2101A)
#define SID_INT_L_OSC3_RND ((unsigned char *)0x00C2101B)
#define SID_INT_L_ENV3 ((unsigned char *)0x00C2101C)
#define SID_INT_L_NOT_USED0 ((unsigned char *)0x00C2101D)
#define SID_INT_L_NOT_USED1 ((unsigned char *)0x00C2101E)
#define SID_INT_L_NOT_USED2 ((unsigned char *)0x00C2101F)
#define SID_INT_L_V1_FREQ_LO ((unsigned char *)0xFEC21000)
#define SID_INT_L_V1_FREQ_HI ((unsigned char *)0xFEC21001)
#define SID_INT_L_V1_PW_LO ((unsigned char *)0xFEC21002)
#define SID_INT_L_V1_PW_HI ((unsigned char *)0xFEC21003)
#define SID_INT_L_V1_CTRL ((unsigned char *)0xFEC21004)
#define SID_INT_L_V1_ATCK_DECY ((unsigned char *)0xFEC21005)
#define SID_INT_L_V1_SSTN_RLSE ((unsigned char *)0xFEC21006)
#define SID_INT_L_V2_FREQ_LO ((unsigned char *)0xFEC21007)
#define SID_INT_L_V2_FREQ_HI ((unsigned char *)0xFEC21008)
#define SID_INT_L_V2_PW_LO ((unsigned char *)0xFEC21009)
#define SID_INT_L_V2_PW_HI ((unsigned char *)0xFEC2100A)
#define SID_INT_L_V2_CTRL ((unsigned char *)0xFEC2100B)
#define SID_INT_L_V2_ATCK_DECY ((unsigned char *)0xFEC2100C)
#define SID_INT_L_V2_SSTN_RLSE ((unsigned char *)0xFEC2100D)
#define SID_INT_L_V3_FREQ_LO ((unsigned char *)0xFEC2100E)
#define SID_INT_L_V3_FREQ_HI ((unsigned char *)0xFEC2100F)
#define SID_INT_L_V3_PW_LO ((unsigned char *)0xFEC21010)
#define SID_INT_L_V3_PW_HI ((unsigned char *)0xFEC21011)
#define SID_INT_L_V3_CTRL ((unsigned char *)0xFEC21012)
#define SID_INT_L_V3_ATCK_DECY ((unsigned char *)0xFEC21013)
#define SID_INT_L_V3_SSTN_RLSE ((unsigned char *)0xFEC21014)
#define SID_INT_L_FC_LO ((unsigned char *)0xFEC21015)
#define SID_INT_L_FC_HI ((unsigned char *)0xFEC21016)
#define SID_INT_L_RES_FILT ((unsigned char *)0xFEC21017)
#define SID_INT_L_MODE_VOL ((unsigned char *)0xFEC21018)
#define SID_INT_L_POT_X ((unsigned char *)0xFEC21019)
#define SID_INT_L_POT_Y ((unsigned char *)0xFEC2101A)
#define SID_INT_L_OSC3_RND ((unsigned char *)0xFEC2101B)
#define SID_INT_L_ENV3 ((unsigned char *)0xFEC2101C)
#define SID_INT_L_NOT_USED0 ((unsigned char *)0xFEC2101D)
#define SID_INT_L_NOT_USED1 ((unsigned char *)0xFEC2101E)
#define SID_INT_L_NOT_USED2 ((unsigned char *)0xFEC2101F)
/*
* Internal SID Right Channel
*/
#define SID_INT_R_V1_FREQ_LO ((unsigned char *)0x00C21200)
#define SID_INT_R_V1_FREQ_HI ((unsigned char *)0x00C21201)
#define SID_INT_R_V1_PW_LO ((unsigned char *)0x00C21202)
#define SID_INT_R_V1_PW_HI ((unsigned char *)0x00C21203)
#define SID_INT_R_V1_CTRL ((unsigned char *)0x00C21204)
#define SID_INT_R_V1_ATCK_DECY ((unsigned char *)0x00C21205)
#define SID_INT_R_V1_SSTN_RLSE ((unsigned char *)0x00C21206)
#define SID_INT_R_V2_FREQ_LO ((unsigned char *)0x00C21207)
#define SID_INT_R_V2_FREQ_HI ((unsigned char *)0x00C21208)
#define SID_INT_R_V2_PW_LO ((unsigned char *)0x00C21209)
#define SID_INT_R_V2_PW_HI ((unsigned char *)0x00C2120A)
#define SID_INT_R_V2_CTRL ((unsigned char *)0x00C2120B)
#define SID_INT_R_V2_ATCK_DECY ((unsigned char *)0x00C2120C)
#define SID_INT_R_V2_SSTN_RLSE ((unsigned char *)0x00C2120D)
#define SID_INT_R_V3_FREQ_LO ((unsigned char *)0x00C2120E)
#define SID_INT_R_V3_FREQ_HI ((unsigned char *)0x00C2120F)
#define SID_INT_R_V3_PW_LO ((unsigned char *)0x00C21210)
#define SID_INT_R_V3_PW_HI ((unsigned char *)0x00C21211)
#define SID_INT_R_V3_CTRL ((unsigned char *)0x00C21212)
#define SID_INT_R_V3_ATCK_DECY ((unsigned char *)0x00C21213)
#define SID_INT_R_V3_SSTN_RLSE ((unsigned char *)0x00C21214)
#define SID_INT_R_FC_LO ((unsigned char *)0x00C21215)
#define SID_INT_R_FC_HI ((unsigned char *)0x00C21216)
#define SID_INT_R_RES_FILT ((unsigned char *)0x00C21217)
#define SID_INT_R_MODE_VOL ((unsigned char *)0x00C21218)
#define SID_INT_R_POT_X ((unsigned char *)0x00C21219)
#define SID_INT_R_POT_Y ((unsigned char *)0x00C2121A)
#define SID_INT_R_OSC3_RND ((unsigned char *)0x00C2121B)
#define SID_INT_R_ENV3 ((unsigned char *)0x00C2121C)
#define SID_INT_R_NOT_USED0 ((unsigned char *)0x00C2121D)
#define SID_INT_R_NOT_USED1 ((unsigned char *)0x00C2121E)
#define SID_INT_R_NOT_USED2 ((unsigned char *)0x00C2121F)
#define SID_INT_R_V1_FREQ_LO ((unsigned char *)0xFEC21200)
#define SID_INT_R_V1_FREQ_HI ((unsigned char *)0xFEC21201)
#define SID_INT_R_V1_PW_LO ((unsigned char *)0xFEC21202)
#define SID_INT_R_V1_PW_HI ((unsigned char *)0xFEC21203)
#define SID_INT_R_V1_CTRL ((unsigned char *)0xFEC21204)
#define SID_INT_R_V1_ATCK_DECY ((unsigned char *)0xFEC21205)
#define SID_INT_R_V1_SSTN_RLSE ((unsigned char *)0xFEC21206)
#define SID_INT_R_V2_FREQ_LO ((unsigned char *)0xFEC21207)
#define SID_INT_R_V2_FREQ_HI ((unsigned char *)0xFEC21208)
#define SID_INT_R_V2_PW_LO ((unsigned char *)0xFEC21209)
#define SID_INT_R_V2_PW_HI ((unsigned char *)0xFEC2120A)
#define SID_INT_R_V2_CTRL ((unsigned char *)0xFEC2120B)
#define SID_INT_R_V2_ATCK_DECY ((unsigned char *)0xFEC2120C)
#define SID_INT_R_V2_SSTN_RLSE ((unsigned char *)0xFEC2120D)
#define SID_INT_R_V3_FREQ_LO ((unsigned char *)0xFEC2120E)
#define SID_INT_R_V3_FREQ_HI ((unsigned char *)0xFEC2120F)
#define SID_INT_R_V3_PW_LO ((unsigned char *)0xFEC21210)
#define SID_INT_R_V3_PW_HI ((unsigned char *)0xFEC21211)
#define SID_INT_R_V3_CTRL ((unsigned char *)0xFEC21212)
#define SID_INT_R_V3_ATCK_DECY ((unsigned char *)0xFEC21213)
#define SID_INT_R_V3_SSTN_RLSE ((unsigned char *)0xFEC21214)
#define SID_INT_R_FC_LO ((unsigned char *)0xFEC21215)
#define SID_INT_R_FC_HI ((unsigned char *)0xFEC21216)
#define SID_INT_R_RES_FILT ((unsigned char *)0xFEC21217)
#define SID_INT_R_MODE_VOL ((unsigned char *)0xFEC21218)
#define SID_INT_R_POT_X ((unsigned char *)0xFEC21219)
#define SID_INT_R_POT_Y ((unsigned char *)0xFEC2121A)
#define SID_INT_R_OSC3_RND ((unsigned char *)0xFEC2121B)
#define SID_INT_R_ENV3 ((unsigned char *)0xFEC2121C)
#define SID_INT_R_NOT_USED0 ((unsigned char *)0xFEC2121D)
#define SID_INT_R_NOT_USED1 ((unsigned char *)0xFEC2121E)
#define SID_INT_R_NOT_USED2 ((unsigned char *)0xFEC2121F)
/*
* Internal SID Neutral Channel - When writting here, the value is written in R and L Channel at the same time
*/
#define SID_INT_N_V1_FREQ_LO ((unsigned char *)0x00C41200)
#define SID_INT_N_V1_FREQ_HI ((unsigned char *)0x00C41201)
#define SID_INT_N_V1_PW_LO ((unsigned char *)0x00C41202)
#define SID_INT_N_V1_PW_HI ((unsigned char *)0x00C41203)
#define SID_INT_N_V1_CTRL ((unsigned char *)0x00C41204)
#define SID_INT_N_V1_ATCK_DECY ((unsigned char *)0x00C41205)
#define SID_INT_N_V1_SSTN_RLSE ((unsigned char *)0x00C41206)
#define SID_INT_N_V2_FREQ_LO ((unsigned char *)0x00C41207)
#define SID_INT_N_V2_FREQ_HI ((unsigned char *)0x00C41208)
#define SID_INT_N_V2_PW_LO ((unsigned char *)0x00C41209)
#define SID_INT_N_V2_PW_HI ((unsigned char *)0x00C4120A)
#define SID_INT_N_V2_CTRL ((unsigned char *)0x00C4120B)
#define SID_INT_N_V2_ATCK_DECY ((unsigned char *)0x00C4120C)
#define SID_INT_N_V2_SSTN_RLSE ((unsigned char *)0x00C4120D)
#define SID_INT_N_V3_FREQ_LO ((unsigned char *)0x00C4120E)
#define SID_INT_N_V3_FREQ_HI ((unsigned char *)0x00C4120F)
#define SID_INT_N_V3_PW_LO ((unsigned char *)0x00C41210)
#define SID_INT_N_V3_PW_HI ((unsigned char *)0x00C41211)
#define SID_INT_N_V3_CTRL ((unsigned char *)0x00C41212)
#define SID_INT_N_V3_ATCK_DECY ((unsigned char *)0x00C41213)
#define SID_INT_N_V3_SSTN_RLSE ((unsigned char *)0x00C41214)
#define SID_INT_N_FC_LO ((unsigned char *)0x00C41215)
#define SID_INT_N_FC_HI ((unsigned char *)0x00C41216)
#define SID_INT_N_RES_FILT ((unsigned char *)0x00C41217)
#define SID_INT_N_MODE_VOL ((unsigned char *)0x00C41218)
#define SID_INT_N_POT_X ((unsigned char *)0x00C41219)
#define SID_INT_N_POT_Y ((unsigned char *)0x00C4121A)
#define SID_INT_N_OSC3_RND ((unsigned char *)0x00C4121B)
#define SID_INT_N_ENV3 ((unsigned char *)0x00C4121C)
#define SID_INT_N_NOT_USED0 ((unsigned char *)0x00C4121D)
#define SID_INT_N_NOT_USED1 ((unsigned char *)0x00C4121E)
#define SID_INT_N_NOT_USED2 ((unsigned char *)0x00C4121F)
#define SID_INT_N_V1_FREQ_LO ((unsigned char *)0xFEC41200)
#define SID_INT_N_V1_FREQ_HI ((unsigned char *)0xFEC41201)
#define SID_INT_N_V1_PW_LO ((unsigned char *)0xFEC41202)
#define SID_INT_N_V1_PW_HI ((unsigned char *)0xFEC41203)
#define SID_INT_N_V1_CTRL ((unsigned char *)0xFEC41204)
#define SID_INT_N_V1_ATCK_DECY ((unsigned char *)0xFEC41205)
#define SID_INT_N_V1_SSTN_RLSE ((unsigned char *)0xFEC41206)
#define SID_INT_N_V2_FREQ_LO ((unsigned char *)0xFEC41207)
#define SID_INT_N_V2_FREQ_HI ((unsigned char *)0xFEC41208)
#define SID_INT_N_V2_PW_LO ((unsigned char *)0xFEC41209)
#define SID_INT_N_V2_PW_HI ((unsigned char *)0xFEC4120A)
#define SID_INT_N_V2_CTRL ((unsigned char *)0xFEC4120B)
#define SID_INT_N_V2_ATCK_DECY ((unsigned char *)0xFEC4120C)
#define SID_INT_N_V2_SSTN_RLSE ((unsigned char *)0xFEC4120D)
#define SID_INT_N_V3_FREQ_LO ((unsigned char *)0xFEC4120E)
#define SID_INT_N_V3_FREQ_HI ((unsigned char *)0xFEC4120F)
#define SID_INT_N_V3_PW_LO ((unsigned char *)0xFEC41210)
#define SID_INT_N_V3_PW_HI ((unsigned char *)0xFEC41211)
#define SID_INT_N_V3_CTRL ((unsigned char *)0xFEC41212)
#define SID_INT_N_V3_ATCK_DECY ((unsigned char *)0xFEC41213)
#define SID_INT_N_V3_SSTN_RLSE ((unsigned char *)0xFEC41214)
#define SID_INT_N_FC_LO ((unsigned char *)0xFEC41215)
#define SID_INT_N_FC_HI ((unsigned char *)0xFEC41216)
#define SID_INT_N_RES_FILT ((unsigned char *)0xFEC41217)
#define SID_INT_N_MODE_VOL ((unsigned char *)0xFEC41218)
#define SID_INT_N_POT_X ((unsigned char *)0xFEC41219)
#define SID_INT_N_POT_Y ((unsigned char *)0xFEC4121A)
#define SID_INT_N_OSC3_RND ((unsigned char *)0xFEC4121B)
#define SID_INT_N_ENV3 ((unsigned char *)0xFEC4121C)
#define SID_INT_N_NOT_USED0 ((unsigned char *)0xFEC4121D)
#define SID_INT_N_NOT_USED1 ((unsigned char *)0xFEC4121E)
#define SID_INT_N_NOT_USED2 ((unsigned char *)0xFEC4121F)
#endif

View file

@ -0,0 +1,64 @@
/**
* @file timers_a2560k.h
*
* Define timer registers on the A2560K
*/
#ifndef __A2560K_TIMERS_H
#define __A2560K_TIMERS_H
/** Timer control register 0: timers 0, 1, and 2 */
#define TIMER_TCR0 ((unsigned long *)0xFEC00200)
#define TCR_ENABLE_0 0x00000001 /** Enable counter 0 */
#define TCR_CLEAR_0 0x00000002 /** Master clear of counter 0 */
#define TCR_LOAD_0 0x00000004 /** Master load of counter 0 */
#define TCR_CNTUP_0 0x00000008 /** Counter 0 Count up if 1, count down if 0 */
#define TCR_INE_0 0x00000080 /** Interrupt enable for counter 0 */
#define TCR_ENABLE_1 0x00000100 /** Enable counter 1 */
#define TCR_CLEAR_1 0x00000200 /** Master clear of counter 1 */
#define TCR_LOAD_1 0x00000400 /** Master load of counter 1 */
#define TCR_CNTUP_1 0x00000800 /** Counter 1 Count up if 1, count down if 0 */
#define TCR_INE_1 0x00008000 /** Interrupt enable for counter 1 */
#define TCR_ENABLE_2 0x00010000 /** Enable counter 2 */
#define TCR_CLEAR_2 0x00020000 /** Master clear of counter 2 */
#define TCR_LOAD_2 0x00040000 /** Master load of counter 2 */
#define TCR_CNTUP_2 0x00080000 /** Counter 2 Count up if 1, count down if 0 */
#define TCR_INE_2 0x00800000 /** Interrupt enable for counter 2 */
/** Timer control register 1: timers 3 and 4 */
#define TIMER_TCR1 ((unsigned long *)0xFEC00204)
#define TCR_ENABLE_3 0x00000001 /** Enable counter 3 */
#define TCR_CLEAR_3 0x00000002 /** Master clear of counter 3 */
#define TCR_LOAD_3 0x00000004 /** Master load of counter 3 */
#define TCR_CNTUP_3 0x00000008 /** Counter 3 Count up if 1, count down if 0 */
#define TCR_RECLR_3 0x00000010 /** Enable reclear of timer 3 */
#define TCR_RELOAD_3 0x00000020 /** Enable reload of timer 3 */
#define TCR_INE_3 0x00000080 /** Interrupt enable for counter 3 */
#define TCR_ENABLE_4 0x00000100 /** Enable counter 4 */
#define TCR_CLEAR_4 0x00000200 /** Master clear of counter 4 */
#define TCR_LOAD_4 0x00000400 /** Master load of counter 4 */
#define TCR_CNTUP_4 0x00000800 /** Counter 4 Count up if 1, count down if 0 */
#define TCR_RECLR_4 0x00001000 /** Enable reclear of timer 4 */
#define TCR_RELOAD_4 0x00002000 /** Enable reload of timer 4 */
#define TCR_INE_4 0x00008000 /** Interrupt enable for counter 4 */
#define TCR_STAT_EQ0 0x08000000 /** Read only: timer 0 is equal to its comparison value */
#define TCR_STAT_EQ1 0x10000000 /** Read only: timer 1 is equal to its comparison value */
#define TCR_STAT_EQ2 0x20000000 /** Read only: timer 2 is equal to its comparison value */
#define TCR_STAT_EQ3 0x40000000 /** Read only: timer 3 is equal to its comparison value */
#define TIMER_VALUE_0 ((unsigned long *)0xFEC00208)
#define TIMER_COMPARE_0 ((unsigned long *)0xFEC0020C)
#define TIMER_VALUE_1 ((unsigned long *)0xFEC00210)
#define TIMER_COMPARE_1 ((unsigned long *)0xFEC00214)
#define TIMER_VALUE_2 ((unsigned long *)0xFEC00218)
#define TIMER_COMPARE_2 ((unsigned long *)0xFEC0021C)
#define TIMER_VALUE_3 ((unsigned long *)0xFEC00220)
#define TIMER_COMPARE_3 ((unsigned long *)0xFEC00224)
#define TIMER_VALUE_4 ((unsigned long *)0xFEC00228)
#define TIMER_COMPARE_4 ((unsigned long *)0xFEC0022C)
#endif

View file

@ -0,0 +1,52 @@
/**
* @file vky_chan_a.h
*
* Define register addresses needed for A2560K channel A text driver
*/
#ifndef __VKY_CHAN_A_H
#define __VKY_CHAN_A_H
/** Master Control Register for Channel A, and its supported bits */
#define VKY3_A_MCR ((volatile unsigned long *)0xFEC40000)
#define VKY3_A_MCR_TEXT 0x00000001 /**< Text mode enable bit */
#define VKY3_A_MCR_SLEEP 0x00040000 /**< Monitor sleep (synch disable) bit */
#define VKY3_A_1024x768 0x00000800 /**< Bit to select 1024x768 screen resolution */
#define VKY3_A_HIRES 0x40000000 /**< Bit to indicate on read if hi-res display is requested on the DIP switches */
#define VKY3_A_CLK40 0x80000000 /**< Indicate if PLL is 25MHz (0) or 40MHz (1) */
/** Border control register for Channel A */
#define VKY3_A_BCR ((volatile unsigned long *)0xFEC40004)
#define VKY3_A_BCR_ENABLE 0x00000001 /**< Bit to enable the display of the border */
/** Border color register for Channel A */
#define VKY3_A_BRDCOLOR ((volatile unsigned long *)0xFEC40008)
/** Cursor Control Register for Channel A */
#define VKY3_A_CCR ((volatile unsigned long *)0xFEC40010)
#define VKY3_A_CCR_ENABLE 0x00000001 /**< Bit to enable the display of the cursor */
#define VKY3_A_CCR_RATE0 0x00000002 /**< Bit0 to specify the blink rate */
#define VKY3_A_CCR_RATE1 0x00000004 /**< Bit1 to specify the blink rate */
/** Cursor Position Register for Channel A */
#define VKY3_A_CPR ((volatile unsigned long *)0xFEC40014)
/** Font Manager Registers for Channel A */
#define VKY3_A_FM0 ((volatile unsigned long *)0xFEC40020)
#define VKY3_A_FM1 ((volatile unsigned long *)0xFEC40024)
/** Font memory block for Channel A */
#define VKY3_A_FONT_MEMORY ((volatile unsigned char *)0xFEC48000)
/** Text Matrix for Channel A */
#define VKY3_A_TEXT_MATRIX ((volatile unsigned char *)0xFEC60000)
/** Color Matrix for Channel A */
#define VKY3_A_COLOR_MATRIX ((volatile unsigned char *)0xFEC68000)
/* Text Color LUTs for Channel A */
#define VKY3_A_LUT_SIZE 16
#define VKY3_A_TEXT_LUT_FG ((volatile unsigned long *)0xFEC6C400) /**< Text foreground color look up table for channel A */
#define VKY3_A_TEXT_LUT_BG ((volatile unsigned long *)0xFEC6C440) /**< Text background color look up table for channel A */
#endif

View file

@ -0,0 +1,57 @@
/**
* @file vky_chan_b.h
*
* Define register addresses needed for A2560K channel B text driver
*/
#ifndef __VKY_CHAN_B_H
#define __VKY_CHAN_B_H
/** Master Control Register for Channel B, and its supported bits */
#define VKY3_B_MCR ((volatile unsigned long *)0xFEC80000)
#define VKY3_B_MCR_TEXT 0x00000001 /**< Text mode enable bit */
#define VKY3_B_MCR_TXT_OVR 0x00000002 /**< Text overlay enable bit */
#define VKY3_B_MCR_GRAPHICS 0x00000004 /**< Graphics mode enable bit */
#define VKY3_B_MCR_BITMAP 0x00000008 /**< Bitmap engineg enable bit */
#define VKY3_B_MCR_TILE 0x00000010 /**< Tile engine enable bit */
#define VKY3_B_MCR_SPRITE 0x00000020 /**< Sprite engine enable bit */
#define VKY3_B_MCR_BLANK 0x00000080 /**< Disable display engine enable bit */
#define VKY3_B_MODE0 0x00000100 /**< Video Mode Bit 0 */
#define VKY3_B_MODE1 0x00000200 /**< Video Mode Bit 1 */
#define VKY3_B_DOUBLE 0x00000400 /**< Pixel Double Enable bit */
#define VKY3_B_HIRES 0x40000000 /**< DIP switch for hires mode */
#define VKY3_B_PLL 0x00000800 /**< Controls dot clock */
#define VKY3_B_MCR_SLEEP 0x00040000 /**< Monitor sleep (synch disable) bit */
#define VKY3_B_CLK40 0x80000000 /**< Indicate if PLL is 25MHz (0) or 40MHz (1) */
/** Border control register for Channel B */
#define VKY3_B_BCR ((volatile unsigned long *)0xFEC80004)
#define VKY3_B_BCR_ENABLE 0x00000001 /**< Bit to enable the display of the border */
/** Border color register for Channel B */
#define VKY3_B_BRDCOLOR ((volatile unsigned long *)0xFEC80008)
/** Cursor Control Register for Channel B */
#define VKY3_B_CCR ((volatile unsigned long *)0xFEC80010)
#define VKY3_B_CCR_ENABLE 0x00000001 /**< Bit to enable the display of the cursor */
#define VKY3_B_CCR_RATE0 0x00000002 /**< Bit0 to specify the blink rate */
#define VKY3_B_CCR_RATE1 0x00000004 /**< Bit1 to specify the blink rate */
/** Cursor Position Register for Channel B */
#define VKY3_B_CPR ((volatile unsigned long *)0xFEC80014)
/** Font memory block for Channel B */
#define VKY3_B_FONT_MEMORY ((volatile unsigned char *)0xFEC88000)
/** Text Matrix for Channel B */
#define VKY3_B_TEXT_MATRIX ((volatile unsigned char *)0xFECA0000)
/** Color Matrix for Channel B */
#define VKY3_B_COLOR_MATRIX ((volatile unsigned char *)0xFECA8000)
/* Text Color LUTs for Channel B */
#define VKY3_B_LUT_SIZE 16
#define VKY3_B_TEXT_LUT_FG ((volatile unsigned long *)0xFECAC400) /**< Text foreground color look up table for channel B */
#define VKY3_B_TEXT_LUT_BG ((volatile unsigned long *)0xFECAC440) /**< Text background color look up table for channel B */
#endif

View file

@ -0,0 +1,48 @@
/**
* @file gabe_a2560u.h
*
* Define miscellaneous GABE registers
*/
#ifndef __GABE_A2560U_H
#define __GABE_A2560U_H
#define GABE_CTRL_REG ((volatile unsigned short *)0x00B00000)
#define POWER_ON_LED 0x0001
#define SDCARD_LED 0x0002
#define BUZZER_CONTROL 0x0010
#define MANUAL_RESET 0x8000 // Make sure the word "DEAD" is written in GABE_RESET_ID
#define GABE_RESET_ID ((volatile unsigned short *)0x00B00002)
#define GABE_LFSR_REG0 ((volatile unsigned short *)0x00B00004)
#define GABE_LFSR_REG1 ((volatile unsigned short *)0x00B00006)
#define RGB_LED_L ((volatile unsigned short *)0x00B00008) // Writing Only - A2560K Only - 0x__RR
#define RGB_LED_H ((volatile unsigned short *)0x00B0000A) // Writing Only - A2560K Only - 0xGGBB
#define GABE_LFSR_DATA ((volatile unsigned short *)0x00B00008) // Read Only
#define GABE_LFSR_STAT ((volatile unsigned short *)0x00B0000A) // Read Only
#define GABE_MACHINE_ID ((volatile unsigned short *)0x00B0000C) // Machine ID - Read Only
#define GABE_MACH_ID_MASK 0x0003 // 1001 = A2560U and U+
#define GABE_MEMORY_BANKS 0x00C0 // 10 = 2 MB, 11 = 4 MB
#define GABE_CPU_SPEED 0x0F00
#define GABE_CPU_ID 0xF000 // 0000 = MC68SEC000 @ 20MHz
#define FPGA_DATE_YEAR ((volatile unsigned short *)0x00B40030) // YYYY
#define FPGA_DATE_MONTHDAY ((volatile unsigned short *)0x00B40032) // MMDD
#define PCB_REV_1 ((volatile unsigned short *)0x00B40034) // Null terminated string describing the PCB
#define PCB_REV_2 ((volatile unsigned short *)0x00B40036)
#define FPGA_SUBVER ((volatile unsigned short *)0x00B40038)
#define FPGA_VER ((volatile unsigned short *)0x00B4003A)
#define FPGA_MODEL_L ((volatile unsigned short *)0x00B4003C)
#define FPGA_MODEL_H ((volatile unsigned short *)0x00B4003E)
#define GABE_CHIP_SUBREV ((volatile unsigned short *)0x00B0000E)
#define GABE_CHIP_VERSION ((volatile unsigned short *)0x00B00010)
#define GABE_CHIP_NUMBER ((volatile unsigned short *)0x00B00012)
#define GABE_DIP_REG ((volatile unsigned short *)0x00B00518)
#define GABE_DIP_BOOT_MASK 0x0003 /* Mask for the boot mode: */
#define GABE_DIP_USER_MASK 0x0300 /* Mask for the user switches: */

View file

@ -0,0 +1,54 @@
/**
* @file timers_a2560u.h
*
* Define timer registers on the A2560U and U+
*/
#ifndef __A2560U_TIMERS_H
#define __A2560U_TIMERS_H
/** Timer control register 0: timers 0, 1, and 2 */
#define TIMER_TCR0 ((unsigned long *)0x00B00200)
#define TCR_ENABLE_0 0x00000001 /** Enable counter 0 */
#define TCR_CLEAR_0 0x00000002 /** Master clear of counter 0 */
#define TCR_LOAD_0 0x00000004 /** Master load of counter 0 */
#define TCR_CNTUP_0 0x00000008 /** Counter 0 Count up if 1, count down if 0 */
#define TCR_INE_0 0x00000080 /** Interrupt enable for counter 0 */
#define TCR_ENABLE_1 0x00000100 /** Enable counter 1 */
#define TCR_CLEAR_1 0x00000200 /** Master clear of counter 1 */
#define TCR_LOAD_1 0x00000400 /** Master load of counter 1 */
#define TCR_CNTUP_1 0x00000800 /** Counter 1 Count up if 1, count down if 0 */
#define TCR_INE_1 0x00008000 /** Interrupt enable for counter 1 */
#define TCR_ENABLE_2 0x00010000 /** Enable counter 2 */
#define TCR_CLEAR_2 0x00020000 /** Master clear of counter 2 */
#define TCR_LOAD_2 0x00040000 /** Master load of counter 2 */
#define TCR_CNTUP_2 0x00080000 /** Counter 2 Count up if 1, count down if 0 */
#define TCR_INE_2 0x00800000 /** Interrupt enable for counter 2 */
/** Timer control register 1: timer 3 */
#define TIMER_TCR1 ((unsigned long *)0x00B00204)
#define TCR_ENABLE_3 0x00000001 /** Enable counter 3 */
#define TCR_CLEAR_3 0x00000002 /** Master clear of counter 3 */
#define TCR_LOAD_3 0x00000004 /** Master load of counter 3 */
#define TCR_CNTUP_3 0x00000008 /** Counter 3 Count up if 1, count down if 0 */
#define TCR_RECLR_3 0x00000010 /** Enable reclear of timer 3 */
#define TCR_RELOAD_3 0x00000020 /** Enable reload of timer 3 */
#define TCR_INE_3 0x00000080 /** Interrupt enable for counter 3 */
#define TCR_STAT_EQ0 0x08000000 /** Read only: timer 0 is equal to its comparison value */
#define TCR_STAT_EQ1 0x10000000 /** Read only: timer 1 is equal to its comparison value */
#define TCR_STAT_EQ2 0x20000000 /** Read only: timer 2 is equal to its comparison value */
#define TCR_STAT_EQ3 0x40000000 /** Read only: timer 3 is equal to its comparison value */
#define TIMER_VALUE_0 ((unsigned long *)0x00B00208)
#define TIMER_COMPARE_0 ((unsigned long *)0x00B0020C)
#define TIMER_VALUE_1 ((unsigned long *)0x00B00210)
#define TIMER_COMPARE_1 ((unsigned long *)0x00B00214)
#define TIMER_VALUE_2 ((unsigned long *)0x00B00218)
#define TIMER_COMPARE_2 ((unsigned long *)0x00B0021C)
#define TIMER_VALUE_3 ((unsigned long *)0x00B00220)
#define TIMER_COMPARE_3 ((unsigned long *)0x00B00224)
#endif

View file

@ -15,7 +15,7 @@
* Definitions of special characters
*/
#define CHAR_ESC '\x2b' /* Escape character */
#define CHAR_ESC '\x1b' /* Escape character */
#define CHAR_NL '\r' /* Newline character */
#define CHAR_BS '\b' /* Backspace */

View file

@ -10,6 +10,8 @@
* Miscellaneous definitions
*/
#define FSYS_SECTOR_SZ 512 /* Size of a sector */
#define MAX_PATH_LEN 256 /* Maximum length of a file path */
#define MAX_TRIES_BUSY 100000 /* The maximum number of times to check for an operation to complete (general purpose) */
/*
@ -22,4 +24,24 @@
#define CHAR_NL '\x0A' /* Linefeed */
#define CHAR_BS '\b' /* Backspace */
/*
* File access mode and open method flags
*/
#define FSYS_READ 0x01
#define FSYS_WRITE 0x02
#define FSYS_OPEN_EXISTING 0x00
#define FSYS_CREATE_NEW 0x04
#define FSYS_CREATE_ALWAYS 0x08
#define FSYS_OPEN_ALWAYS 0x10
#define FSYS_OPEN_APPEND 0x30
/*
* File attribute bits for directory entry
*/
#define FSYS_AM_RDO 0x01 /* Read only */
#define FSYS_AM_HID 0x02 /* Hidden */
#define FSYS_AM_SYS 0x04 /* System */
#define FSYS_AM_DIR 0x10 /* Directory */
#define FSYS_AM_ARC 0x20 /* Archive */
#endif

View file

@ -45,4 +45,8 @@
#define FSYS_ERR_TOO_MANY_OPEN_FILES -35 /* (18) Number of open files > FF_FS_LOCK */
#define FSYS_ERR_INVALID_PARAMETER -36 /* (19) Given parameter is invalid */
#define ERR_NOT_SUPPORTED -37 /* Device does not support the file or operation */
#define ERR_BAD_ARGUMENT -38 /* An invalid argument was provided */
#define ERR_MEDIA_CHANGE -39 /* Removable media has changed */
#endif

View file

@ -44,4 +44,36 @@
* Bit[0..1] = Data rate
*/
/*
* Controller status 1 register bits
*/
#define FDC_ST1_IC 0xC0 /* Interrupt code: 00 = normal, 01 = Abnormal termination, 10 = Invalid command, 11 = Abnormal termination (polling) */
#define FDC_ST1_SE 0x20 /* Seek, Recalibrate finished */
#define FDC_ST1_EC 0x10 /* Head failed to recalibrate to track 0 */
#define FDC_ST1_HEAD 0x04 /* Head number */
#define FDC_ST1_DS1 0x02 /* Drive select #1 */
#define FDC_ST1_DS0 0x01 /* Drive select #0 */
/*
* Controller status 2 register bits
*/
#define FDC_ST2_EN 0x80 /* End of cylinder... tried to access sector beyond last on track */
#define FDC_ST2_DE 0x20 /* Data Error: bad CRC */
#define FDC_ST2_OR 0x10 /* Overrun/Underrun error */
#define FDC_ST2_ND 0x04 /* No data: could not find the sector, track, or ID */
#define FDC_ST2_NW 0x02 /* Not writeable */
#define FDC_ST2_MA 0x01 /* Missing address mark */
/*
* Controller status 3 register bits
*/
#define FDC_ST3_WP 0x40 /* Write Protect tab */
#define FDC_ST3_TRACK0 0x10 /* Track 0 indicator */
#define FDC_ST3_HEAD 0x04 /* Head number */
#define FDC_ST3_DS1 0x02 /* Drive Select #1 */
#define FDC_ST3_DS0 0x01 /* Drive Select #0 */
#endif

View file

@ -1,92 +1,14 @@
/*
/**
* @file gabe_reg.h
*
* Define the various GABE control registers
*/
#ifndef __GABE_REG_H
#define __GABE_REG_H
#include "sys_general.h"
#define POWER_ON_LED 0x0001
#define SDCARD_LED 0x0002
#define BUZZER_CONTROL 0x0004
#define MANUAL_RESET 0x8000 // Make sure the word "DEAD" is written in GABE_RESET_ID
#if MODEL == MODEL_FOENIX_A2560K
#define GABE_CTRL_REG ((volatile unsigned short *)0x00C00000)
#define GABE_RESET_ID ((volatile unsigned short *)0x00C00002)
#define GABE_LFSR_REG0 ((volatile unsigned short *)0x00C00004)
#define GABE_LFSR_REG1 ((volatile unsigned short *)0x00C00006)
#define RGB_LED_L ((volatile unsigned short *)0x00C00008) // Writing Only - A2560K Only - 0x__RR
#define RGB_LED_H ((volatile unsigned short *)0x00C0000A) // Writing Only - A2560K Only - 0xGGBB
#define GABE_LFSR_DATA ((volatile unsigned short *)0x00C00008) // Read Only
#define GABE_LFSR_STAT ((volatile unsigned short *)0x00C0000A) // Read Only
#define GABE_MACHINE_ID ((volatile unsigned short *)0x00C0000C) // Machine ID - Read Only
#define GABE_CHIP_SUBREV ((volatile unsigned short *)0x00C0000E)
#define GABE_CHIP_VERSION ((volatile unsigned short *)0x00C00010)
#define GABE_CHIP_NUMBER ((volatile unsigned short *)0x00C00012)
#define GABE_DIP_REG ((volatile unsigned short *)0x00C00518)
#define GABE_DIP_BOOT_MASK 0x0003 /* Mask for the boot mode: */
#define GABE_DIP_USER_MASK 0x0300 /* Mask for the user switches: */
/*
* 16-bit register controlling the key of the A2560K built-in keyboard
*/
#define GABE_MO_LEDS ((volatile unsigned short *)0x00C0000C)
#define GABE_MO_LED_0_B 0x0001 /* LED 0 (Close to DEL key) -- Blue ON */
#define GABE_MO_LED_0_G 0x0002 /* LED 0 (Close to DEL key) -- Green ON */
#define GABE_MO_LED_0_R 0x0004 /* LED 0 (Close to DEL key) -- Red ON */
#define GABE_MO_LED_1_B 0x0008 /* LED 1 (Below #0) -- Blue ON */
#define GABE_MO_LED_1_G 0x0010 /* LED 1 (Below #0) -- Green ON */
#define GABE_MO_LED_1_R 0x0020 /* LED 1 (Below #0) -- Red ON */
#define GABE_MO_LED_2_B 0x0040 /* LED 2 (above arrow) -- Blue ON */
#define GABE_MO_LED_2_G 0x0080 /* LED 2 (above arrow) -- Green ON */
#define GABE_MO_LED_2_R 0x0100 /* LED 2 (above arrow) -- Red ON */
#define GABE_MO_LED_3_B 0x0200 /* LED 2 (caps lock, Rev C) -- Blue ON */
#define GABE_MO_LED_3_G 0x0400 /* LED 2 (caps lock, Rev C) -- Green ON */
#define GABE_MO_LED_3_R 0x0800 /* LED 2 (caps lock, Rev C) -- Red ON */
#include "A2560K/gabe_a2560k.h"
#elif MODEL == MODEL_FOENIX_A2560U || MODEL == MODEL_FOENIX_A2560U_PLUS
#define GABE_CTRL_REG ((volatile unsigned short *)0x00B00000)
#define GABE_RESET_ID ((volatile unsigned short *)0x00B00002)
#define GABE_LFSR_REG0 ((volatile unsigned short *)0x00B00004)
#define GABE_LFSR_REG1 ((volatile unsigned short *)0x00B00006)
#define RGB_LED_L ((volatile unsigned short *)0x00B00008) // Writing Only - A2560K Only - 0x__RR
#define RGB_LED_H ((volatile unsigned short *)0x00B0000A) // Writing Only - A2560K Only - 0xGGBB
#define GABE_LFSR_DATA ((volatile unsigned short *)0x00B00008) // Read Only
#define GABE_LFSR_STAT ((volatile unsigned short *)0x00B0000A) // Read Only
#define GABE_MACHINE_ID ((volatile unsigned short *)0x00B0000C) // Machine ID - Read Only
#define GABE_MACH_ID_MASK 0x0003 // 1001 = A2560U and U+
#define GABE_MEMORY_BANKS 0x00C0 // 10 = 2 MB, 11 = 4 MB
#define GABE_CPU_SPEED 0x0F00
#define GABE_CPU_ID 0xF000 // 0000 = MC68SEC000 @ 20MHz
#define FPGA_DATE_YEAR ((volatile unsigned short *)0x00B40030) // YYYY
#define FPGA_DATE_MONTHDAY ((volatile unsigned short *)0x00B40032) // MMDD
#define PCB_REV_1 ((volatile unsigned short *)0x00B40034) // Null terminated string describing the PCB
#define PCB_REV_2 ((volatile unsigned short *)0x00B40036)
#define FPGA_SUBVER ((volatile unsigned short *)0x00B40038)
#define FPGA_VER ((volatile unsigned short *)0x00B4003A)
#define FPGA_MODEL_L ((volatile unsigned short *)0x00B4003C)
#define FPGA_MODEL_H ((volatile unsigned short *)0x00B4003E)
#define GABE_CHIP_SUBREV ((volatile unsigned short *)0x00B0000E)
#define GABE_CHIP_VERSION ((volatile unsigned short *)0x00B00010)
#define GABE_CHIP_NUMBER ((volatile unsigned short *)0x00B00012)
#define GABE_DIP_REG ((volatile unsigned short *)0x00B00518)
#define GABE_DIP_BOOT_MASK 0x0003 /* Mask for the boot mode: */
#define GABE_DIP_USER_MASK 0x0300 /* Mask for the user switches: */
#endif
#include "A2560U/gabe_a2560u.h"
#endif

36
src/include/lpt_reg.h Normal file
View file

@ -0,0 +1,36 @@
/**
* @file lpt_reg.h
* Define the registers for the parallel port
*/
#ifndef __LPT_REG_H
#define __LPT_REG_H
#include "sys_general.h"
#if MODEL == MODEL_FOENIX_A2560K
#define LPT_DATA_PORT ((volatile unsigned char *)0xFEC02378)
#define LPT_STAT_PORT ((volatile unsigned char *)0xFEC02379)
#define LPT_CTRL_PORT ((volatile unsigned char *)0xFEC0237A)
#endif
#define LPT_STAT_nBUSY 0x80
#define LPT_STAT_nACK 0x40
#define LPT_STAT_PO 0x20
#define LPT_STAT_SELECT 0x10
#define LPT_STAT_nERROR 0x08
#define LPT_STAT_IRQ 0x04
#define LPT_CTRL_STROBE 0x01
#define LPT_CTRL_AL 0x02
#define LPT_CTRL_mINIT 0x04
#define LPT_CTRL_SELECT 0x08
#define LPT_CTRL_IRQE 0x10
#define LPT_CTRL_BI 0x20
#define LPT_INIT_ON 0x04 /* Start the printer initialization process */
#define LPT_INIT_OFF 0x0C /* Stop the printer initialization process */
#define LPT_STROBE_ON 0x0D /* Strobe the printer */
#define LPT_STROBE_OFF 0x0C /* Drop the strobe to the printer */
#endif

View file

@ -8,9 +8,9 @@
#include "sys_general.h"
#if MODEL == MODEL_FOENIX_A2560K
#define MIDI_DATA ((volatile unsigned char *)0x00C02330)
#define MIDI_STAT ((volatile unsigned char *)0x00C02331)
#define MIDI_CMD ((volatile unsigned char *)0x00C02331)
#define MIDI_DATA ((volatile unsigned char *)0xFEC02330)
#define MIDI_STAT ((volatile unsigned char *)0xFEC02331)
#define MIDI_CMD ((volatile unsigned char *)0xFEC02331)
#define MIDI_STAT_TX_BUSY 0x80
#define MIDI_STAT_RX_EMPTY 0x40

View file

@ -9,23 +9,23 @@
#if MODEL == MODEL_FOENIX_A2560K
#define RTC_BASE ((volatile unsigned char *)0x00C00080)
#define RTC_SEC ((volatile unsigned char *)0x00C00080)
#define RTC_ALRM_SEC ((volatile unsigned char *)0x00C00081)
#define RTC_MIN ((volatile unsigned char *)0x00C00082)
#define RTC_ALRM_MIN ((volatile unsigned char *)0x00C00083)
#define RTC_HOUR ((volatile unsigned char *)0x00C00084)
#define RTC_ALRM_HOUR ((volatile unsigned char *)0x00C00085)
#define RTC_DAY ((volatile unsigned char *)0x00C00086)
#define RTC_ALRM_DAY ((volatile unsigned char *)0x00C00087)
#define RTC_DAY_OF_WEEK ((volatile unsigned char *)0x00C00088)
#define RTC_MONTH ((volatile unsigned char *)0x00C00089)
#define RTC_YEAR ((volatile unsigned char *)0x00C0008A)
#define RTC_RATES ((volatile unsigned char *)0x00C0008B)
#define RTC_ENABLES ((volatile unsigned char *)0x00C0008C)
#define RTC_FLAGS ((volatile unsigned char *)0x00C0008D)
#define RTC_CTRL ((volatile unsigned char *)0x00C0008E)
#define RTC_CENTURY ((volatile unsigned char *)0x00C0008F)
#define RTC_BASE ((volatile unsigned char *)0xFEC00080)
#define RTC_SEC ((volatile unsigned char *)0xFEC00080)
#define RTC_ALRM_SEC ((volatile unsigned char *)0xFEC00081)
#define RTC_MIN ((volatile unsigned char *)0xFEC00082)
#define RTC_ALRM_MIN ((volatile unsigned char *)0xFEC00083)
#define RTC_HOUR ((volatile unsigned char *)0xFEC00084)
#define RTC_ALRM_HOUR ((volatile unsigned char *)0xFEC00085)
#define RTC_DAY ((volatile unsigned char *)0xFEC00086)
#define RTC_ALRM_DAY ((volatile unsigned char *)0xFEC00087)
#define RTC_DAY_OF_WEEK ((volatile unsigned char *)0xFEC00088)
#define RTC_MONTH ((volatile unsigned char *)0xFEC00089)
#define RTC_YEAR ((volatile unsigned char *)0xFEC0008A)
#define RTC_RATES ((volatile unsigned char *)0xFEC0008B)
#define RTC_ENABLES ((volatile unsigned char *)0xFEC0008C)
#define RTC_FLAGS ((volatile unsigned char *)0xFEC0008D)
#define RTC_CTRL ((volatile unsigned char *)0xFEC0008E)
#define RTC_CENTURY ((volatile unsigned char *)0xFEC0008F)
#elif MODEL_FOENIX_A2560U || MODEL == MODEL_FOENIX_A2560U_PLUS
@ -53,9 +53,9 @@
#define RTC_RATES_WD 0xf0
#define RTC_RATES_RS 0x0f
#define RTC_RATE_976us 0x06
#define RTC_RATE_4ms 0x04
#define RTC_RATE_4ms 0x08
#define RTC_RATE_15ms 0x0A
#define RTC_RATE_500ms 0x0F
/* Enable bits */
#define RTC_AIE 0x08

View file

@ -9,102 +9,102 @@
#ifndef __SUPERIO_H
#define __SUPERIO_H
#define PME_STS_REG ((volatile unsigned char *)0x00C02100)
#define PME_EN_REG ((volatile unsigned char *)0x00C02102)
#define PME_STS_REG ((volatile unsigned char *)0xFEC02100)
#define PME_EN_REG ((volatile unsigned char *)0xFEC02102)
#define PME_STS1_REG ((volatile unsigned char *)0x00C02104)
#define PME_STS2_REG ((volatile unsigned char *)0x00C02105)
#define PME_STS3_REG ((volatile unsigned char *)0x00C02106)
#define PME_STS4_REG ((volatile unsigned char *)0x00C02107)
#define PME_STS5_REG ((volatile unsigned char *)0x00C02108)
#define PME_STS1_REG ((volatile unsigned char *)0xFEC02104)
#define PME_STS2_REG ((volatile unsigned char *)0xFEC02105)
#define PME_STS3_REG ((volatile unsigned char *)0xFEC02106)
#define PME_STS4_REG ((volatile unsigned char *)0xFEC02107)
#define PME_STS5_REG ((volatile unsigned char *)0xFEC02108)
#define PME_EN1_REG ((volatile unsigned char *)0x00C0210A)
#define PME_EN2_REG ((volatile unsigned char *)0x00C0210B)
#define PME_EN3_REG ((volatile unsigned char *)0x00C0210C)
#define PME_EN4_REG ((volatile unsigned char *)0x00C0210D)
#define PME_EN5_REG ((volatile unsigned char *)0x00C0210E)
#define PME_EN1_REG ((volatile unsigned char *)0xFEC0210A)
#define PME_EN2_REG ((volatile unsigned char *)0xFEC0210B)
#define PME_EN3_REG ((volatile unsigned char *)0xFEC0210C)
#define PME_EN4_REG ((volatile unsigned char *)0xFEC0210D)
#define PME_EN5_REG ((volatile unsigned char *)0xFEC0210E)
#define SMI_STS1_REG ((volatile unsigned char *)0x00C02110)
#define SMI_STS2_REG ((volatile unsigned char *)0x00C02111)
#define SMI_STS3_REG ((volatile unsigned char *)0x00C02112)
#define SMI_STS4_REG ((volatile unsigned char *)0x00C02113)
#define SMI_STS5_REG ((volatile unsigned char *)0x00C02114)
#define SMI_STS1_REG ((volatile unsigned char *)0xFEC02110)
#define SMI_STS2_REG ((volatile unsigned char *)0xFEC02111)
#define SMI_STS3_REG ((volatile unsigned char *)0xFEC02112)
#define SMI_STS4_REG ((volatile unsigned char *)0xFEC02113)
#define SMI_STS5_REG ((volatile unsigned char *)0xFEC02114)
#define SMI_EN1_REG ((volatile unsigned char *)0x00C02116)
#define SMI_EN2_REG ((volatile unsigned char *)0x00C02117)
#define SMI_EN3_REG ((volatile unsigned char *)0x00C02118)
#define SMI_EN4_REG ((volatile unsigned char *)0x00C02119)
#define SMI_EN5_REG ((volatile unsigned char *)0x00C0211A)
#define SMI_EN1_REG ((volatile unsigned char *)0xFEC02116)
#define SMI_EN2_REG ((volatile unsigned char *)0xFEC02117)
#define SMI_EN3_REG ((volatile unsigned char *)0xFEC02118)
#define SMI_EN4_REG ((volatile unsigned char *)0xFEC02119)
#define SMI_EN5_REG ((volatile unsigned char *)0xFEC0211A)
#define MSC_ST_REG ((volatile unsigned char *)0x00C0211C)
#define FORCE_DISK_CHANGE ((volatile unsigned char *)0x00C0211E)
#define FLOPPY_DATA_RATE ((volatile unsigned char *)0x00C0211F)
#define MSC_ST_REG ((volatile unsigned char *)0xFEC0211C)
#define FORCE_DISK_CHANGE ((volatile unsigned char *)0xFEC0211E)
#define FLOPPY_DATA_RATE ((volatile unsigned char *)0xFEC0211F)
#define UART1_FIFO_CTRL_SHDW ((volatile unsigned char *)0x00C02120)
#define UART2_FIFO_CTRL_SHDW ((volatile unsigned char *)0x00C02121)
#define DEV_DISABLE_REG ((volatile unsigned char *)0x00C02122)
#define UART1_FIFO_CTRL_SHDW ((volatile unsigned char *)0xFEC02120)
#define UART2_FIFO_CTRL_SHDW ((volatile unsigned char *)0xFEC02121)
#define DEV_DISABLE_REG ((volatile unsigned char *)0xFEC02122)
#define GP10_REG ((volatile unsigned char *)0x00C02123)
#define GP11_REG ((volatile unsigned char *)0x00C02124)
#define GP12_REG ((volatile unsigned char *)0x00C02125)
#define GP13_REG ((volatile unsigned char *)0x00C02126)
#define GP14_REG ((volatile unsigned char *)0x00C02127)
#define GP15_REG ((volatile unsigned char *)0x00C02128)
#define GP16_REG ((volatile unsigned char *)0x00C02129)
#define GP17_REG ((volatile unsigned char *)0x00C0212A)
#define GP10_REG ((volatile unsigned char *)0xFEC02123)
#define GP11_REG ((volatile unsigned char *)0xFEC02124)
#define GP12_REG ((volatile unsigned char *)0xFEC02125)
#define GP13_REG ((volatile unsigned char *)0xFEC02126)
#define GP14_REG ((volatile unsigned char *)0xFEC02127)
#define GP15_REG ((volatile unsigned char *)0xFEC02128)
#define GP16_REG ((volatile unsigned char *)0xFEC02129)
#define GP17_REG ((volatile unsigned char *)0xFEC0212A)
#define GP20_REG ((volatile unsigned char *)0x00C0212B)
#define GP21_REG ((volatile unsigned char *)0x00C0212C)
#define GP22_REG ((volatile unsigned char *)0x00C0212D)
#define GP23_REG ((volatile unsigned char *)0x00C0212E)
#define GP24_REG ((volatile unsigned char *)0x00C0212F)
#define GP25_REG ((volatile unsigned char *)0x00C02130)
#define GP26_REG ((volatile unsigned char *)0x00C02131)
#define GP27_REG ((volatile unsigned char *)0x00C02132)
#define GP20_REG ((volatile unsigned char *)0xFEC0212B)
#define GP21_REG ((volatile unsigned char *)0xFEC0212C)
#define GP22_REG ((volatile unsigned char *)0xFEC0212D)
#define GP23_REG ((volatile unsigned char *)0xFEC0212E)
#define GP24_REG ((volatile unsigned char *)0xFEC0212F)
#define GP25_REG ((volatile unsigned char *)0xFEC02130)
#define GP26_REG ((volatile unsigned char *)0xFEC02131)
#define GP27_REG ((volatile unsigned char *)0xFEC02132)
#define GP30_REG ((volatile unsigned char *)0x00C02133)
#define GP31_REG ((volatile unsigned char *)0x00C02134)
#define GP32_REG ((volatile unsigned char *)0x00C02135)
#define GP33_REG ((volatile unsigned char *)0x00C02136)
#define GP34_REG ((volatile unsigned char *)0x00C02137)
#define GP35_REG ((volatile unsigned char *)0x00C02138)
#define GP36_REG ((volatile unsigned char *)0x00C02139)
#define GP37_REG ((volatile unsigned char *)0x00C0213A)
#define GP30_REG ((volatile unsigned char *)0xFEC02133)
#define GP31_REG ((volatile unsigned char *)0xFEC02134)
#define GP32_REG ((volatile unsigned char *)0xFEC02135)
#define GP33_REG ((volatile unsigned char *)0xFEC02136)
#define GP34_REG ((volatile unsigned char *)0xFEC02137)
#define GP35_REG ((volatile unsigned char *)0xFEC02138)
#define GP36_REG ((volatile unsigned char *)0xFEC02139)
#define GP37_REG ((volatile unsigned char *)0xFEC0213A)
#define GP40_REG ((volatile unsigned char *)0x00C0213B)
#define GP41_REG ((volatile unsigned char *)0x00C0213C)
#define GP42_REG ((volatile unsigned char *)0x00C0213D)
#define GP43_REG ((volatile unsigned char *)0x00C0213E)
#define GP40_REG ((volatile unsigned char *)0xFEC0213B)
#define GP41_REG ((volatile unsigned char *)0xFEC0213C)
#define GP42_REG ((volatile unsigned char *)0xFEC0213D)
#define GP43_REG ((volatile unsigned char *)0xFEC0213E)
#define GP50_REG ((volatile unsigned char *)0x00C0213F)
#define GP51_REG ((volatile unsigned char *)0x00C02140)
#define GP52_REG ((volatile unsigned char *)0x00C02141)
#define GP53_REG ((volatile unsigned char *)0x00C02142)
#define GP54_REG ((volatile unsigned char *)0x00C02143)
#define GP55_REG ((volatile unsigned char *)0x00C02144)
#define GP56_REG ((volatile unsigned char *)0x00C02145)
#define GP57_REG ((volatile unsigned char *)0x00C02146)
#define GP50_REG ((volatile unsigned char *)0xFEC0213F)
#define GP51_REG ((volatile unsigned char *)0xFEC02140)
#define GP52_REG ((volatile unsigned char *)0xFEC02141)
#define GP53_REG ((volatile unsigned char *)0xFEC02142)
#define GP54_REG ((volatile unsigned char *)0xFEC02143)
#define GP55_REG ((volatile unsigned char *)0xFEC02144)
#define GP56_REG ((volatile unsigned char *)0xFEC02145)
#define GP57_REG ((volatile unsigned char *)0xFEC02146)
#define GP60_REG ((volatile unsigned char *)0x00C02147)
#define GP61_REG ((volatile unsigned char *)0x00C02148)
#define GP60_REG ((volatile unsigned char *)0xFEC02147)
#define GP61_REG ((volatile unsigned char *)0xFEC02148)
#define GP1_REG ((volatile unsigned char *)0x00C0214B)
#define GP2_REG ((volatile unsigned char *)0x00C0214C)
#define GP3_REG ((volatile unsigned char *)0x00C0214D)
#define GP4_REG ((volatile unsigned char *)0x00C0214E)
#define GP5_REG ((volatile unsigned char *)0x00C0214F)
#define GP6_REG ((volatile unsigned char *)0x00C02150)
#define GP1_REG ((volatile unsigned char *)0xFEC0214B)
#define GP2_REG ((volatile unsigned char *)0xFEC0214C)
#define GP3_REG ((volatile unsigned char *)0xFEC0214D)
#define GP4_REG ((volatile unsigned char *)0xFEC0214E)
#define GP5_REG ((volatile unsigned char *)0xFEC0214F)
#define GP6_REG ((volatile unsigned char *)0xFEC02150)
#define FAN1_REG ((volatile unsigned char *)0x00C02156)
#define FAN2_REG ((volatile unsigned char *)0x00C02157)
#define FAN_CTRL_REG ((volatile unsigned char *)0x00C02158)
#define FAN1_TACH_REG ((volatile unsigned char *)0x00C02159)
#define FAN2_TACH_REG ((volatile unsigned char *)0x00C0215A)
#define FAN1_PRELOAD_REG ((volatile unsigned char *)0x00C0215B)
#define FAN2_PRELOAD_REG ((volatile unsigned char *)0x00C0215C)
#define FAN1_REG ((volatile unsigned char *)0xFEC02156)
#define FAN2_REG ((volatile unsigned char *)0xFEC02157)
#define FAN_CTRL_REG ((volatile unsigned char *)0xFEC02158)
#define FAN1_TACH_REG ((volatile unsigned char *)0xFEC02159)
#define FAN2_TACH_REG ((volatile unsigned char *)0xFEC0215A)
#define FAN1_PRELOAD_REG ((volatile unsigned char *)0xFEC0215B)
#define FAN2_PRELOAD_REG ((volatile unsigned char *)0xFEC0215C)
#define LED1_REG ((volatile unsigned char *)0x00C0215D)
#define LED2_REG ((volatile unsigned char *)0x00C0215E)
#define KEYBOARD_SCAN_CODE ((volatile unsigned char *)0x00C0215F)
#define LED1_REG ((volatile unsigned char *)0xFEC0215D)
#define LED2_REG ((volatile unsigned char *)0xFEC0215E)
#define KEYBOARD_SCAN_CODE ((volatile unsigned char *)0xFEC0215F)
#endif

View file

@ -16,6 +16,7 @@
#include "dev/block.h"
#include "dev/fsys.h"
#include "dev/rtc.h"
#include "dev/txt_screen.h"
/*
* Syscall function numbers
@ -48,7 +49,8 @@
#define KFN_CHAN_REGISTER 0x19 /* Register a channel device driver */
#define KFN_CHAN_OPEN 0x1A /* Open a channel device */
#define KFN_CHAN_CLOSE 0x1B /* Close an open channel (not for files) */
#define KFN_TEXT_SETSIZES 0x1C /* Adjusts the screen size based on the current graphics mode */
#define KFN_CHAN_SWAP 0x1C /* Swap the channel ID assignment of two channels */
#define KFN_CHAN_DEVICE 0x1D /* Get the number of the device associated with the channel */
/* Block device system calls */
@ -59,6 +61,7 @@
#define KFN_BDEV_STATUS 0x23 /* Get the status of a block device */
#define KFN_BDEV_IOCTRL 0x24 /* Send a command to a block device (device dependent functionality) */
#define KFN_BDEV_REGISTER 0x25 /* Register a block device driver */
#define KFN_STAT 0x2F /* Check for file existance and return file information */
/* File/Directory system calls */
@ -82,6 +85,11 @@
/* Process and memory calls */
#define KFN_RUN 0x40 /* Load an execute a binary file */
#define KFN_MEM_GET_RAMTOP 0x41 /* Get the upper limit of the top of system RAM */
#define KFN_MEM_RESERVE 0x42 /* Reserve a block of memory at the top of system RAM */
#define KFN_ELEVATE 0x43 /* Switch the user process to a full privilege */
#define KFN_VAR_SET 0x44 /* Set the value of a system variable */
#define KFN_VAR_GET 0x45 /* Get the value of a system variable */
/* Misc calls */
@ -92,6 +100,28 @@
#define KFN_KBD_LAYOUT 0x54 /* Set the translation tables for the keyboard */
#define KFN_ERR_MESSAGE 0x55 /* Return an error description, given an error number */
/* Text Device Calls */
#define KFN_TEXT_INIT_SCREEN 0x60 /* Reset a screen to its default mode */
#define KFN_TXT_GET_CAPS 0x61 /* Get the capabilities of a screen */
#define KFN_TXT_SET_MODE 0x62 /* Set the display mode of a screen */
#define KFN_TEXT_SETSIZES 0x63 /* Adjusts the screen size based on the current graphics mode */
#define KFN_TXT_SET_RESOLUTION 0x64 /* Set the base display resolution for a screen */
#define KFN_TXT_SET_BORDER 0x65 /* Set the size of the border */
#define KFN_TXT_SET_BORDERCOLOR 0x66 /* Set the border color */
#define KFN_TXT_SET_FONT 0x67 /* Set the font for the screen's text mode (if applicable) */
#define KFN_TXT_SET_CURSOR 0x68 /* Set the text-mode cursor look */
#define KFN_TXT_SET_REGION 0x69 /* Sets the clipping/scrolling region for further text operations */
#define KFN_TXT_GET_REGION 0x6A /* Gets the current clipping/scrolling region */
#define KFN_TXT_SET_COLOR 0x6B /* Sets the foreground and background text colors */
#define KFN_TXT_GET_COLOR 0x6C /* Gets the foreground and background text colors */
#define KFN_TXT_SET_XY 0x6D /* Sets the cursor's position */
#define KFN_TXT_GET_XY 0x6E /* Gets the cursor's position */
#define KFN_TXT_SCROLL 0x6F /* Scroll the current region */
// #define KFN_TXT_FILL 0x70 /* Fill the current region */
#define KFN_TXT_SET_CURSOR_VIS 0x71 /* Set cursor visibility */
#define KFN_TXT_GET_SIZES 0x72 /* Get the screen size (visible text cells and total pixel resolution) */
/*
* Call into the kernel (provided by assembly)
*/
@ -320,6 +350,26 @@ extern short sys_chan_open(short dev, const uint8_t * path, short mode);
*/
extern short sys_chan_close(short chan);
/**
* Swap the channel ID assignments for two channels
*
* Before call: channel1 = "Channel A", channel2 = "Channel B"
* After call: channel1 = "Channel B", channel2 = "Channel A"
*
* @param channel1 the ID of one of the channels
* @param channel2 the ID of the other channel
* @return 0 on success, any other number is an error
*/
extern short sys_chan_swap(short channel1, short channel2);
/**
* Return the device associated with the channel
*
* @param channel the ID of the channel to query
* @return the ID of the device associated with the channel, negative number for error
*/
extern short sys_chan_device(short channel);
/*
* Compute the size information for the text screen based on the current settings in VICKY
* These settings are needed to correctly position text on the screen.
@ -327,7 +377,7 @@ extern short sys_chan_close(short chan);
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
*/
extern void text_setsizes(short chan);
extern void sys_text_setsizes(short chan);
/***
*** Block device system calls
@ -619,6 +669,37 @@ extern short sys_fsys_load(const char * path, long destination, long * start);
*/
extern short sys_fsys_register_loader(const char * extension, p_file_loader loader);
/**
* Check to see if the file is present.
* If it is not, return a file not found error.
* If it is, populate the file info record
*
* @param path the path to the file to check
* @param file pointer to a file info record to fill in, if the file is found.
* @return 0 on success, negative number on error
*/
extern short sys_fsys_stat(const char * path, p_file_info file);
/**
* Memory
*/
/**
* Return the top of system RAM... the user program must not use any
* system memory from this address and above.
*
* @return the address of the first byte of reserved system RAM (one above the last byte the user program can use)
*/
extern unsigned long sys_mem_get_ramtop();
/**
* Reserve a block of memory at the top of system RAM.
*
* @param bytes the number of bytes to reserve
* @return address of the first byte of the reserved block
*/
extern unsigned long sys_mem_reserve(unsigned long bytes);
/*
* Miscellaneous
*/
@ -684,4 +765,160 @@ extern const char * sys_err_message(short err_number);
*/
extern short sys_kbd_layout(const char * tables);
/**
* Load and execute an executable file
*
* @param path the path to the executable file
* @param argc the number of arguments passed
* @param argv the array of string arguments
* @return the return result of the program
*/
extern short sys_proc_run(const char * path, int argc, char * argv[]);
/**
* Set the value of a variable
*
* @param name the name of the variable to set
* @param value the value the variable should have
* @return 0 on success, negative number on error
*/
extern short sys_var_set(const char *name, const char *value);
/**
* Get the value of a variable
*
* @param name the name of the variable to set
* @return pointer to the string on success, 0 if not found
*/
extern const char * sys_var_get(const char *name);
//
// Text screen calls
//
/**
* Gets the description of a screen's capabilities
*
* @param screen the number of the text device
*
* @return a pointer to the read-only description (0 on error)
*/
extern const p_txt_capabilities sys_txt_get_capabilities(short screen);
/**
* Set the display mode for the screen
*
* @param screen the number of the text device
* @param mode a bitfield of desired display mode options
*
* @return 0 on success, any other number means the mode is invalid for the screen
*/
extern short sys_txt_set_mode(short screen, short mode);
/**
* Set the position of the cursor to (x, y) relative to the current region
* If the (x, y) coordinate is outside the region, it will be clipped to the region.
* If y is greater than the height of the region, the region will scroll until that relative
* position would be within view.
*
* @param screen the number of the text device
* @param x the column for the cursor
* @param y the row for the cursor
*/
extern void sys_txt_set_xy(short screen, short x, short y);
/**
* Get the position of the cursor (x, y) relative to the current region
*
* @param screen the number of the text device
* @param position pointer to a t_point record to fill out
*/
extern void sys_txt_get_xy(short screen, p_point position);
/**
* Get the current region.
*
* @param screen the number of the text device
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
extern short sys_txt_get_region(short screen, p_rect region);
/**
* Set a region to restrict further character display, scrolling, etc.
* Note that a region of zero size will reset the region to the full size of the screen.
*
* @param screen the number of the text device
* @param region pointer to a t_rect describing the rectangular region (using character cells for size and size)
*
* @return 0 on success, any other number means the region was invalid
*/
extern short sys_txt_set_region(short screen, p_rect region);
/**
* Set the default foreground and background colors for printing
*
* @param screen the number of the text device
* @param foreground the Text LUT index of the new current foreground color (0 - 15)
* @param background the Text LUT index of the new current background color (0 - 15)
*/
extern void sys_txt_set_color(short screen, unsigned char foreground, unsigned char background);
/*
* Get the foreground and background color for printing
*
* Inputs:
* screen = the screen number 0 for channel A, 1 for channel B
* foreground = pointer to the foreground color number
* background = pointer to the background color number
*/
extern void sys_txt_get_color(short screen, unsigned char * foreground, unsigned char * background);
/**
* Set if the cursor is visible or not
*
* @param screen the screen number 0 for channel A, 1 for channel B
* @param is_visible TRUE if the cursor should be visible, FALSE (0) otherwise
*/
extern void sys_txt_set_cursor_visible(short screen, short is_visible);
/**
* Load a font as the current font for the screen
*
* @param screen the number of the text device
* @param width width of a character in pixels
* @param height of a character in pixels
* @param data pointer to the raw font data to be loaded
*/
extern short sys_txt_set_font(short screen, short width, short height, unsigned char * data);
/**
* Get the display resolutions
*
* @param screen the screen number 0 for channel A, 1 for channel B
* @param text_size the size of the screen in visible characters (may be null)
* @param pixel_size the size of the screen in pixels (may be null)
*/
extern void sys_txt_get_sizes(short screen, p_extent text_size, p_extent pixel_size);
/**
* Set the size of the border of the screen (if supported)
*
* @param screen the number of the text device
* @param width the horizontal size of one side of the border (0 - 32 pixels)
* @param height the vertical size of one side of the border (0 - 32 pixels)
*/
extern void sys_txt_set_border(short screen, short width, short height);
/**
* Set the size of the border of the screen (if supported)
*
* @param screen the number of the text device
* @param red the red component of the color (0 - 255)
* @param green the green component of the color (0 - 255)
* @param blue the blue component of the color (0 - 255)
*/
extern void sys_txt_set_border_color(short screen, unsigned char red, unsigned char green, unsigned char blue);
#endif

16
src/include/timers_reg.h Normal file
View file

@ -0,0 +1,16 @@
/**
* @file timers_reg.h
*
* Load register definitions for the various timers on the Foenix
*/
#ifndef __TIMERS_REG_H
#define __TIMERS_REG_H
#if MODEL == MODEL_FOENIX_A2560K
#include "A2560K/timers_a2560k.h"
#elif MODEL == MODEL_FOENIX_A2560U || MODEL == MODEL_FOENIX_A2560U_PLUS
#include "A2560U/timers_a2560u.h"
#endif
#endif

View file

@ -8,14 +8,35 @@
#include <stdint.h>
#include <stdbool.h>
/*
* Function types
/**
* @struct s_extent
*
* An extent or size of a rectangular area
*/
typedef struct s_extent {
short width; /**< The width of the region */
short height; /**< The height of the region */
} t_extent, *p_extent;
/*
* Integer types in their standard sizes, signed and unsigned.
/**
* @struct s_point
*
* A point on a plane
*/
typedef struct s_point {
short x; /**< The column of the point */
short y; /**< The row of the point */
} t_point, *p_point;
/**
* @struct s_rect
*
* A rectangle on the screen
*/
typedef struct s_rect {
t_point origin; /**< The upper-left corner of the rectangle */
t_extent size; /**< The size of the rectangle */
} t_rect, *p_rect;
//
// A color (BGR)
@ -40,6 +61,7 @@ typedef struct s_color4 {
* Function types
*/
typedef short (*FUNC_V_2_V)();
typedef short (*FUNC_V_2_S)();
typedef short (*FUNC_S_2_S)(char *);
typedef short (*FUNC_BS_2_S)(unsigned char *, short);

View file

@ -8,8 +8,8 @@
#include "sys_general.h"
#if MODEL == MODEL_FOENIX_A2560K
#define UART1_BASE 0x00C023F8 /* Base address for UART 1 (COM1) */
#define UART2_BASE 0x00C022F8 /* Base address for UART 2 (COM2) */
#define UART1_BASE 0xFEC023F8 /* Base address for UART 1 (COM1) */
#define UART2_BASE 0xFEC022F8 /* Base address for UART 2 (COM2) */
#elif MODEL == MODEL_FOENIX_A2560U || MODEL == MODEL_FOENIX_A2560U_PLUS
#define UART1_BASE 0x00B028F8 /* Base address for UART 1 (COM1) */

Some files were not shown because too many files have changed in this diff Show more