Adding the source of a Loader for Apple II

This commit is contained in:
Christophe Meneboeuf 2016-12-08 00:53:00 +01:00
parent fe0e433b21
commit f6d7230c0d
42 changed files with 538 additions and 56 deletions

17
Loader_Apple2/Makefile Normal file
View File

@ -0,0 +1,17 @@
APPLE2_CL := $(CC65_HOME)/bin/cl65
APPLE2_CC := $(CC65_HOME)/bin/cc65
APPLE2_SRC := src/file_io.c src/mli.asm src/main.c
APPLE2_MAP := hires.map
APPLE2_CFLAGS := -Oirs -v -t apple2
APPLE2_OUT := bin/hires.a2
all: directories apple2
directories:
mkdir -p bin
apple2: $(APPLE2_SRC)
$(APPLE2_CL) -m $(APPLE2_MAP) -o $(APPLE2_OUT) $? $(APPLE2_CFLAGS)
clean: $(SRC)
rm -f $(APPLE2_MAP) src/*.o src/*.s & rm -r bin/

229
Loader_Apple2/src/file_io.c Normal file
View File

@ -0,0 +1,229 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Standard headers */
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
/* My Headers */
#include "file_io.h"
uint8_t call_to_mli( uint8_t call, void* ptr_parameter );
#define CREATE 0xC0
#define OPEN 0xC8
#define READ 0xCA
#define WRITE 0xCB
#define CLOSE 0xCC
#define FLUSH 0xCD
#define SET_MARK 0xCE
const char* VOLUME_NAME = "/PRODOS.2.4.1/";
char Filename[ 65 ];
static uint8_t Io[ 1024+256 ]; //I need an adress aligned on 256: I'll use the 1st one inside Io
static uint8_t Error = 0u;
char* get_full_path( const char* p_filename )
{
uint8_t len = strlen(VOLUME_NAME);
if( len > 64u ) {
return 0;
}
Filename[0] = len + strlen(p_filename);
strcpy( 1 + Filename, VOLUME_NAME );
strcpy( 1 + Filename + len, p_filename );
return Filename;
}
/**************************/
typedef struct {
uint8_t param_count;
char* pathname;
uint8_t access;
uint8_t file_type;
uint16_t aux_type;
uint8_t storage_type;
uint16_t create_date;
uint16_t create_time;
} create_param_t;
void file_create( char* p_filename )
{
create_param_t param;
char* filename = get_full_path( p_filename );
if( filename == 0 ) {
Error = BAD_NAME;
return;
}
param.param_count = 7u;
param.pathname = filename;
param.access = 0xE3;
param.file_type = 0x6;
param.aux_type = 0;
param.storage_type = 1;
param.create_date = (78<<8) + (04<<4) + 10;
param.create_time = (12<<8) + 0;
Error = call_to_mli( CREATE, &param );
return;
}
/*****************************/
typedef struct {
uint8_t param_count;
char* pathname;
uint8_t* io_buffer;
uint8_t ref_num;
} open_param_t;
void file_open( char* p_filename, uint8_t* ref_num )
{
open_param_t param;
char* filename = get_full_path( p_filename );
if( filename == 0 ) {
Error = OPEN_ERROR;
return;
}
param.param_count = 3u;
param.pathname = filename;
param.io_buffer = (uint8_t*)((uint16_t)(Io)+256-(uint16_t)(Io)%256); //Getting the 256byte aligned adrress
Error = call_to_mli( OPEN, &param );
if( Error == 0x44 || Error == 0x46 ) {
file_create( p_filename );
if( Error == NO_ERROR ) {
Error = call_to_mli( OPEN, &param );
}
}
if( Error == 0 ) {
*ref_num = param.ref_num;
}
return;
}
/*****************************/
typedef struct {
uint8_t param_count;
uint8_t ref_num;
uint16_t position;
uint8_t dummy; /* high byte always 0 */
} set_mark_param_t;
void file_set_offset( const uint8_t handle, const uint16_t offset )
{
set_mark_param_t param;
param.param_count = 2u;
param.ref_num = handle;
param.position = offset;
param.dummy = 0;
Error = call_to_mli( SET_MARK, &param );
}
/********************************/
typedef struct {
uint8_t param_count;
uint8_t ref_num;
uint8_t* data_buffer;
uint16_t request_count;
uint16_t trans_count;
} read_param_t;
uint16_t file_read( const uint8_t handle, uint8_t* buffer, const uint16_t len )
{
read_param_t param;
param.param_count = 4u;
param.ref_num = handle;
param.data_buffer = buffer;
param.request_count = len;
Error = call_to_mli( READ, &param );
return param.trans_count;
}
/********************************/
typedef struct {
uint8_t param_count;
uint8_t ref_num;
uint8_t* data_buffer;
uint16_t request_count;
uint16_t trans_count;
} write_param_t;
uint16_t file_write( const uint8_t handle, uint8_t* buffer, const uint16_t len )
{
write_param_t param;
param.param_count = 4u;
param.ref_num = handle;
param.data_buffer = buffer;
param.request_count = len;
Error = call_to_mli( WRITE, &param );
return param.trans_count;
}
/*************************/
typedef struct {
uint8_t param_count;
uint8_t ref_num;
} close_param_t;
void file_close( const uint8_t handle )
{
close_param_t param;
param.param_count = 1u;
param.ref_num = handle;
Error = call_to_mli( CLOSE, &param );
}
/*************************/
typedef struct {
uint8_t param_count;
uint8_t ref_num;
} flush_param_t;
void file_flush( const uint8_t handle )
{
flush_param_t param;
param.param_count = 1u;
param.ref_num = handle;
Error = call_to_mli( FLUSH, &param );
}
/*************************/
uint8_t file_error( void )
{
return Error;
}

View File

@ -0,0 +1,41 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __FILE_IO_H__
#define __FILE_IO_H__
#include <stdint.h>
void file_create( char* p_filename );
void file_open( char* p_filename, uint8_t* handle ); /* returns a handle to the file or OPEN_ERROR error code */
void file_set_offset( const uint8_t handle, const uint16_t offset );
uint16_t file_read( const uint8_t handle, uint8_t* out_buffer, const uint16_t len ); /* returns the nb bytes read */
uint16_t file_write( const uint8_t handle, uint8_t* in_buffer, const uint16_t len ); /* returns the nb bytes written */
void file_flush( const uint8_t handle );
void file_close( const uint8_t handle );
uint8_t file_error( void ); /* returns the last file error */
enum {
NO_ERROR = 0u,
FILE_OPENED = 2u,
BAD_NAME,
BAD_LENGTH = 4u,
OPEN_ERROR = 0xFF
};
#endif

60
Loader_Apple2/src/main.c Normal file
View File

@ -0,0 +1,60 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Standard headers */
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <conio.h>
/* My headers */
#include "file_io.h"
#define HIRES_PAGE1 0x2000
#define HIRES_PAGE_SIZE 0x2000
#define SWITCH_GRAPHICS *((uint8_t*)0xC050)=1
#define SWITCH_FULLSCREEN *((uint8_t*)0xC052)=1
#define SWITCH_PAGE1 *((uint8_t*)0xC054)=1
#define SWITCH_HIRES *((uint8_t*)0xC057)=1
void __fastcall__ error(const uint8_t err) {
printf("\n ERROR: %u", err);
exit(-1);
}
static char Filename[64] = "test.picture";
int main( int argc, char* argv[] )
{
uint8_t handle;
(void)argc;
(void)argv;
file_open(Filename, &handle);
if( file_read( handle, (uint8_t*)HIRES_PAGE1, HIRES_PAGE_SIZE ) != HIRES_PAGE_SIZE ) {
error(file_error());
}
file_close(handle);
SWITCH_GRAPHICS;
SWITCH_FULLSCREEN;
SWITCH_PAGE1;
SWITCH_HIRES;
return 0;
}

24
Readme.md Normal file
View File

@ -0,0 +1,24 @@
#Rgb2Hires
This program coverts an RGB image to the Apple II's "HiRes" format. Provided it complies with its constraints:
* Source image must be 140x280. Pixels are anamorphic: twice wider than tall.
* Source image must contains six colors : BLACK, WHITE, ORANGE, GREEN, BLUE and PURPLE
For more information about the "Hires" format and its limitations, please refer to Wikipedia: https://en.wikipedia.org/wiki/Apple_II_graphics#High-Resolution_.28Hi-Res.29_graphics
## Compiling
### Rgb2Hires
The source is provided as a Visual Studio project. It's standard C++11 without any Windows dependency so it should compile on Linux and macOs without any modification.
#### Dependencies
* Magick++ : On Windows, you have provide an environment variable called *MAGICK_HOME* and pointing to the ImageMagick folder.
### Loader (for Apple II)
This program will compile as an Apple II executable that you can run on the actual hardware.
#### Dependencies
* CC65: Please provide an environment variable, *CC65_HOME*, pointing to your CC65 folder.
# Running
A correct source image, *test.png*, is provided as an example. Convert it into a file named *test.picture* as the Apple II Loader will try to load and display a file called like that.

View File

@ -33,6 +33,7 @@
<Keyword>Win32Proj</Keyword>
<RootNamespace>RgbToHiRes</RootNamespace>
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
<ProjectName>Rgb2HiRes</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">

41
Rgb2Hires_PC/src/Common.h Normal file
View File

@ -0,0 +1,41 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __COMMON_H__
#define __COMMON_H__
#include <Magick++.h>
namespace RgbToHires {
static Magick::Color WHITE("white");
static Magick::Color BLACK("black");
static Magick::Color BLUE("blue");
static Magick::Color GREEN("green");
static Magick::Color ORANGE("orange");
static Magick::Color VIOLET("purple");
static constexpr unsigned WIDTH = 140u;
static constexpr unsigned HEIGHT = 192u;
}
#endif

View File

@ -1,4 +1,21 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exception>
#include "ImageQuantized.h"
#include "HiRes.h"

View File

@ -1,3 +1,22 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __HIRES_H__
#define __HIRES_H__

View File

@ -1,4 +1,22 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <iterator>
#include "ImageQuantized.h"

View File

@ -0,0 +1,53 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __IMAGEQUANTIZED_H__
#define __IMAGEQUANTIZED_H__
#include <memory>
#include <array>
#include "Common.h"
namespace RgbToHires {
class ImageQuantized :
public Magick::Image
{
public:
using Block = std::array<Magick::PixelPacket,7>;
using Line = std::array<Block, 20>;
using Blob = std::array<Line, 192>;
ImageQuantized(const Magick::Image& src);
~ImageQuantized()=default;
std::unique_ptr<Blob> getBlob() const;
private:
double Distance(const Magick::Color&, const Magick::Color&);
};
}
#endif

View File

@ -1,4 +1,22 @@
/* Rgb2Hires
* Copyright (C) 2016 Christophe Meneboeuf <christophe@xtof.info>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <exception>
#include <iostream>
#include <fstream>

BIN
Rgb2Hires_PC/test.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@ -1,22 +0,0 @@
#ifndef __COMMON_H__
#define __COMMON_H__
#include <Magick++.h>
namespace RgbToHires {
static Magick::Color WHITE("white");
static Magick::Color BLACK("black");
static Magick::Color BLUE("blue");
static Magick::Color GREEN("green");
static Magick::Color ORANGE("orange");
static Magick::Color VIOLET("purple");
static constexpr unsigned WIDTH = 140u;
static constexpr unsigned HEIGHT = 192u;
}
#endif

View File

@ -1,34 +0,0 @@
#ifndef __IMAGEQUANTIZED_H__
#define __IMAGEQUANTIZED_H__
#include <memory>
#include <array>
#include "Common.h"
namespace RgbToHires {
class ImageQuantized :
public Magick::Image
{
public:
using Block = std::array<Magick::PixelPacket,7>;
using Line = std::array<Block, 20>;
using Blob = std::array<Line, 192>;
ImageQuantized(const Magick::Image& src);
~ImageQuantized()=default;
std::unique_ptr<Blob> getBlob() const;
private:
double Distance(const Magick::Color&, const Magick::Color&);
};
}
#endif