Revision 192
Added by markw almost 11 years ago
firmware_5200/Makefile | ||
---|---|---|
BASE = zpu-elf
|
||
CC = $(BASE)-gcc
|
||
LD = $(BASE)-gcc
|
||
AS = $(BASE)-as
|
||
CP = $(BASE)-objcopy
|
||
DUMP = $(BASE)-objdump
|
||
|
||
# we use mincrt0.s from here
|
||
STARTUP_DIR = .
|
||
|
||
# we fetch ROM prologue / epilogue from here
|
||
RTL_DIR = $(ZPUFLEXDIR)/RTL/
|
||
|
||
|
||
BUILD_DIR=zpu_obj
|
||
|
||
#MINSTARTUP_SRC = mincrt0.s
|
||
MINSTARTUP_SRC = mycrt0.s
|
||
MINSTARTUP_OBJ = $(patsubst $(STARTUP_DIR)/%.s,$(BUILD_DIR)/%.o,$(MINSTARTUP_SRC))
|
||
|
||
AEON_LITE_PRJ = AEON_LITE
|
||
AEON_LITE_SRC = main_aeon_lite.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c de1/dirs.c
|
||
AEON_LITE_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(AEON_LITE_SRC))
|
||
|
||
DE1_PRJ = DE1
|
||
DE1_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c de1/dirs.c
|
||
DE1_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(DE1_SRC))
|
||
|
||
CHAMELEON_PRJ = CHAMELEON
|
||
CHAMELEON_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c chameleon/dirs.c
|
||
CHAMELEON_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(CHAMELEON_SRC))
|
||
|
||
MCC_PRJ = MCC216
|
||
MCC_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c sd_direct/spi.c sd_direct/mmc2.c mcc/dirs.c
|
||
MCC_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(MCC_SRC))
|
||
|
||
MIST_PRJ = MIST
|
||
MIST_SRC = main.c regs.c freeze.c joystick.c fileutils.c fileselector.c pokey/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c mist/diskio_sectorrequest.c mist/dirs.c
|
||
MIST_OBJ = $(patsubst %.c,$(BUILD_DIR)/%.o,$(MIST_SRC))
|
||
|
||
LINKMAP = ./standalone_simple.ld
|
||
|
||
|
||
# Commandline options for each tool.
|
||
|
||
#ZPUOPTS= -mno-poppcrel -mno-pushspadd -mno-callpcrel -mno-shortop -mno-neg # No-neg requires bugfixed toolchain
|
||
#Include everything -> need to include emulation rom...
|
||
ZPUOPTS =
|
||
CFLAGS = -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -Os $(ZPUOPTS) -DDISABLE_UART_RX
|
||
|
||
LFLAGS = -nostartfiles -Wl,--relax -g -Os
|
||
#LFLAGS = -nostartfiles -Os
|
||
|
||
|
||
# Our target.
|
||
all: mcc mist de1 aeon_lite chameleon
|
||
|
||
install:
|
||
cd ../common/romgen && ./createall && cd ../../firmware
|
||
|
||
aeon_lite: $(BUILD_DIR) $(AEON_LITE_PRJ).bin $(AEON_LITE_PRJ).rpt
|
||
|
||
de1: $(BUILD_DIR) $(DE1_PRJ).bin $(DE1_PRJ).rpt
|
||
|
||
chameleon: $(BUILD_DIR) $(CHAMELEON_PRJ).bin $(CHAMELEON_PRJ).rpt
|
||
|
||
mcc: $(BUILD_DIR) $(MCC_PRJ).bin $(MCC_PRJ).rpt
|
||
|
||
mist: $(BUILD_DIR) $(MIST_PRJ).bin $(MIST_PRJ).rpt
|
||
|
||
clean:
|
||
rm -rf $(BUILD_DIR)/* *.hex *.elf *.map *.lst *.srec *.bin *.rpt
|
||
|
||
|
||
# Convert ELF binary to bin file.
|
||
%.bin: %.elf
|
||
$(CP) -O binary $< $@
|
||
|
||
%.rpt: %.elf
|
||
echo >$@ -n "End of code:\t"
|
||
$(DUMP) -x $< | grep >>$@ _romend
|
||
echo >>$@ -n "Start of BSS:\t"
|
||
$(DUMP) -x $< | grep >>$@ __bss_start__
|
||
echo >>$@ -n "End of BSS:\t"
|
||
$(DUMP) -x $< | grep >>$@ __bss_end__
|
||
cat $@
|
||
|
||
# Link - this produces an ELF binary.
|
||
|
||
$(AEON_LITE_PRJ).elf: $(MINSTARTUP_OBJ) $(AEON_LITE_OBJ)
|
||
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
|
||
|
||
$(DE1_PRJ).elf: $(MINSTARTUP_OBJ) $(DE1_OBJ)
|
||
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
|
||
|
||
$(CHAMELEON_PRJ).elf: $(MINSTARTUP_OBJ) $(CHAMELEON_OBJ)
|
||
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
|
||
|
||
$(MCC_PRJ).elf: $(MINSTARTUP_OBJ) $(MCC_OBJ)
|
||
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
|
||
|
||
$(MIST_PRJ).elf: $(MINSTARTUP_OBJ) $(MIST_OBJ)
|
||
$(LD) $(LFLAGS) -T $(LINKMAP) -o $@ $+ $(LIBS)
|
||
|
||
$(BUILD_DIR)/%.o: %.c Makefile
|
||
mkdir -p `dirname $@`
|
||
$(CC) $(CFLAGS) -o $@ -c $<
|
||
|
||
$(BUILD_DIR)/%.o: %.s
|
||
$(AS) -o $@ $<
|
||
|
||
$(BUILD_DIR)/%.o: $(STARTUP_DIR)/%.s
|
||
$(AS) -o $@ $<
|
||
|
||
$(BUILD_DIR):
|
||
mkdir $(BUILD_DIR)
|
||
|
firmware_5200/sdram_common/memory.h | ||
---|---|---|
#pragma once
|
||
|
||
// Memory usage...
|
||
// 0x410000-0x44FFFF (0xc10000 in zpu space) = directory cache - 256k
|
||
// 0x450000-0x46FFFF (0xc50000 in zpu space) = freeze backup
|
||
// 0x700000-0x77FFFF (0xf00000 in zpu space) = os rom/basic rom
|
||
|
||
#define DIR_INIT_MEM 0xc10000
|
||
#define DIR_INIT_MEMSIZE 262144
|
||
#define FREEZE_MEM 0xc50000
|
||
#define ROM_MEM 0x700000
|
||
|
firmware_5200/test_joy.c | ||
---|---|---|
#include "joystick.h"
|
||
|
||
#include <stdio.h>
|
||
#include <poll.h>
|
||
#include <termios.h>
|
||
#include <unistd.h>
|
||
|
||
extern char native_porta;
|
||
extern char native_trig;
|
||
|
||
void read_keys();
|
||
|
||
struct termios oldt, newt;
|
||
void term_init()
|
||
{
|
||
tcgetattr(STDIN_FILENO, &oldt);
|
||
newt = oldt;
|
||
newt.c_lflag &= ~( ICANON | ECHO );
|
||
tcsetattr( STDIN_FILENO, TCSANOW, &newt);
|
||
}
|
||
|
||
void term_close()
|
||
{
|
||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
term_init();
|
||
|
||
fprintf(stderr,"Polling\n");
|
||
int i;
|
||
for (i=0;i!=200;++i)
|
||
{
|
||
struct joystick_status joy;
|
||
read_keys();
|
||
joystick_poll(&joy);
|
||
|
||
fprintf(stderr, "x:%d y:%d fire:%d\n", joy.x_, joy.y_, joy.fire_);
|
||
|
||
usleep(100000);
|
||
}
|
||
|
||
|
||
//void joystick_poll(struct joystick_status * status);
|
||
//void joystick_wait(struct joystick_status * status, enum JoyWait waitFor);
|
||
|
||
term_close();
|
||
|
||
return 0;
|
||
}
|
||
|
||
void read_keys()
|
||
{
|
||
struct pollfd fds[1];
|
||
fds[0].fd = STDIN_FILENO;
|
||
fds[0].events = POLLIN;
|
||
native_porta = 0xff;
|
||
native_trig = 0xff;
|
||
while (poll(&fds[0], 1, 0))
|
||
{
|
||
char buffer[0];
|
||
read(0,&buffer[0],1);
|
||
|
||
if (buffer[0] == 0x41) fprintf(stderr, "UP\n");
|
||
if (buffer[0] == 0x42) fprintf(stderr, "DOWN\n");
|
||
if (buffer[0] == 0x44) fprintf(stderr, "LEFT\n");
|
||
if (buffer[0] == 0x43) fprintf(stderr, "RIGHT\n");
|
||
if (buffer[0] == 0x20) fprintf(stderr, "FIRE\n");
|
||
|
||
// RLDU
|
||
if (buffer[0] == 0x41) native_porta=0xff&~(1<<0);
|
||
if (buffer[0] == 0x42) native_porta=0xff&~(1<<1);
|
||
if (buffer[0] == 0x44) native_porta=0xff&~(1<<2);
|
||
if (buffer[0] == 0x43) native_porta=0xff&~(1<<3);
|
||
if (buffer[0] == 0x20) native_trig=0xff&~1;
|
||
|
||
fds[0].fd = STDIN_FILENO;
|
||
fds[0].events = POLLIN;
|
||
}
|
||
}
|
||
|
||
|
firmware_5200/fileutils.c | ||
---|---|---|
#include "printf.h"
|
||
|
||
#include "utils.h"
|
||
|
||
int compare_ext(char const * filename, char const * ext)
|
||
{
|
||
int dot = 0;
|
||
//printf("WTFA:%s %s\n",filenamein, extin);
|
||
//printf("WTFB:%s %s\n",filename, ext);
|
||
|
||
char const * end = strlen(filename) + filename;
|
||
while (--end != filename)
|
||
{
|
||
if (*end == '.')
|
||
break;
|
||
}
|
||
if (0==stricmp(end+1,ext)) return 1;
|
||
|
||
return 0;
|
||
}
|
||
|
firmware_5200/build_native_joystick | ||
---|---|---|
gcc -g -O0 test_joy.c joystick.c native/regs.c -I.
|
||
firmware_5200/fileutils.h | ||
---|---|---|
#pragma once
|
||
|
||
int compare_ext(char const * filename, char const * ext);
|
||
|
firmware_5200/pokey/uart.c | ||
---|---|---|
#include "uart.h"
|
||
|
||
#include "regs.h"
|
||
|
||
void actions();
|
||
|
||
int USART_Data_Needed()
|
||
{
|
||
int needed = 0==(0x10&(*zpu_pokey_irqen));
|
||
if (needed)
|
||
{
|
||
*zpu_pokey_irqen = 0x28;
|
||
*zpu_pokey_irqen = 0x38;
|
||
}
|
||
return needed;
|
||
}
|
||
|
||
int USART_Data_Ready()
|
||
{
|
||
int ready = 0==(0x20&(*zpu_pokey_irqen));
|
||
if (ready)
|
||
{
|
||
*zpu_pokey_irqen = 0x18;
|
||
*zpu_pokey_irqen = 0x38;
|
||
}
|
||
return ready;
|
||
}
|
||
|
||
void USART_Init( u08 value )
|
||
{
|
||
// value is pokey div + 6
|
||
*zpu_pokey_skctl = 0;
|
||
wait_us(10);
|
||
USART_Receive_Mode(); // turn of reset and listen to commands
|
||
*zpu_pokey_audctl = 0x78; // linked channels, fast clocked
|
||
*zpu_pokey_audf1 = 0x00;
|
||
*zpu_pokey_audf0 = value-6;
|
||
*zpu_pokey_audf3 = 0x00;
|
||
*zpu_pokey_audf2 = value-6;
|
||
|
||
*zpu_pokey_irqen = 0x00;
|
||
*zpu_pokey_irqen = 0x38;
|
||
}
|
||
|
||
void USART_Transmit_Byte( unsigned char data )
|
||
{
|
||
*zpu_pokey_serout = data;
|
||
|
||
// wait until next byte is needed
|
||
while (!USART_Data_Needed());
|
||
}
|
||
unsigned char USART_Receive_Byte( void )
|
||
{
|
||
// wait for data
|
||
while (!USART_Data_Ready())
|
||
{
|
||
actions();
|
||
}
|
||
|
||
u08 res = *zpu_pokey_serout; //serin at same address
|
||
return res;
|
||
}
|
||
|
||
void USART_Transmit_Mode()
|
||
{
|
||
*zpu_pokey_skctl = 0x23; // 010 for transmission
|
||
*zpu_pokey_skrest = 0xff;
|
||
*zpu_pokey_irqen = 0x28; // clear data needed
|
||
*zpu_pokey_irqen = 0x38;
|
||
}
|
||
|
||
void USART_Receive_Mode()
|
||
{
|
||
*zpu_pokey_skctl = 0x13; // 001 for receiving
|
||
*zpu_pokey_skrest = 0xff;
|
||
}
|
||
|
||
int USART_Framing_Error()
|
||
{
|
||
if (0xc0&(*zpu_pokey_skctl))
|
||
{
|
||
return 0;
|
||
}
|
||
else
|
||
{
|
||
return 1;
|
||
}
|
||
}
|
||
|
||
void USART_Wait_Transmit_Complete()
|
||
{
|
||
while (1)
|
||
{
|
||
int ready = 0==(0x08&(*zpu_pokey_irqen));
|
||
if (ready)
|
||
{
|
||
*zpu_pokey_irqen = 0x30;
|
||
*zpu_pokey_irqen = 0x38;
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
int USART_Command_Line()
|
||
{
|
||
return (1&(*zpu_sio));
|
||
}
|
||
|
firmware_5200/common/utils.c | ||
---|---|---|
#include "utils.h"
|
||
|
||
int strcmp(char const * a, char const * b)
|
||
{
|
||
while (*a || *b)
|
||
{
|
||
if (*a<*b)
|
||
return -1;
|
||
else if (*a>*b)
|
||
return 1;
|
||
|
||
++a;
|
||
++b;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
int stricmp(char const * a, char const * b)
|
||
{
|
||
char buffer[128];
|
||
char buffer2[128];
|
||
stricpy(&buffer[0],a);
|
||
stricpy(&buffer2[0],b);
|
||
return strcmp(&buffer[0],&buffer2[0]);
|
||
}
|
||
|
||
void strcpy(char * dest, char const * src)
|
||
{
|
||
while (*dest++=*src++);
|
||
}
|
||
|
||
void stricpy(char * dest, char const * src)
|
||
{
|
||
while (*src)
|
||
{
|
||
char val = *src++;
|
||
if (val>='A' && val<='Z') val+=-'A'+'a';
|
||
|
||
*dest++ = val;
|
||
}
|
||
*dest = '\0';
|
||
}
|
||
|
||
int strlen(char const * a)
|
||
{
|
||
int count;
|
||
for (count=0; *a; ++a,++count);
|
||
return count;
|
||
}
|
||
|
firmware_5200/common/integer.h | ||
---|---|---|
#ifndef _INTEGER
|
||
#define _INTEGER
|
||
|
||
/* These types must be 16-bit, 32-bit or larger integer */
|
||
typedef int INT;
|
||
typedef unsigned int UINT;
|
||
|
||
/* These types must be 8-bit integer */
|
||
typedef char CHAR;
|
||
typedef unsigned char UCHAR;
|
||
typedef unsigned char BYTE;
|
||
typedef unsigned char u08;
|
||
typedef unsigned char uint8_t;
|
||
|
||
/* These types must be 16-bit integer */
|
||
typedef short SHORT;
|
||
typedef unsigned short USHORT;
|
||
typedef unsigned short WORD;
|
||
typedef unsigned short WCHAR;
|
||
typedef unsigned short u16;
|
||
|
||
/* These types must be 32-bit integer */
|
||
typedef long LONG;
|
||
typedef unsigned long ULONG;
|
||
typedef unsigned long DWORD;
|
||
typedef unsigned int u32;
|
||
|
||
#define EEMEM
|
||
|
||
#endif
|
firmware_5200/common/utils.h | ||
---|---|---|
int strcmp(char const * a, char const * b);
|
||
int stricmp(char const * a, char const * b);
|
||
void strcpy(char * dest, char const * src);
|
||
void stricpy(char * dest, char const * src);
|
||
int strlen(char const * a);
|
||
|
firmware_5200/common/x | ||
---|---|---|
g++: error: fat/pff_file.c: No such file or directory
|
||
g++: fatal error: no input files
|
||
compilation terminated.
|
firmware_5200/chameleon/dirs.c | ||
---|---|---|
char USER_DIR[]="/atari800/user";
|
||
char ROM_DIR[]="/atari800/rom";
|
firmware_5200/build_native_drive | ||
---|---|---|
gcc -g -O0 -DLITTLE_ENDIAN test_drive.c fileutils.c atari_drive_emulator.c native/uart.c hexdump.c printf/printf.c fat/pff_file.c fat/pff.c common/utils.c sd_direct/diskio_mmc.c native/mmc.c -I. -Iprintf -Ifat -Icommon
|
||
firmware_5200/build | ||
---|---|---|
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/uart.o -c pokey/uart.c
|
||
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/hexdump.o -c hexdump.c
|
||
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/printf.o -c printf/printf.c
|
||
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/pff_file.o -c fat/pff_file.c
|
||
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/pff.o -c fat/pff.c
|
||
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/utils.o -c common/utils.c
|
||
zpu-elf-gcc -I. -Isd_direct -Iprintf -Ifat -Icommon -c -g -O2 -DDISABLE_UART_RX -o zpu_obj/diskio_mmc.o -c diskio_mmc.c
|
||
zpu-elf-gcc -nostartfiles -Wl,--relax -g -Os -T ./standalone_simple.ld -o JustStartAtari.elf mycrt0.s zpu_obj/main.o zpu_obj/regs.o zpu_obj/atari_drive_emulator.o zpu_obj/pokey/uart.o zpu_obj/hexdump.o zpu_obj/printf/printf.o zpu_obj/fat/pff_file.o zpu_obj/fat/pff.o zpu_obj/common/utils.o zpu_obj/diskio_mmc.o
|
||
zpu-elf-objcopy -O binary JustStartAtari.elf JustStartAtari.bin
|
||
echo >JustStartAtari.rpt -n "End of code:\t"
|
||
zpu-elf-objdump -x JustStartAtari.elf | grep >>JustStartAtari.rpt _romend
|
||
echo >>JustStartAtari.rpt -n "Start of BSS:\t"
|
||
zpu-elf-objdump -x JustStartAtari.elf | grep >>JustStartAtari.rpt __bss_start__
|
||
echo >>JustStartAtari.rpt -n "End of BSS:\t"
|
||
zpu-elf-objdump -x JustStartAtari.elf | grep >>JustStartAtari.rpt __bss_end__
|
||
cat JustStartAtari.rpt
|
||
|
||
firmware_5200/standalone_simple.ld | ||
---|---|---|
|
||
/* Memory Definitions for a ZPU program running either from external RAM (up to 8 meg).
|
||
or from unremapped Boot ROM / Stack RAM. */
|
||
|
||
MEMORY
|
||
{
|
||
CODE (rx) : ORIGIN = 0x00000000, LENGTH = 0x04000 /* 16k */
|
||
RAM (rx) : ORIGIN = 0x0000f000, LENGTH = 0x600 /* 32 bytes */
|
||
}
|
||
|
||
|
||
/* Section Definitions */
|
||
|
||
SECTIONS
|
||
{
|
||
/* first section is .fixed_vectors which is used for startup code */
|
||
. = 0x0000000;
|
||
.fixed_vectors :
|
||
{
|
||
*(.fixed_vectors)
|
||
}>CODE
|
||
|
||
/* Remaining code sections */
|
||
. = ALIGN(4);
|
||
.text :
|
||
{
|
||
*(.text) /* remaining code */
|
||
} >CODE
|
||
|
||
/* .rodata section which is used for read-only data (constants) */
|
||
. = ALIGN(4);
|
||
.rodata :
|
||
{
|
||
*(.rodata)
|
||
} >CODE
|
||
. = ALIGN(4);
|
||
|
||
/* .data section which is used for initialized data. */
|
||
. = ALIGN(4);
|
||
.data :
|
||
{
|
||
_data = . ;
|
||
*(.data)
|
||
SORT(CONSTRUCTORS)
|
||
. = ALIGN(4);
|
||
} >CODE
|
||
_romend = . ;
|
||
|
||
/* .bss section which is used for uninitialized data */
|
||
. = ALIGN(4);
|
||
.bss :
|
||
{
|
||
__bss_start = . ;
|
||
__bss_start__ = . ;
|
||
*(.bss)
|
||
*(COMMON)
|
||
} >RAM
|
||
__bss_end__ = . ;
|
||
}
|
firmware_5200/test_file.c | ||
---|---|---|
#include "simpledir.h"
|
||
#include "simplefile.h"
|
||
#include "fileselector.h"
|
||
|
||
//#include "fat/pff_file.h"
|
||
// XXX - BEST NOT to include this?
|
||
char USER_DIR[]="/";
|
||
char ROM_DIR[]="/atari800/rom";
|
||
|
||
#include "stdio.h"
|
||
#include "stdlib.h"
|
||
|
||
int debug_pos = 0;
|
||
int prev_debug_pos = 0;
|
||
int debug_adjust = 0;
|
||
void wait_us(int us)
|
||
{
|
||
usleep(us);
|
||
}
|
||
|
||
struct SimpleFile * file;
|
||
#define ROM_MEM 0x700000
|
||
|
||
void char_out ( void* p, char c)
|
||
{
|
||
if (debug_pos!=prev_debug_pos)
|
||
{
|
||
fprintf(stderr,"\n");
|
||
}
|
||
//fprintf(stderr,"\n%dWTFWTF\n", debug_pos);
|
||
if (debug_adjust == 128)
|
||
{
|
||
putc('*',stderr);
|
||
}
|
||
putc(c, stderr);
|
||
++debug_pos;
|
||
prev_debug_pos = debug_pos;
|
||
}
|
||
|
||
struct SimpleFile * temp_file;
|
||
|
||
/*void loadrom(char const * path, int size, void * ram_address)
|
||
{
|
||
filter = 0;
|
||
fprintf(stderr,"loadrom:%s\n",path);
|
||
ram_address += 0x800000;
|
||
if (SimpleFile_OK == file_open_name(path, temp_file))
|
||
{
|
||
int read = 0;
|
||
//file_read(temp_file, ram_address, size, &read);
|
||
printf("file_read:%s %x %x\n",file_name(temp_file), ram_address,size);
|
||
}
|
||
else
|
||
{
|
||
printf("%s:FAILED\n",path);
|
||
}
|
||
}*/
|
||
|
||
void loadromfile(struct SimpleFile * file, int size, void * ram_address)
|
||
{
|
||
ram_address += 0x800000;
|
||
int read = 0;
|
||
//file_read(file, ram_address, size, &read);
|
||
printf("file_read:%s %x %x\n",file_name(temp_file), ram_address,size);
|
||
}
|
||
|
||
void loadrom(char const * path, int size, void * ram_address)
|
||
{
|
||
if (SimpleFile_OK == file_open_name(path, temp_file))
|
||
{
|
||
loadromfile(temp_file, size, ram_address);
|
||
}
|
||
else
|
||
{
|
||
printf("%s:FAILED\n",path);
|
||
}
|
||
}
|
||
|
||
void loadrom_indir(struct SimpleDirEntry * entries, char const * filename, int size, void * ram_address)
|
||
{
|
||
if (SimpleFile_OK == file_open_name_in_dir(entries, filename, temp_file))
|
||
{
|
||
loadromfile(temp_file, size, ram_address);
|
||
}
|
||
else
|
||
{
|
||
printf("FAILED\n");
|
||
}
|
||
}
|
||
|
||
void loadosrom()
|
||
{
|
||
if (file_size(file) == 0x0800)
|
||
{
|
||
printf("Hello world!\n");
|
||
int i=0;
|
||
unsigned char * src = (unsigned char *)(ROM_MEM + 0x4000);
|
||
unsigned char * dest1 = (unsigned char *)(ROM_MEM + 0x4800);
|
||
loadromfile(file,0x0800, (void *)(ROM_MEM + 0x4000));
|
||
for (i=0; i!=0x800; ++i)
|
||
{
|
||
dest1[i] = src[i];
|
||
}
|
||
}
|
||
else if (file_size(file) == 0x4000)
|
||
{
|
||
loadromfile(file,0x4000, (void *)(ROM_MEM + 0x4000));
|
||
}
|
||
else if (file_size(file) ==0x2800)
|
||
{
|
||
loadromfile(file,0x2800, (void *)(ROM_MEM + 0x5800));
|
||
}
|
||
}
|
||
|
||
int main(void)
|
||
{
|
||
init_printf(NULL, char_out);
|
||
|
||
char * mem = (char *)malloc(65536);
|
||
if (SimpleFile_OK != dir_init(mem, 65536))
|
||
{
|
||
fprintf(stderr,"Failed to open dir!");
|
||
return -1;
|
||
}
|
||
struct SimpleDirEntry * entry = dir_entries("");
|
||
while (entry)
|
||
{
|
||
fprintf(stderr, "Path:%s", dir_path(entry));
|
||
fprintf(stderr, " Name:%s", dir_filename(entry));
|
||
fprintf(stderr, " Size:%d", dir_filesize(entry));
|
||
fprintf(stderr, " Subdir:%d\n", dir_is_subdir(entry));
|
||
|
||
entry = dir_next(entry);
|
||
}
|
||
|
||
fprintf(stderr,"\n\n");
|
||
|
||
entry = dir_entries("/atari800");
|
||
while (entry)
|
||
{
|
||
fprintf(stderr, "Path:%s", dir_path(entry));
|
||
fprintf(stderr, " Name:%s", dir_filename(entry));
|
||
fprintf(stderr, " Size:%d", dir_filesize(entry));
|
||
fprintf(stderr, " Subdir:%d\n", dir_is_subdir(entry));
|
||
|
||
entry = dir_next(entry);
|
||
}
|
||
|
||
fprintf(stderr,"\n\n");
|
||
|
||
entry = dir_entries("/atari800/user");
|
||
while (entry)
|
||
{
|
||
fprintf(stderr, "Path:%s", dir_path(entry));
|
||
fprintf(stderr, " Name:%s", dir_filename(entry));
|
||
fprintf(stderr, " Size:%d", dir_filesize(entry));
|
||
fprintf(stderr, " Subdir:%d\n", dir_is_subdir(entry));
|
||
|
||
entry = dir_next(entry);
|
||
}
|
||
|
||
|
||
/*
|
||
fprintf(stderr,"\n\n");
|
||
//enum SimpleFileStatus file_open_name(char const * path, struct SimpleFile * file);
|
||
//enum SimpleFileStatus file_open_dir(struct SimpleDirEntry * filename, struct SimpleFile * file);
|
||
entry = dir_entries("/UAE4ALL");
|
||
entry = dir_next(entry);
|
||
fprintf(stderr, " Name:%s", dir_filename(entry));
|
||
struct SimpleFile * file = alloca(file_struct_size());
|
||
file_open_dir(entry,file);
|
||
|
||
//char const * file_name(struct SimpleFile * file);
|
||
//enum SimpleFileStatus file_read(struct SimpleFile * file, void * buffer, int bytes, int * bytesread);
|
||
//enum SimpleFileStatus file_write(struct SimpleFile * file, void * buffer, int bytes, int * byteswritten);
|
||
//enum SimpleFileStatus file_seek(struct SimpleFile * file, int offsetFromStart);
|
||
//int file_size(struct SimpleFile * file);
|
||
fprintf(stderr, " Size:%d\n---\n", file_size(file));
|
||
|
||
int read = 0;
|
||
char buffer[2048];
|
||
file_seek(file,10);
|
||
file_read(file,&buffer[0],2048,&read);
|
||
int i;
|
||
for (i=0; i!=read; ++i)
|
||
{
|
||
//fprintf(stderr,"%02x", buffer[i]);
|
||
fprintf(stderr,"%c", buffer[i]);
|
||
}
|
||
|
||
fprintf(stderr,"\n\n");
|
||
|
||
int written;
|
||
file_seek(file,10);
|
||
file_write(file,"Mark",4,&written); // in order to write 'mark' as position 10...
|
||
//file_write_flush(); // Done automatically on next read, or can be forced with this...
|
||
|
||
file_seek(file,512);
|
||
// for (i=0;i!=130;++i)
|
||
// {
|
||
// char towrite[9];
|
||
// sprintf(&towrite[0],"Mark:%03d",i);
|
||
// fprintf(stderr,"Writing \"%s\"\n",towrite);
|
||
// file_write(file,towrite,8,&written);
|
||
// }
|
||
// file_write(file,"Blah",4,&written);
|
||
|
||
printf("\n*** WTF:%s - %s - %s\n",file_name(file), file_of("/WTF"),file_of("/BLAH/BOOP"));
|
||
|
||
// So... for write can only seek to nearest 512...
|
||
|
||
fprintf(stderr,"\n\n");
|
||
file_seek(file,10);
|
||
file_read(file,&buffer[0],2048,&read);
|
||
for (i=0; i!=read; ++i)
|
||
{
|
||
//fprintf(stderr,"%02x", buffer[i]);
|
||
fprintf(stderr,"%c", buffer[i]);
|
||
}
|
||
*/
|
||
|
||
temp_file = alloca(file_struct_size());
|
||
loadrom("ASTEROID.BIN",0x4000, (void *)0x704000);
|
||
loadrom("asteroid.bin",0x4000, (void *)0x704000);
|
||
loadrom("xlorig.rom",0x4000, (void *)0x704000);
|
||
loadrom("xlhias.rom",0x4000, (void *)0x708000);
|
||
loadrom("ultimon.rom",0x4000, (void *)0x70c000);
|
||
loadrom("osbhias.rom",0x4000, (void *)0x710000);
|
||
loadrom("osborig.rom",0x2800, (void *)0x715800);
|
||
loadrom("osaorig.rom",0x2800, (void *)0x719800);
|
||
loadrom("ataribas.rom",0x2000,(void *)0x700000);
|
||
|
||
/*{
|
||
printf("WTF\n");
|
||
struct SimpleDirEntry * entries = dir_entries("/system/rom/atari800");
|
||
entries = dir_next(entries);
|
||
printf("WTF:%s\n",dir_filename(entries));
|
||
|
||
loadrom_indir(entries,"xlorig.rom",0x4000, (void *)0x704000);
|
||
loadrom_indir(entries,"xlhias.rom",0x4000, (void *)0x708000);
|
||
loadrom_indir(entries,"ultimon.rom",0x4000, (void *)0x70c000);
|
||
loadrom_indir(entries,"osbhias.rom",0x4000, (void *)0x710000);
|
||
loadrom_indir(entries,"osborig.rom",0x2800, (void *)0x715800);
|
||
loadrom_indir(entries,"osaorig.rom",0x2800, (void *)0x719800);
|
||
loadrom_indir(entries,"ataribas.rom",0x2000,(void *)0x700000);
|
||
}*/
|
||
|
||
//entry = dir_entries("/atari800/user");
|
||
//entry = dir_next(entry);
|
||
//fprintf(stderr, " Name:%s", dir_filename(entry));
|
||
file = alloca(file_struct_size());
|
||
//file_open_name("/atari800/user/acid800.atr",file);
|
||
//fprintf(stderr, "XXX Name:%s", file_name(file));
|
||
filter = filter_disks;
|
||
//file_selector(file);
|
||
|
||
fprintf(stderr, "\n\n\n HERE WE GO!\n\n\n");
|
||
|
||
{
|
||
struct SimpleDirEntry * entries = dir_entries(ROM_DIR);
|
||
|
||
fprintf(stderr, "\n\n\n HERE WE GO! 222 \n\n\n");
|
||
|
||
if (SimpleFile_OK == file_open_name_in_dir(entries, "5200.rom", file))
|
||
{
|
||
fprintf(stderr, "\n\n\n HERE WE GO! 333 \n\n\n");
|
||
loadosrom();
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|
firmware_5200/setup | ||
---|---|---|
export PATH=${PATH}:/home/markw/fpga/zpugcc/toolchain/install/bin/
|
firmware_5200/test_freeze.c | ||
---|---|---|
#include "regs.h"
|
||
|
||
#include "stdlib.h"
|
||
#include "stdio.h"
|
||
|
||
#undef atari_regbase
|
||
static char * atari_regbase = (char *)malloc(65536);
|
||
#undef atari_regmirror
|
||
static char * atari_regmirror = (char *)malloc(65536);
|
||
#include "freeze.h"
|
||
#include "freeze.c"
|
||
#include "regs.c"
|
||
|
||
int main(void)
|
||
{
|
||
char * buffer = (char *)malloc(1024*128);
|
||
freeze_init(buffer);
|
||
|
||
for (int i=0; i!=64*1024; ++i)
|
||
{
|
||
*((unsigned char *)(atari_regbase+i)) = i%256;
|
||
}
|
||
|
||
for (int i=0;i!=0x10000;++i)
|
||
{
|
||
*((atari_regmirror+i)) = i%256-2;
|
||
}
|
||
freeze();
|
||
/*for (int i=0; i!=64*1024; ++i)
|
||
{
|
||
fprintf(stderr,"i:%x val:%x\n",i,*((unsigned char *)(buffer+i)));
|
||
if (i%256!=*((unsigned char *)(buffer+i)))
|
||
{
|
||
fprintf(stderr,"!!FAIL!%d %d %d", i, i%256, *(unsigned char *)(atari_regbase+i));
|
||
return -1;
|
||
}
|
||
}*/
|
||
|
||
for (int i=0;i!=0xd000; ++i)
|
||
{
|
||
*((atari_regbase+i)) = 0;
|
||
}
|
||
for (int i=0xd800;i!=0x10000; ++i)
|
||
{
|
||
*((atari_regbase+i)) = 0;
|
||
}
|
||
restore();
|
||
|
||
for (int i=0; i!=64*1024; ++i)
|
||
{
|
||
unsigned char exp = i%256;
|
||
if (i>=0xd000 && i<0xd800) exp-=2;
|
||
if (i>=0xd020 && i<0xd200) exp+=2;
|
||
if (i>=0xd220 && i<0xd400) exp+=2;
|
||
if (i>=0xd410 && i<0xd800) exp+=2;
|
||
if (exp!=*((unsigned char *)(atari_regbase+i)))
|
||
{
|
||
fprintf(stderr,"FAIL!addr:%x exp:%d got:%d", i, exp, *(unsigned char *)(atari_regbase+i));
|
||
return -1;
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
firmware_5200/fileselector.c | ||
---|---|---|
#include "simplefile.h"
|
||
#include "simpledir.h"
|
||
#include "joystick.h"
|
||
#include "regs.h" // NO NEED!!!
|
||
#include "printf.h"
|
||
#include "fileutils.h"
|
||
|
||
extern int debug_pos; // ARG!
|
||
extern int debug_adjust; // ARG!
|
||
extern char USER_DIR[];
|
||
|
||
// TODO!
|
||
#define MAX_PATH_LENGTH (9*5 + 8+3+1 + 1)
|
||
|
||
int (* filter)(struct SimpleDirEntry * entry);
|
||
|
||
int filter_disks(struct SimpleDirEntry * entry)
|
||
{
|
||
if (dir_is_subdir(entry)) return 1;
|
||
char const * f = dir_filename(entry);
|
||
int res = (compare_ext(f,"ATR") || compare_ext(f,"XFD") || compare_ext(f,"XEX"));
|
||
printf("filter_disks:%s:%d\n",f,res);
|
||
return res;
|
||
}
|
||
|
||
int filter_roms(struct SimpleDirEntry * entry)
|
||
{
|
||
if (dir_is_subdir(entry)) return 1;
|
||
char const * f = dir_filename(entry);
|
||
return (compare_ext(f,"ROM"));
|
||
}
|
||
|
||
int filter_bins(struct SimpleDirEntry * entry)
|
||
{
|
||
if (dir_is_subdir(entry)) return 1;
|
||
char const * f = dir_filename(entry);
|
||
return (compare_ext(f,"BIN"));
|
||
}
|
||
|
||
void dir_of(char * dir, char const * path); // TODO - into simpledir
|
||
|
||
void file_selector(struct SimpleFile * file)
|
||
{
|
||
char dir[MAX_PATH_LENGTH];
|
||
if (file_name(file)[0] == '\0')
|
||
{
|
||
strcpy(&dir[0],USER_DIR);
|
||
}
|
||
else
|
||
{
|
||
dir_of(&dir[0],file_path(file));
|
||
}
|
||
for (;;)
|
||
{
|
||
struct SimpleDirEntry * entry = dir_entries_filtered(dir,filter);
|
||
|
||
// Count how many we have
|
||
int entries = 0;
|
||
struct SimpleDirEntry * temp_entry = entry;
|
||
while (temp_entry)
|
||
{
|
||
++entries;
|
||
temp_entry = dir_next(temp_entry);
|
||
}
|
||
//printf("Entries:%d\n",entries);
|
||
|
||
// Selected item
|
||
int pos = 0;
|
||
int prevstartpos = -1;
|
||
|
||
struct joystick_status joy;
|
||
joy.x_ = joy.y_ = joy.fire_ = 0;
|
||
|
||
for (;;)
|
||
{
|
||
if (pos<0) pos = 0;
|
||
if (pos>=entries) pos = entries-1;
|
||
|
||
// render
|
||
{
|
||
// find which chunk to render
|
||
int startpos = pos-10;
|
||
//printf("\nA pos:%d, startpos:%d\n",pos,startpos);
|
||
//startpos &= 0xfffffffe;
|
||
//printf("startpos:%d\n",startpos);
|
||
if (startpos<0) startpos=0;
|
||
//printf("pos:%d, startpos:%d\n",pos,startpos);
|
||
|
||
// get the dir entries for these
|
||
struct SimpleDirEntry * render_entry = entry;
|
||
int skip = startpos;
|
||
while (skip-->0)
|
||
{
|
||
render_entry = dir_next(render_entry);
|
||
}
|
||
|
||
// clear the screen
|
||
if (startpos!=prevstartpos)
|
||
{
|
||
clearscreen();
|
||
prevstartpos = startpos;
|
||
}
|
||
|
||
// find selected entry
|
||
struct SimpleDirEntry * sel_entry = entry;
|
||
skip = pos;
|
||
while (skip-->0)
|
||
{
|
||
sel_entry = dir_next(sel_entry);
|
||
}
|
||
|
||
// output the new entries
|
||
int line;
|
||
debug_pos = 0;
|
||
debug_adjust = 0;
|
||
printf("Choose ");
|
||
debug_adjust = 128;
|
||
printf("file");
|
||
debug_pos = 40;
|
||
int end = 22*40;
|
||
for (;;)
|
||
{
|
||
if (!render_entry) break;
|
||
|
||
int prev_debug_pos = debug_pos;
|
||
if (render_entry == sel_entry)
|
||
{
|
||
debug_adjust = 128;
|
||
}
|
||
else
|
||
{
|
||
debug_adjust = 0;
|
||
}
|
||
if (dir_is_subdir(render_entry))
|
||
{
|
||
printf("DIR:");
|
||
}
|
||
printf("%s",dir_filename(render_entry));
|
||
|
||
render_entry = dir_next(render_entry);
|
||
|
||
while(prev_debug_pos<debug_pos)
|
||
{
|
||
prev_debug_pos+=40;
|
||
}
|
||
debug_pos = prev_debug_pos;
|
||
//printf("debug_pos:%d",debug_pos);
|
||
if (debug_pos>=end) break;
|
||
}
|
||
|
||
debug_pos = 40*23;
|
||
if (sel_entry)
|
||
{
|
||
//printf("%s %s %d %d %d",dir_is_subdir(sel_entry) ? "DIR":"", dir_filename(sel_entry), joy.x_, joy.y_, pos);
|
||
printf("%s %s",dir_is_subdir(sel_entry) ? "DIR":"", dir_filename(sel_entry));
|
||
}
|
||
int i;
|
||
for (i=0;i!=40;++i) printf(" ");
|
||
}
|
||
|
||
// Slow it down a bit
|
||
wait_us(100000);
|
||
|
||
// move
|
||
joystick_wait(&joy,WAIT_QUIET);
|
||
joystick_wait(&joy,WAIT_EITHER);
|
||
|
||
if (joy.fire_)
|
||
{
|
||
int i = pos;
|
||
while(i--)
|
||
{
|
||
if (!entry) break;
|
||
entry = dir_next(entry);
|
||
}
|
||
|
||
if (entry)
|
||
{
|
||
if (!dir_is_subdir(entry))
|
||
{
|
||
file_open_dir(entry, file);
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
char const *f = dir_filename(entry);
|
||
if (strcmp("..",f)==0)
|
||
{
|
||
int x = strlen(dir);
|
||
while (x-->0)
|
||
{
|
||
if (dir[x] == '/')
|
||
{
|
||
dir[x] = '\0';
|
||
break;
|
||
}
|
||
}
|
||
//printf("\nDIR UP! %s\n",dir);
|
||
}
|
||
else
|
||
{
|
||
//strcpy(dir + strlen(dir),"/");
|
||
//strcpy(dir + strlen(dir),f);
|
||
//printf("\nDIR DOWN:%s -> %s\n",f,dir);
|
||
strcpy(dir,dir_path(entry));
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
pos += joy.x_*10;
|
||
pos += joy.y_;
|
||
}
|
||
}
|
||
}
|
||
|
firmware_5200/uart.h | ||
---|---|---|
#ifndef UART_H
|
||
#define UART_H
|
||
|
||
#include "integer.h"
|
||
|
||
// Might be simplest to use another Pokey as the UART...
|
||
|
||
void USART_Init( u08 value ); // value is baud rate
|
||
// must flush too
|
||
|
||
void USART_Transmit_Byte( unsigned char data );
|
||
unsigned char USART_Receive_Byte( void );
|
||
|
||
int USART_Data_Ready();
|
||
|
||
void USART_Transmit_Mode();
|
||
void USART_Receive_Mode();
|
||
|
||
int USART_Framing_Error();
|
||
|
||
void USART_Wait_Transmit_Complete();
|
||
|
||
int USART_Command_Line();
|
||
|
||
#endif
|
firmware_5200/printf/printf.c | ||
---|---|---|
/*
|
||
* Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
|
||
*
|
||
* All rights reserved.
|
||
*
|
||
* Redistribution and use in source and binary forms, with or without modification,
|
||
* are permitted provided that the following conditions are met:
|
||
*
|
||
* Redistributions of source code must retain the above copyright notice, this list
|
||
* of conditions and the following disclaimer.
|
||
*
|
||
* Redistributions in binary form must reproduce the above copyright notice, this
|
||
* list of conditions and the following disclaimer in the documentation and/or other
|
||
* materials provided with the distribution.
|
||
*
|
||
* Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
|
||
* contributors may be used to endorse or promote products derived from this software
|
||
* without specific prior written permission.
|
||
*
|
||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
||
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||
* OF SUCH DAMAGE.
|
||
*/
|
||
|
||
#include "printf.h"
|
||
|
||
typedef void (*putcf) (void*,char);
|
||
static putcf stdout_putf;
|
||
static void* stdout_putp;
|
||
|
||
|
||
#ifdef PRINTF_LONG_SUPPORT
|
||
|
||
static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf)
|
||
{
|
||
int n=0;
|
||
unsigned int d=1;
|
||
while (num/d >= base)
|
||
d*=base;
|
||
while (d!=0) {
|
||
int dgt = num / d;
|
||
num%=d;
|
||
d/=base;
|
||
if (n || dgt>0|| d==0) {
|
||
*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
|
||
++n;
|
||
}
|
||
}
|
||
*bf=0;
|
||
}
|
||
|
||
static void li2a (long num, char * bf)
|
||
{
|
||
if (num<0) {
|
||
num=-num;
|
||
*bf++ = '-';
|
||
}
|
||
uli2a(num,10,0,bf);
|
||
}
|
||
|
||
#endif
|
||
|
||
static void ui2a(unsigned int num, unsigned int base, int uc,char * bf)
|
||
{
|
||
int n=0;
|
||
unsigned int d=1;
|
||
while (num/d >= base)
|
||
d*=base;
|
||
while (d!=0) {
|
||
int dgt = num / d;
|
||
num%= d;
|
||
d/=base;
|
||
if (n || dgt>0 || d==0) {
|
||
*bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10);
|
||
++n;
|
||
}
|
||
}
|
||
*bf=0;
|
||
}
|
||
|
||
static void i2a (int num, char * bf)
|
||
{
|
||
if (num<0) {
|
||
num=-num;
|
||
*bf++ = '-';
|
||
}
|
||
ui2a(num,10,0,bf);
|
||
}
|
||
|
||
static int a2d(char ch)
|
||
{
|
||
if (ch>='0' && ch<='9')
|
||
return ch-'0';
|
||
else if (ch>='a' && ch<='f')
|
||
return ch-'a'+10;
|
||
else if (ch>='A' && ch<='F')
|
||
return ch-'A'+10;
|
||
else return -1;
|
||
}
|
||
|
||
static char a2i(char ch, char** src,int base,int* nump)
|
||
{
|
||
char* p= *src;
|
||
int num=0;
|
||
int digit;
|
||
while ((digit=a2d(ch))>=0) {
|
||
if (digit>base) break;
|
||
num=num*base+digit;
|
||
ch=*p++;
|
||
}
|
||
*src=p;
|
||
*nump=num;
|
||
return ch;
|
||
}
|
||
|
||
static void putchw(void* putp,putcf putf,int n, char z, char* bf)
|
||
{
|
||
char fc=z? '0' : ' ';
|
||
char ch;
|
||
char* p=bf;
|
||
while (*p++ && n > 0)
|
||
n--;
|
||
while (n-- > 0)
|
||
putf(putp,fc);
|
||
while ((ch= *bf++))
|
||
putf(putp,ch);
|
||
}
|
||
|
||
void tfp_format(void* putp,putcf putf,char *fmt, va_list va)
|
||
{
|
||
char bf[12];
|
||
|
||
char ch;
|
||
|
||
|
||
while ((ch=*(fmt++))) {
|
||
if (ch!='%')
|
||
putf(putp,ch);
|
||
else {
|
||
char lz=0;
|
||
#ifdef PRINTF_LONG_SUPPORT
|
||
char lng=0;
|
||
#endif
|
||
int w=0;
|
||
ch=*(fmt++);
|
||
if (ch=='0') {
|
||
ch=*(fmt++);
|
||
lz=1;
|
||
}
|
||
if (ch>='0' && ch<='9') {
|
||
ch=a2i(ch,&fmt,10,&w);
|
||
}
|
||
#ifdef PRINTF_LONG_SUPPORT
|
||
if (ch=='l') {
|
||
ch=*(fmt++);
|
||
lng=1;
|
||
}
|
||
#endif
|
||
switch (ch) {
|
||
case 0:
|
||
goto abort;
|
||
case 'u' : {
|
||
#ifdef PRINTF_LONG_SUPPORT
|
||
if (lng)
|
||
uli2a(va_arg(va, unsigned long int),10,0,bf);
|
||
else
|
||
#endif
|
||
ui2a(va_arg(va, unsigned int),10,0,bf);
|
||
putchw(putp,putf,w,lz,bf);
|
||
break;
|
||
}
|
||
case 'd' : {
|
||
#ifdef PRINTF_LONG_SUPPORT
|
||
if (lng)
|
||
li2a(va_arg(va, unsigned long int),bf);
|
||
else
|
||
#endif
|
||
i2a(va_arg(va, int),bf);
|
||
putchw(putp,putf,w,lz,bf);
|
||
break;
|
||
}
|
||
case 'x': case 'X' :
|
||
#ifdef PRINTF_LONG_SUPPORT
|
||
if (lng)
|
||
uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf);
|
||
else
|
||
#endif
|
||
ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf);
|
||
putchw(putp,putf,w,lz,bf);
|
||
break;
|
||
case 'c' :
|
||
putf(putp,(char)(va_arg(va, int)));
|
||
break;
|
||
case 's' :
|
||
putchw(putp,putf,w,0,va_arg(va, char*));
|
||
break;
|
||
case '%' :
|
||
putf(putp,ch);
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
abort:;
|
||
}
|
||
|
||
|
||
void init_printf(void* putp,void (*putf) (void*,char))
|
||
{
|
||
stdout_putf=putf;
|
||
stdout_putp=putp;
|
||
}
|
||
|
||
void tfp_printf(char *fmt, ...)
|
||
{
|
||
va_list va;
|
||
va_start(va,fmt);
|
||
tfp_format(stdout_putp,stdout_putf,fmt,va);
|
||
va_end(va);
|
||
}
|
||
|
||
static void putcp(void* p,char c)
|
||
{
|
||
*(*((char**)p))++ = c;
|
||
}
|
||
|
||
|
||
|
||
void tfp_sprintf(char* s,char *fmt, ...)
|
||
{
|
||
va_list va;
|
||
va_start(va,fmt);
|
||
tfp_format(&s,putcp,fmt,va);
|
||
putcp(&s,0);
|
||
va_end(va);
|
||
}
|
||
|
||
|
||
firmware_5200/printf/printf.h | ||
---|---|---|
/*
|
||
File: printf.h
|
||
|
||
Copyright (c) 2004,2012 Kustaa Nyholm / SpareTimeLabs
|
||
|
||
All rights reserved.
|
||
|
||
Redistribution and use in source and binary forms, with or without modification,
|
||
are permitted provided that the following conditions are met:
|
||
|
||
Redistributions of source code must retain the above copyright notice, this list
|
||
of conditions and the following disclaimer.
|
||
|
||
Redistributions in binary form must reproduce the above copyright notice, this
|
||
list of conditions and the following disclaimer in the documentation and/or other
|
||
materials provided with the distribution.
|
||
|
||
Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its
|
||
contributors may be used to endorse or promote products derived from this software
|
||
without specific prior written permission.
|
||
|
Also available in: Unified diff
Merged into main firmware dir