Merge remote-tracking branch 'original/main' into merge-220530
This commit is contained in:
commit
adc37b784e
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -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
BIN
C256Mgr.zip
Normal file
Binary file not shown.
Binary file not shown.
|
@ -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))
|
||||
|
|
18
FEATURES.md
18
FEATURES.md
|
@ -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
|
||||
|
|
23
README.md
23
README.md
|
@ -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
BIN
build/foenixmcp_a2560k.bin
Normal file
Binary file not shown.
4
c256.ini
4
c256.ini
|
@ -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
BIN
docs/Memory Map.odg
Normal file
Binary file not shown.
Binary file not shown.
16
docs/notes/LEDs.txt
Normal file
16
docs/notes/LEDs.txt
Normal 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.
|
49
docs/notes/a2560k_memory.txt
Normal file
49
docs/notes/a2560k_memory.txt
Normal 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
51
docs/notes/bootsector.md
Normal 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
|
71
src/Makefile
71
src/Makefile
|
@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
src/bin/foenixmcp_a2560k_20220417.bin
Normal file
BIN
src/bin/foenixmcp_a2560k_20220417.bin
Normal file
Binary file not shown.
585
src/boot.c
Normal file
585
src/boot.c
Normal 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, ®ion);
|
||||
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, ®ion);
|
||||
|
||||
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
44
src/boot.h
Normal 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
0
src/build.log
Normal file
|
@ -1,4 +1,4 @@
|
|||
[DEFAULT]
|
||||
port=COM6
|
||||
port=COM5
|
||||
labels=sample.lbl
|
||||
flash_address=380000
|
||||
flash_address=010000
|
||||
|
|
939
src/cli/cli.c
939
src/cli/cli.c
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
365
src/cli/dos_copy.c
Normal 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
14
src/cli/dos_copy.h
Normal 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
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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... */
|
||||
return ERR_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;
|
||||
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;
|
||||
|
||||
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 {
|
||||
char message[80];
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Reset the text screen */
|
||||
text_init();
|
||||
fsys_close(chan);
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(message, "Unable to read font file: %d\n", b);
|
||||
sys_chan_write(screen, message, strlen(message));
|
||||
// 8x16 is not a supported font size
|
||||
return ERR_NOT_SUPPORTED;
|
||||
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
fsys_close(chan);
|
||||
}
|
||||
} else {
|
||||
print(screen, "Could not load font file.\n");
|
||||
return -1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Font setter -- GET FONT <path>
|
||||
/**
|
||||
* 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);
|
||||
|
||||
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);
|
||||
cli_set_register("VOLUME", "VOLUME <0 - 255> -- set the master volume", cli_volume_set, cli_volume_get);
|
||||
}
|
||||
|
|
1046
src/cli/sound_cmds.c
1046
src/cli/sound_cmds.c
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
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;
|
||||
}
|
||||
|
||||
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));
|
||||
uart_index = cdev - CDEV_COM1;
|
||||
uart_address = (unsigned long)uart_get_base(uart_index);
|
||||
|
||||
for (;;) {
|
||||
c = kbd_getc();
|
||||
if (c != 0) {
|
||||
if (c == 0x1b) {
|
||||
return 0;
|
||||
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');
|
||||
}
|
||||
uart_put(0, c);
|
||||
} else if (uart_has_bytes(0)) {
|
||||
c = uart_get(0);
|
||||
sys_chan_write_b(channel, c);
|
||||
}
|
||||
|
||||
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();
|
||||
short lpt = sys_chan_open(CDEV_LPT, 0, 0);
|
||||
if (lpt > 0) {
|
||||
print(screen, "Sending test patterns to printer (ESC to quit)...\n");
|
||||
|
||||
sprintf(message, "Sending test patterns to printer (ESC to quit)...\n");
|
||||
sys_chan_write(screen, message, strlen(message));
|
||||
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);
|
||||
|
||||
while (scancode != 0x01) {
|
||||
scancode = sys_kbd_scancode();
|
||||
lpt_write(0, test_pattern, strlen(test_pattern));
|
||||
sprintf(message, "Printer status: %02X\n", sys_chan_status(lpt));
|
||||
print(screen, message);
|
||||
break;
|
||||
}
|
||||
scancode = sys_kbd_scancode();
|
||||
}
|
||||
|
||||
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, ®ion);
|
||||
txt_fill(screen, 'X');
|
||||
region.origin.x = 1;
|
||||
region.origin.y = 21;
|
||||
region.size.width = 18;
|
||||
region.size.height = 8;
|
||||
txt_set_region(screen, ®ion);
|
||||
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, ®ion);
|
||||
txt_fill(screen, 'X');
|
||||
region.origin.x = 22;
|
||||
region.origin.y = 21;
|
||||
region.size.width = 18;
|
||||
region.size.height = 8;
|
||||
txt_set_region(screen, ®ion);
|
||||
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, ®ion);
|
||||
txt_fill(screen, 'X');
|
||||
region.origin.x = 43;
|
||||
region.origin.y = 21;
|
||||
region.size.width = 18;
|
||||
region.size.height = 8;
|
||||
txt_set_region(screen, ®ion);
|
||||
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}
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
return cdev->init();
|
||||
if (cdev->init) {
|
||||
return cdev->init();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
return DEV_ERR_BADDEV;
|
||||
}
|
||||
|
@ -210,14 +217,22 @@ 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 */
|
||||
result = cdev->open(chan, path, mode);
|
||||
if (result == 0) {
|
||||
/* Success: return the channel number */
|
||||
return chan->number;
|
||||
if (cdev->open) {
|
||||
result = cdev->open(chan, path, mode);
|
||||
if (result == 0) {
|
||||
/* Success: return the channel number */
|
||||
return chan->number;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
return result;
|
||||
// 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) {
|
||||
cdev->close(chan);
|
||||
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);
|
||||
return cdev->read(chan, buffer, size);
|
||||
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) {
|
||||
return cdev->readline(chan, buffer, size);
|
||||
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) {
|
||||
return cdev->read_b(chan);
|
||||
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) {
|
||||
return cdev->write(chan, buffer, size);
|
||||
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) {
|
||||
return cdev->write_b(chan, b);
|
||||
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) {
|
||||
return cdev->status(chan);
|
||||
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) {
|
||||
return cdev->flush(chan);
|
||||
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) {
|
||||
return cdev->seek(chan, position, base);
|
||||
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) {
|
||||
return cdev->ioctrl(chan, command, buffer, size);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
// Echo the character to the screen
|
||||
con_write_b(chan, c);
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
/**
|
||||
* Implementation of the console channel device
|
||||
*
|
||||
*
|
||||
* The console maps to the main screen and keyboard.
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
#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
|
||||
//
|
||||
|
|
1072
src/dev/fdc.c
1072
src/dev/fdc.c
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
292
src/dev/fsys.c
292
src/dev/fsys.c
|
@ -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;
|
||||
}
|
||||
|
||||
if (destination == 0) {
|
||||
/* Find the extension */
|
||||
char * point = strrchr(path, '.');
|
||||
if (point != 0) {
|
||||
point++;
|
||||
for (i = 0; i < MAX_EXT; i++) {
|
||||
char c = *point++;
|
||||
if (c) {
|
||||
extension[i] = toupper(c);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
log2(LOG_VERBOSE, "fsys_load ext: ", extension);
|
||||
static int get_app_ext(const char * path, char * extension) {
|
||||
char * point = strrchr(path, '.');
|
||||
extension[0] = 0;
|
||||
if (point != 0) {
|
||||
point++;
|
||||
for (int i = 0; i < MAX_EXT; i++) {
|
||||
char c = *point++;
|
||||
if (c) {
|
||||
extension[i] = toupper(c);
|
||||
} else {
|
||||
extension[i] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
418
src/dev/kbd_mo.c
418
src/dev/kbd_mo.c
|
@ -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,11 +12,14 @@
|
|||
#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_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 */
|
||||
#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 */
|
||||
|
||||
/*
|
||||
* Modifier bit flags
|
||||
|
@ -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,20 +469,89 @@ 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;
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
195
src/dev/lpt.c
195
src/dev/lpt.c
|
@ -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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
*LPT_DATA_PORT = b; /* Send the byte */
|
||||
*LPT_CTRL_PORT = LPT_STROBE_ON; /* Strobe the interface */
|
||||
/* Send the byte */
|
||||
*LPT_DATA_PORT = b;
|
||||
|
||||
/* 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 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;
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
*LPT_CTRL_PORT = LPT_STROBE_OFF; /* Drop the strobe */
|
||||
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; /* Return success */
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
216
src/dev/midi.c
216
src/dev/midi.c
|
@ -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()) ;
|
||||
dummy = *MIDI_DATA;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* Send the byte */
|
||||
*MIDI_DATA = b;
|
||||
/**
|
||||
* 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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
@ -714,7 +714,7 @@ void kbd_handle_irq() {
|
|||
default:
|
||||
// TODO: kernel panic?
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -44,6 +44,8 @@ extern unsigned short kbd_get_scancode();
|
|||
*/
|
||||
extern char kbd_getc();
|
||||
|
||||
extern char kbd_getc_poll();
|
||||
|
||||
/*
|
||||
* Set the keyboard translation tables
|
||||
*
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
670
src/dev/txt_a2560k_a.c
Normal 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(®ion);
|
||||
|
||||
/* 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
21
src/dev/txt_a2560k_a.h
Normal 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
704
src/dev/txt_a2560k_b.c
Normal 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(®ion);
|
||||
|
||||
/* 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
19
src/dev/txt_a2560k_b.h
Normal 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
714
src/dev/txt_screen.c
Normal 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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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, ®ion);
|
||||
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
354
src/dev/txt_screen.h
Normal 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
|
348
src/dev/uart.c
348
src/dev/uart.c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
return RES_PARERR;
|
||||
if (result == ERR_MEDIA_CHANGE) {
|
||||
log(LOG_ERROR, "disk changed.");
|
||||
return RES_NOTRDY;
|
||||
} else {
|
||||
log(LOG_ERROR, "gerneral error");
|
||||
return RES_PARERR;
|
||||
}
|
||||
} else {
|
||||
sector++;
|
||||
}
|
||||
|
|
194
src/foenixmcp.c
194
src/foenixmcp.c
|
@ -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.");
|
||||
|
||||
|
|
Binary file not shown.
|
@ -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
496
src/include/A2560K/YM2151.h
Normal 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
|
297
src/include/A2560K/YM2612_Ext.h
Normal file
297
src/include/A2560K/YM2612_Ext.h
Normal 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 LSB’s 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 envelope’s 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 B4′s 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
|
||||
|
||||
|
|
@ -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
|
||||
|
|
53
src/include/A2560K/gabe_a2560k.h
Normal file
53
src/include/A2560K/gabe_a2560k.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
64
src/include/A2560K/timers_a2560k.h
Normal file
64
src/include/A2560K/timers_a2560k.h
Normal 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
|
52
src/include/A2560K/vky_chan_a.h
Normal file
52
src/include/A2560K/vky_chan_a.h
Normal 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
|
57
src/include/A2560K/vky_chan_b.h
Normal file
57
src/include/A2560K/vky_chan_b.h
Normal 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
|
48
src/include/A2560U/gabe_a2560u.h
Normal file
48
src/include/A2560U/gabe_a2560u.h
Normal 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: */
|
54
src/include/A2560U/timers_a2560u.h
Normal file
54
src/include/A2560U/timers_a2560u.h
Normal 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
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -10,7 +10,9 @@
|
|||
* Miscellaneous definitions
|
||||
*/
|
||||
|
||||
#define MAX_TRIES_BUSY 100000 /* The maximum number of times to check for an operation to complete (general purpose) */
|
||||
#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) */
|
||||
|
||||
/*
|
||||
* Definitions of special characters
|
||||
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
36
src/include/lpt_reg.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
16
src/include/timers_reg.h
Normal 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
|
|
@ -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);
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue