mirror of
https://github.com/aotta/PicoPAC
synced 2024-12-21 20:38:48 -05:00
Add files via upload
This commit is contained in:
parent
066b048ec0
commit
11c324e398
BIN
GERBER-PicoPAC.zip
Normal file
BIN
GERBER-PicoPAC.zip
Normal file
Binary file not shown.
BIN
PicoPAC_cart.uf2
Normal file
BIN
PicoPAC_cart.uf2
Normal file
Binary file not shown.
55
VSC-PicoPAC/CMakeLists.txt
Normal file
55
VSC-PicoPAC/CMakeLists.txt
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
|
# initialize the SDK based on PICO_SDK_PATH
|
||||||
|
# note: this must happen before project()
|
||||||
|
include(pico_sdk_import.cmake)
|
||||||
|
|
||||||
|
project(PicoPAC_cart)
|
||||||
|
|
||||||
|
set(PICO_BOARD_HEADER_DIRS ${CMAKE_SOURCE_DIR})
|
||||||
|
set(PICO_BOARD myboard)
|
||||||
|
|
||||||
|
# initialize the Raspberry Pi Pico SDK
|
||||||
|
pico_sdk_init()
|
||||||
|
|
||||||
|
add_executable(PicoPAC_cart)
|
||||||
|
|
||||||
|
# 16megs of flash on purple pico clones
|
||||||
|
target_compile_definitions(PicoPAC_cart PRIVATE
|
||||||
|
PICO_FLASH_SIZE_BYTES=16777216
|
||||||
|
)
|
||||||
|
|
||||||
|
target_compile_options(PicoPAC_cart PRIVATE "-Os")
|
||||||
|
|
||||||
|
#pico_set_linker_script(PicoPAC_cart ${CMAKE_CURRENT_SOURCE_DIR}/memmap_custom.ld)
|
||||||
|
|
||||||
|
target_sources(PicoPAC_cart PUBLIC
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/main.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/picopac_cart.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/msc_disk.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/usb_descriptors.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/fatfs_disk.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/flash_fs.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/fatfs/ff.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/fatfs/ffunicode.c
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/fatfs/diskio.c
|
||||||
|
)
|
||||||
|
|
||||||
|
target_include_directories(PicoPAC_cart PUBLIC
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/fatfs
|
||||||
|
)
|
||||||
|
|
||||||
|
# Enable usb output, disable uart output
|
||||||
|
pico_enable_stdio_usb(PicoPAC_cart 1)
|
||||||
|
pico_enable_stdio_uart(PicoPAC_cart 0)
|
||||||
|
|
||||||
|
# In addition to pico_stdlib required for common PicoSDK functionality, add dependency on tinyusb_device
|
||||||
|
# for TinyUSB device support
|
||||||
|
target_link_libraries(PicoPAC_cart PUBLIC pico_stdlib hardware_flash tinyusb_device pico_multicore)
|
||||||
|
#target_link_libraries(PicoPAC_cart PUBLIC pico_stdlib hardware_flash)
|
||||||
|
|
||||||
|
# create map/bin/hex/uf2 file in addition to ELF.
|
||||||
|
pico_add_extra_outputs(PicoPAC_cart)
|
||||||
|
|
||||||
|
|
15
VSC-PicoPAC/CMakeSettings.json
Normal file
15
VSC-PicoPAC/CMakeSettings.json
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "x64-Debug",
|
||||||
|
"generator": "Ninja",
|
||||||
|
"configurationType": "Debug",
|
||||||
|
"inheritEnvironments": [ "msvc_x64_x64" ],
|
||||||
|
"buildRoot": "${projectDir}\\out\\build\\${name}",
|
||||||
|
"installRoot": "${projectDir}\\out\\install\\${name}",
|
||||||
|
"cmakeCommandArgs": "",
|
||||||
|
"buildCommandArgs": "",
|
||||||
|
"ctestCommandArgs": ""
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
369
VSC-PicoPAC/fatfs/00history.txt
Normal file
369
VSC-PicoPAC/fatfs/00history.txt
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
----------------------------------------------------------------------------
|
||||||
|
Revision history of FatFs module
|
||||||
|
----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
R0.00 (February 26, 2006)
|
||||||
|
|
||||||
|
Prototype.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.01 (April 29, 2006)
|
||||||
|
|
||||||
|
The first release.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.02 (June 01, 2006)
|
||||||
|
|
||||||
|
Added FAT12 support.
|
||||||
|
Removed unbuffered mode.
|
||||||
|
Fixed a problem on small (<32M) partition.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.02a (June 10, 2006)
|
||||||
|
|
||||||
|
Added a configuration option (_FS_MINIMUM).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.03 (September 22, 2006)
|
||||||
|
|
||||||
|
Added f_rename().
|
||||||
|
Changed option _FS_MINIMUM to _FS_MINIMIZE.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.03a (December 11, 2006)
|
||||||
|
|
||||||
|
Improved cluster scan algorithm to write files fast.
|
||||||
|
Fixed f_mkdir() creates incorrect directory on FAT32.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04 (February 04, 2007)
|
||||||
|
|
||||||
|
Added f_mkfs().
|
||||||
|
Supported multiple drive system.
|
||||||
|
Changed some interfaces for multiple drive system.
|
||||||
|
Changed f_mountdrv() to f_mount().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04a (April 01, 2007)
|
||||||
|
|
||||||
|
Supported multiple partitions on a physical drive.
|
||||||
|
Added a capability of extending file size to f_lseek().
|
||||||
|
Added minimization level 3.
|
||||||
|
Fixed an endian sensitive code in f_mkfs().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.04b (May 05, 2007)
|
||||||
|
|
||||||
|
Added a configuration option _USE_NTFLAG.
|
||||||
|
Added FSINFO support.
|
||||||
|
Fixed DBCS name can result FR_INVALID_NAME.
|
||||||
|
Fixed short seek (<= csize) collapses the file object.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.05 (August 25, 2007)
|
||||||
|
|
||||||
|
Changed arguments of f_read(), f_write() and f_mkfs().
|
||||||
|
Fixed f_mkfs() on FAT32 creates incorrect FSINFO.
|
||||||
|
Fixed f_mkdir() on FAT32 creates incorrect directory.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.05a (February 03, 2008)
|
||||||
|
|
||||||
|
Added f_truncate() and f_utime().
|
||||||
|
Fixed off by one error at FAT sub-type determination.
|
||||||
|
Fixed btr in f_read() can be mistruncated.
|
||||||
|
Fixed cached sector is not flushed when create and close without write.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.06 (April 01, 2008)
|
||||||
|
|
||||||
|
Added fputc(), fputs(), fprintf() and fgets().
|
||||||
|
Improved performance of f_lseek() on moving to the same or following cluster.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07 (April 01, 2009)
|
||||||
|
|
||||||
|
Merged Tiny-FatFs as a configuration option. (_FS_TINY)
|
||||||
|
Added long file name feature. (_USE_LFN)
|
||||||
|
Added multiple code page feature. (_CODE_PAGE)
|
||||||
|
Added re-entrancy for multitask operation. (_FS_REENTRANT)
|
||||||
|
Added auto cluster size selection to f_mkfs().
|
||||||
|
Added rewind option to f_readdir().
|
||||||
|
Changed result code of critical errors.
|
||||||
|
Renamed string functions to avoid name collision.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07a (April 14, 2009)
|
||||||
|
|
||||||
|
Septemberarated out OS dependent code on reentrant cfg.
|
||||||
|
Added multiple sector size feature.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07c (June 21, 2009)
|
||||||
|
|
||||||
|
Fixed f_unlink() can return FR_OK on error.
|
||||||
|
Fixed wrong cache control in f_lseek().
|
||||||
|
Added relative path feature.
|
||||||
|
Added f_chdir() and f_chdrive().
|
||||||
|
Added proper case conversion to extended character.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.07e (November 03, 2009)
|
||||||
|
|
||||||
|
Septemberarated out configuration options from ff.h to ffconf.h.
|
||||||
|
Fixed f_unlink() fails to remove a sub-directory on _FS_RPATH.
|
||||||
|
Fixed name matching error on the 13 character boundary.
|
||||||
|
Added a configuration option, _LFN_UNICODE.
|
||||||
|
Changed f_readdir() to return the SFN with always upper case on non-LFN cfg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08 (May 15, 2010)
|
||||||
|
|
||||||
|
Added a memory configuration option. (_USE_LFN = 3)
|
||||||
|
Added file lock feature. (_FS_SHARE)
|
||||||
|
Added fast seek feature. (_USE_FASTSEEK)
|
||||||
|
Changed some types on the API, XCHAR->TCHAR.
|
||||||
|
Changed .fname in the FILINFO structure on Unicode cfg.
|
||||||
|
String functions support UTF-8 encoding files on Unicode cfg.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08a (August 16, 2010)
|
||||||
|
|
||||||
|
Added f_getcwd(). (_FS_RPATH = 2)
|
||||||
|
Added sector erase feature. (_USE_ERASE)
|
||||||
|
Moved file lock semaphore table from fs object to the bss.
|
||||||
|
Fixed f_mkfs() creates wrong FAT32 volume.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.08b (January 15, 2011)
|
||||||
|
|
||||||
|
Fast seek feature is also applied to f_read() and f_write().
|
||||||
|
f_lseek() reports required table size on creating CLMP.
|
||||||
|
Extended format syntax of f_printf().
|
||||||
|
Ignores duplicated directory separators in given path name.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09 (September 06, 2011)
|
||||||
|
|
||||||
|
f_mkfs() supports multiple partition to complete the multiple partition feature.
|
||||||
|
Added f_fdisk().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09a (August 27, 2012)
|
||||||
|
|
||||||
|
Changed f_open() and f_opendir() reject null object pointer to avoid crash.
|
||||||
|
Changed option name _FS_SHARE to _FS_LOCK.
|
||||||
|
Fixed assertion failure due to OS/2 EA on FAT12/16 volume.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.09b (January 24, 2013)
|
||||||
|
|
||||||
|
Added f_setlabel() and f_getlabel().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10 (October 02, 2013)
|
||||||
|
|
||||||
|
Added selection of character encoding on the file. (_STRF_ENCODE)
|
||||||
|
Added f_closedir().
|
||||||
|
Added forced full FAT scan for f_getfree(). (_FS_NOFSINFO)
|
||||||
|
Added forced mount feature with changes of f_mount().
|
||||||
|
Improved behavior of volume auto detection.
|
||||||
|
Improved write throughput of f_puts() and f_printf().
|
||||||
|
Changed argument of f_chdrive(), f_mkfs(), disk_read() and disk_write().
|
||||||
|
Fixed f_write() can be truncated when the file size is close to 4GB.
|
||||||
|
Fixed f_open(), f_mkdir() and f_setlabel() can return incorrect value on error.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10a (January 15, 2014)
|
||||||
|
|
||||||
|
Added arbitrary strings as drive number in the path name. (_STR_VOLUME_ID)
|
||||||
|
Added a configuration option of minimum sector size. (_MIN_SS)
|
||||||
|
2nd argument of f_rename() can have a drive number and it will be ignored.
|
||||||
|
Fixed f_mount() with forced mount fails when drive number is >= 1. (appeared at R0.10)
|
||||||
|
Fixed f_close() invalidates the file object without volume lock.
|
||||||
|
Fixed f_closedir() returns but the volume lock is left acquired. (appeared at R0.10)
|
||||||
|
Fixed creation of an entry with LFN fails on too many SFN collisions. (appeared at R0.07)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10b (May 19, 2014)
|
||||||
|
|
||||||
|
Fixed a hard error in the disk I/O layer can collapse the directory entry.
|
||||||
|
Fixed LFN entry is not deleted when delete/rename an object with lossy converted SFN. (appeared at R0.07)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.10c (November 09, 2014)
|
||||||
|
|
||||||
|
Added a configuration option for the platforms without RTC. (_FS_NORTC)
|
||||||
|
Changed option name _USE_ERASE to _USE_TRIM.
|
||||||
|
Fixed volume label created by Mac OS X cannot be retrieved with f_getlabel(). (appeared at R0.09b)
|
||||||
|
Fixed a potential problem of FAT access that can appear on disk error.
|
||||||
|
Fixed null pointer dereference on attempting to delete the root direcotry. (appeared at R0.08)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.11 (February 09, 2015)
|
||||||
|
|
||||||
|
Added f_findfirst(), f_findnext() and f_findclose(). (_USE_FIND)
|
||||||
|
Fixed f_unlink() does not remove cluster chain of the file. (appeared at R0.10c)
|
||||||
|
Fixed _FS_NORTC option does not work properly. (appeared at R0.10c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.11a (September 05, 2015)
|
||||||
|
|
||||||
|
Fixed wrong media change can lead a deadlock at thread-safe configuration.
|
||||||
|
Added code page 771, 860, 861, 863, 864, 865 and 869. (_CODE_PAGE)
|
||||||
|
Removed some code pages actually not exist on the standard systems. (_CODE_PAGE)
|
||||||
|
Fixed errors in the case conversion teble of code page 437 and 850 (ff.c).
|
||||||
|
Fixed errors in the case conversion teble of Unicode (cc*.c).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12 (April 12, 2016)
|
||||||
|
|
||||||
|
Added support for exFAT file system. (_FS_EXFAT)
|
||||||
|
Added f_expand(). (_USE_EXPAND)
|
||||||
|
Changed some members in FINFO structure and behavior of f_readdir().
|
||||||
|
Added an option _USE_CHMOD.
|
||||||
|
Removed an option _WORD_ACCESS.
|
||||||
|
Fixed errors in the case conversion table of Unicode (cc*.c).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12a (July 10, 2016)
|
||||||
|
|
||||||
|
Added support for creating exFAT volume with some changes of f_mkfs().
|
||||||
|
Added a file open method FA_OPEN_APPEND. An f_lseek() following f_open() is no longer needed.
|
||||||
|
f_forward() is available regardless of _FS_TINY.
|
||||||
|
Fixed f_mkfs() creates wrong volume. (appeared at R0.12)
|
||||||
|
Fixed wrong memory read in create_name(). (appeared at R0.12)
|
||||||
|
Fixed compilation fails at some configurations, _USE_FASTSEEK and _USE_FORWARD.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12b (September 04, 2016)
|
||||||
|
|
||||||
|
Made f_rename() be able to rename objects with the same name but case.
|
||||||
|
Fixed an error in the case conversion teble of code page 866. (ff.c)
|
||||||
|
Fixed writing data is truncated at the file offset 4GiB on the exFAT volume. (appeared at R0.12)
|
||||||
|
Fixed creating a file in the root directory of exFAT volume can fail. (appeared at R0.12)
|
||||||
|
Fixed f_mkfs() creating exFAT volume with too small cluster size can collapse unallocated memory. (appeared at R0.12)
|
||||||
|
Fixed wrong object name can be returned when read directory at Unicode cfg. (appeared at R0.12)
|
||||||
|
Fixed large file allocation/removing on the exFAT volume collapses allocation bitmap. (appeared at R0.12)
|
||||||
|
Fixed some internal errors in f_expand() and f_lseek(). (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.12c (March 04, 2017)
|
||||||
|
|
||||||
|
Improved write throughput at the fragmented file on the exFAT volume.
|
||||||
|
Made memory usage for exFAT be able to be reduced as decreasing _MAX_LFN.
|
||||||
|
Fixed successive f_getfree() can return wrong count on the FAT12/16 volume. (appeared at R0.12)
|
||||||
|
Fixed configuration option _VOLUMES cannot be set 10. (appeared at R0.10c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13 (May 21, 2017)
|
||||||
|
|
||||||
|
Changed heading character of configuration keywords "_" to "FF_".
|
||||||
|
Removed ASCII-only configuration, FF_CODE_PAGE = 1. Use FF_CODE_PAGE = 437 instead.
|
||||||
|
Added f_setcp(), run-time code page configuration. (FF_CODE_PAGE = 0)
|
||||||
|
Improved cluster allocation time on stretch a deep buried cluster chain.
|
||||||
|
Improved processing time of f_mkdir() with large cluster size by using FF_USE_LFN = 3.
|
||||||
|
Improved NoFatChain flag of the fragmented file to be set after it is truncated and got contiguous.
|
||||||
|
Fixed archive attribute is left not set when a file on the exFAT volume is renamed. (appeared at R0.12)
|
||||||
|
Fixed exFAT FAT entry can be collapsed when write or lseek operation to the existing file is done. (appeared at R0.12c)
|
||||||
|
Fixed creating a file can fail when a new cluster allocation to the exFAT directory occures. (appeared at R0.12c)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13a (October 14, 2017)
|
||||||
|
|
||||||
|
Added support for UTF-8 encoding on the API. (FF_LFN_UNICODE = 2)
|
||||||
|
Added options for file name output buffer. (FF_LFN_BUF, FF_SFN_BUF).
|
||||||
|
Added dynamic memory allocation option for working buffer of f_mkfs() and f_fdisk().
|
||||||
|
Fixed f_fdisk() and f_mkfs() create the partition table with wrong CHS parameters. (appeared at R0.09)
|
||||||
|
Fixed f_unlink() can cause lost clusters at fragmented file on the exFAT volume. (appeared at R0.12c)
|
||||||
|
Fixed f_setlabel() rejects some valid characters for exFAT volume. (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13b (April 07, 2018)
|
||||||
|
|
||||||
|
Added support for UTF-32 encoding on the API. (FF_LFN_UNICODE = 3)
|
||||||
|
Added support for Unix style volume ID. (FF_STR_VOLUME_ID = 2)
|
||||||
|
Fixed accesing any object on the exFAT root directory beyond the cluster boundary can fail. (appeared at R0.12c)
|
||||||
|
Fixed f_setlabel() does not reject some invalid characters. (appeared at R0.09b)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.13c (October 14, 2018)
|
||||||
|
Supported stdint.h for C99 and later. (integer.h was included in ff.h)
|
||||||
|
Fixed reading a directory gets infinite loop when the last directory entry is not empty. (appeared at R0.12)
|
||||||
|
Fixed creating a sub-directory in the fragmented sub-directory on the exFAT volume collapses FAT chain of the parent directory. (appeared at R0.12)
|
||||||
|
Fixed f_getcwd() cause output buffer overrun when the buffer has a valid drive number. (appeared at R0.13b)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.14 (October 14, 2019)
|
||||||
|
Added support for 64-bit LBA and GUID partition table (FF_LBA64 = 1)
|
||||||
|
Changed some API functions, f_mkfs() and f_fdisk().
|
||||||
|
Fixed f_open() function cannot find the file with file name in length of FF_MAX_LFN characters.
|
||||||
|
Fixed f_readdir() function cannot retrieve long file names in length of FF_MAX_LFN - 1 characters.
|
||||||
|
Fixed f_readdir() function returns file names with wrong case conversion. (appeared at R0.12)
|
||||||
|
Fixed f_mkfs() function can fail to create exFAT volume in the second partition. (appeared at R0.12)
|
||||||
|
|
||||||
|
|
||||||
|
R0.14a (December 5, 2020)
|
||||||
|
Limited number of recursive calls in f_findnext().
|
||||||
|
Fixed old floppy disks formatted with MS-DOS 2.x and 3.x cannot be mounted.
|
||||||
|
Fixed some compiler warnings.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.14b (April 17, 2021)
|
||||||
|
Made FatFs uses standard library <string.h> for copy, compare and search instead of built-in string functions.
|
||||||
|
Added support for long long integer and floating point to f_printf(). (FF_STRF_LLI and FF_STRF_FP)
|
||||||
|
Made path name parser ignore the terminating separator to allow "dir/".
|
||||||
|
Improved the compatibility in Unix style path name feature.
|
||||||
|
Fixed the file gets dead-locked when f_open() failed with some conditions. (appeared at R0.12a)
|
||||||
|
Fixed f_mkfs() can create wrong exFAT volume due to a timing dependent error. (appeared at R0.12)
|
||||||
|
Fixed code page 855 cannot be set by f_setcp().
|
||||||
|
Fixed some compiler warnings.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
R0.15 (November 6, 2022)
|
||||||
|
Changed user provided synchronization functions in order to completely eliminate the platform dependency from FatFs code.
|
||||||
|
FF_SYNC_t is removed from the configuration options.
|
||||||
|
Fixed a potential error in f_mount when FF_FS_REENTRANT.
|
||||||
|
Fixed file lock control FF_FS_LOCK is not mutal excluded when FF_FS_REENTRANT && FF_VOLUMES > 1 is true.
|
||||||
|
Fixed f_mkfs() creates broken exFAT volume when the size of volume is >= 2^32 sectors.
|
||||||
|
Fixed string functions cannot write the unicode characters not in BMP when FF_LFN_UNICODE == 2 (UTF-8).
|
||||||
|
Fixed a compatibility issue in identification of GPT header.
|
||||||
|
|
21
VSC-PicoPAC/fatfs/00readme.txt
Normal file
21
VSC-PicoPAC/fatfs/00readme.txt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
FatFs Module Source Files R0.15
|
||||||
|
|
||||||
|
|
||||||
|
FILES
|
||||||
|
|
||||||
|
00readme.txt This file.
|
||||||
|
00history.txt Revision history.
|
||||||
|
ff.c FatFs module.
|
||||||
|
ffconf.h Configuration file of FatFs module.
|
||||||
|
ff.h Common include file for FatFs and application module.
|
||||||
|
diskio.h Common include file for FatFs and disk I/O module.
|
||||||
|
diskio.c An example of glue function to attach existing disk I/O module to FatFs.
|
||||||
|
ffunicode.c Optional Unicode utility functions.
|
||||||
|
ffsystem.c An example of optional O/S related functions.
|
||||||
|
|
||||||
|
|
||||||
|
Low level disk I/O module is not included in this archive because the FatFs
|
||||||
|
module is only a generic file system layer and it does not depend on any specific
|
||||||
|
storage device. You need to provide a low level disk I/O module written to
|
||||||
|
control the storage device that attached to the target system.
|
||||||
|
|
149
VSC-PicoPAC/fatfs/diskio.c
Normal file
149
VSC-PicoPAC/fatfs/diskio.c
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Low level disk I/O module SKELETON for FatFs (C)ChaN, 2019 */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* If a working storage control module is available, it should be */
|
||||||
|
/* attached to the FatFs via a glue function rather than modifying it. */
|
||||||
|
/* This is an example of glue functions to attach various exsisting */
|
||||||
|
/* storage control modules to the FatFs module with a defined API. */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "ff.h" /* Obtains integer types */
|
||||||
|
#include "diskio.h" /* Declarations of disk functions */
|
||||||
|
|
||||||
|
/* Definitions of physical drive number for each drive */
|
||||||
|
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
|
||||||
|
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
|
||||||
|
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
|
||||||
|
|
||||||
|
#include "fatfs_disk.h"
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Get Drive Status */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DSTATUS disk_status (
|
||||||
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DSTATUS stat;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (pdrv == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return STA_NOINIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Inidialize a Drive */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DSTATUS disk_initialize (
|
||||||
|
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DSTATUS stat;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (pdrv == 0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return STA_NOINIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Read Sector(s) */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DRESULT disk_read (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||||
|
BYTE *buff, /* Data buffer to store read data */
|
||||||
|
LBA_t sector, /* Start sector in LBA */
|
||||||
|
UINT count /* Number of sectors to read */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DRESULT res;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (pdrv == 0)
|
||||||
|
{
|
||||||
|
res = fatfs_disk_read((uint8_t*)buff, sector, count);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Write Sector(s) */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if FF_FS_READONLY == 0
|
||||||
|
|
||||||
|
DRESULT disk_write (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
||||||
|
const BYTE *buff, /* Data to be written */
|
||||||
|
LBA_t sector, /* Start sector in LBA */
|
||||||
|
UINT count /* Number of sectors to write */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DRESULT res;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (pdrv == 0)
|
||||||
|
{
|
||||||
|
res = fatfs_disk_write((const uint8_t*)buff, sector, count);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
/* Miscellaneous Functions */
|
||||||
|
/*-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DRESULT disk_ioctl (
|
||||||
|
BYTE pdrv, /* Physical drive nmuber (0..) */
|
||||||
|
BYTE cmd, /* Control code */
|
||||||
|
void *buff /* Buffer to send/receive control data */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
DRESULT res;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
if (pdrv == 0)
|
||||||
|
{
|
||||||
|
switch(cmd) {
|
||||||
|
case CTRL_SYNC:
|
||||||
|
fatfs_disk_sync();
|
||||||
|
return RES_OK;
|
||||||
|
case GET_SECTOR_COUNT:
|
||||||
|
*(LBA_t*) buff = SECTOR_NUM;
|
||||||
|
return RES_OK;
|
||||||
|
case GET_SECTOR_SIZE:
|
||||||
|
*(WORD*) buff = SECTOR_SIZE;
|
||||||
|
return RES_OK;
|
||||||
|
case GET_BLOCK_SIZE:
|
||||||
|
*(DWORD*) buff = 1;
|
||||||
|
return RES_OK;
|
||||||
|
case CTRL_TRIM:
|
||||||
|
return RES_OK;
|
||||||
|
default:
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RES_PARERR;
|
||||||
|
}
|
||||||
|
|
77
VSC-PicoPAC/fatfs/diskio.h
Normal file
77
VSC-PicoPAC/fatfs/diskio.h
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
/*-----------------------------------------------------------------------/
|
||||||
|
/ Low level disk interface modlue include file (C)ChaN, 2019 /
|
||||||
|
/-----------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef _DISKIO_DEFINED
|
||||||
|
#define _DISKIO_DEFINED
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Status of Disk Functions */
|
||||||
|
typedef BYTE DSTATUS;
|
||||||
|
|
||||||
|
/* Results of Disk Functions */
|
||||||
|
typedef enum {
|
||||||
|
RES_OK = 0, /* 0: Successful */
|
||||||
|
RES_ERROR, /* 1: R/W Error */
|
||||||
|
RES_WRPRT, /* 2: Write Protected */
|
||||||
|
RES_NOTRDY, /* 3: Not Ready */
|
||||||
|
RES_PARERR /* 4: Invalid Parameter */
|
||||||
|
} DRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------*/
|
||||||
|
/* Prototypes for disk control functions */
|
||||||
|
|
||||||
|
|
||||||
|
DSTATUS disk_initialize (BYTE pdrv);
|
||||||
|
DSTATUS disk_status (BYTE pdrv);
|
||||||
|
DRESULT disk_read (BYTE pdrv, BYTE* buff, LBA_t sector, UINT count);
|
||||||
|
DRESULT disk_write (BYTE pdrv, const BYTE* buff, LBA_t sector, UINT count);
|
||||||
|
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
||||||
|
|
||||||
|
|
||||||
|
/* Disk Status Bits (DSTATUS) */
|
||||||
|
|
||||||
|
#define STA_NOINIT 0x01 /* Drive not initialized */
|
||||||
|
#define STA_NODISK 0x02 /* No medium in the drive */
|
||||||
|
#define STA_PROTECT 0x04 /* Write protected */
|
||||||
|
|
||||||
|
|
||||||
|
/* Command code for disk_ioctrl fucntion */
|
||||||
|
|
||||||
|
/* Generic command (Used by FatFs) */
|
||||||
|
#define CTRL_SYNC 0 /* Complete pending write process (needed at FF_FS_READONLY == 0) */
|
||||||
|
#define GET_SECTOR_COUNT 1 /* Get media size (needed at FF_USE_MKFS == 1) */
|
||||||
|
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at FF_MAX_SS != FF_MIN_SS) */
|
||||||
|
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at FF_USE_MKFS == 1) */
|
||||||
|
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at FF_USE_TRIM == 1) */
|
||||||
|
|
||||||
|
/* Generic command (Not used by FatFs) */
|
||||||
|
#define CTRL_POWER 5 /* Get/Set power status */
|
||||||
|
#define CTRL_LOCK 6 /* Lock/Unlock media removal */
|
||||||
|
#define CTRL_EJECT 7 /* Eject media */
|
||||||
|
#define CTRL_FORMAT 8 /* Create physical format on the media */
|
||||||
|
|
||||||
|
/* MMC/SDC specific ioctl command */
|
||||||
|
#define MMC_GET_TYPE 10 /* Get card type */
|
||||||
|
#define MMC_GET_CSD 11 /* Get CSD */
|
||||||
|
#define MMC_GET_CID 12 /* Get CID */
|
||||||
|
#define MMC_GET_OCR 13 /* Get OCR */
|
||||||
|
#define MMC_GET_SDSTAT 14 /* Get SD status */
|
||||||
|
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
||||||
|
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
||||||
|
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
||||||
|
|
||||||
|
/* ATA/CF specific ioctl command */
|
||||||
|
#define ATA_GET_REV 20 /* Get F/W revision */
|
||||||
|
#define ATA_GET_MODEL 21 /* Get model name */
|
||||||
|
#define ATA_GET_SN 22 /* Get serial number */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
7084
VSC-PicoPAC/fatfs/ff.c
Normal file
7084
VSC-PicoPAC/fatfs/ff.c
Normal file
File diff suppressed because it is too large
Load Diff
429
VSC-PicoPAC/fatfs/ff.h
Normal file
429
VSC-PicoPAC/fatfs/ff.h
Normal file
@ -0,0 +1,429 @@
|
|||||||
|
/*----------------------------------------------------------------------------/
|
||||||
|
/ FatFs - Generic FAT Filesystem module R0.15 /
|
||||||
|
/-----------------------------------------------------------------------------/
|
||||||
|
/
|
||||||
|
/ Copyright (C) 2022, ChaN, all right reserved.
|
||||||
|
/
|
||||||
|
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||||
|
/ source and binary forms, with or without modification, are permitted provided
|
||||||
|
/ that the following condition is met:
|
||||||
|
|
||||||
|
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
/ this condition and the following disclaimer.
|
||||||
|
/
|
||||||
|
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||||
|
/ and any warranties related to this software are DISCLAIMED.
|
||||||
|
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||||
|
/ by use of this software.
|
||||||
|
/
|
||||||
|
/----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FF_DEFINED
|
||||||
|
#define FF_DEFINED 80286 /* Revision ID */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "ffconf.h" /* FatFs configuration options */
|
||||||
|
|
||||||
|
#if FF_DEFINED != FFCONF_DEF
|
||||||
|
#error Wrong configuration file (ffconf.h).
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Integer types used for FatFs API */
|
||||||
|
|
||||||
|
#if defined(_WIN32) /* Windows VC++ (for development only) */
|
||||||
|
#define FF_INTDEF 2
|
||||||
|
#include <windows.h>
|
||||||
|
typedef unsigned __int64 QWORD;
|
||||||
|
#include <float.h>
|
||||||
|
#define isnan(v) _isnan(v)
|
||||||
|
#define isinf(v) (!_finite(v))
|
||||||
|
|
||||||
|
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||||
|
#define FF_INTDEF 2
|
||||||
|
#include <stdint.h>
|
||||||
|
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||||
|
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||||
|
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||||
|
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||||
|
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||||
|
typedef WORD WCHAR; /* UTF-16 character type */
|
||||||
|
|
||||||
|
#else /* Earlier than C99 */
|
||||||
|
#define FF_INTDEF 1
|
||||||
|
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||||
|
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||||
|
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
||||||
|
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
||||||
|
typedef WORD WCHAR; /* UTF-16 character type */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of file size and LBA variables */
|
||||||
|
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
#if FF_INTDEF != 2
|
||||||
|
#error exFAT feature wants C99 or later
|
||||||
|
#endif
|
||||||
|
typedef QWORD FSIZE_t;
|
||||||
|
#if FF_LBA64
|
||||||
|
typedef QWORD LBA_t;
|
||||||
|
#else
|
||||||
|
typedef DWORD LBA_t;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if FF_LBA64
|
||||||
|
#error exFAT needs to be enabled when enable 64-bit LBA
|
||||||
|
#endif
|
||||||
|
typedef DWORD FSIZE_t;
|
||||||
|
typedef DWORD LBA_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Type of path name strings on FatFs API (TCHAR) */
|
||||||
|
|
||||||
|
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||||
|
typedef WCHAR TCHAR;
|
||||||
|
#define _T(x) L ## x
|
||||||
|
#define _TEXT(x) L ## x
|
||||||
|
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||||
|
typedef char TCHAR;
|
||||||
|
#define _T(x) u8 ## x
|
||||||
|
#define _TEXT(x) u8 ## x
|
||||||
|
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||||
|
typedef DWORD TCHAR;
|
||||||
|
#define _T(x) U ## x
|
||||||
|
#define _TEXT(x) U ## x
|
||||||
|
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||||
|
#error Wrong FF_LFN_UNICODE setting
|
||||||
|
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||||
|
typedef char TCHAR;
|
||||||
|
#define _T(x) x
|
||||||
|
#define _TEXT(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Definitions of volume management */
|
||||||
|
|
||||||
|
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||||
|
typedef struct {
|
||||||
|
BYTE pd; /* Physical drive number */
|
||||||
|
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||||
|
} PARTITION;
|
||||||
|
extern PARTITION VolToPart[]; /* Volume - Partition mapping table */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if FF_STR_VOLUME_ID
|
||||||
|
#ifndef FF_VOLUME_STRS
|
||||||
|
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Filesystem object structure (FATFS) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||||
|
BYTE pdrv; /* Volume hosting physical drive */
|
||||||
|
BYTE ldrv; /* Logical drive number (used only when FF_FS_REENTRANT) */
|
||||||
|
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||||
|
BYTE wflag; /* win[] status (b0:dirty) */
|
||||||
|
BYTE fsi_flag; /* FSINFO status (b7:disabled, b0:dirty) */
|
||||||
|
WORD id; /* Volume mount ID */
|
||||||
|
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||||
|
WORD csize; /* Cluster size [sectors] */
|
||||||
|
#if FF_MAX_SS != FF_MIN_SS
|
||||||
|
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||||
|
#endif
|
||||||
|
#if FF_USE_LFN
|
||||||
|
WCHAR* lfnbuf; /* LFN working buffer */
|
||||||
|
#endif
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||||
|
#endif
|
||||||
|
#if !FF_FS_READONLY
|
||||||
|
DWORD last_clst; /* Last allocated cluster */
|
||||||
|
DWORD free_clst; /* Number of free clusters */
|
||||||
|
#endif
|
||||||
|
#if FF_FS_RPATH
|
||||||
|
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||||
|
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||||
|
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||||
|
DWORD fsize; /* Number of sectors per FAT */
|
||||||
|
LBA_t volbase; /* Volume base sector */
|
||||||
|
LBA_t fatbase; /* FAT base sector */
|
||||||
|
LBA_t dirbase; /* Root directory base sector (FAT12/16) or cluster (FAT32/exFAT) */
|
||||||
|
LBA_t database; /* Data base sector */
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
LBA_t bitbase; /* Allocation bitmap base sector */
|
||||||
|
#endif
|
||||||
|
LBA_t winsect; /* Current sector appearing in the win[] */
|
||||||
|
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||||
|
} FATFS;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Object ID and allocation information (FFOBJID) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||||
|
WORD id; /* Hosting volume's mount ID */
|
||||||
|
BYTE attr; /* Object attribute */
|
||||||
|
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
||||||
|
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||||
|
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||||
|
#if FF_FS_EXFAT
|
||||||
|
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||||
|
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||||
|
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||||
|
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||||
|
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||||
|
#endif
|
||||||
|
#if FF_FS_LOCK
|
||||||
|
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||||
|
#endif
|
||||||
|
} FFOBJID;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File object structure (FIL) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||||
|
BYTE flag; /* File status flags */
|
||||||
|
BYTE err; /* Abort flag (error code) */
|
||||||
|
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||||
|
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||||
|
LBA_t sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||||
|
#if !FF_FS_READONLY
|
||||||
|
LBA_t dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||||
|
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||||
|
#endif
|
||||||
|
#if FF_USE_FASTSEEK
|
||||||
|
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||||
|
#endif
|
||||||
|
#if !FF_FS_TINY
|
||||||
|
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||||
|
#endif
|
||||||
|
} FIL;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Directory object structure (DIR) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FFOBJID obj; /* Object identifier */
|
||||||
|
DWORD dptr; /* Current read/write offset */
|
||||||
|
DWORD clust; /* Current cluster */
|
||||||
|
LBA_t sect; /* Current sector (0:Read operation has terminated) */
|
||||||
|
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||||
|
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||||
|
#if FF_USE_LFN
|
||||||
|
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||||
|
#endif
|
||||||
|
#if FF_USE_FIND
|
||||||
|
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||||
|
#endif
|
||||||
|
} DIR;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File information structure (FILINFO) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FSIZE_t fsize; /* File size */
|
||||||
|
WORD fdate; /* Modified date */
|
||||||
|
WORD ftime; /* Modified time */
|
||||||
|
BYTE fattrib; /* File attribute */
|
||||||
|
#if FF_USE_LFN
|
||||||
|
TCHAR altname[FF_SFN_BUF + 1];/* Alternative file name */
|
||||||
|
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||||
|
#else
|
||||||
|
TCHAR fname[12 + 1]; /* File name */
|
||||||
|
#endif
|
||||||
|
} FILINFO;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Format parameter structure (MKFS_PARM) */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
BYTE fmt; /* Format option (FM_FAT, FM_FAT32, FM_EXFAT and FM_SFD) */
|
||||||
|
BYTE n_fat; /* Number of FATs */
|
||||||
|
UINT align; /* Data area alignment (sector) */
|
||||||
|
UINT n_root; /* Number of root directory entries */
|
||||||
|
DWORD au_size; /* Cluster size (byte) */
|
||||||
|
} MKFS_PARM;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* File function return code (FRESULT) */
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FR_OK = 0, /* (0) Succeeded */
|
||||||
|
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||||
|
FR_INT_ERR, /* (2) Assertion failed */
|
||||||
|
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||||
|
FR_NO_FILE, /* (4) Could not find the file */
|
||||||
|
FR_NO_PATH, /* (5) Could not find the path */
|
||||||
|
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||||
|
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||||
|
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||||
|
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||||
|
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||||
|
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||||
|
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||||
|
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||||
|
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||||
|
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||||
|
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||||
|
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||||
|
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||||
|
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
||||||
|
} FRESULT;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* FatFs Module Application Interface */
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||||
|
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||||
|
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||||
|
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||||
|
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||||
|
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||||
|
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||||
|
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||||
|
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||||
|
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||||
|
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||||
|
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||||
|
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||||
|
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||||
|
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||||
|
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||||
|
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||||
|
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||||
|
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||||
|
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||||
|
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||||
|
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||||
|
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||||
|
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||||
|
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||||
|
FRESULT f_expand (FIL* fp, FSIZE_t fsz, BYTE opt); /* Allocate a contiguous block to the file */
|
||||||
|
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||||
|
FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len); /* Create a FAT volume */
|
||||||
|
FRESULT f_fdisk (BYTE pdrv, const LBA_t ptbl[], void* work); /* Divide a physical drive into some partitions */
|
||||||
|
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||||
|
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||||
|
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||||
|
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||||
|
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||||
|
|
||||||
|
/* Some API fucntions are implemented as macro */
|
||||||
|
|
||||||
|
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||||
|
#define f_error(fp) ((fp)->err)
|
||||||
|
#define f_tell(fp) ((fp)->fptr)
|
||||||
|
#define f_size(fp) ((fp)->obj.objsize)
|
||||||
|
#define f_rewind(fp) f_lseek((fp), 0)
|
||||||
|
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||||
|
#define f_rmdir(path) f_unlink(path)
|
||||||
|
#define f_unmount(path) f_mount(0, path, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Additional Functions */
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* RTC function (provided by user) */
|
||||||
|
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||||
|
DWORD get_fattime (void); /* Get current time */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* LFN support functions (defined in ffunicode.c) */
|
||||||
|
|
||||||
|
#if FF_USE_LFN >= 1
|
||||||
|
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||||
|
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||||
|
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* O/S dependent functions (samples available in ffsystem.c) */
|
||||||
|
|
||||||
|
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||||
|
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||||
|
void ff_memfree (void* mblock); /* Free memory block */
|
||||||
|
#endif
|
||||||
|
#if FF_FS_REENTRANT /* Sync functions */
|
||||||
|
int ff_mutex_create (int vol); /* Create a sync object */
|
||||||
|
void ff_mutex_delete (int vol); /* Delete a sync object */
|
||||||
|
int ff_mutex_take (int vol); /* Lock sync object */
|
||||||
|
void ff_mutex_give (int vol); /* Unlock sync object */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
/* Flags and Offset Address */
|
||||||
|
/*--------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* File access mode and open method flags (3rd argument of f_open) */
|
||||||
|
#define FA_READ 0x01
|
||||||
|
#define FA_WRITE 0x02
|
||||||
|
#define FA_OPEN_EXISTING 0x00
|
||||||
|
#define FA_CREATE_NEW 0x04
|
||||||
|
#define FA_CREATE_ALWAYS 0x08
|
||||||
|
#define FA_OPEN_ALWAYS 0x10
|
||||||
|
#define FA_OPEN_APPEND 0x30
|
||||||
|
|
||||||
|
/* Fast seek controls (2nd argument of f_lseek) */
|
||||||
|
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||||
|
|
||||||
|
/* Format options (2nd argument of f_mkfs) */
|
||||||
|
#define FM_FAT 0x01
|
||||||
|
#define FM_FAT32 0x02
|
||||||
|
#define FM_EXFAT 0x04
|
||||||
|
#define FM_ANY 0x07
|
||||||
|
#define FM_SFD 0x08
|
||||||
|
|
||||||
|
/* Filesystem type (FATFS.fs_type) */
|
||||||
|
#define FS_FAT12 1
|
||||||
|
#define FS_FAT16 2
|
||||||
|
#define FS_FAT32 3
|
||||||
|
#define FS_EXFAT 4
|
||||||
|
|
||||||
|
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||||
|
#define AM_RDO 0x01 /* Read only */
|
||||||
|
#define AM_HID 0x02 /* Hidden */
|
||||||
|
#define AM_SYS 0x04 /* System */
|
||||||
|
#define AM_DIR 0x10 /* Directory */
|
||||||
|
#define AM_ARC 0x20 /* Archive */
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FF_DEFINED */
|
296
VSC-PicoPAC/fatfs/ffconf.h
Normal file
296
VSC-PicoPAC/fatfs/ffconf.h
Normal file
@ -0,0 +1,296 @@
|
|||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Configurations of FatFs Module
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define FFCONF_DEF 80286 /* Revision ID */
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Function Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define FF_FS_READONLY 0
|
||||||
|
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||||
|
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||||
|
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||||
|
/ and optional writing functions as well. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_MINIMIZE 0
|
||||||
|
/* This option defines minimization level to remove some basic API functions.
|
||||||
|
/
|
||||||
|
/ 0: Basic functions are fully enabled.
|
||||||
|
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||||
|
/ are removed.
|
||||||
|
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||||
|
/ 3: f_lseek() function is removed in addition to 2. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_FIND 0
|
||||||
|
/* This option switches filtered directory read functions, f_findfirst() and
|
||||||
|
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_MKFS 1
|
||||||
|
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_FASTSEEK 0
|
||||||
|
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_EXPAND 0
|
||||||
|
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_CHMOD 0
|
||||||
|
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||||
|
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_LABEL 1
|
||||||
|
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||||
|
/ (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_FORWARD 0
|
||||||
|
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_STRFUNC 1
|
||||||
|
#define FF_PRINT_LLI 1
|
||||||
|
#define FF_PRINT_FLOAT 1
|
||||||
|
#define FF_STRF_ENCODE 3
|
||||||
|
/* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and
|
||||||
|
/ f_printf().
|
||||||
|
/
|
||||||
|
/ 0: Disable. FF_PRINT_LLI, FF_PRINT_FLOAT and FF_STRF_ENCODE have no effect.
|
||||||
|
/ 1: Enable without LF-CRLF conversion.
|
||||||
|
/ 2: Enable with LF-CRLF conversion.
|
||||||
|
/
|
||||||
|
/ FF_PRINT_LLI = 1 makes f_printf() support long long argument and FF_PRINT_FLOAT = 1/2
|
||||||
|
/ makes f_printf() support floating point argument. These features want C99 or later.
|
||||||
|
/ When FF_LFN_UNICODE >= 1 with LFN enabled, string functions convert the character
|
||||||
|
/ encoding in it. FF_STRF_ENCODE selects assumption of character encoding ON THE FILE
|
||||||
|
/ to be read/written via those functions.
|
||||||
|
/
|
||||||
|
/ 0: ANSI/OEM in current CP
|
||||||
|
/ 1: Unicode in UTF-16LE
|
||||||
|
/ 2: Unicode in UTF-16BE
|
||||||
|
/ 3: Unicode in UTF-8
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Locale and Namespace Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define FF_CODE_PAGE 437
|
||||||
|
/* This option specifies the OEM code page to be used on the target system.
|
||||||
|
/ Incorrect code page setting can cause a file open failure.
|
||||||
|
/
|
||||||
|
/ 437 - U.S.
|
||||||
|
/ 720 - Arabic
|
||||||
|
/ 737 - Greek
|
||||||
|
/ 771 - KBL
|
||||||
|
/ 775 - Baltic
|
||||||
|
/ 850 - Latin 1
|
||||||
|
/ 852 - Latin 2
|
||||||
|
/ 855 - Cyrillic
|
||||||
|
/ 857 - Turkish
|
||||||
|
/ 860 - Portuguese
|
||||||
|
/ 861 - Icelandic
|
||||||
|
/ 862 - Hebrew
|
||||||
|
/ 863 - Canadian French
|
||||||
|
/ 864 - Arabic
|
||||||
|
/ 865 - Nordic
|
||||||
|
/ 866 - Russian
|
||||||
|
/ 869 - Greek 2
|
||||||
|
/ 932 - Japanese (DBCS)
|
||||||
|
/ 936 - Simplified Chinese (DBCS)
|
||||||
|
/ 949 - Korean (DBCS)
|
||||||
|
/ 950 - Traditional Chinese (DBCS)
|
||||||
|
/ 0 - Include all code pages above and configured by f_setcp()
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_LFN 1
|
||||||
|
#define FF_MAX_LFN 255
|
||||||
|
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||||
|
/
|
||||||
|
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||||
|
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||||
|
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||||
|
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||||
|
/
|
||||||
|
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||||
|
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||||
|
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||||
|
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||||
|
/ be in range of 12 to 255. It is recommended to be set it 255 to fully support LFN
|
||||||
|
/ specification.
|
||||||
|
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||||
|
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||||
|
/ ff_memfree() exemplified in ffsystem.c, need to be added to the project. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_LFN_UNICODE 0
|
||||||
|
/* This option switches the character encoding on the API when LFN is enabled.
|
||||||
|
/
|
||||||
|
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||||
|
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||||
|
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||||
|
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||||
|
/
|
||||||
|
/ Also behavior of string I/O functions will be affected by this option.
|
||||||
|
/ When LFN is not enabled, this option has no effect. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_LFN_BUF 255
|
||||||
|
#define FF_SFN_BUF 12
|
||||||
|
/* This set of options defines size of file name members in the FILINFO structure
|
||||||
|
/ which is used to read out directory items. These values should be suffcient for
|
||||||
|
/ the file names to read. The maximum possible length of the read file name depends
|
||||||
|
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_RPATH 0
|
||||||
|
/* This option configures support for relative path.
|
||||||
|
/
|
||||||
|
/ 0: Disable relative path and remove related functions.
|
||||||
|
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||||
|
/ 2: f_getcwd() function is available in addition to 1.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ Drive/Volume Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define FF_VOLUMES 1
|
||||||
|
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_STR_VOLUME_ID 0
|
||||||
|
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||||
|
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||||
|
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||||
|
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||||
|
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||||
|
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||||
|
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||||
|
/ not defined, a user defined volume string table is needed as:
|
||||||
|
/
|
||||||
|
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_MULTI_PARTITION 0
|
||||||
|
/* This option switches support for multiple volumes on the physical drive.
|
||||||
|
/ By default (0), each logical drive number is bound to the same physical drive
|
||||||
|
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||||
|
/ When this function is enabled (1), each logical drive number can be bound to
|
||||||
|
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||||
|
/ function will be available. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_MIN_SS 512
|
||||||
|
#define FF_MAX_SS 512
|
||||||
|
/* This set of options configures the range of sector size to be supported. (512,
|
||||||
|
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||||
|
/ harddisk, but a larger value may be required for on-board flash memory and some
|
||||||
|
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||||
|
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||||
|
/ GET_SECTOR_SIZE command. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_LBA64 0
|
||||||
|
/* This option switches support for 64-bit LBA. (0:Disable or 1:Enable)
|
||||||
|
/ To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_MIN_GPT 0x10000000
|
||||||
|
/* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and
|
||||||
|
/ f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_USE_TRIM 0
|
||||||
|
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||||
|
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||||
|
/ disk_ioctl() function. */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------/
|
||||||
|
/ System Configurations
|
||||||
|
/---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define FF_FS_TINY 0
|
||||||
|
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||||
|
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||||
|
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||||
|
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_EXFAT 0
|
||||||
|
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||||
|
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||||
|
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_NORTC 1
|
||||||
|
#define FF_NORTC_MON 1
|
||||||
|
#define FF_NORTC_MDAY 1
|
||||||
|
#define FF_NORTC_YEAR 2023
|
||||||
|
/* The option FF_FS_NORTC switches timestamp feature. If the system does not have
|
||||||
|
/ an RTC or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable the
|
||||||
|
/ timestamp feature. Every object modified by FatFs will have a fixed timestamp
|
||||||
|
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||||
|
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||||
|
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||||
|
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||||
|
/ These options have no effect in read-only configuration (FF_FS_READONLY = 1). */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_NOFSINFO 0
|
||||||
|
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||||
|
/ option, and f_getfree() function at the first time after volume mount will force
|
||||||
|
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||||
|
/
|
||||||
|
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||||
|
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||||
|
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||||
|
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_LOCK 0
|
||||||
|
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||||
|
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||||
|
/ is 1.
|
||||||
|
/
|
||||||
|
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||||
|
/ should avoid illegal open, remove and rename to the open objects.
|
||||||
|
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||||
|
/ can be opened simultaneously under file lock control. Note that the file
|
||||||
|
/ lock control is independent of re-entrancy. */
|
||||||
|
|
||||||
|
|
||||||
|
#define FF_FS_REENTRANT 0
|
||||||
|
#define FF_FS_TIMEOUT 1000
|
||||||
|
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||||
|
/ module itself. Note that regardless of this option, file access to different
|
||||||
|
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||||
|
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||||
|
/ to the same volume is under control of this featuer.
|
||||||
|
/
|
||||||
|
/ 0: Disable re-entrancy. FF_FS_TIMEOUT have no effect.
|
||||||
|
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||||
|
/ ff_mutex_create(), ff_mutex_delete(), ff_mutex_take() and ff_mutex_give()
|
||||||
|
/ function, must be added to the project. Samples are available in ffsystem.c.
|
||||||
|
/
|
||||||
|
/ The FF_FS_TIMEOUT defines timeout period in unit of O/S time tick.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*--- End of configuration options ---*/
|
208
VSC-PicoPAC/fatfs/ffsystem.c
Normal file
208
VSC-PicoPAC/fatfs/ffsystem.c
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* A Sample Code of User Provided OS Dependent Functions for FatFs */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "ff.h"
|
||||||
|
|
||||||
|
|
||||||
|
#if FF_USE_LFN == 3 /* Use dynamic memory allocation */
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Allocate/Free a Memory Block */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include <stdlib.h> /* with POSIX API */
|
||||||
|
|
||||||
|
|
||||||
|
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
|
||||||
|
UINT msize /* Number of bytes to allocate */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return malloc((size_t)msize); /* Allocate a new memory block */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ff_memfree (
|
||||||
|
void* mblock /* Pointer to the memory block to free (no effect if null) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
free(mblock); /* Free the memory block */
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if FF_FS_REENTRANT /* Mutal exclusion */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Definitions of Mutex */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define OS_TYPE 0 /* 0:Win32, 1:uITRON4.0, 2:uC/OS-II, 3:FreeRTOS, 4:CMSIS-RTOS */
|
||||||
|
|
||||||
|
|
||||||
|
#if OS_TYPE == 0 /* Win32 */
|
||||||
|
#include <windows.h>
|
||||||
|
static HANDLE Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
|
||||||
|
|
||||||
|
#elif OS_TYPE == 1 /* uITRON */
|
||||||
|
#include "itron.h"
|
||||||
|
#include "kernel.h"
|
||||||
|
static mtxid Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
|
||||||
|
|
||||||
|
#elif OS_TYPE == 2 /* uc/OS-II */
|
||||||
|
#include "includes.h"
|
||||||
|
static OS_EVENT *Mutex[FF_VOLUMES + 1]; /* Table of mutex pinter */
|
||||||
|
|
||||||
|
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
static SemaphoreHandle_t Mutex[FF_VOLUMES + 1]; /* Table of mutex handle */
|
||||||
|
|
||||||
|
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||||
|
#include "cmsis_os.h"
|
||||||
|
static osMutexId Mutex[FF_VOLUMES + 1]; /* Table of mutex ID */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Create a Mutex */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called in f_mount function to create a new mutex
|
||||||
|
/ or semaphore for the volume. When a 0 is returned, the f_mount function
|
||||||
|
/ fails with FR_INT_ERR.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ff_mutex_create ( /* Returns 1:Function succeeded or 0:Could not create the mutex */
|
||||||
|
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#if OS_TYPE == 0 /* Win32 */
|
||||||
|
Mutex[vol] = CreateMutex(NULL, FALSE, NULL);
|
||||||
|
return (int)(Mutex[vol] != INVALID_HANDLE_VALUE);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 1 /* uITRON */
|
||||||
|
T_CMTX cmtx = {TA_TPRI,1};
|
||||||
|
|
||||||
|
Mutex[vol] = acre_mtx(&cmtx);
|
||||||
|
return (int)(Mutex[vol] > 0);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 2 /* uC/OS-II */
|
||||||
|
OS_ERR err;
|
||||||
|
|
||||||
|
Mutex[vol] = OSMutexCreate(0, &err);
|
||||||
|
return (int)(err == OS_NO_ERR);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||||
|
Mutex[vol] = xSemaphoreCreateMutex();
|
||||||
|
return (int)(Mutex[vol] != NULL);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||||
|
osMutexDef(cmsis_os_mutex);
|
||||||
|
|
||||||
|
Mutex[vol] = osMutexCreate(osMutex(cmsis_os_mutex));
|
||||||
|
return (int)(Mutex[vol] != NULL);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Delete a Mutex */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called in f_mount function to delete a mutex or
|
||||||
|
/ semaphore of the volume created with ff_mutex_create function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ff_mutex_delete ( /* Returns 1:Function succeeded or 0:Could not delete due to an error */
|
||||||
|
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#if OS_TYPE == 0 /* Win32 */
|
||||||
|
CloseHandle(Mutex[vol]);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 1 /* uITRON */
|
||||||
|
del_mtx(Mutex[vol]);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 2 /* uC/OS-II */
|
||||||
|
OS_ERR err;
|
||||||
|
|
||||||
|
OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||||
|
vSemaphoreDelete(Mutex[vol]);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||||
|
osMutexDelete(Mutex[vol]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Request a Grant to Access the Volume */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called on enter file functions to lock the volume.
|
||||||
|
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int ff_mutex_take ( /* Returns 1:Succeeded or 0:Timeout */
|
||||||
|
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#if OS_TYPE == 0 /* Win32 */
|
||||||
|
return (int)(WaitForSingleObject(Mutex[vol], FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 1 /* uITRON */
|
||||||
|
return (int)(tloc_mtx(Mutex[vol], FF_FS_TIMEOUT) == E_OK);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 2 /* uC/OS-II */
|
||||||
|
OS_ERR err;
|
||||||
|
|
||||||
|
OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err));
|
||||||
|
return (int)(err == OS_NO_ERR);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||||
|
return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||||
|
return (int)(osMutexWait(Mutex[vol], FF_FS_TIMEOUT) == osOK);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* Release a Grant to Access the Volume */
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
/* This function is called on leave file functions to unlock the volume.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void ff_mutex_give (
|
||||||
|
int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */
|
||||||
|
)
|
||||||
|
{
|
||||||
|
#if OS_TYPE == 0 /* Win32 */
|
||||||
|
ReleaseMutex(Mutex[vol]);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 1 /* uITRON */
|
||||||
|
unl_mtx(Mutex[vol]);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 2 /* uC/OS-II */
|
||||||
|
OSMutexPost(Mutex[vol]);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 3 /* FreeRTOS */
|
||||||
|
xSemaphoreGive(Mutex[vol]);
|
||||||
|
|
||||||
|
#elif OS_TYPE == 4 /* CMSIS-RTOS */
|
||||||
|
osMutexRelease(Mutex[vol]);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* FF_FS_REENTRANT */
|
||||||
|
|
15593
VSC-PicoPAC/fatfs/ffunicode.c
Normal file
15593
VSC-PicoPAC/fatfs/ffunicode.c
Normal file
File diff suppressed because it is too large
Load Diff
101
VSC-PicoPAC/fatfs_disk.c
Normal file
101
VSC-PicoPAC/fatfs_disk.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "ff.h"
|
||||||
|
#include "diskio.h"
|
||||||
|
#include "fatfs_disk.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "hardware/flash.h"
|
||||||
|
|
||||||
|
bool flashfs_is_mounted = false;
|
||||||
|
|
||||||
|
bool mount_fatfs_disk()
|
||||||
|
{
|
||||||
|
int err = flash_fs_mount();
|
||||||
|
if (err)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
flashfs_is_mounted = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool fatfs_is_mounted() { return flashfs_is_mounted; }
|
||||||
|
|
||||||
|
void create_fatfs_disk()
|
||||||
|
{
|
||||||
|
flash_fs_create();
|
||||||
|
flashfs_is_mounted = true;
|
||||||
|
|
||||||
|
// now create a fatfs on the flash_fs filesystem :-)
|
||||||
|
|
||||||
|
FATFS fs; /* Filesystem object */
|
||||||
|
FIL fil; /* File object */
|
||||||
|
FRESULT res; /* API result code */
|
||||||
|
BYTE work[FF_MAX_SS]; /* Work area (larger is better for processing time) */
|
||||||
|
|
||||||
|
/* Format the default drive with default parameters */
|
||||||
|
printf("making fatfs\n");
|
||||||
|
res = f_mkfs("", 0, work, sizeof work);
|
||||||
|
f_mount(&fs, "", 0);
|
||||||
|
f_setlabel("PicoPAC");
|
||||||
|
res = f_open(&fil, "WELCOME.TXT", FA_CREATE_NEW | FA_WRITE);
|
||||||
|
f_puts("PicoPAC\r\n(c)2024 AOtta\r\nDrag ROM files in here!\r\n", &fil);
|
||||||
|
f_close(&fil);
|
||||||
|
f_mount(0, "", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fatfs_disk_read(uint8_t* buff, uint32_t sector, uint32_t count)
|
||||||
|
{
|
||||||
|
// printf("fatfs_disk_read sector=%d, count=%d\n", sector, count);
|
||||||
|
if (!flashfs_is_mounted) return RES_ERROR;
|
||||||
|
if (sector < 0 || sector >= SECTOR_NUM)
|
||||||
|
return RES_PARERR;
|
||||||
|
|
||||||
|
/* copy data to buffer */
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
flash_fs_read_FAT_sector(sector + i, buff + (i*SECTOR_SIZE));
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t fatfs_disk_write(const uint8_t* buff, uint32_t sector, uint32_t count)
|
||||||
|
{
|
||||||
|
// printf("fatfs_disk_write sector=%d, count=%d\n", sector, count);
|
||||||
|
if (!flashfs_is_mounted) return RES_ERROR;
|
||||||
|
if (sector < 0 || sector >= SECTOR_NUM)
|
||||||
|
return RES_PARERR;
|
||||||
|
|
||||||
|
/* copy data to buffer */
|
||||||
|
for (int i=0; i<count; i++) {
|
||||||
|
flash_fs_write_FAT_sector(sector + i, buff + (i*SECTOR_SIZE));
|
||||||
|
// verify
|
||||||
|
if (!flash_fs_verify_FAT_sector(sector + i, buff + (i*SECTOR_SIZE))) {
|
||||||
|
printf("VERIFY ERROR!");
|
||||||
|
return RES_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return RES_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void fatfs_disk_sync()
|
||||||
|
{
|
||||||
|
flash_fs_sync();
|
||||||
|
}
|
36
VSC-PicoPAC/fatfs_disk.h
Normal file
36
VSC-PicoPAC/fatfs_disk.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __FATFS_DISK_H__
|
||||||
|
#define __FATFS_DISK_H__
|
||||||
|
|
||||||
|
#include "flash_fs.h"
|
||||||
|
|
||||||
|
#define SECTOR_NUM 30716 //2044 //1800
|
||||||
|
#define SECTOR_SIZE 512
|
||||||
|
|
||||||
|
void create_fatfs_disk();
|
||||||
|
bool mount_fatfs_disk();
|
||||||
|
bool fatfs_is_mounted();
|
||||||
|
uint32_t fatfs_disk_read(uint8_t* buff, uint32_t sector, uint32_t count);
|
||||||
|
uint32_t fatfs_disk_write(const uint8_t* buff, uint32_t sector, uint32_t count);
|
||||||
|
void fatfs_disk_sync();
|
||||||
|
|
||||||
|
#endif
|
242
VSC-PicoPAC/filelist.h
Normal file
242
VSC-PicoPAC/filelist.h
Normal file
@ -0,0 +1,242 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
char gamelist[255][32]= {
|
||||||
|
// 12345678901234567890123456789012
|
||||||
|
"60 PLUS -TRANS.BIN", // TO CORRECT
|
||||||
|
"BR-16.BIN",
|
||||||
|
"BR-17.BIN",
|
||||||
|
"BR-19.BIN",
|
||||||
|
"BR-21.BIN",
|
||||||
|
"BR-46.BIN",
|
||||||
|
"BR-50.BIN",
|
||||||
|
"BR-54.BIN",
|
||||||
|
"BR-55.BIN",
|
||||||
|
"BR-58.BIN",
|
||||||
|
"BR-CLAY-PIGEON.BIN",
|
||||||
|
"BR-COMMANDO-NOTURNO.BIN",
|
||||||
|
"br_frogger.bin",
|
||||||
|
"br_popeye.bin",
|
||||||
|
"br_super-cobra.bin",
|
||||||
|
"csv1.bin",
|
||||||
|
"csv2.bin",
|
||||||
|
"im_atlantis.bin",
|
||||||
|
"im_demon-attack.bin",
|
||||||
|
"jo_basket-bowling_pl.bin",
|
||||||
|
"jo_billard_pl.bin",
|
||||||
|
"jo_chez-maxime.bin",
|
||||||
|
"jo_demon-attack_pl.bin",
|
||||||
|
"jo_exojet_pl.bin",
|
||||||
|
"jo_flipper_pl.bin",
|
||||||
|
"jo_le-tresor-englouti_pl.bin",
|
||||||
|
"jo_moto-crash_pl.bin",
|
||||||
|
"jo_syracuse.bin",
|
||||||
|
"LISTFILES.TXT",
|
||||||
|
"mod_01pl.bin",
|
||||||
|
"mod_05_g7400.bin",
|
||||||
|
"mod_06pl.bin",
|
||||||
|
"mod_11pl.bin",
|
||||||
|
"mod_14fix.bin",
|
||||||
|
"mod_19_g7400.bin",
|
||||||
|
"mod_20pl.bin",
|
||||||
|
"mod_24pl.bin",
|
||||||
|
"mod_28fix.bin",
|
||||||
|
"mod_30fix.bin",
|
||||||
|
"mod_31_g7400.bin",
|
||||||
|
"mod_35pl_fix.bin",
|
||||||
|
"mod_36fix.bin",
|
||||||
|
"mod_40_g7400.bin",
|
||||||
|
"mod_43pl.bin",
|
||||||
|
"mod_55pl.bin",
|
||||||
|
"mod_br21_fix.bin",
|
||||||
|
"mod_demon-attack_pl.bin",
|
||||||
|
"mod_moto-crash_g7000.bin",
|
||||||
|
"mod_playtag_fix.bin",
|
||||||
|
"mod_tutankham_fix.bin",
|
||||||
|
"mod_vp31_examples.bin",
|
||||||
|
"mod_vp9_examples.bin",
|
||||||
|
"new_amok.bin",
|
||||||
|
"new_amok_alt.bin",
|
||||||
|
"new_calculator.bin",
|
||||||
|
"new_helicopter_buzzword.bin",
|
||||||
|
"new_jg-munchkin.bin",
|
||||||
|
"new_kc-pacman.bin",
|
||||||
|
"new_kc-pacvid.bin",
|
||||||
|
"new_ktaa-demo1.bin",
|
||||||
|
"new_ktaa-demo2.bin",
|
||||||
|
"new_ktaa.bin",
|
||||||
|
"new_mrroboto.bin",
|
||||||
|
"new_planet-lander.bin",
|
||||||
|
"new_pong.bin",
|
||||||
|
"new_pong_all.bin",
|
||||||
|
"new_ppp-o2em.bin",
|
||||||
|
"new_puzzle-piece-panic.bin",
|
||||||
|
"new_route66.bin",
|
||||||
|
"ntsc_57.bin",
|
||||||
|
"ntsc_chez-maxime.bin",
|
||||||
|
"ntsc_exojet_pl.bin",
|
||||||
|
"ntsc_interpol.bin",
|
||||||
|
"ntsc_moto-crash.bin",
|
||||||
|
"ntsc_shark-hunter.bin",
|
||||||
|
"ntsc_tutankham.bin",
|
||||||
|
"o2_06.bin",
|
||||||
|
"o2_07.bin",
|
||||||
|
"o2_10.bin",
|
||||||
|
"o2_11.bin",
|
||||||
|
"o2_14.bin",
|
||||||
|
"o2_16.bin",
|
||||||
|
"o2_19.bin",
|
||||||
|
"o2_21.bin",
|
||||||
|
"o2_30.bin",
|
||||||
|
"o2_33.bin",
|
||||||
|
"o2_35.bin",
|
||||||
|
"o2_38.bin",
|
||||||
|
"o2_39.bin",
|
||||||
|
"o2_40.bin",
|
||||||
|
"o2_41.bin",
|
||||||
|
"o2_43.bin",
|
||||||
|
"o2_45.bin",
|
||||||
|
"o2_46.bin",
|
||||||
|
"o2_47.bin",
|
||||||
|
"o2_48.bin",
|
||||||
|
"o2_48alt.bin",
|
||||||
|
"pal_acrobats.bin",
|
||||||
|
"pal_flashpoint.bin",
|
||||||
|
"pal_nimble-numbers-ned.bin",
|
||||||
|
"pal_type-and-tell.bin",
|
||||||
|
"pb_frogger.bin",
|
||||||
|
"pb_popeye.bin",
|
||||||
|
"pb_q-bert.bin",
|
||||||
|
"pb_super-cobra.bin",
|
||||||
|
"pr_clay-pigeon_pl.bin",
|
||||||
|
"pr_clay-pigeon_pl_alt.bin",
|
||||||
|
"pr_interpol.bin",
|
||||||
|
"pr_martian-threat.bin",
|
||||||
|
"pr_martian-threat_alt.bin",
|
||||||
|
"pr_mission-impossible.bin",
|
||||||
|
"pr_nightfighter.bin",
|
||||||
|
"pr_pinball.bin",
|
||||||
|
"pr_playtag.bin",
|
||||||
|
"pr_red-baron.bin",
|
||||||
|
"pr_red-baron_alt.bin",
|
||||||
|
"pr_robot-city.bin",
|
||||||
|
"pr_shark-hunter.bin",
|
||||||
|
"pr_spiderman.bin",
|
||||||
|
"pr_spiderman_alt.bin",
|
||||||
|
"pr_tutankham.bin",
|
||||||
|
"vp01+_F.bin",
|
||||||
|
"Vp01_F.bin",
|
||||||
|
"Vp05_F.bin",
|
||||||
|
"Vp06_F.bin",
|
||||||
|
"Vp07_F.bin",
|
||||||
|
"Vp11+_F.bin",
|
||||||
|
"Vp11_F.bin",
|
||||||
|
"Vp12_F.bin",
|
||||||
|
"Vp18_F.bin",
|
||||||
|
"Vp23_F.bin",
|
||||||
|
"Vp24_F.bin",
|
||||||
|
"Vp25_F.bin",
|
||||||
|
"Vp28_F.bin",
|
||||||
|
"Vp29_F.bin",
|
||||||
|
"Vp35_F.bin",
|
||||||
|
"Vp36_F.bin",
|
||||||
|
"Vp40_F.bin",
|
||||||
|
"Vp42_F.bin",
|
||||||
|
"Vp45_F.bin",
|
||||||
|
"Vp47_F.bin",
|
||||||
|
"Vp52+_F.bin",
|
||||||
|
"vp_01.bin",
|
||||||
|
"vp_01hack.bin",
|
||||||
|
"vp_01pl.bin",
|
||||||
|
"vp_02.bin",
|
||||||
|
"vp_03.bin",
|
||||||
|
"vp_04.bin",
|
||||||
|
"vp_05.bin",
|
||||||
|
"vp_06.bin",
|
||||||
|
"vp_06pl.bin",
|
||||||
|
"vp_07.bin",
|
||||||
|
"vp_08.bin",
|
||||||
|
"vp_09.bin",
|
||||||
|
"vp_10.bin",
|
||||||
|
"vp_11.bin",
|
||||||
|
"vp_11alt.bin",
|
||||||
|
"vp_11pl.bin",
|
||||||
|
"vp_12.bin",
|
||||||
|
"vp_13.bin",
|
||||||
|
"vp_14.bin",
|
||||||
|
"vp_15.bin",
|
||||||
|
"vp_16.bin",
|
||||||
|
"vp_17.bin",
|
||||||
|
"vp_18.bin",
|
||||||
|
"vp_19.bin",
|
||||||
|
"vp_20.bin",
|
||||||
|
"vp_20pl.bin",
|
||||||
|
"vp_21.bin",
|
||||||
|
"vp_22.bin",
|
||||||
|
"vp_22hack.bin",
|
||||||
|
"vp_23.bin",
|
||||||
|
"vp_24.bin",
|
||||||
|
"vp_24pl.bin",
|
||||||
|
"vp_25.bin",
|
||||||
|
"vp_26.bin",
|
||||||
|
"vp_27.bin",
|
||||||
|
"vp_28.bin",
|
||||||
|
"vp_29.bin",
|
||||||
|
"vp_30.bin",
|
||||||
|
"vp_31.bin",
|
||||||
|
"vp_32.bin",
|
||||||
|
"vp_33.bin",
|
||||||
|
"vp_33alt.bin",
|
||||||
|
"vp_34.bin",
|
||||||
|
"vp_34pl.bin",
|
||||||
|
"vp_35.bin",
|
||||||
|
"vp_35pl.bin",
|
||||||
|
"vp_36.bin",
|
||||||
|
"vp_37.bin",
|
||||||
|
"vp_38.bin",
|
||||||
|
"vp_39.bin",
|
||||||
|
"vp_39pl.bin",
|
||||||
|
"vp_40.bin",
|
||||||
|
"vp_41.bin",
|
||||||
|
"vp_42.bin",
|
||||||
|
"vp_43.bin",
|
||||||
|
"vp_43pl.bin",
|
||||||
|
"vp_44.bin",
|
||||||
|
"vp_45.bin",
|
||||||
|
"vp_46.bin",
|
||||||
|
"vp_47.bin",
|
||||||
|
"vp_48.bin",
|
||||||
|
"vp_49.bin",
|
||||||
|
"vp_50.bin",
|
||||||
|
"vp_51pl.bin",
|
||||||
|
"vp_52pl.bin",
|
||||||
|
"vp_53.bin",
|
||||||
|
"vp_53pl.bin",
|
||||||
|
"vp_54.bin",
|
||||||
|
"vp_54pl.bin",
|
||||||
|
"vp_55.bin",
|
||||||
|
"vp_55_12.bin",
|
||||||
|
"vp_55_12fix.bin",
|
||||||
|
"vp_56pl.bin",
|
||||||
|
"vp_57.bin",
|
||||||
|
"vp_58_12.bin",
|
||||||
|
"vp_59_16.bin",
|
||||||
|
"vp_60_16.bin",
|
||||||
|
"vp_a.bin",
|
||||||
|
"vp_C7010.bin",
|
||||||
|
"vp_v.bin"
|
||||||
|
}
|
254
VSC-PicoPAC/flash_fs.c
Normal file
254
VSC-PicoPAC/flash_fs.c
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "hardware/flash.h"
|
||||||
|
#include "hardware/sync.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "flash_fs.h"
|
||||||
|
|
||||||
|
// Implements 512 byte FAT sectors on 4096 byte flash sectors.
|
||||||
|
// Doesn't really implement wear levelling (e.g. the fs_map) so not for heavy use but should be
|
||||||
|
// fine for the intended use case.
|
||||||
|
|
||||||
|
#define HW_FLASH_STORAGE_BASE (1024 * 1024)
|
||||||
|
#define MAGIC_8_BYTES "RHE!FS30"
|
||||||
|
|
||||||
|
#define NUM_FAT_SECTORS 30716 // 15megs / 512bytes = 30720, but we used 4 records for the header (8 bytes)
|
||||||
|
#define NUM_FLASH_SECTORS 3840 // 15megs / 4096bytes = 3840
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t header[8];
|
||||||
|
uint16_t sectors[NUM_FAT_SECTORS]; // map FAT sectors -> flash sectors
|
||||||
|
} sector_map;
|
||||||
|
|
||||||
|
sector_map fs_map;
|
||||||
|
bool fs_map_needs_written[15];
|
||||||
|
|
||||||
|
uint8_t used_bitmap[NUM_FLASH_SECTORS]; // we will use 256 flash sectors for 2048 fat sectors
|
||||||
|
|
||||||
|
uint16_t write_sector = 0; // which flash sector we are writing to
|
||||||
|
uint8_t write_sector_bitmap = 0; // 1 for each free 512 byte page on the sector
|
||||||
|
|
||||||
|
// each sector entry in the sector map is:
|
||||||
|
// 13 bits of sector (indexing 8192 4k flash sectors)
|
||||||
|
// 3 bits of offset (0->7 512 byte FAT sectors in each 4k flash sector)
|
||||||
|
uint16_t getMapSector(uint16_t mapEntry) { return (mapEntry & 0xFFF8) >> 3; }
|
||||||
|
uint8_t getMapOffset(uint16_t mapEntry) { return mapEntry & 0x7; }
|
||||||
|
uint16_t makeMapEntry(uint16_t sector, uint8_t offset) { return (sector << 3) | offset; };
|
||||||
|
|
||||||
|
// forward declns
|
||||||
|
void flash_read_sector(uint16_t sector, uint8_t offset, void *buffer, uint16_t size);
|
||||||
|
void flash_erase_sector(uint16_t sector);
|
||||||
|
void flash_write_sector(uint16_t sector, uint8_t offset, const void *buffer, uint16_t size);
|
||||||
|
void flash_erase_with_copy_sector(uint16_t sector, uint8_t preserve_bitmap);
|
||||||
|
|
||||||
|
void debug_print_in_use() {
|
||||||
|
return;
|
||||||
|
// just shows first 1meg
|
||||||
|
printf("IN USE-----------------------------------\n");
|
||||||
|
for (int i=0; i<16; i++) {
|
||||||
|
printf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||||
|
used_bitmap[i*16+0], used_bitmap[i*16+1], used_bitmap[i*16+2], used_bitmap[i*16+3],
|
||||||
|
used_bitmap[i*16+4], used_bitmap[i*16+5], used_bitmap[i*16+6], used_bitmap[i*16+7],
|
||||||
|
used_bitmap[i*16+8], used_bitmap[i*16+9], used_bitmap[i*16+10], used_bitmap[i*16+11],
|
||||||
|
used_bitmap[i*16+12], used_bitmap[i*16+13], used_bitmap[i*16+14], used_bitmap[i*16+15]);
|
||||||
|
}
|
||||||
|
printf("END--------------------------------------\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void write_fs_map()
|
||||||
|
{
|
||||||
|
debug_print_in_use();
|
||||||
|
for (int i=0; i<15; i++) {
|
||||||
|
if (fs_map_needs_written[i]) {
|
||||||
|
// printf("Writing FS Map %d\n", i);
|
||||||
|
flash_erase_sector(i);
|
||||||
|
flash_write_sector(i, 0, (uint8_t*)&fs_map+(4096*i), 4096);
|
||||||
|
fs_map_needs_written[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t getNextWriteSector()
|
||||||
|
{
|
||||||
|
static uint16_t search_start_pos = 0;
|
||||||
|
int i;
|
||||||
|
if (write_sector == 0 || write_sector_bitmap == 0)
|
||||||
|
{ // first try to find a completely free sector
|
||||||
|
for (i=0; i<NUM_FLASH_SECTORS; i++) {
|
||||||
|
if (used_bitmap[(i + search_start_pos) % NUM_FLASH_SECTORS] == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i < NUM_FLASH_SECTORS) {
|
||||||
|
write_sector = (i + search_start_pos) % NUM_FLASH_SECTORS;
|
||||||
|
write_sector_bitmap = 0xFF;
|
||||||
|
flash_erase_sector(write_sector);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // no completely free sector, just return the first sector with space
|
||||||
|
for (i=0; i<NUM_FLASH_SECTORS; i++) {
|
||||||
|
if (used_bitmap[(i + search_start_pos) % NUM_FLASH_SECTORS] != 0xFF)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
write_sector = (i + search_start_pos) % NUM_FLASH_SECTORS;
|
||||||
|
write_sector_bitmap = ~used_bitmap[write_sector];
|
||||||
|
flash_erase_with_copy_sector(write_sector, used_bitmap[write_sector]);
|
||||||
|
}
|
||||||
|
search_start_pos = (i + search_start_pos) % NUM_FLASH_SECTORS;
|
||||||
|
}
|
||||||
|
// if we get here, then at least one 512 byte page is free on the write_sector
|
||||||
|
for (i=0; i<8; i++) {
|
||||||
|
if (write_sector_bitmap & (1 << i))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// mark the offset used
|
||||||
|
write_sector_bitmap &= ~(1 << i);
|
||||||
|
return makeMapEntry(write_sector, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_used_bitmap() {
|
||||||
|
memset(used_bitmap, 0, NUM_FLASH_SECTORS);
|
||||||
|
for (int i=0; i<15; i++)
|
||||||
|
used_bitmap[i] = 0xFF; // first 15 flash sectors used by fs map
|
||||||
|
|
||||||
|
for (int i=0; i<NUM_FAT_SECTORS; i++) {
|
||||||
|
uint16_t mapEntry = fs_map.sectors[i];
|
||||||
|
if (mapEntry)
|
||||||
|
used_bitmap[getMapSector(mapEntry)] |= (1 << getMapOffset(mapEntry));
|
||||||
|
}
|
||||||
|
write_sector = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flash_fs_mount()
|
||||||
|
{
|
||||||
|
for (int i=0; i<15; i++)
|
||||||
|
fs_map_needs_written[i] = false;
|
||||||
|
|
||||||
|
// read the first sector, with header
|
||||||
|
flash_read_sector(0, 0, &fs_map, 4096);
|
||||||
|
if (memcmp(fs_map.header, MAGIC_8_BYTES, 8) != 0) {
|
||||||
|
printf("mountFlashFS() - magic bytes not found\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// read the remaining 14 sectors without headers
|
||||||
|
for (int i=1; i<15; i++)
|
||||||
|
flash_read_sector(i, 0, (uint8_t*)&fs_map+(4096*i), 4096);
|
||||||
|
|
||||||
|
init_used_bitmap();
|
||||||
|
debug_print_in_use();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_fs_create()
|
||||||
|
{
|
||||||
|
printf("flash_fs_create()\n");
|
||||||
|
memset(&fs_map, 0, sizeof(fs_map));
|
||||||
|
strcpy(fs_map.header, MAGIC_8_BYTES);
|
||||||
|
for (int i=0; i<15; i++)
|
||||||
|
fs_map_needs_written[i] = true;
|
||||||
|
write_fs_map();
|
||||||
|
init_used_bitmap();
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_fs_sync()
|
||||||
|
{
|
||||||
|
write_fs_map();
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_fs_read_FAT_sector(uint16_t fat_sector, void *buffer)
|
||||||
|
{
|
||||||
|
int mapEntry = fs_map.sectors[fat_sector];
|
||||||
|
if (mapEntry)
|
||||||
|
flash_read_sector(getMapSector(mapEntry), getMapOffset(mapEntry), buffer, 512);
|
||||||
|
else
|
||||||
|
memset(buffer, 0, 512);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_fs_write_FAT_sector(uint16_t fat_sector, const void *buffer)
|
||||||
|
{
|
||||||
|
uint16_t mapEntry = fs_map.sectors[fat_sector];
|
||||||
|
if (mapEntry)
|
||||||
|
{ // mark any previous flash allocated as unused
|
||||||
|
used_bitmap[getMapSector(mapEntry)] &= ~(1 << getMapOffset(mapEntry));
|
||||||
|
}
|
||||||
|
mapEntry = getNextWriteSector();
|
||||||
|
fs_map.sectors[fat_sector] = mapEntry;
|
||||||
|
if (fat_sector < 2044)
|
||||||
|
fs_map_needs_written[0] = true;
|
||||||
|
else
|
||||||
|
fs_map_needs_written[1+((fat_sector-2044)/2048)] = true;
|
||||||
|
|
||||||
|
used_bitmap[getMapSector(mapEntry)] |= (1 << getMapOffset(mapEntry));
|
||||||
|
|
||||||
|
flash_write_sector(getMapSector(mapEntry), getMapOffset(mapEntry), buffer, 512);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool flash_fs_verify_FAT_sector(uint16_t fat_sector, const void *buffer)
|
||||||
|
{
|
||||||
|
uint8_t read_buf[512];
|
||||||
|
flash_fs_read_FAT_sector(fat_sector, read_buf);
|
||||||
|
if (memcmp(buffer, read_buf, 512) == 0) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Low level flash functions */
|
||||||
|
|
||||||
|
void flash_read_sector(uint16_t sector, uint8_t offset, void *buffer, uint16_t size)
|
||||||
|
{
|
||||||
|
// printf("[FS] READ: %d, %d (%d)\n", sector, offset, size);
|
||||||
|
uint32_t fs_start = XIP_BASE + HW_FLASH_STORAGE_BASE;
|
||||||
|
uint32_t addr = fs_start + (sector * FLASH_SECTOR_SIZE) + (offset * 512);
|
||||||
|
memcpy(buffer, (unsigned char *)addr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_erase_sector(uint16_t sector)
|
||||||
|
{
|
||||||
|
// printf("[FS] ERASE: %d\n", sector);
|
||||||
|
uint32_t fs_start = HW_FLASH_STORAGE_BASE;
|
||||||
|
uint32_t offset = fs_start + (sector * FLASH_SECTOR_SIZE);
|
||||||
|
uint32_t ints = save_and_disable_interrupts();
|
||||||
|
flash_range_erase(offset, FLASH_SECTOR_SIZE);
|
||||||
|
restore_interrupts(ints);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_write_sector(uint16_t sector, uint8_t offset, const void *buffer, uint16_t size)
|
||||||
|
{
|
||||||
|
// printf("[FS] WRITE: %d, %d (%d)\n", sector, offset, size);
|
||||||
|
uint32_t fs_start = HW_FLASH_STORAGE_BASE;
|
||||||
|
uint32_t addr = fs_start + (sector * FLASH_SECTOR_SIZE) + (offset * 512);
|
||||||
|
uint32_t ints = save_and_disable_interrupts();
|
||||||
|
flash_range_program(addr, (const uint8_t *)buffer, size);
|
||||||
|
restore_interrupts(ints);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_erase_with_copy_sector(uint16_t sector, uint8_t preserve_bitmap)
|
||||||
|
{
|
||||||
|
// printf("[FS] ERASE with COPY: %d\n", sector);
|
||||||
|
uint8_t buf[FLASH_SECTOR_SIZE];
|
||||||
|
flash_read_sector(sector, 0, buf, FLASH_SECTOR_SIZE);
|
||||||
|
flash_erase_sector(sector);
|
||||||
|
for (int i=0; i<8; i++) {
|
||||||
|
if (preserve_bitmap & (1 << i))
|
||||||
|
flash_write_sector(sector, i, buf + (i * 512), 512);
|
||||||
|
}
|
||||||
|
}
|
33
VSC-PicoPAC/flash_fs.h
Normal file
33
VSC-PicoPAC/flash_fs.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __FLASH_FS_H__
|
||||||
|
#define __FLASH_FS_H__
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
int flash_fs_mount();
|
||||||
|
void flash_fs_create();
|
||||||
|
void flash_fs_sync();
|
||||||
|
void flash_fs_read_FAT_sector(uint16_t fat_sector, void *buffer);
|
||||||
|
void flash_fs_write_FAT_sector(uint16_t fat_sector, const void *buffer);
|
||||||
|
bool flash_fs_verify_FAT_sector(uint16_t fat_sector, const void *buffer);
|
||||||
|
|
||||||
|
#endif
|
222
VSC-PicoPAC/gamelist.h
Normal file
222
VSC-PicoPAC/gamelist.h
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
char gamelist[255][32]= {
|
||||||
|
// 12345678901234567890123456789012
|
||||||
|
"vp_60_16.bin", // pag 1
|
||||||
|
"br_16.bin",
|
||||||
|
"br_17.bin",
|
||||||
|
"br_19.BIN",
|
||||||
|
"br_21.BIN",
|
||||||
|
"br_46.BIN",
|
||||||
|
"br_50.BIN",
|
||||||
|
"br_54.BIN",
|
||||||
|
"br_55.BIN", // pag 2
|
||||||
|
"br_58.BIN",
|
||||||
|
"br_clay-pigeon.bin",
|
||||||
|
"br_comando-noturno.bin",
|
||||||
|
"br_frogger.bin",
|
||||||
|
"br_popeye.bin",
|
||||||
|
"br_super-cobra.bin",
|
||||||
|
"csv1.bin",
|
||||||
|
"csv2.bin", // pag 3
|
||||||
|
"deat race rco4.bin", // to correct
|
||||||
|
"helicopter rescue.bin", // to correct
|
||||||
|
"im_atlantis.bin",
|
||||||
|
"im_demon-attack.bin",
|
||||||
|
"jo_basket-bowling_pl.bin",
|
||||||
|
"jo_billard_pl.bin",
|
||||||
|
"jo_chez-maxime.bin",
|
||||||
|
"jo_demon-attack_pl.bin", // pag 4
|
||||||
|
"jo_exojet_pl.bin",
|
||||||
|
"jo_flipper_pl.bin",
|
||||||
|
"jo_le-tresor-englouti_pl.bin",
|
||||||
|
"jo_moto-crash_pl.bin",
|
||||||
|
"jo_syracuse.bin",
|
||||||
|
"mod_01pl.bin",
|
||||||
|
"mod_05_g7400.bin",
|
||||||
|
"mod_06pl.bin", // pag 5
|
||||||
|
"mod_11pl.bin",
|
||||||
|
"mod_14fix.bin",
|
||||||
|
"mod_19_g7400.bin",
|
||||||
|
"mod_20pl.bin",
|
||||||
|
"mod_24pl.bin",
|
||||||
|
"mod_28fix.bin",
|
||||||
|
"mod_30fix.bin",
|
||||||
|
"mod_31_g7400.bin", // pag 6
|
||||||
|
"mod_35pl_fix.bin",
|
||||||
|
"mod_36fix.bin",
|
||||||
|
"mod_40_g7400.bin",
|
||||||
|
"mod_43pl.bin",
|
||||||
|
"mod_55pl.bin",
|
||||||
|
"mod_br21_fix.bin",
|
||||||
|
"mod_demon-attack_pl.bin",
|
||||||
|
"mod_moto-crash_g7000.bin", // pag 7
|
||||||
|
"mod_playtag_fix.bin",
|
||||||
|
"mod_tutankham_fix.bin",
|
||||||
|
"mod_vp9_examples.bin",
|
||||||
|
"mod_vp31_examples.bin",
|
||||||
|
"mousecat.bin",
|
||||||
|
"new_amok.bin",
|
||||||
|
"new_amok_alt.bin",
|
||||||
|
"new_calculator.bin", // pag 8
|
||||||
|
"new_helicopter_buzzword.bin",
|
||||||
|
"new_jg-munchkin.bin",
|
||||||
|
"new_kc-pacman.bin",
|
||||||
|
"new_kc-pacvid.bin",
|
||||||
|
"new_ktaa.bin",
|
||||||
|
"new_ktaa-demo1.bin",
|
||||||
|
"new_ktaa-demo2.bin",
|
||||||
|
"new_mrroboto.bin", // pag 9
|
||||||
|
"new_planet-lander.bin",
|
||||||
|
"new_pong.bin",
|
||||||
|
"new_pong_all.bin",
|
||||||
|
"new_ppp-o2em.bin",
|
||||||
|
"new_puzzle-piece-panic.bin",
|
||||||
|
"new_route66.bin",
|
||||||
|
"norseman /europe", // to fix
|
||||||
|
"ntsc_57.bin", // pag 10
|
||||||
|
"ntsc_chez-maxime.bin",
|
||||||
|
"ntsc_exojet_pl.bin",
|
||||||
|
"ntsc_interpol.bin",
|
||||||
|
"ntsc_moto-crash.bin",
|
||||||
|
"ntsc_shark-hunter.bin",
|
||||||
|
"ntsc_tutankham.bin",
|
||||||
|
"o2_06.bin",
|
||||||
|
"o2_07.bin", // pag 11
|
||||||
|
"o2_10.bin",
|
||||||
|
"o2_11.bin",
|
||||||
|
"o2_14.bin",
|
||||||
|
"o2_16.bin",
|
||||||
|
"o2_19.bin",
|
||||||
|
"o2_21.bin",
|
||||||
|
"o2_30.bin",
|
||||||
|
"o2_33.bin", // pag 12
|
||||||
|
"o2_35.bin",
|
||||||
|
"o2_38.bin",
|
||||||
|
"o2_39.bin",
|
||||||
|
"o2_40.bin",
|
||||||
|
"o2_41.bin",
|
||||||
|
"o2_43.bin",
|
||||||
|
"o2_45.bin",
|
||||||
|
"o2_46.bin", // pag 13
|
||||||
|
"o2_47.bin",
|
||||||
|
"o2_48.bin",
|
||||||
|
"o2_48alt.bin",
|
||||||
|
"pal_acrobats.bin",
|
||||||
|
"pal_flashpoint.bin",
|
||||||
|
"pal_nimble-numbers-ned.bin",
|
||||||
|
"pal_type-and-tell.bin",
|
||||||
|
"pb_frogger.bin", // pag 14
|
||||||
|
"pb_popeye.bin",
|
||||||
|
"pb_q-bert.bin",
|
||||||
|
"pb_super-cobra.bin",
|
||||||
|
"pr_clay-pigeon_pl.bin",
|
||||||
|
"pr_clay-pigeon_pl_alt.bin",
|
||||||
|
"pr_interpol.bin",
|
||||||
|
"pr_martian-threat.bin",
|
||||||
|
"pr_martian-threat_alt.bin", // pag 15
|
||||||
|
"pr_mission-impossible.bin",
|
||||||
|
"pr_nightfighter.bin",
|
||||||
|
"pr_pinball.bin",
|
||||||
|
"pr_playtag.bin",
|
||||||
|
"pr_red-baron.bin",
|
||||||
|
"pr_red-baron_alt.bin",
|
||||||
|
"pr_robot-city.bin",
|
||||||
|
"pr_shark-hunter.bin", // pag 16
|
||||||
|
"pr_spiderman.bin",
|
||||||
|
"pr_spiderman_alt.bin",
|
||||||
|
"pr_tutankham.bin",
|
||||||
|
"vp_01.bin",
|
||||||
|
"vp_01hack.bin",
|
||||||
|
"vp_01pl.bin",
|
||||||
|
"vp_02.bin",
|
||||||
|
"vp_03.bin", // pag 17
|
||||||
|
"vp_04.bin",
|
||||||
|
"vp_05.bin",
|
||||||
|
"vp_06.bin",
|
||||||
|
"vp_06pl.bin",
|
||||||
|
"vp_07.bin",
|
||||||
|
"vp_08.bin",
|
||||||
|
"vp_09.bin",
|
||||||
|
"vp_10.bin", // pag 18
|
||||||
|
"vp_11.bin",
|
||||||
|
"vp_11alt.bin",
|
||||||
|
"vp_11pl.bin",
|
||||||
|
"vp_12.bin",
|
||||||
|
"vp_13.bin",
|
||||||
|
"vp_14.bin",
|
||||||
|
"vp_15.bin",
|
||||||
|
"vp_16.bin", // pag 19
|
||||||
|
"vp_17.bin",
|
||||||
|
"vp_18.bin",
|
||||||
|
"vp_19.bin",
|
||||||
|
"vp_20.bin",
|
||||||
|
"vp_20pl.bin",
|
||||||
|
"vp_21.bin",
|
||||||
|
"vp_22.bin",
|
||||||
|
"vp_22hack.bin", // pag 20
|
||||||
|
"vp_23.bin",
|
||||||
|
"vp_24.bin",
|
||||||
|
"vp_24pl.bin",
|
||||||
|
"vp_25.bin",
|
||||||
|
"vp_26.bin",
|
||||||
|
"vp_27.bin",
|
||||||
|
"vp_28.bin",
|
||||||
|
"vp_29.bin", // pag 21
|
||||||
|
"vp_30.bin",
|
||||||
|
"vp_31.bin",
|
||||||
|
"vp_32.bin",
|
||||||
|
"vp_33.bin",
|
||||||
|
"vp_33alt.bin",
|
||||||
|
"vp_34.bin",
|
||||||
|
"vp_34pl.bin",
|
||||||
|
"vp_35.bin", // pag 22
|
||||||
|
"vp_35pl.bin",
|
||||||
|
"vp_36.bin",
|
||||||
|
"vp_37.bin",
|
||||||
|
"vp_38.bin",
|
||||||
|
"vp_39.bin",
|
||||||
|
"vp_39pl.bin",
|
||||||
|
"vp_40.bin",
|
||||||
|
"vp_41.bin", // pag 23
|
||||||
|
"vp_42.bin",
|
||||||
|
"vp_43.bin",
|
||||||
|
"vp_43pl.bin",
|
||||||
|
"vp_44.bin",
|
||||||
|
"vp_45.bin",
|
||||||
|
"vp_46.bin",
|
||||||
|
"vp_47.bin",
|
||||||
|
"vp_48.bin", // pag 24
|
||||||
|
"vp_49.bin",
|
||||||
|
"vp_50.bin",
|
||||||
|
"vp_51pl.bin",
|
||||||
|
"vp_52pl.bin",
|
||||||
|
"vp_53.bin",
|
||||||
|
"vp_53pl.bin",
|
||||||
|
"vp_54.bin",
|
||||||
|
"vp_54pl.bin", // pag 25
|
||||||
|
"vp_55.bin",
|
||||||
|
"vp_55_12.bin",
|
||||||
|
"vp_55_12fix.bin",
|
||||||
|
"vp_56pl.bin",
|
||||||
|
"vp_57.bin",
|
||||||
|
"vp_58_12.bin",
|
||||||
|
"vp_59_16.bin",
|
||||||
|
"vp_60_16.bin", // pag 26
|
||||||
|
};
|
||||||
|
|
153
VSC-PicoPAC/main.c
Normal file
153
VSC-PicoPAC/main.c
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "pico/time.h"
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
#include "picopac_cart.h"
|
||||||
|
#include "fatfs_disk.h"
|
||||||
|
|
||||||
|
//void cdc_task(void);
|
||||||
|
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// USB CDC
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
void cdc_task(void)
|
||||||
|
{
|
||||||
|
// connected() check for DTR bit
|
||||||
|
// Most but not all terminal client set this when making connection
|
||||||
|
// if ( tud_cdc_connected() )
|
||||||
|
{
|
||||||
|
// connected and there are data available
|
||||||
|
if ( tud_cdc_available() )
|
||||||
|
{
|
||||||
|
// read data
|
||||||
|
char buf[64];
|
||||||
|
uint32_t count = tud_cdc_read(buf, sizeof(buf));
|
||||||
|
(void) count;
|
||||||
|
|
||||||
|
// Echo back
|
||||||
|
// Note: Skip echo by commenting out write() and write_flush()
|
||||||
|
// for throughput test e.g
|
||||||
|
// $ dd if=/dev/zero of=/dev/ttyACM0 count=10000
|
||||||
|
tud_cdc_write(buf, count);
|
||||||
|
tud_cdc_write_flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when cdc when line state changed e.g connected/disconnected
|
||||||
|
void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
|
||||||
|
{
|
||||||
|
(void) itf;
|
||||||
|
(void) rts;
|
||||||
|
|
||||||
|
// TODO set some indicator
|
||||||
|
if ( dtr )
|
||||||
|
{
|
||||||
|
// Terminal connected
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// Terminal disconnected
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when CDC interface received data from host
|
||||||
|
void tud_cdc_rx_cb(uint8_t itf)
|
||||||
|
{
|
||||||
|
(void) itf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
tusb_init();
|
||||||
|
stdio_init_all(); // for serial output, via printf()
|
||||||
|
|
||||||
|
tud_init(BOARD_TUD_RHPORT);
|
||||||
|
gpio_init_mask(FLAG_MASK);
|
||||||
|
gpio_set_dir_in_masked(FLAG_MASK);
|
||||||
|
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||||
|
gpio_set_dir(PICO_DEFAULT_LED_PIN,true);
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN,true);
|
||||||
|
|
||||||
|
while(1) {
|
||||||
|
|
||||||
|
while (to_ms_since_boot(get_absolute_time()) < 200)
|
||||||
|
{
|
||||||
|
if (gpio_get(PSEN_PIN)==1)
|
||||||
|
picopac_cart_main();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// init device stack on configured roothub port
|
||||||
|
// we are presumably powered from USB
|
||||||
|
// enter USB mass storage mode
|
||||||
|
// tud_init(BOARD_TUD_RHPORT);
|
||||||
|
// stdio_init_all(); // for serial output, via printf()
|
||||||
|
// printf("Start\n");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
tud_task(); // tinyusb device task
|
||||||
|
|
||||||
|
cdc_task();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device callbacks
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// Invoked when device is mounted
|
||||||
|
void tud_mount_cb(void)
|
||||||
|
{
|
||||||
|
printf("Device mounted\n");
|
||||||
|
if (!mount_fatfs_disk())
|
||||||
|
create_fatfs_disk();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when device is unmounted
|
||||||
|
void tud_umount_cb(void)
|
||||||
|
{
|
||||||
|
printf("Device unmounted\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when usb bus is suspended
|
||||||
|
// remote_wakeup_en : if host allow us to perform remote wakeup
|
||||||
|
// Within 7ms, device must draw an average of current less than 2.5 mA from bus
|
||||||
|
void tud_suspend_cb(bool remote_wakeup_en)
|
||||||
|
{
|
||||||
|
(void) remote_wakeup_en;
|
||||||
|
// blink_interval_ms = BLINK_SUSPENDED;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when usb bus is resumed
|
||||||
|
void tud_resume_cb(void)
|
||||||
|
{
|
||||||
|
// blink_interval_ms = BLINK_MOUNTED;
|
||||||
|
}
|
||||||
|
|
252
VSC-PicoPAC/memmap_custom.ld
Normal file
252
VSC-PicoPAC/memmap_custom.ld
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
/* Based on GCC ARM embedded samples.
|
||||||
|
Defines the following symbols for use by code:
|
||||||
|
__exidx_start
|
||||||
|
__exidx_end
|
||||||
|
__etext
|
||||||
|
__data_start__
|
||||||
|
__preinit_array_start
|
||||||
|
__preinit_array_end
|
||||||
|
__init_array_start
|
||||||
|
__init_array_end
|
||||||
|
__fini_array_start
|
||||||
|
__fini_array_end
|
||||||
|
__data_end__
|
||||||
|
__bss_start__
|
||||||
|
__bss_end__
|
||||||
|
__end__
|
||||||
|
end
|
||||||
|
__HeapLimit
|
||||||
|
__StackLimit
|
||||||
|
__StackTop
|
||||||
|
__stack (== StackTop)
|
||||||
|
*/
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
FLASH(rx) : ORIGIN = 0x10000000, LENGTH = 2048k
|
||||||
|
RAM(rwx) : ORIGIN = 0x20000000, LENGTH = 256k
|
||||||
|
SCRATCH_X(rwx) : ORIGIN = 0x20040000, LENGTH = 4k
|
||||||
|
SCRATCH_Y(rwx) : ORIGIN = 0x20041000, LENGTH = 4k
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY(_entry_point)
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
/* Second stage bootloader is prepended to the image. It must be 256 bytes big
|
||||||
|
and checksummed. It is usually built by the boot_stage2 target
|
||||||
|
in the Raspberry Pi Pico SDK
|
||||||
|
*/
|
||||||
|
|
||||||
|
.flash_begin : {
|
||||||
|
__flash_binary_start = .;
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.boot2 : {
|
||||||
|
__boot2_start__ = .;
|
||||||
|
KEEP (*(.boot2))
|
||||||
|
__boot2_end__ = .;
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
ASSERT(__boot2_end__ - __boot2_start__ == 256,
|
||||||
|
"ERROR: Pico second stage bootloader must be 256 bytes in size")
|
||||||
|
|
||||||
|
/* The second stage will always enter the image at the start of .text.
|
||||||
|
The debugger will use the ELF entry point, which is the _entry_point
|
||||||
|
symbol if present, otherwise defaults to start of .text.
|
||||||
|
This can be used to transfer control back to the bootrom on debugger
|
||||||
|
launches only, to perform proper flash setup.
|
||||||
|
*/
|
||||||
|
|
||||||
|
.text : {
|
||||||
|
__logical_binary_start = .;
|
||||||
|
KEEP (*(.vectors))
|
||||||
|
KEEP (*(.binary_info_header))
|
||||||
|
__binary_info_header_end = .;
|
||||||
|
KEEP (*(.reset))
|
||||||
|
/* TODO revisit this now memset/memcpy/float in ROM */
|
||||||
|
/* bit of a hack right now to exclude all floating point and time critical (e.g. memset, memcpy) code from
|
||||||
|
* FLASH ... we will include any thing excluded here in .data below by default */
|
||||||
|
*(.init)
|
||||||
|
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .text*)
|
||||||
|
*(.fini)
|
||||||
|
/* Pull all c'tors into .text */
|
||||||
|
*crtbegin.o(.ctors)
|
||||||
|
*crtbegin?.o(.ctors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)
|
||||||
|
*(SORT(.ctors.*))
|
||||||
|
*(.ctors)
|
||||||
|
/* Followed by destructors */
|
||||||
|
*crtbegin.o(.dtors)
|
||||||
|
*crtbegin?.o(.dtors)
|
||||||
|
*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)
|
||||||
|
*(SORT(.dtors.*))
|
||||||
|
*(.dtors)
|
||||||
|
|
||||||
|
*(.eh_frame*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.rodata : {
|
||||||
|
*(EXCLUDE_FILE(*libgcc.a: *libc.a:*lib_a-mem*.o *libm.a:) .rodata*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.flashdata*)))
|
||||||
|
. = ALIGN(4);
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
.ARM.extab :
|
||||||
|
{
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
__exidx_start = .;
|
||||||
|
.ARM.exidx :
|
||||||
|
{
|
||||||
|
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||||
|
} > FLASH
|
||||||
|
__exidx_end = .;
|
||||||
|
|
||||||
|
/* Machine inspectable binary information */
|
||||||
|
. = ALIGN(4);
|
||||||
|
__binary_info_start = .;
|
||||||
|
.binary_info :
|
||||||
|
{
|
||||||
|
KEEP(*(.binary_info.keep.*))
|
||||||
|
*(.binary_info.*)
|
||||||
|
} > FLASH
|
||||||
|
__binary_info_end = .;
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
/* End of .text-like segments */
|
||||||
|
__etext = .;
|
||||||
|
|
||||||
|
.ram_vector_table (COPY): {
|
||||||
|
*(.ram_vector_table)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.data : {
|
||||||
|
__data_start__ = .;
|
||||||
|
*(vtable)
|
||||||
|
|
||||||
|
*(.time_critical*)
|
||||||
|
|
||||||
|
/* remaining .text and .rodata; i.e. stuff we exclude above because we want it in RAM */
|
||||||
|
*(.text*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.rodata*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
|
||||||
|
*(.data*)
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.after_data.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__mutex_array_start = .);
|
||||||
|
KEEP(*(SORT(.mutex_array.*)))
|
||||||
|
KEEP(*(.mutex_array))
|
||||||
|
PROVIDE_HIDDEN (__mutex_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* preinit data */
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_start = .);
|
||||||
|
KEEP(*(SORT(.preinit_array.*)))
|
||||||
|
KEEP(*(.preinit_array))
|
||||||
|
PROVIDE_HIDDEN (__preinit_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* init data */
|
||||||
|
PROVIDE_HIDDEN (__init_array_start = .);
|
||||||
|
KEEP(*(SORT(.init_array.*)))
|
||||||
|
KEEP(*(.init_array))
|
||||||
|
PROVIDE_HIDDEN (__init_array_end = .);
|
||||||
|
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* finit data */
|
||||||
|
PROVIDE_HIDDEN (__fini_array_start = .);
|
||||||
|
*(SORT(.fini_array.*))
|
||||||
|
*(.fini_array)
|
||||||
|
PROVIDE_HIDDEN (__fini_array_end = .);
|
||||||
|
|
||||||
|
*(.jcr)
|
||||||
|
. = ALIGN(4);
|
||||||
|
/* All data end */
|
||||||
|
__data_end__ = .;
|
||||||
|
} > RAM AT> FLASH
|
||||||
|
|
||||||
|
.uninitialized_data (COPY): {
|
||||||
|
. = ALIGN(4);
|
||||||
|
*(.uninitialized_data*)
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* Start and end symbols must be word-aligned */
|
||||||
|
.scratch_x : {
|
||||||
|
__scratch_x_start__ = .;
|
||||||
|
*(.scratch_x.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__scratch_x_end__ = .;
|
||||||
|
} > SCRATCH_X AT > FLASH
|
||||||
|
__scratch_x_source__ = LOADADDR(.scratch_x);
|
||||||
|
|
||||||
|
.scratch_y : {
|
||||||
|
__scratch_y_start__ = .;
|
||||||
|
*(.scratch_y.*)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__scratch_y_end__ = .;
|
||||||
|
} > SCRATCH_Y AT > FLASH
|
||||||
|
__scratch_y_source__ = LOADADDR(.scratch_y);
|
||||||
|
|
||||||
|
.bss : {
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_start__ = .;
|
||||||
|
*(SORT_BY_ALIGNMENT(SORT_BY_NAME(.bss*)))
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN(4);
|
||||||
|
__bss_end__ = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
.heap (COPY):
|
||||||
|
{
|
||||||
|
__end__ = .;
|
||||||
|
end = __end__;
|
||||||
|
*(.heap*)
|
||||||
|
__HeapLimit = .;
|
||||||
|
} > RAM
|
||||||
|
|
||||||
|
/* .stack*_dummy section doesn't contains any symbols. It is only
|
||||||
|
* used for linker to calculate size of stack sections, and assign
|
||||||
|
* values to stack symbols later
|
||||||
|
*
|
||||||
|
* stack1 section may be empty/missing if platform_launch_core1 is not used */
|
||||||
|
|
||||||
|
/* by default we put core 0 stack at the end of scratch Y, so that if core 1
|
||||||
|
* stack is not used then all of SCRATCH_X is free.
|
||||||
|
*/
|
||||||
|
.stack1_dummy (COPY):
|
||||||
|
{
|
||||||
|
*(.stack1*)
|
||||||
|
} > SCRATCH_X
|
||||||
|
.stack_dummy (COPY):
|
||||||
|
{
|
||||||
|
*(.stack*)
|
||||||
|
} > SCRATCH_Y
|
||||||
|
|
||||||
|
.flash_end : {
|
||||||
|
__flash_binary_end = .;
|
||||||
|
} > FLASH
|
||||||
|
|
||||||
|
/* stack limit is poorly named, but historically is maximum heap ptr */
|
||||||
|
__StackLimit = ORIGIN(RAM) + LENGTH(RAM);
|
||||||
|
__StackOneTop = ORIGIN(SCRATCH_X) + LENGTH(SCRATCH_X);
|
||||||
|
__StackTop = ORIGIN(SCRATCH_Y) + LENGTH(SCRATCH_Y);
|
||||||
|
__StackOneBottom = __StackOneTop - SIZEOF(.stack1_dummy);
|
||||||
|
__StackBottom = __StackTop - SIZEOF(.stack_dummy);
|
||||||
|
PROVIDE(__stack = __StackTop);
|
||||||
|
|
||||||
|
/* Check if data + heap + stack exceeds RAM limit */
|
||||||
|
ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed")
|
||||||
|
|
||||||
|
ASSERT( __binary_info_header_end - __logical_binary_start <= 256, "Binary info must be in first 256 bytes of the binary")
|
||||||
|
/* todo assert on extra code */
|
||||||
|
}
|
||||||
|
|
176
VSC-PicoPAC/msc_disk.c
Normal file
176
VSC-PicoPAC/msc_disk.c
Normal file
@ -0,0 +1,176 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
#include "fatfs_disk.h"
|
||||||
|
|
||||||
|
// whether host does safe-eject
|
||||||
|
static bool ejected = false;
|
||||||
|
|
||||||
|
|
||||||
|
// Invoked when received SCSI_CMD_INQUIRY
|
||||||
|
// Application fill vendor id, product id and revision with string up to 8, 16, 4 characters respectively
|
||||||
|
void tud_msc_inquiry_cb(uint8_t lun, uint8_t vendor_id[8], uint8_t product_id[16], uint8_t product_rev[4])
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
const char vid[] = "PicoCart";
|
||||||
|
const char pid[] = "Mass Storage";
|
||||||
|
const char rev[] = "1.0";
|
||||||
|
|
||||||
|
memcpy(vendor_id , vid, strlen(vid));
|
||||||
|
memcpy(product_id , pid, strlen(pid));
|
||||||
|
memcpy(product_rev, rev, strlen(rev));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received Test Unit Ready command.
|
||||||
|
// return true allowing host to read/write this LUN e.g SD card inserted
|
||||||
|
bool tud_msc_test_unit_ready_cb(uint8_t lun)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
// RAM disk is ready until ejected
|
||||||
|
if (ejected) {
|
||||||
|
// Additional Sense 3A-00 is NOT_FOUND
|
||||||
|
tud_msc_set_sense(lun, SCSI_SENSE_NOT_READY, 0x3a, 0x00);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received SCSI_CMD_READ_CAPACITY_10 and SCSI_CMD_READ_FORMAT_CAPACITY to determine the disk size
|
||||||
|
// Application update block count and block size
|
||||||
|
void tud_msc_capacity_cb(uint8_t lun, uint32_t* block_count, uint16_t* block_size)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
*block_count = SECTOR_NUM;
|
||||||
|
*block_size = SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received Start Stop Unit command
|
||||||
|
// - Start = 0 : stopped power mode, if load_eject = 1 : unload disk storage
|
||||||
|
// - Start = 1 : active mode, if load_eject = 1 : load disk storage
|
||||||
|
bool tud_msc_start_stop_cb(uint8_t lun, uint8_t power_condition, bool start, bool load_eject)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
(void) power_condition;
|
||||||
|
|
||||||
|
if ( load_eject )
|
||||||
|
{
|
||||||
|
if (start)
|
||||||
|
{
|
||||||
|
// load disk storage
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// unload disk storage
|
||||||
|
ejected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback invoked when received READ10 command.
|
||||||
|
// Copy disk's data to buffer (up to bufsize) and return number of copied bytes.
|
||||||
|
int32_t tud_msc_read10_cb(uint8_t lun, uint32_t lba, uint32_t offset, void* buffer, uint32_t bufsize)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
if(offset != 0) return -1;
|
||||||
|
if(bufsize != SECTOR_SIZE) return -1;
|
||||||
|
|
||||||
|
uint32_t status = fatfs_disk_read(buffer, lba, 1);
|
||||||
|
if(status != 0) return -1;
|
||||||
|
return (int32_t) bufsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool tud_msc_is_writable_cb (uint8_t lun)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback invoked when received WRITE10 command.
|
||||||
|
// Process data in buffer to disk's storage and return number of written bytes
|
||||||
|
alarm_id_t alarm_id = -1;
|
||||||
|
int64_t sync_callback(alarm_id_t id, void *user_data)
|
||||||
|
{
|
||||||
|
fatfs_disk_sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tud_msc_write10_cb(uint8_t lun, uint32_t lba, uint32_t offset, uint8_t* buffer, uint32_t bufsize)
|
||||||
|
{
|
||||||
|
(void) lun;
|
||||||
|
|
||||||
|
if(offset != 0) return -1;
|
||||||
|
if(bufsize != SECTOR_SIZE) return -1;
|
||||||
|
|
||||||
|
uint32_t status = fatfs_disk_write(buffer, lba, 1);
|
||||||
|
|
||||||
|
// we need to sync the flash but only do it when activity dies down :-)
|
||||||
|
if(alarm_id >= 0)
|
||||||
|
cancel_alarm(alarm_id);
|
||||||
|
alarm_id = add_alarm_in_ms(250, sync_callback, NULL, false);
|
||||||
|
|
||||||
|
if(status != 0) return -1;
|
||||||
|
return (int32_t) bufsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Callback invoked when received an SCSI command not in built-in list below
|
||||||
|
// - READ_CAPACITY10, READ_FORMAT_CAPACITY, INQUIRY, MODE_SENSE6, REQUEST_SENSE
|
||||||
|
// - READ10 and WRITE10 has their own callbacks
|
||||||
|
int32_t tud_msc_scsi_cb (uint8_t lun, uint8_t const scsi_cmd[16], void* buffer, uint16_t bufsize)
|
||||||
|
{
|
||||||
|
// read10 & write10 has their own callback and MUST not be handled here
|
||||||
|
|
||||||
|
void const* response = NULL;
|
||||||
|
int32_t resplen = 0;
|
||||||
|
|
||||||
|
// most scsi handled is input
|
||||||
|
bool in_xfer = true;
|
||||||
|
|
||||||
|
switch (scsi_cmd[0])
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
// Set Sense = Invalid Command Operation
|
||||||
|
tud_msc_set_sense(lun, SCSI_SENSE_ILLEGAL_REQUEST, 0x20, 0x00);
|
||||||
|
|
||||||
|
// negative means error -> tinyusb could stall and/or response with failed status
|
||||||
|
resplen = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return resplen must not larger than bufsize
|
||||||
|
if ( resplen > bufsize ) resplen = bufsize;
|
||||||
|
|
||||||
|
if ( response && (resplen > 0) )
|
||||||
|
{
|
||||||
|
if(in_xfer)
|
||||||
|
{
|
||||||
|
memcpy(buffer, response, (size_t) resplen);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// SCSI output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (int32_t) resplen;
|
||||||
|
}
|
9
VSC-PicoPAC/myboard.h
Normal file
9
VSC-PicoPAC/myboard.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
// myboard.h
|
||||||
|
|
||||||
|
// setting first overrides the value in the default header
|
||||||
|
|
||||||
|
//#define PICO_FLASH_SPI_CLKDIV 2 // use for winbond flash
|
||||||
|
#define PICO_FLASH_SPI_CLKDIV 4 // use for slower flash (e.g. zbit)
|
||||||
|
|
||||||
|
// pick up the rest of the settings
|
||||||
|
#include "boards/pico.h"
|
73
VSC-PicoPAC/pico_sdk_import.cmake
Normal file
73
VSC-PicoPAC/pico_sdk_import.cmake
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
# This is a copy of <PICO_SDK_PATH>/external/pico_sdk_import.cmake
|
||||||
|
|
||||||
|
# This can be dropped into an external project to help locate this SDK
|
||||||
|
# It should be include()ed prior to project()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_PATH} AND (NOT PICO_SDK_PATH))
|
||||||
|
set(PICO_SDK_PATH $ENV{PICO_SDK_PATH})
|
||||||
|
message("Using PICO_SDK_PATH from environment ('${PICO_SDK_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT} AND (NOT PICO_SDK_FETCH_FROM_GIT))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT $ENV{PICO_SDK_FETCH_FROM_GIT})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT from environment ('${PICO_SDK_FETCH_FROM_GIT}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (DEFINED ENV{PICO_SDK_FETCH_FROM_GIT_PATH} AND (NOT PICO_SDK_FETCH_FROM_GIT_PATH))
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_PATH $ENV{PICO_SDK_FETCH_FROM_GIT_PATH})
|
||||||
|
message("Using PICO_SDK_FETCH_FROM_GIT_PATH from environment ('${PICO_SDK_FETCH_FROM_GIT_PATH}')")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH "${PICO_SDK_PATH}" CACHE PATH "Path to the Raspberry Pi Pico SDK")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT "${PICO_SDK_FETCH_FROM_GIT}" CACHE BOOL "Set to ON to fetch copy of SDK from git if not otherwise locatable")
|
||||||
|
set(PICO_SDK_FETCH_FROM_GIT_PATH "${PICO_SDK_FETCH_FROM_GIT_PATH}" CACHE FILEPATH "location to download SDK")
|
||||||
|
|
||||||
|
if (NOT PICO_SDK_PATH)
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT)
|
||||||
|
include(FetchContent)
|
||||||
|
set(FETCHCONTENT_BASE_DIR_SAVE ${FETCHCONTENT_BASE_DIR})
|
||||||
|
if (PICO_SDK_FETCH_FROM_GIT_PATH)
|
||||||
|
get_filename_component(FETCHCONTENT_BASE_DIR "${PICO_SDK_FETCH_FROM_GIT_PATH}" REALPATH BASE_DIR "${CMAKE_SOURCE_DIR}")
|
||||||
|
endif ()
|
||||||
|
# GIT_SUBMODULES_RECURSE was added in 3.17
|
||||||
|
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.17.0")
|
||||||
|
FetchContent_Declare(
|
||||||
|
pico_sdk
|
||||||
|
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||||
|
GIT_TAG master
|
||||||
|
GIT_SUBMODULES_RECURSE FALSE
|
||||||
|
)
|
||||||
|
else ()
|
||||||
|
FetchContent_Declare(
|
||||||
|
pico_sdk
|
||||||
|
GIT_REPOSITORY https://github.com/raspberrypi/pico-sdk
|
||||||
|
GIT_TAG master
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
if (NOT pico_sdk)
|
||||||
|
message("Downloading Raspberry Pi Pico SDK")
|
||||||
|
FetchContent_Populate(pico_sdk)
|
||||||
|
set(PICO_SDK_PATH ${pico_sdk_SOURCE_DIR})
|
||||||
|
endif ()
|
||||||
|
set(FETCHCONTENT_BASE_DIR ${FETCHCONTENT_BASE_DIR_SAVE})
|
||||||
|
else ()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"SDK location was not specified. Please set PICO_SDK_PATH or set PICO_SDK_FETCH_FROM_GIT to on to fetch from git."
|
||||||
|
)
|
||||||
|
endif ()
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
get_filename_component(PICO_SDK_PATH "${PICO_SDK_PATH}" REALPATH BASE_DIR "${CMAKE_BINARY_DIR}")
|
||||||
|
if (NOT EXISTS ${PICO_SDK_PATH})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' not found")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_INIT_CMAKE_FILE ${PICO_SDK_PATH}/pico_sdk_init.cmake)
|
||||||
|
if (NOT EXISTS ${PICO_SDK_INIT_CMAKE_FILE})
|
||||||
|
message(FATAL_ERROR "Directory '${PICO_SDK_PATH}' does not appear to contain the Raspberry Pi Pico SDK")
|
||||||
|
endif ()
|
||||||
|
|
||||||
|
set(PICO_SDK_PATH ${PICO_SDK_PATH} CACHE PATH "Path to the Raspberry Pi Pico SDK" FORCE)
|
||||||
|
|
||||||
|
include(${PICO_SDK_INIT_CMAKE_FILE})
|
656
VSC-PicoPAC/picopac_cart.c
Normal file
656
VSC-PicoPAC/picopac_cart.c
Normal file
@ -0,0 +1,656 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "pico/multicore.h"
|
||||||
|
#include "hardware/gpio.h"
|
||||||
|
#include "pico/platform.h"
|
||||||
|
#include "pico/stdlib.h"
|
||||||
|
#include "hardware/vreg.h"
|
||||||
|
#include "pico/divider.h"
|
||||||
|
#include "hardware/flash.h"
|
||||||
|
#include "hardware/sync.h"
|
||||||
|
|
||||||
|
|
||||||
|
#include "gamelist.h"
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
#include "ff.h"
|
||||||
|
#include "fatfs_disk.h"
|
||||||
|
|
||||||
|
// Pico pin usage definitions
|
||||||
|
|
||||||
|
#define A0_PIN 0
|
||||||
|
#define A1_PIN 1
|
||||||
|
#define A2_PIN 2
|
||||||
|
#define A3_PIN 3
|
||||||
|
#define A4_PIN 4
|
||||||
|
#define A5_PIN 5
|
||||||
|
#define A6_PIN 6
|
||||||
|
#define A7_PIN 7
|
||||||
|
#define A8_PIN 8
|
||||||
|
#define A9_PIN 9
|
||||||
|
#define A10_PIN 10
|
||||||
|
#define A11_PIN 11
|
||||||
|
#define P11_PIN 12
|
||||||
|
#define P10_PIN 13
|
||||||
|
#define D0_PIN 14
|
||||||
|
#define D1_PIN 15
|
||||||
|
#define D2_PIN 16
|
||||||
|
#define D3_PIN 17
|
||||||
|
#define D4_PIN 18
|
||||||
|
#define D5_PIN 19
|
||||||
|
#define D6_PIN 20
|
||||||
|
#define D7_PIN 21
|
||||||
|
#define PSEN_PIN 22
|
||||||
|
#define WR_PIN 23
|
||||||
|
#define CS_PIN 24 // P14
|
||||||
|
#define LED_PIN 25
|
||||||
|
#define NOTCS_PIN 26
|
||||||
|
#define TD_PIN 27
|
||||||
|
|
||||||
|
// Pico pin usage masks
|
||||||
|
#define A0_PIN_MASK 0x00000001L //gpio 0
|
||||||
|
#define A1_PIN_MASK 0x00000002L
|
||||||
|
#define A2_PIN_MASK 0x00000004L
|
||||||
|
#define A3_PIN_MASK 0x00000008L
|
||||||
|
#define A4_PIN_MASK 0x00000010L
|
||||||
|
#define A5_PIN_MASK 0x00000020L
|
||||||
|
#define A6_PIN_MASK 0x00000040L
|
||||||
|
#define A7_PIN_MASK 0x00000080L
|
||||||
|
#define A8_PIN_MASK 0x00000100L
|
||||||
|
#define A9_PIN_MASK 0x00000200L
|
||||||
|
#define A10_PIN_MASK 0x00000400L
|
||||||
|
#define A11_PIN_MASK 0x00000800L
|
||||||
|
#define P11_PIN_MASK 0x00001000L // P11 high bank select
|
||||||
|
#define P10_PIN_MASK 0x00002000L // P10 low bank select
|
||||||
|
#define D0_PIN_MASK 0x00004000L //gpio 14
|
||||||
|
#define D1_PIN_MASK 0x00008000L
|
||||||
|
#define D2_PIN_MASK 0x00010000L
|
||||||
|
#define D3_PIN_MASK 0x00020000L
|
||||||
|
#define D4_PIN_MASK 0x00040000L
|
||||||
|
#define D5_PIN_MASK 0x00080000L // gpio 19
|
||||||
|
#define D6_PIN_MASK 0x00100000L
|
||||||
|
#define D7_PIN_MASK 0x00200000L
|
||||||
|
#define PSEN_PIN_MASK 0x00400000L //gpio 22
|
||||||
|
#define WR_PIN_MASK 0x00800000L //gpio 23
|
||||||
|
#define CS_PIN_MASK 0x01000000L //gpio 24 - P14
|
||||||
|
#define LED_PIN_MASK 0x02000000L //gpio 25
|
||||||
|
#define NOTCS_PIN_MASK 0x04000000L //gpio 26
|
||||||
|
#define TD_PIN_MASK 0x08000000L //gpio 27
|
||||||
|
|
||||||
|
// Aggregate Pico pin usage masks
|
||||||
|
#define ALL_GPIO_MASK 0x0FFFFFFFL
|
||||||
|
#define BUS_PIN_MASK 0x00003FFFL
|
||||||
|
#define BANK_PIN_MASK 0x00003000L
|
||||||
|
#define DATA_PIN_MASK 0x003FC000L
|
||||||
|
#define FLAG_MASK 0x0FC00000L
|
||||||
|
#define ALWAYS_IN_MASK (BUS_PIN_MASK | FLAG_MASK)
|
||||||
|
#define ALWAYS_OUT_MASK (DATA_PIN_MASK )
|
||||||
|
|
||||||
|
#define SET_DATA_MODE_OUT gpio_set_dir_out_masked(DATA_PIN_MASK)
|
||||||
|
#define SET_DATA_MODE_IN gpio_set_dir_in_masked(DATA_PIN_MASK)
|
||||||
|
#define SET_LED_ON gpio_init(PICO_DEFAULT_LED_PIN);(PICO_DEFAULT_LED_PIN,GPIO_OUT);gpio_put(PICO_DEFAULT_LED_PIN,true);
|
||||||
|
#define SET_LED_OFF gpio_init(PICO_DEFAULT_LED_PIN);gpio_set_dir(PICO_DEFAULT_LED_PIN,GPIO_OUT);gpio_put(PICO_DEFAULT_LED_PIN,false);
|
||||||
|
|
||||||
|
// We're going to erase and reprogram a region 256k from the start of flash.
|
||||||
|
// Once done, we can access this at XIP_BASE + 256k.
|
||||||
|
|
||||||
|
|
||||||
|
char RBLo,RBHi;
|
||||||
|
#define BINLENGTH 1024*128+1
|
||||||
|
unsigned char rom_table[8][4096];
|
||||||
|
unsigned char new_rom_table[8][4096];
|
||||||
|
unsigned char extROM[1024];
|
||||||
|
unsigned char RAM[1024];
|
||||||
|
unsigned char files[256*100] = {0};
|
||||||
|
unsigned char nomefiles[32*25] = {0};
|
||||||
|
char curPath[256] = "";
|
||||||
|
char path[256];
|
||||||
|
int fileda=0,filea=0;
|
||||||
|
volatile char cmd=0;
|
||||||
|
char errorBuf[40];
|
||||||
|
bool cmd_executing;
|
||||||
|
volatile int bankswitch;
|
||||||
|
int bksw=0;
|
||||||
|
int romsize;
|
||||||
|
int lastpos;
|
||||||
|
volatile u_int8_t bank_type=1;
|
||||||
|
volatile u_int8_t new_bank_type=1;
|
||||||
|
volatile char gamechoosen=0;
|
||||||
|
volatile char newgame=0;
|
||||||
|
char extram[0xff];
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Error(N)
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
void error(int numblink){
|
||||||
|
multicore_lockout_start_blocking();
|
||||||
|
gpio_init(PICO_DEFAULT_LED_PIN);
|
||||||
|
gpio_set_dir(PICO_DEFAULT_LED_PIN,GPIO_OUT);
|
||||||
|
while(1){
|
||||||
|
|
||||||
|
for(int i=0;i<numblink;i++) {
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN,true);
|
||||||
|
sleep_ms(600);
|
||||||
|
gpio_put(PICO_DEFAULT_LED_PIN,false);
|
||||||
|
sleep_ms(500);
|
||||||
|
}
|
||||||
|
sleep_ms(2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Theory of Operation
|
||||||
|
-------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize ("O3")
|
||||||
|
|
||||||
|
void __not_in_flash_func(core1_main()) {
|
||||||
|
uint32_t addr;
|
||||||
|
char dataWrite=0;
|
||||||
|
uint32_t pins;
|
||||||
|
u_int8_t bank=0;
|
||||||
|
u_int8_t romlatch=0;
|
||||||
|
|
||||||
|
multicore_lockout_victim_init();
|
||||||
|
|
||||||
|
//gpio_set_dir_in_masked(ALWAYS_IN_MASK);
|
||||||
|
|
||||||
|
newgame=0;
|
||||||
|
|
||||||
|
// Initial conditions
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
while(newgame==0) {
|
||||||
|
pins=gpio_get_all();
|
||||||
|
addr = (pins & 0b0111111111111);
|
||||||
|
if((gpio_get(CS_PIN)==0) && (gpio_get(WR_PIN)==0)) {
|
||||||
|
extram[addr & 0xff]=((pins & DATA_PIN_MASK)>>D0_PIN);
|
||||||
|
if (extram[0x7e]==0x0a) {
|
||||||
|
gamechoosen=extram[0x7f];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bank=3-((gpio_get(P10_PIN)+(gpio_get(P11_PIN)*2)));
|
||||||
|
|
||||||
|
if (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,(rom_table[bank][addr])<<D0_PIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
|
||||||
|
switch (new_bank_type) {
|
||||||
|
case 0: // standard 2k / 4k
|
||||||
|
while(1) {
|
||||||
|
pins=gpio_get_all();
|
||||||
|
addr = (pins & 0b0111111111111);
|
||||||
|
if (gpio_get(P10_PIN)) {
|
||||||
|
bank=0;
|
||||||
|
} else {
|
||||||
|
bank=1;
|
||||||
|
}
|
||||||
|
if (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,(rom_table[bank][addr])<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1: // standard 8k
|
||||||
|
while(1) {
|
||||||
|
pins=gpio_get_all();
|
||||||
|
addr = (pins & 0b0111111111111);
|
||||||
|
bank=3-((gpio_get(P10_PIN)+(gpio_get(P11_PIN)*2)));
|
||||||
|
|
||||||
|
if (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,(rom_table[bank][addr])<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // XROM
|
||||||
|
while(1) {
|
||||||
|
pins=gpio_get_all();
|
||||||
|
addr = (pins & 0b0111111111111); // for all cart but xrom
|
||||||
|
if ((gpio_get(PSEN_PIN)==0 )) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,(rom_table[0][addr])<<D0_PIN);
|
||||||
|
}
|
||||||
|
if ((gpio_get(P11_PIN)==1 )) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,(extROM[addr])<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: // 12k/16k
|
||||||
|
while(1) {
|
||||||
|
pins=gpio_get_all();
|
||||||
|
addr = (pins & 0b0111111111111); // for all cart but xrom
|
||||||
|
if((gpio_get(CS_PIN)==0) && (gpio_get(WR_PIN)==0)) {
|
||||||
|
if ((addr & 0xff)>=0x80) {
|
||||||
|
romlatch=((~(pins & DATA_PIN_MASK)>>D0_PIN)&7);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (gpio_get(P10_PIN)==0) {
|
||||||
|
bank=romlatch;
|
||||||
|
} else {
|
||||||
|
bank=0;
|
||||||
|
}
|
||||||
|
if (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,(rom_table[bank][addr])<<D0_PIN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#pragma GCC pop_options
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// MENU Reset
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
|
||||||
|
//multicore_lockout_start_blocking();
|
||||||
|
|
||||||
|
while (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,0x84<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
while (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,0x00<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
|
||||||
|
sleep_ms(5);
|
||||||
|
|
||||||
|
while (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,0x84<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
while (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,0x00<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
|
||||||
|
while (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,0x84<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
while (gpio_get(PSEN_PIN)==0) {
|
||||||
|
SET_DATA_MODE_OUT;
|
||||||
|
gpio_put_masked(DATA_PIN_MASK,0x00<<D0_PIN);
|
||||||
|
}
|
||||||
|
SET_DATA_MODE_IN;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char isDir;
|
||||||
|
char filename[13];
|
||||||
|
char long_filename[32];
|
||||||
|
char full_path[210];
|
||||||
|
} DIR_ENTRY; // 256 bytes = 256 entries in 64k
|
||||||
|
|
||||||
|
int num_dir_entries = 0; // how many entries in the current directory
|
||||||
|
|
||||||
|
int entry_compare(const void* p1, const void* p2)
|
||||||
|
{
|
||||||
|
DIR_ENTRY* e1 = (DIR_ENTRY*)p1;
|
||||||
|
DIR_ENTRY* e2 = (DIR_ENTRY*)p2;
|
||||||
|
if (e1->isDir && !e2->isDir) return -1;
|
||||||
|
else if (!e1->isDir && e2->isDir) return 1;
|
||||||
|
else return strcasecmp(e1->long_filename, e2->long_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *get_filename_ext(char *filename) {
|
||||||
|
char *dot = strrchr(filename, '.');
|
||||||
|
if(!dot || dot == filename) return "";
|
||||||
|
return dot + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int is_valid_file(char *filename) {
|
||||||
|
char *ext = get_filename_ext(filename);
|
||||||
|
if (strcasecmp(ext, "BIN") == 0 || strcasecmp(ext, "ROM") == 0 || strcasecmp(ext, "CV") )
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILINFO fno;
|
||||||
|
char search_fname[FF_LFN_BUF + 1];
|
||||||
|
|
||||||
|
// polyfill :-)
|
||||||
|
char *stristr(const char *str, const char *strSearch) {
|
||||||
|
char *sors, *subs, *res = NULL;
|
||||||
|
if ((sors = strdup (str)) != NULL) {
|
||||||
|
if ((subs = strdup (strSearch)) != NULL) {
|
||||||
|
res = strstr (strlwr (sors), strlwr (subs));
|
||||||
|
if (res != NULL)
|
||||||
|
res = (char*)str + (res - sors);
|
||||||
|
free (subs);
|
||||||
|
}
|
||||||
|
free (sors);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int scan_files(char *path, char *search)
|
||||||
|
{
|
||||||
|
FRESULT res;
|
||||||
|
DIR dir;
|
||||||
|
UINT i;
|
||||||
|
|
||||||
|
res = f_opendir(&dir, path);
|
||||||
|
if (res == FR_OK) {
|
||||||
|
for (;;) {
|
||||||
|
if (num_dir_entries == 99) break;
|
||||||
|
res = f_readdir(&dir, &fno);
|
||||||
|
if (res != FR_OK || fno.fname[0] == 0) break;
|
||||||
|
if (fno.fattrib & (AM_HID | AM_SYS)) continue;
|
||||||
|
if (fno.fattrib & AM_DIR) {
|
||||||
|
i = strlen(path);
|
||||||
|
strcat(path, "/");
|
||||||
|
if (fno.altname[0]) // no altname when lfn is 8.3
|
||||||
|
strcat(path, fno.altname);
|
||||||
|
else
|
||||||
|
strcat(path, fno.fname);
|
||||||
|
if (strlen(path) >= 210) continue; // no more room for path in DIR_ENTRY
|
||||||
|
res = scan_files(path, search);
|
||||||
|
if (res != FR_OK) break;
|
||||||
|
path[i] = 0;
|
||||||
|
}
|
||||||
|
else if (is_valid_file(fno.fname))
|
||||||
|
{
|
||||||
|
char *match = stristr(fno.fname, search);
|
||||||
|
if (match) {
|
||||||
|
DIR_ENTRY *dst = (DIR_ENTRY *)&files[0];
|
||||||
|
dst += num_dir_entries;
|
||||||
|
// fill out a record
|
||||||
|
dst->isDir = (match == fno.fname) ? 1 : 0; // use this for a "score"
|
||||||
|
strncpy(dst->long_filename, fno.fname, 31);
|
||||||
|
dst->long_filename[31] = 0;
|
||||||
|
// 8.3 name
|
||||||
|
if (fno.altname[0])
|
||||||
|
strcpy(dst->filename, fno.altname);
|
||||||
|
else { // no altname when lfn is 8.3
|
||||||
|
strncpy(dst->filename, fno.fname, 12);
|
||||||
|
dst->filename[12] = 0;
|
||||||
|
}
|
||||||
|
// full path for search results
|
||||||
|
strcpy(dst->full_path, path);
|
||||||
|
|
||||||
|
num_dir_entries++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f_closedir(&dir);
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int search_directory(char *path, char *search) {
|
||||||
|
char pathBuf[256];
|
||||||
|
strcpy(pathBuf, path);
|
||||||
|
num_dir_entries = 0;
|
||||||
|
int i;
|
||||||
|
FATFS FatFs;
|
||||||
|
if (f_mount(&FatFs, "", 1) == FR_OK) {
|
||||||
|
if (scan_files(pathBuf, search) == FR_OK) {
|
||||||
|
// sort by score, name
|
||||||
|
qsort((DIR_ENTRY *)&files[0], num_dir_entries, sizeof(DIR_ENTRY), entry_compare);
|
||||||
|
DIR_ENTRY *dst = (DIR_ENTRY *)&files[0];
|
||||||
|
// re-set the pointer back to 0
|
||||||
|
for (i=0; i<num_dir_entries; i++)
|
||||||
|
dst[i].isDir = 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strcpy(errorBuf, "Problem searching flash");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int filesize(char *filename) {
|
||||||
|
if (!fatfs_is_mounted())
|
||||||
|
mount_fatfs_disk();
|
||||||
|
|
||||||
|
FATFS FatFs;
|
||||||
|
int car_file = 0;
|
||||||
|
UINT br = 0;
|
||||||
|
if (f_mount(&FatFs, "", 1) != FR_OK) {
|
||||||
|
error(1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
FIL fil;
|
||||||
|
if (f_open(&fil, filename, FA_READ) != FR_OK) {
|
||||||
|
sleep_ms(100);
|
||||||
|
error(2);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int byteslong = f_size(&fil);
|
||||||
|
romsize=byteslong;
|
||||||
|
|
||||||
|
closefile:
|
||||||
|
f_close(&fil);
|
||||||
|
cleanup:
|
||||||
|
f_mount(0, "", 1);
|
||||||
|
|
||||||
|
return byteslong;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* load file in ROM (rom_table) */
|
||||||
|
|
||||||
|
int load_file(char *filename) {
|
||||||
|
FATFS FatFs;
|
||||||
|
UINT br = 0;
|
||||||
|
UINT bw = 0;
|
||||||
|
int l,nb;
|
||||||
|
int k=0;
|
||||||
|
|
||||||
|
memset(rom_table,0,1024*8*4);
|
||||||
|
|
||||||
|
l=filesize(filename);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if (f_mount(&FatFs, "", 1) != FR_OK) {
|
||||||
|
error(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
nb = l/2048; // nb = number of banks, l=file size)
|
||||||
|
|
||||||
|
bank_type=0;
|
||||||
|
if (nb==4) bank_type=1;
|
||||||
|
if (nb>4) bank_type=3;
|
||||||
|
|
||||||
|
FIL fil;
|
||||||
|
if (f_open(&fil, filename, FA_READ) != FR_OK) {
|
||||||
|
error(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// read the file to flash RAM
|
||||||
|
|
||||||
|
for (int i = nb - 1; i >= 0; i--) {
|
||||||
|
if (f_read(&fil,&rom_table[i][1024], 2048, &br)!= FR_OK) {
|
||||||
|
error(3);
|
||||||
|
}
|
||||||
|
k=k+1;
|
||||||
|
memcpy(&rom_table[i][3072], &rom_table[i][2048], 1024); /* simulate missing A10 */
|
||||||
|
}
|
||||||
|
// mirror ROM in higher banks
|
||||||
|
if (nb<2) memcpy(&rom_table[1],&rom_table[0],4096);
|
||||||
|
if (nb<4) memcpy(&rom_table[2],&rom_table[0],8192);
|
||||||
|
|
||||||
|
closefile:
|
||||||
|
f_close(&fil);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
f_mount(0, "", 1);
|
||||||
|
|
||||||
|
return br;
|
||||||
|
}
|
||||||
|
|
||||||
|
int load_newfile(char *filename) {
|
||||||
|
FATFS FatFs;
|
||||||
|
UINT br = 0;
|
||||||
|
UINT bw = 0;
|
||||||
|
int l,nb;
|
||||||
|
int k=0;
|
||||||
|
|
||||||
|
memset(new_rom_table,0,1024*8*4);
|
||||||
|
|
||||||
|
l=filesize(filename);
|
||||||
|
|
||||||
|
if (f_mount(&FatFs, "", 1) != FR_OK) {
|
||||||
|
error(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
FIL fil;
|
||||||
|
if (f_open(&fil, filename, FA_READ) != FR_OK) {
|
||||||
|
error(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
nb = l/2048; // nb = number of banks, l=file size)
|
||||||
|
|
||||||
|
if ((strcmp(filename,"vp_40.bin")==0)||((strcmp(filename,"vp_31.bin")==0))) { // 3k games
|
||||||
|
if (f_read(&fil, &extROM[0], 1024, &br) != FR_OK) {
|
||||||
|
error(2);
|
||||||
|
}
|
||||||
|
if (f_read(&fil, &new_rom_table[0][1024], 3072, &br) != FR_OK) {
|
||||||
|
error(3);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
|
||||||
|
{
|
||||||
|
new_bank_type=0;
|
||||||
|
if (nb==4) new_bank_type=1;
|
||||||
|
if (nb>4) new_bank_type=3;
|
||||||
|
|
||||||
|
for (int i = nb - 1; i >= 0; i--) {
|
||||||
|
if (f_read(&fil,&new_rom_table[i][1024], 2048, &br)!= FR_OK) {
|
||||||
|
error(3);
|
||||||
|
}
|
||||||
|
k=k+1;
|
||||||
|
memcpy(&new_rom_table[i][3072], &new_rom_table[i][2048], 1024); /* simulate missing A10 */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// mirror ROM in higher banks
|
||||||
|
if (nb<2) memcpy(&new_rom_table[1],&new_rom_table[0],4096);
|
||||||
|
if (nb<4) memcpy(&new_rom_table[2],&new_rom_table[0],8192);
|
||||||
|
|
||||||
|
|
||||||
|
closefile:
|
||||||
|
f_close(&fil);
|
||||||
|
|
||||||
|
cleanup:
|
||||||
|
f_mount(0, "", 1);
|
||||||
|
|
||||||
|
return br;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// PicoPAC Cart Main
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void picopac_cart_main()
|
||||||
|
{
|
||||||
|
uint32_t pins;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t dataOut=0;
|
||||||
|
uint16_t dataWrite=0;
|
||||||
|
int ret=0;
|
||||||
|
|
||||||
|
int l, nb;
|
||||||
|
// overclocking isn't necessary for most functions - but XEGS carts weren't working without it
|
||||||
|
// I guess we might as well have it on all the time.
|
||||||
|
|
||||||
|
set_sys_clock_khz(270000, true);
|
||||||
|
//set_sys_clock_khz(170000, true);
|
||||||
|
|
||||||
|
|
||||||
|
gpio_init_mask(ALL_GPIO_MASK);
|
||||||
|
|
||||||
|
|
||||||
|
stdio_init_all(); // for serial output, via printf()
|
||||||
|
printf("Start\n");
|
||||||
|
|
||||||
|
|
||||||
|
sleep_ms(400);
|
||||||
|
|
||||||
|
multicore_launch_core1(core1_main);
|
||||||
|
sleep_ms(200);
|
||||||
|
|
||||||
|
load_file("/selectgame.bin");
|
||||||
|
//load_file("/pb_q-bert.bin");
|
||||||
|
|
||||||
|
memset(extram,0,0xff);
|
||||||
|
//load_file("/vp_38.bin");
|
||||||
|
//load_file("/vp_59_16.bin");
|
||||||
|
|
||||||
|
|
||||||
|
// Initial conditions
|
||||||
|
curPath[0]=0;
|
||||||
|
while (1) {
|
||||||
|
cmd_executing=false;
|
||||||
|
|
||||||
|
if ((gamechoosen>=1)) {
|
||||||
|
|
||||||
|
sleep_ms(1800);
|
||||||
|
|
||||||
|
load_newfile(gamelist[gamechoosen-1]);
|
||||||
|
//reset();
|
||||||
|
memcpy(rom_table,new_rom_table,1024*32);
|
||||||
|
|
||||||
|
newgame=1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
29
VSC-PicoPAC/picopac_cart.h
Normal file
29
VSC-PicoPAC/picopac_cart.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
// PicoPAC MultiCART by Andrea Ottaviani 2024
|
||||||
|
//
|
||||||
|
// VIDEOPAC multicart based on Raspberry Pico board -
|
||||||
|
//
|
||||||
|
// More info on https://github.com/aotta/
|
||||||
|
//
|
||||||
|
// parts of code are directly from the A8PicoCart project by Robin Edwards 2023
|
||||||
|
//
|
||||||
|
// Needs to be a release NOT debug build for the cartridge emulation to work
|
||||||
|
//
|
||||||
|
// Edit myboard.h depending on the type of flash memory on the pico clone//
|
||||||
|
//
|
||||||
|
// v. 1.0 2024-08-05 : Initial version for Pi Pico
|
||||||
|
//
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef __picopac_CART_H__
|
||||||
|
#define __picopac_CART_H__
|
||||||
|
|
||||||
|
#define FLAG_MASK 0x0FC00000L
|
||||||
|
#define PSEN_PIN 22
|
||||||
|
|
||||||
|
|
||||||
|
void picopac_cart_main();
|
||||||
|
|
||||||
|
#endif
|
114
VSC-PicoPAC/tusb_config.h
Normal file
114
VSC-PicoPAC/tusb_config.h
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TUSB_CONFIG_H_
|
||||||
|
#define _TUSB_CONFIG_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Board Specific Configuration
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// RHPort number used for device can be defined by board.mk, default to port 0
|
||||||
|
#ifndef BOARD_TUD_RHPORT
|
||||||
|
#define BOARD_TUD_RHPORT 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// RHPort max operational speed can defined by board.mk
|
||||||
|
#ifndef BOARD_TUD_MAX_SPEED
|
||||||
|
#define BOARD_TUD_MAX_SPEED OPT_MODE_DEFAULT_SPEED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// Common Configuration
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
// defined by compiler flags for flexibility
|
||||||
|
#ifndef CFG_TUSB_MCU
|
||||||
|
#error CFG_TUSB_MCU must be defined
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_OS
|
||||||
|
#define CFG_TUSB_OS OPT_OS_NONE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_DEBUG
|
||||||
|
#define CFG_TUSB_DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Enable Device stack
|
||||||
|
#define CFG_TUD_ENABLED 1
|
||||||
|
|
||||||
|
// Default is max speed that hardware controller could support with on-chip PHY
|
||||||
|
#define CFG_TUD_MAX_SPEED BOARD_TUD_MAX_SPEED
|
||||||
|
|
||||||
|
/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment.
|
||||||
|
* Tinyusb use follows macros to declare transferring memory so that they can be put
|
||||||
|
* into those specific section.
|
||||||
|
* e.g
|
||||||
|
* - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") ))
|
||||||
|
* - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4)))
|
||||||
|
*/
|
||||||
|
#ifndef CFG_TUSB_MEM_SECTION
|
||||||
|
#define CFG_TUSB_MEM_SECTION
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CFG_TUSB_MEM_ALIGN
|
||||||
|
#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4)))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
// DEVICE CONFIGURATION
|
||||||
|
//--------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef CFG_TUD_ENDPOINT0_SIZE
|
||||||
|
#define CFG_TUD_ENDPOINT0_SIZE 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//------------- CLASS -------------//
|
||||||
|
#define CFG_TUD_CDC 1
|
||||||
|
#define CFG_TUD_MSC 1
|
||||||
|
#define CFG_TUD_HID 0
|
||||||
|
#define CFG_TUD_MIDI 0
|
||||||
|
#define CFG_TUD_VENDOR 0
|
||||||
|
|
||||||
|
// CDC FIFO size of TX and RX
|
||||||
|
#define CFG_TUD_CDC_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||||
|
#define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||||
|
|
||||||
|
// CDC Endpoint transfer buffer size, more is faster
|
||||||
|
#define CFG_TUD_CDC_EP_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64)
|
||||||
|
|
||||||
|
// MSC Buffer size of Device Mass storage
|
||||||
|
#define CFG_TUD_MSC_EP_BUFSIZE 512
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _TUSB_CONFIG_H_ */
|
288
VSC-PicoPAC/usb_descriptors.c
Normal file
288
VSC-PicoPAC/usb_descriptors.c
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019 Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tusb.h"
|
||||||
|
|
||||||
|
/* A combination of interfaces must have a unique product id, since PC will save device driver after the first plug.
|
||||||
|
* Same VID/PID with different interface e.g MSC (first), then CDC (later) will possibly cause system error on PC.
|
||||||
|
*
|
||||||
|
* Auto ProductID layout's Bitmap:
|
||||||
|
* [MSB] HID | MSC | CDC [LSB]
|
||||||
|
*/
|
||||||
|
#define _PID_MAP(itf, n) ( (CFG_TUD_##itf) << (n) )
|
||||||
|
#define USB_PID (0x4000 | _PID_MAP(CDC, 0) | _PID_MAP(MSC, 1) | _PID_MAP(HID, 2) | \
|
||||||
|
_PID_MAP(MIDI, 3) | _PID_MAP(VENDOR, 4) )
|
||||||
|
|
||||||
|
#define USB_VID 0xCafe
|
||||||
|
#define USB_BCD 0x0200
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Device Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
tusb_desc_device_t const desc_device =
|
||||||
|
{
|
||||||
|
.bLength = sizeof(tusb_desc_device_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_DEVICE,
|
||||||
|
.bcdUSB = USB_BCD,
|
||||||
|
|
||||||
|
// Use Interface Association Descriptor (IAD) for CDC
|
||||||
|
// As required by USB Specs IAD's subclass must be common class (2) and protocol must be IAD (1)
|
||||||
|
.bDeviceClass = TUSB_CLASS_MISC,
|
||||||
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||||
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||||
|
|
||||||
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
|
||||||
|
.idVendor = USB_VID,
|
||||||
|
.idProduct = USB_PID,
|
||||||
|
.bcdDevice = 0x0100,
|
||||||
|
|
||||||
|
.iManufacturer = 0x01,
|
||||||
|
.iProduct = 0x02,
|
||||||
|
.iSerialNumber = 0x03,
|
||||||
|
|
||||||
|
.bNumConfigurations = 0x01
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET DEVICE DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
uint8_t const * tud_descriptor_device_cb(void)
|
||||||
|
{
|
||||||
|
return (uint8_t const *) &desc_device;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// Configuration Descriptor
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ITF_NUM_CDC = 0,
|
||||||
|
ITF_NUM_CDC_DATA,
|
||||||
|
ITF_NUM_MSC,
|
||||||
|
ITF_NUM_TOTAL
|
||||||
|
};
|
||||||
|
|
||||||
|
#if CFG_TUSB_MCU == OPT_MCU_LPC175X_6X || CFG_TUSB_MCU == OPT_MCU_LPC177X_8X || CFG_TUSB_MCU == OPT_MCU_LPC40XX
|
||||||
|
// LPC 17xx and 40xx endpoint type (bulk/interrupt/iso) are fixed by its number
|
||||||
|
// 0 control, 1 In, 2 Bulk, 3 Iso, 4 In, 5 Bulk etc ...
|
||||||
|
#define EPNUM_CDC_NOTIF 0x81
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x82
|
||||||
|
|
||||||
|
#define EPNUM_MSC_OUT 0x05
|
||||||
|
#define EPNUM_MSC_IN 0x85
|
||||||
|
|
||||||
|
#elif CFG_TUSB_MCU == OPT_MCU_SAMG || CFG_TUSB_MCU == OPT_MCU_SAMX7X
|
||||||
|
// SAMG & SAME70 don't support a same endpoint number with different direction IN and OUT
|
||||||
|
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||||
|
#define EPNUM_CDC_NOTIF 0x81
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x83
|
||||||
|
|
||||||
|
#define EPNUM_MSC_OUT 0x04
|
||||||
|
#define EPNUM_MSC_IN 0x85
|
||||||
|
|
||||||
|
#elif CFG_TUSB_MCU == OPT_MCU_CXD56
|
||||||
|
// CXD56 doesn't support a same endpoint number with different direction IN and OUT
|
||||||
|
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||||
|
// CXD56 USB driver has fixed endpoint type (bulk/interrupt/iso) and direction (IN/OUT) by its number
|
||||||
|
// 0 control (IN/OUT), 1 Bulk (IN), 2 Bulk (OUT), 3 In (IN), 4 Bulk (IN), 5 Bulk (OUT), 6 In (IN)
|
||||||
|
#define EPNUM_CDC_NOTIF 0x83
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x81
|
||||||
|
|
||||||
|
#define EPNUM_MSC_OUT 0x05
|
||||||
|
#define EPNUM_MSC_IN 0x84
|
||||||
|
|
||||||
|
#elif CFG_TUSB_MCU == OPT_MCU_FT90X || CFG_TUSB_MCU == OPT_MCU_FT93X
|
||||||
|
// FT9XX doesn't support a same endpoint number with different direction IN and OUT
|
||||||
|
// e.g EP1 OUT & EP1 IN cannot exist together
|
||||||
|
#define EPNUM_CDC_NOTIF 0x81
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x83
|
||||||
|
|
||||||
|
#define EPNUM_MSC_OUT 0x04
|
||||||
|
#define EPNUM_MSC_IN 0x85
|
||||||
|
|
||||||
|
#else
|
||||||
|
#define EPNUM_CDC_NOTIF 0x81
|
||||||
|
#define EPNUM_CDC_OUT 0x02
|
||||||
|
#define EPNUM_CDC_IN 0x82
|
||||||
|
|
||||||
|
#define EPNUM_MSC_OUT 0x03
|
||||||
|
#define EPNUM_MSC_IN 0x83
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + TUD_MSC_DESC_LEN)
|
||||||
|
|
||||||
|
// full speed configuration
|
||||||
|
uint8_t const desc_fs_configuration[] =
|
||||||
|
{
|
||||||
|
// Config number, interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||||
|
|
||||||
|
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
|
||||||
|
|
||||||
|
// Interface number, string index, EP Out & EP In address, EP size
|
||||||
|
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 64),
|
||||||
|
};
|
||||||
|
|
||||||
|
#if TUD_OPT_HIGH_SPEED
|
||||||
|
// Per USB specs: high speed capable device must report device_qualifier and other_speed_configuration
|
||||||
|
|
||||||
|
// high speed configuration
|
||||||
|
uint8_t const desc_hs_configuration[] =
|
||||||
|
{
|
||||||
|
// Config number, interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
|
||||||
|
|
||||||
|
// Interface number, string index, EP notification address and size, EP data address (out, in) and size.
|
||||||
|
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 512),
|
||||||
|
|
||||||
|
// Interface number, string index, EP Out & EP In address, EP size
|
||||||
|
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC_OUT, EPNUM_MSC_IN, 512),
|
||||||
|
};
|
||||||
|
|
||||||
|
// other speed configuration
|
||||||
|
uint8_t desc_other_speed_config[CONFIG_TOTAL_LEN];
|
||||||
|
|
||||||
|
// device qualifier is mostly similar to device descriptor since we don't change configuration based on speed
|
||||||
|
tusb_desc_device_qualifier_t const desc_device_qualifier =
|
||||||
|
{
|
||||||
|
.bLength = sizeof(tusb_desc_device_qualifier_t),
|
||||||
|
.bDescriptorType = TUSB_DESC_DEVICE_QUALIFIER,
|
||||||
|
.bcdUSB = USB_BCD,
|
||||||
|
|
||||||
|
.bDeviceClass = TUSB_CLASS_MISC,
|
||||||
|
.bDeviceSubClass = MISC_SUBCLASS_COMMON,
|
||||||
|
.bDeviceProtocol = MISC_PROTOCOL_IAD,
|
||||||
|
|
||||||
|
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE,
|
||||||
|
.bNumConfigurations = 0x01,
|
||||||
|
.bReserved = 0x00
|
||||||
|
};
|
||||||
|
|
||||||
|
// Invoked when received GET DEVICE QUALIFIER DESCRIPTOR request
|
||||||
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete.
|
||||||
|
// device_qualifier descriptor describes information about a high-speed capable device that would
|
||||||
|
// change if the device were operating at the other speed. If not highspeed capable stall this request.
|
||||||
|
uint8_t const* tud_descriptor_device_qualifier_cb(void)
|
||||||
|
{
|
||||||
|
return (uint8_t const*) &desc_device_qualifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received GET OTHER SEED CONFIGURATION DESCRIPTOR request
|
||||||
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
|
// Configuration descriptor in the other speed e.g if high speed then this is for full speed and vice versa
|
||||||
|
uint8_t const* tud_descriptor_other_speed_configuration_cb(uint8_t index)
|
||||||
|
{
|
||||||
|
(void) index; // for multiple configurations
|
||||||
|
|
||||||
|
// if link speed is high return fullspeed config, and vice versa
|
||||||
|
// Note: the descriptor type is OHER_SPEED_CONFIG instead of CONFIG
|
||||||
|
memcpy(desc_other_speed_config,
|
||||||
|
(tud_speed_get() == TUSB_SPEED_HIGH) ? desc_fs_configuration : desc_hs_configuration,
|
||||||
|
CONFIG_TOTAL_LEN);
|
||||||
|
|
||||||
|
desc_other_speed_config[1] = TUSB_DESC_OTHER_SPEED_CONFIG;
|
||||||
|
|
||||||
|
return desc_other_speed_config;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // highspeed
|
||||||
|
|
||||||
|
|
||||||
|
// Invoked when received GET CONFIGURATION DESCRIPTOR
|
||||||
|
// Application return pointer to descriptor
|
||||||
|
// Descriptor contents must exist long enough for transfer to complete
|
||||||
|
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
|
||||||
|
{
|
||||||
|
(void) index; // for multiple configurations
|
||||||
|
|
||||||
|
#if TUD_OPT_HIGH_SPEED
|
||||||
|
// Although we are highspeed, host may be fullspeed.
|
||||||
|
return (tud_speed_get() == TUSB_SPEED_HIGH) ? desc_hs_configuration : desc_fs_configuration;
|
||||||
|
#else
|
||||||
|
return desc_fs_configuration;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// String Descriptors
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
// array of pointer to string descriptors
|
||||||
|
char const* string_desc_arr [] =
|
||||||
|
{
|
||||||
|
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
|
||||||
|
"MindSoft", // 1: Manufacturer
|
||||||
|
"SDPicoCart", // 2: Product
|
||||||
|
"123456789012", // 3: Serials, should use chip ID
|
||||||
|
"SDPicoCart CDC", // 4: CDC Interface
|
||||||
|
"SDPicoCart MSC", // 5: MSC Interface
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint16_t _desc_str[32];
|
||||||
|
|
||||||
|
// Invoked when received GET STRING DESCRIPTOR request
|
||||||
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
|
uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
|
||||||
|
{
|
||||||
|
(void) langid;
|
||||||
|
|
||||||
|
uint8_t chr_count;
|
||||||
|
|
||||||
|
if ( index == 0)
|
||||||
|
{
|
||||||
|
memcpy(&_desc_str[1], string_desc_arr[0], 2);
|
||||||
|
chr_count = 1;
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// Note: the 0xEE index string is a Microsoft OS 1.0 Descriptors.
|
||||||
|
// https://docs.microsoft.com/en-us/windows-hardware/drivers/usbcon/microsoft-defined-usb-descriptors
|
||||||
|
|
||||||
|
if ( !(index < sizeof(string_desc_arr)/sizeof(string_desc_arr[0])) ) return NULL;
|
||||||
|
|
||||||
|
const char* str = string_desc_arr[index];
|
||||||
|
|
||||||
|
// Cap at max char
|
||||||
|
chr_count = (uint8_t) strlen(str);
|
||||||
|
if ( chr_count > 31 ) chr_count = 31;
|
||||||
|
|
||||||
|
// Convert ASCII string into UTF-16
|
||||||
|
for(uint8_t i=0; i<chr_count; i++)
|
||||||
|
{
|
||||||
|
_desc_str[1+i] = str[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// first byte is length (including header), second byte is string type
|
||||||
|
_desc_str[0] = (uint16_t) ((TUSB_DESC_STRING << 8 ) | (2*chr_count + 2));
|
||||||
|
|
||||||
|
return _desc_str;
|
||||||
|
}
|
BIN
selectgame.bin
Normal file
BIN
selectgame.bin
Normal file
Binary file not shown.
18
selectgame/c.bat
Normal file
18
selectgame/c.bat
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
bin\asw -cpu 8048 text-engine_V31.asm
|
||||||
|
bin\asw -cpu 8048 text-engine_bank2.asm
|
||||||
|
bin\asw -cpu 8048 text-engine_bank1.asm
|
||||||
|
bin\asw -cpu 8048 text-engine_bank0.asm
|
||||||
|
cd ..
|
||||||
|
del o2em\roms\text-engine_0123.bin
|
||||||
|
cd asw
|
||||||
|
bin\p2bin text-engine_V31.p text-engine_bank3.bin -r 1024-3071
|
||||||
|
bin\p2bin text-engine_bank2.p text-engine_bank2.bin -r 1024-3071
|
||||||
|
bin\p2bin text-engine_bank1.p text-engine_bank1.bin -r 1024-3071
|
||||||
|
bin\p2bin text-engine_bank0.p text-engine_bank0.bin -r 1024-3071
|
||||||
|
copy /b text-engine_bank0.bin+text-engine_bank1.bin+text-engine_bank2.bin+text-engine_bank3.bin text-engine_0123.bin
|
||||||
|
copy text-engine_0123.bin ..\O2em\roms\selectgame.bin
|
||||||
|
cd ..\O2em\
|
||||||
|
o2emlauncher
|
||||||
|
cd ..\asw
|
||||||
|
|
||||||
|
|
399
selectgame/g7000.h
Normal file
399
selectgame/g7000.h
Normal file
@ -0,0 +1,399 @@
|
|||||||
|
; This file contains definitions I use in my programs.
|
||||||
|
|
||||||
|
; $Id: g7000.h 594 2006-12-08 13:59:35Z sgust $
|
||||||
|
|
||||||
|
; Version 1.3
|
||||||
|
|
||||||
|
; Copyright (C) 1997-2006 by Soeren Gust, sgust@ithh.informationstheater.de
|
||||||
|
|
||||||
|
; Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
; of this software and associated documentation files (the "Software"), to deal
|
||||||
|
; in the Software without restriction, including without limitation the rights
|
||||||
|
; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
; copies of the Software, and to permit persons to whom the Software is
|
||||||
|
; furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
; The above copyright notice and this permission notice shall be included in
|
||||||
|
; all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
; THE SOFTWARE.
|
||||||
|
|
||||||
|
; NOTE: Since version 0.8.8 I have changed the license conditions. The former
|
||||||
|
; GNU Public License did not really make sense since this is just an include
|
||||||
|
; file and does not generate code on its own.
|
||||||
|
|
||||||
|
; You can always get the latest version at http://soeren.informationstheater.de
|
||||||
|
|
||||||
|
; BIOS routines for Videopac G7000
|
||||||
|
irq equ 0009h
|
||||||
|
irqend equ 0014h
|
||||||
|
vsyncirq equ 001Ah
|
||||||
|
soundirq equ 0044h
|
||||||
|
parsesnd equ 004Bh
|
||||||
|
copyregs equ 0089h ; internal
|
||||||
|
readkey equ 00B0h
|
||||||
|
readkey_plus equ 00BCh ; entry point for readkey on VP+ G7400
|
||||||
|
vdcenable equ 00E7h
|
||||||
|
extramenable equ 00ECh
|
||||||
|
init equ 00F1h
|
||||||
|
gfxoff equ 011Ch
|
||||||
|
gfxon equ 0127h
|
||||||
|
tableend equ 0132h
|
||||||
|
waitforkey equ 013Dh
|
||||||
|
calcchar23 equ 014Bh
|
||||||
|
clearchar equ 016Bh
|
||||||
|
waitvsync equ 0176h
|
||||||
|
tablebcdbyte equ 017Ch
|
||||||
|
tableprintchar equ 0197h
|
||||||
|
playsound equ 01A2h
|
||||||
|
doclock equ 01B0h
|
||||||
|
tablechar23 equ 022Ch
|
||||||
|
tablebcdnibble equ 0229h
|
||||||
|
tableput2 equ 0235h
|
||||||
|
initclock equ 023Ah
|
||||||
|
putchar23 equ 0261h
|
||||||
|
bittest equ 026Ah ; not available on Videopac+ G7400
|
||||||
|
bitclear equ 0280h ; not available on Videopac+ G7400
|
||||||
|
bitset equ 028Ah ; not available on Videopac+ G7400
|
||||||
|
random equ 0293h ; not available on Videopac+ G7400
|
||||||
|
nibblemixer equ 02A4h ; not available on Videopac+ G7400
|
||||||
|
selectgame equ 02C3h
|
||||||
|
bank02 equ 037Fh
|
||||||
|
bank01 equ 0383h
|
||||||
|
bank0 equ 0387h
|
||||||
|
bank3 equ 038Bh
|
||||||
|
getjoystick equ 038Fh
|
||||||
|
getjoystick_p17 equ 0395h ; entry point for getjoystick when using P17
|
||||||
|
decodejoystick equ 03B1h
|
||||||
|
divide equ 03DDh
|
||||||
|
multiply equ 03CFh
|
||||||
|
printchar equ 03EAh
|
||||||
|
|
||||||
|
; the vdc registers
|
||||||
|
vdc_spr0_ctrl equ 000h
|
||||||
|
vdc_spr1_ctrl equ 004h
|
||||||
|
vdc_spr2_ctrl equ 008h
|
||||||
|
vdc_spr3_ctrl equ 00Ch
|
||||||
|
|
||||||
|
vdc_char0 equ 010h
|
||||||
|
vdc_char1 equ 014h
|
||||||
|
vdc_char2 equ 018h
|
||||||
|
vdc_char3 equ 01Ch
|
||||||
|
vdc_char4 equ 020h
|
||||||
|
vdc_char5 equ 024h
|
||||||
|
vdc_char6 equ 028h
|
||||||
|
vdc_char7 equ 02Ch
|
||||||
|
vdc_char8 equ 030h
|
||||||
|
vdc_char9 equ 034h
|
||||||
|
vdc_chara equ 038h
|
||||||
|
vdc_charb equ 03Ch
|
||||||
|
|
||||||
|
vdc_quad0 equ 040h
|
||||||
|
vdc_quad1 equ 050h
|
||||||
|
vdc_quad2 equ 060h
|
||||||
|
vdc_quad3 equ 070h
|
||||||
|
|
||||||
|
vdc_spr0_shape equ 080h
|
||||||
|
vdc_spr1_shape equ 088h
|
||||||
|
vdc_spr2_shape equ 090h
|
||||||
|
vdc_spr3_shape equ 098h
|
||||||
|
|
||||||
|
vdc_control equ 0a0h
|
||||||
|
vdc_status equ 0a1h
|
||||||
|
vdc_collision equ 0a2h
|
||||||
|
vdc_color equ 0a3h
|
||||||
|
vdc_scanline equ 0a4h
|
||||||
|
vdc_scanrow equ 0a5h
|
||||||
|
;vdc_unknown equ 0a6h
|
||||||
|
vdc_sound0 equ 0a7h
|
||||||
|
vdc_sound1 equ 0a8h
|
||||||
|
vdc_sound2 equ 0a9h
|
||||||
|
vdc_soundctrl equ 0aah
|
||||||
|
|
||||||
|
vdc_gridh0 equ 0C0h
|
||||||
|
vdc_gridh1 equ 0C1h
|
||||||
|
vdc_gridh2 equ 0C2h
|
||||||
|
vdc_gridh3 equ 0C3h
|
||||||
|
vdc_gridh4 equ 0C4h
|
||||||
|
vdc_gridh5 equ 0C5h
|
||||||
|
vdc_gridh6 equ 0C6h
|
||||||
|
vdc_gridh7 equ 0C7h
|
||||||
|
vdc_gridh8 equ 0C8h
|
||||||
|
|
||||||
|
vdc_gridi0 equ 0D0h
|
||||||
|
vdc_gridi1 equ 0D1h
|
||||||
|
vdc_gridi2 equ 0D2h
|
||||||
|
vdc_gridi3 equ 0D3h
|
||||||
|
vdc_gridi4 equ 0D4h
|
||||||
|
vdc_gridi5 equ 0D5h
|
||||||
|
vdc_gridi6 equ 0D6h
|
||||||
|
vdc_gridi7 equ 0D7h
|
||||||
|
vdc_gridi8 equ 0D8h
|
||||||
|
|
||||||
|
vdc_gridv0 equ 0E0h
|
||||||
|
vdc_gridv1 equ 0E1h
|
||||||
|
vdc_gridv2 equ 0E2h
|
||||||
|
vdc_gridv3 equ 0E3h
|
||||||
|
vdc_gridv4 equ 0E4h
|
||||||
|
vdc_gridv5 equ 0E5h
|
||||||
|
vdc_gridv6 equ 0E6h
|
||||||
|
vdc_gridv7 equ 0E7h
|
||||||
|
vdc_gridv8 equ 0E8h
|
||||||
|
vdc_gridv9 equ 0E9h
|
||||||
|
|
||||||
|
; the bits in the vdc_control
|
||||||
|
vdc_ctrl_hint equ 001h
|
||||||
|
vdc_ctrl_beam equ 002h
|
||||||
|
vdc_ctrl_sint equ 004h
|
||||||
|
vdc_ctrl_grid equ 008h
|
||||||
|
vdc_ctrl_ovrlay equ 010h
|
||||||
|
vdc_ctrl_fore equ 020h
|
||||||
|
vdc_ctrl_dot equ 040h
|
||||||
|
vdc_ctrl_fill equ 080h
|
||||||
|
|
||||||
|
; the bits in vdc_status
|
||||||
|
vdc_stat_hblank equ 001h
|
||||||
|
vdc_stat_pstrb equ 002h
|
||||||
|
vdc_stat_sound equ 004h
|
||||||
|
vdc_stat_vblank equ 008h
|
||||||
|
vdc_stat_bit4 equ 010h
|
||||||
|
vdc_stat_bit5 equ 020h
|
||||||
|
vdc_stat_ovrlay equ 040h ; unused in G7000/O^2
|
||||||
|
vdc_stat_chrlap equ 080h
|
||||||
|
|
||||||
|
; the bits in vdc_collision
|
||||||
|
vdc_coll_spr0 equ 001h
|
||||||
|
vdc_coll_spr1 equ 002h
|
||||||
|
vdc_coll_spr2 equ 004h
|
||||||
|
vdc_coll_spr3 equ 008h
|
||||||
|
vdc_coll_vgrd equ 010h
|
||||||
|
vdc_coll_hgrd equ 020h
|
||||||
|
vdc_coll_ext equ 040h ; only used on Videopac+ G7400
|
||||||
|
vdc_coll_char equ 080h
|
||||||
|
|
||||||
|
; the bits in vdc_soundctrl
|
||||||
|
vdc_sound_noise equ 010h
|
||||||
|
vdc_sound_freq equ 020h
|
||||||
|
vdc_sound_loop equ 040h
|
||||||
|
vdc_sound_enab equ 080h
|
||||||
|
|
||||||
|
; the names match the colors on my PAL Videopac G7000
|
||||||
|
|
||||||
|
; the colors for characters
|
||||||
|
col_chr_black equ 00h << 1
|
||||||
|
col_chr_red equ 01h << 1
|
||||||
|
col_chr_green equ 02h << 1
|
||||||
|
col_chr_yellow equ 03h << 1
|
||||||
|
col_chr_blue equ 04h << 1
|
||||||
|
col_chr_violet equ 05h << 1
|
||||||
|
col_chr_cyan equ 06h << 1
|
||||||
|
col_chr_white equ 07h << 1
|
||||||
|
|
||||||
|
; sprite control byte 3
|
||||||
|
spr_evenshift equ 02h
|
||||||
|
spr_double equ 04h
|
||||||
|
; colors for sprites
|
||||||
|
col_spr_black equ 00h << 3
|
||||||
|
col_spr_red equ 01h << 3
|
||||||
|
col_spr_green equ 02h << 3
|
||||||
|
col_spr_yellow equ 03h << 3
|
||||||
|
col_spr_blue equ 04h << 3
|
||||||
|
col_spr_violet equ 05h << 3
|
||||||
|
col_spr_cyan equ 06h << 3
|
||||||
|
col_spr_white equ 07h << 3
|
||||||
|
|
||||||
|
; the colors for the grid
|
||||||
|
col_grd_black equ 00h
|
||||||
|
col_grd_blue equ 01h
|
||||||
|
col_grd_green equ 02h
|
||||||
|
col_grd_cyan equ 03h
|
||||||
|
col_grd_red equ 04h
|
||||||
|
col_grd_violet equ 05h
|
||||||
|
col_grd_yellow equ 06h
|
||||||
|
col_grd_white equ 07h
|
||||||
|
|
||||||
|
; colors for the grid
|
||||||
|
col_bck_black equ 00h << 3
|
||||||
|
col_bck_blue equ 01h << 3
|
||||||
|
col_bck_green equ 02h << 3
|
||||||
|
col_bck_cyan equ 03h << 3
|
||||||
|
col_bck_red equ 04h << 3
|
||||||
|
col_bck_violet equ 05h << 3
|
||||||
|
col_bck_yellow equ 06h << 3
|
||||||
|
col_bck_white equ 07h << 3
|
||||||
|
; use this to make the grid brighter
|
||||||
|
col_grd_lum equ 040h
|
||||||
|
|
||||||
|
_ARROW equ 36h
|
||||||
|
_A equ 20h
|
||||||
|
_B equ 25h
|
||||||
|
_C equ 23h
|
||||||
|
_D equ 1Ah
|
||||||
|
_E equ 12h
|
||||||
|
_F equ 1Bh
|
||||||
|
_G equ 1Ch
|
||||||
|
_H equ 1Dh
|
||||||
|
_I equ 16h
|
||||||
|
_J equ 1Eh
|
||||||
|
_K equ 1Fh
|
||||||
|
_L equ 0Eh
|
||||||
|
_M equ 26h
|
||||||
|
_N equ 2Dh
|
||||||
|
_O equ 17h
|
||||||
|
_P equ 0Fh
|
||||||
|
_Q equ 18h
|
||||||
|
_R equ 13h
|
||||||
|
_S equ 19h
|
||||||
|
_T equ 14h
|
||||||
|
_U equ 15h
|
||||||
|
_V equ 24h
|
||||||
|
_X equ 22h
|
||||||
|
_W equ 11h
|
||||||
|
_Y equ 2Ch
|
||||||
|
_Z equ 21h
|
||||||
|
_0 equ 0h
|
||||||
|
_1 equ 1h
|
||||||
|
_2 equ 2h
|
||||||
|
_3 equ 3h
|
||||||
|
_4 equ 4h
|
||||||
|
_5 equ 5h
|
||||||
|
_6 equ 6h
|
||||||
|
_7 equ 7h
|
||||||
|
_8 equ 8h
|
||||||
|
_9 equ 9h
|
||||||
|
_10 equ 30h
|
||||||
|
|
||||||
|
; the locations in internal ram
|
||||||
|
iram_collision equ 03Dh
|
||||||
|
iram_clock equ 03Eh
|
||||||
|
iram_irqctrl equ 03Fh
|
||||||
|
|
||||||
|
; some bits in the iram
|
||||||
|
; iram_clock
|
||||||
|
clock_stop equ 080h
|
||||||
|
clock_forward equ 040h
|
||||||
|
; iram_irqctrl
|
||||||
|
irq_table equ 080h
|
||||||
|
irq_sound equ 040h
|
||||||
|
|
||||||
|
; the locations in external ram
|
||||||
|
eram_minutes equ 001h
|
||||||
|
eram_seconds equ 002h
|
||||||
|
|
||||||
|
; the builtin tunes
|
||||||
|
tune_beep_error equ 028h
|
||||||
|
tune_explode equ 02Eh
|
||||||
|
tune_alarm equ 03Ch
|
||||||
|
tune_select equ 04Ah
|
||||||
|
tune_keyclick equ 056h
|
||||||
|
tune_buzz equ 05Ah
|
||||||
|
tune_select2 equ 05Eh
|
||||||
|
tune_shoot equ 06Ah
|
||||||
|
|
||||||
|
; BIOS routines for Videopac+ G7400
|
||||||
|
plusready equ 027Dh
|
||||||
|
plusloadr equ 0283h
|
||||||
|
pluscmd equ 0288h
|
||||||
|
plusdata equ 028Ch
|
||||||
|
plushide equ 0296h
|
||||||
|
plusmode equ 0299h
|
||||||
|
plusenable equ 02A1h
|
||||||
|
plusstart equ 02ABh
|
||||||
|
plusselectgame equ 02C2h
|
||||||
|
|
||||||
|
; registers of the EF9340/41
|
||||||
|
vpp_ta_wr equ 0
|
||||||
|
vpp_tb_wr equ 1
|
||||||
|
vpp_ta_cmd equ 2
|
||||||
|
vpp_tb_cmd equ 3
|
||||||
|
vpp_ta_rd equ 4
|
||||||
|
vpp_tb_rd equ 5
|
||||||
|
vpp_busy equ 6
|
||||||
|
; 7 is illegal
|
||||||
|
|
||||||
|
; commandbytes for the Videopac+ G7400
|
||||||
|
plus_cmd_brow equ 000h ; begin row
|
||||||
|
plus_cmd_loady equ 020h ; load Y
|
||||||
|
plus_cmd_loadx equ 040h ; load X
|
||||||
|
plus_cmd_incc equ 060h ; inc C
|
||||||
|
plus_cmd_loadm equ 080h ; load M
|
||||||
|
plus_cmd_loadr equ 0A0h ; load R
|
||||||
|
plus_cmd_loady0 equ 0C0h ; load Y0
|
||||||
|
|
||||||
|
; parallel attributes for the Videopac+ G7400
|
||||||
|
; foreground color
|
||||||
|
col_plus_black equ 0
|
||||||
|
col_plus_red equ 1
|
||||||
|
col_plus_green equ 2
|
||||||
|
col_plus_yellow equ 3
|
||||||
|
col_plus_blue equ 4
|
||||||
|
col_plus_violet equ 5
|
||||||
|
col_plus_cyan equ 6
|
||||||
|
col_plus_white equ 7
|
||||||
|
; background color, only parallel for block gfx
|
||||||
|
col_pbck_black equ 0 << 4
|
||||||
|
col_pbck_red equ 1 << 4
|
||||||
|
col_pbck_green equ 2 << 4
|
||||||
|
col_pbck_yellow equ 3 << 4
|
||||||
|
col_pbck_blue equ 4 << 4
|
||||||
|
col_pbck_violet equ 5 << 4
|
||||||
|
col_pbck_cyan equ 6 << 4
|
||||||
|
col_pbck_white equ 7 << 4
|
||||||
|
; other parallel attributes
|
||||||
|
col_patr_blck equ 080h ; block gfx
|
||||||
|
col_patr_invrt equ 040h ; invert
|
||||||
|
col_patr_dwdth equ 020h ; double width
|
||||||
|
col_patr_dhght equ 010h ; double height
|
||||||
|
col_patr_stable equ 008h ; do not blink
|
||||||
|
|
||||||
|
; serial attributes
|
||||||
|
; other serial attributes
|
||||||
|
col_satr_enable equ 080h ; enable serial attributes
|
||||||
|
col_satr_line equ 004h ; underline
|
||||||
|
col_satr_box equ 002h ; boxing mode
|
||||||
|
col_satr_conc equ 001h ; conceal mode
|
||||||
|
|
||||||
|
; block gfx
|
||||||
|
plus_blck_full equ 040h ; use full blocks
|
||||||
|
|
||||||
|
; parameter for plus_cmd_loadm
|
||||||
|
plus_loadm_wr equ 000h ; write
|
||||||
|
plus_loadm_rd equ 020h ; read
|
||||||
|
plus_loadm_wrni equ 040h ; write without inc
|
||||||
|
plus_loadm_rdni equ 060h ; read without inc
|
||||||
|
plus_loadm_wrsl equ 080h ; write slice
|
||||||
|
plus_loadm_rdsl equ 0A0h ; read slice
|
||||||
|
|
||||||
|
; parameter for plus_cmd_loadr
|
||||||
|
plus_loadr_blnk equ 080h ; enable blink
|
||||||
|
plus_loadr_tt equ 040h ; 50/60 Hz, handled by plusloadr
|
||||||
|
plus_loadr_tl equ 020h ; monitor mode, leave 0
|
||||||
|
plus_loadr_crsr equ 010h ; display cursor
|
||||||
|
plus_loadr_srow equ 008h ; service row (first line)
|
||||||
|
plus_loadr_conc equ 004h ; show concealed
|
||||||
|
plus_loadr_box equ 002h ; box mode enable
|
||||||
|
plus_loadr_dspl equ 001h ; show display
|
||||||
|
|
||||||
|
; parameter for plus_cmd_loady0
|
||||||
|
plus_loady0_zom equ 020h ; global double height
|
||||||
|
|
||||||
|
; registers for the MegaCART/FlashCART, mirrored every 4 bytes
|
||||||
|
ereg_codebank equ 080h ; code bank
|
||||||
|
ereg_databank equ 081h ; data bank
|
||||||
|
ereg_io_out equ 082h ; output port
|
||||||
|
ereg_io_in equ 083h ; input port
|
||||||
|
|
||||||
|
; bits in ereg_io_out
|
||||||
|
eout_tx equ 001h ; send data from FlashCART to PC
|
||||||
|
eout_eecs equ 002h ; chip select for serial EEPROM
|
||||||
|
eout_eeclk equ 004h ; clock for serial EEPROM
|
||||||
|
eout_eedi equ 008h ; data for serial EEPROM
|
||||||
|
|
||||||
|
; bits in ereg_io_in
|
||||||
|
ein_eedo equ 001h ; data from serial EEPROM
|
BIN
selectgame/selectgame.bin
Normal file
BIN
selectgame/selectgame.bin
Normal file
Binary file not shown.
1069
selectgame/text-engine_V31.asm
Normal file
1069
selectgame/text-engine_V31.asm
Normal file
File diff suppressed because it is too large
Load Diff
396
selectgame/text-engine_bank0.asm
Normal file
396
selectgame/text-engine_bank0.asm
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
|
||||||
|
; INTRAM
|
||||||
|
; 20-2f = char temp space
|
||||||
|
; 30 = temp exram pointer
|
||||||
|
; 31 = PAL/NTSC
|
||||||
|
; 32-35 = line colors
|
||||||
|
|
||||||
|
; only alterable during assemble-time: y0, gridfill
|
||||||
|
; alterable during runtime: x0, backcol
|
||||||
|
|
||||||
|
cpu 8048
|
||||||
|
|
||||||
|
include "g7000.h"
|
||||||
|
|
||||||
|
iram_disp_type equ 031h
|
||||||
|
iram_line_selected equ 37h
|
||||||
|
iram_mempage equ 36h
|
||||||
|
iram_timer equ 78h
|
||||||
|
|
||||||
|
x0 equ 018h ; between 000h and 024h
|
||||||
|
y0 equ 01ch ; multiple of 4, between 014h and 038h
|
||||||
|
gridfill equ 080h ; 000h or 080h
|
||||||
|
backcol equ 002h ; grid and background color
|
||||||
|
|
||||||
|
org 400h
|
||||||
|
|
||||||
|
jmp selectgame
|
||||||
|
jmp irq
|
||||||
|
retr
|
||||||
|
nop
|
||||||
|
; jmp vsyncirq ; VSYNC-interrupt
|
||||||
|
jmp vsync
|
||||||
|
jmp start
|
||||||
|
jmp soundirq
|
||||||
|
|
||||||
|
vsync
|
||||||
|
clr f1
|
||||||
|
cpl f1
|
||||||
|
mov r1,#0a2h
|
||||||
|
movx a,@r1
|
||||||
|
mov r0,#03fh
|
||||||
|
jmp 0030h
|
||||||
|
|
||||||
|
change_bank
|
||||||
|
dis i
|
||||||
|
anl p1,#0feh ; change to bank 2
|
||||||
|
call startchkpages
|
||||||
|
orl p1,#003h ;
|
||||||
|
anl p1,#0fdh ; change to bank 1
|
||||||
|
call startchkpages
|
||||||
|
anl p1,#0fch ; change to bank 0
|
||||||
|
call startchkpages
|
||||||
|
orl p1,#003h ; change to bank 3
|
||||||
|
en i
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
start
|
||||||
|
startchkpages
|
||||||
|
mov r1,#iram_mempage
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#18
|
||||||
|
jnz chkpage19
|
||||||
|
call initpage18
|
||||||
|
ret
|
||||||
|
chkpage19
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#19
|
||||||
|
jnz chkpage20
|
||||||
|
call initpage19
|
||||||
|
ret
|
||||||
|
chkpage20
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#20
|
||||||
|
jnz chkpage21
|
||||||
|
call initpage20
|
||||||
|
ret
|
||||||
|
chkpage21
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#21
|
||||||
|
jnz chkpage22
|
||||||
|
call initpage21
|
||||||
|
ret
|
||||||
|
chkpage22
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#22
|
||||||
|
jnz chkpage23
|
||||||
|
call initpage22
|
||||||
|
ret
|
||||||
|
chkpage23
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#23
|
||||||
|
jnz chkpage24
|
||||||
|
call initpage23
|
||||||
|
ret
|
||||||
|
chkpage24
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#24
|
||||||
|
jnz endchkpage
|
||||||
|
call initpage24
|
||||||
|
ret
|
||||||
|
endchkpage
|
||||||
|
ret
|
||||||
|
|
||||||
|
initend
|
||||||
|
|
||||||
|
; --> color data (used for "initchars" and "initpage")
|
||||||
|
|
||||||
|
mov r0,#032h ; set text colors
|
||||||
|
mov @r0,#001h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#023h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#045h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#067h
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
calcchar
|
||||||
|
; call calcY
|
||||||
|
mov a,r5
|
||||||
|
rl a
|
||||||
|
rl a
|
||||||
|
mov r5,a
|
||||||
|
; mov a,r4
|
||||||
|
; rr a
|
||||||
|
; rr a
|
||||||
|
; cpl a
|
||||||
|
; inc a
|
||||||
|
; add a,r5
|
||||||
|
ret
|
||||||
|
putchar
|
||||||
|
call calcchar
|
||||||
|
movx @r1,a
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
align 256
|
||||||
|
initpage18
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata18 & 0ffh
|
||||||
|
intpage18
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage18
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata18:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 006h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 007h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 008h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 009h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 000h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 000h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 001h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 002h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage19
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata19 & 0ffh
|
||||||
|
intpage19
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage19
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata19:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 002h, 01Dh, 020h
|
||||||
|
db 023h, 01Fh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 003h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 004h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 004h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 005h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 006h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 007h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 008h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage20
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata20 & 0ffh
|
||||||
|
intpage20
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage20
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata20:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 002h, 009h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 000h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 001h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 002h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 003h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 003h, 020h, 00Eh
|
||||||
|
db 014h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 004h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 004h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage21
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata21 & 0ffh
|
||||||
|
intpage21
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage21
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata21:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 005h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 005h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 006h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 007h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 008h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 009h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 003h, 009h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 000h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage22
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata22 & 0ffh
|
||||||
|
intpage22
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage22
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata22:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 001h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 002h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 003h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 003h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 004h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 005h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 006h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 007h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage23
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata23 & 0ffh
|
||||||
|
intpage23
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage23
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata23:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 008h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 004h, 009h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 000h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 001h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 002h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 003h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 003h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 004h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage24
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata24 & 0ffh
|
||||||
|
intpage24
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage24
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata24:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 004h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 005h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 005h, 028h, 001h
|
||||||
|
db 002h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 005h, 028h, 001h
|
||||||
|
db 002h, 01Bh, 016h, 022h, 027h, 025h, 016h, 02Dh
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 006h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 007h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 008h, 028h, 001h
|
||||||
|
db 002h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 005h, 009h, 028h, 001h
|
||||||
|
db 006h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
396
selectgame/text-engine_bank1.asm
Normal file
396
selectgame/text-engine_bank1.asm
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
|
||||||
|
; INTRAM
|
||||||
|
; 20-2f = char temp space
|
||||||
|
; 30 = temp exram pointer
|
||||||
|
; 31 = PAL/NTSC
|
||||||
|
; 32-35 = line colors
|
||||||
|
|
||||||
|
; only alterable during assemble-time: y0, gridfill
|
||||||
|
; alterable during runtime: x0, backcol
|
||||||
|
|
||||||
|
cpu 8048
|
||||||
|
|
||||||
|
include "g7000.h"
|
||||||
|
|
||||||
|
iram_disp_type equ 031h
|
||||||
|
iram_line_selected equ 37h
|
||||||
|
iram_mempage equ 36h
|
||||||
|
iram_timer equ 78h
|
||||||
|
|
||||||
|
x0 equ 018h ; between 000h and 024h
|
||||||
|
y0 equ 01ch ; multiple of 4, between 014h and 038h
|
||||||
|
gridfill equ 080h ; 000h or 080h
|
||||||
|
backcol equ 002h ; grid and background color
|
||||||
|
|
||||||
|
org 400h
|
||||||
|
|
||||||
|
jmp selectgame
|
||||||
|
jmp irq
|
||||||
|
retr
|
||||||
|
nop
|
||||||
|
; jmp vsyncirq ; VSYNC-interrupt
|
||||||
|
jmp vsync
|
||||||
|
jmp start
|
||||||
|
jmp soundirq
|
||||||
|
|
||||||
|
vsync
|
||||||
|
clr f1
|
||||||
|
cpl f1
|
||||||
|
mov r1,#0a2h
|
||||||
|
movx a,@r1
|
||||||
|
mov r0,#03fh
|
||||||
|
jmp 0030h
|
||||||
|
|
||||||
|
change_bank
|
||||||
|
dis i
|
||||||
|
anl p1,#0feh ; change to bank 2
|
||||||
|
call startchkpages
|
||||||
|
orl p1,#003h ;
|
||||||
|
anl p1,#0fdh ; change to bank 1
|
||||||
|
call startchkpages
|
||||||
|
anl p1,#0fch ; change to bank 0
|
||||||
|
call startchkpages
|
||||||
|
orl p1,#003h ; change to bank 3
|
||||||
|
en i
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
start
|
||||||
|
startchkpages
|
||||||
|
mov r1,#iram_mempage
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#11
|
||||||
|
jnz chkpage12
|
||||||
|
call initpage11
|
||||||
|
ret
|
||||||
|
chkpage12
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#12
|
||||||
|
jnz chkpage13
|
||||||
|
call initpage12
|
||||||
|
ret
|
||||||
|
chkpage13
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#13
|
||||||
|
jnz chkpage14
|
||||||
|
call initpage13
|
||||||
|
ret
|
||||||
|
chkpage14
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#14
|
||||||
|
jnz chkpage15
|
||||||
|
call initpage14
|
||||||
|
ret
|
||||||
|
chkpage15
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#15
|
||||||
|
jnz chkpage16
|
||||||
|
call initpage15
|
||||||
|
ret
|
||||||
|
chkpage16
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#16
|
||||||
|
jnz chkpage17
|
||||||
|
call initpage16
|
||||||
|
ret
|
||||||
|
chkpage17
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#17
|
||||||
|
jnz chkpage18
|
||||||
|
call initpage17
|
||||||
|
ret
|
||||||
|
chkpage18
|
||||||
|
ret
|
||||||
|
|
||||||
|
initend
|
||||||
|
|
||||||
|
; --> color data (used for "initchars" and "initpage")
|
||||||
|
|
||||||
|
mov r0,#032h ; set text colors
|
||||||
|
mov @r0,#001h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#023h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#045h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#067h
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
calcchar
|
||||||
|
; call calcY
|
||||||
|
mov a,r5
|
||||||
|
rl a
|
||||||
|
rl a
|
||||||
|
mov r5,a
|
||||||
|
; mov a,r4
|
||||||
|
; rr a
|
||||||
|
; rr a
|
||||||
|
; cpl a
|
||||||
|
; inc a
|
||||||
|
; add a,r5
|
||||||
|
ret
|
||||||
|
putchar
|
||||||
|
call calcchar
|
||||||
|
movx @r1,a
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
align 256
|
||||||
|
initpage11
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata11 & 0ffh
|
||||||
|
intpage11
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage11
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata11:
|
||||||
|
db 00Ch, 017h, 002h, 028h, 003h, 003h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 003h, 005h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 003h, 008h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 003h, 009h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 004h, 000h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 004h, 001h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 004h, 003h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 004h, 005h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage12
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata12 & 0ffh
|
||||||
|
intpage12
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage12
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata12:
|
||||||
|
db 00Ch, 017h, 002h, 028h, 004h, 006h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 004h, 007h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 004h, 008h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 004h, 008h, 020h, 00Eh
|
||||||
|
db 014h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 00Fh, 020h, 00Eh, 028h, 020h, 023h, 013h
|
||||||
|
db 017h, 025h, 020h, 014h, 019h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 00Fh, 020h, 00Eh, 028h, 01Bh, 00Eh, 020h
|
||||||
|
db 019h, 01Dh, 00Fh, 017h, 016h, 02Dh, 014h, 027h
|
||||||
|
db 00Ch, 00Fh, 020h, 00Eh, 028h, 02Dh, 016h, 026h
|
||||||
|
db 025h, 00Eh, 012h, 028h, 02Dh, 015h, 026h, 025h
|
||||||
|
db 00Ch, 00Fh, 020h, 00Eh, 028h, 014h, 02Ch, 00Fh
|
||||||
|
db 012h, 028h, 020h, 02Dh, 01Ah, 028h, 014h, 012h
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage13
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata13 & 0ffh
|
||||||
|
intpage13
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage13
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata13:
|
||||||
|
db 00Ch, 00Fh, 025h, 028h, 01Bh, 013h, 017h, 01Ch
|
||||||
|
db 01Ch, 012h, 013h, 027h, 025h, 016h, 02Dh, 00Ch
|
||||||
|
db 00Ch, 00Fh, 025h, 028h, 00Fh, 017h, 00Fh, 012h
|
||||||
|
db 02Ch, 012h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch
|
||||||
|
db 00Ch, 00Fh, 025h, 028h, 018h, 028h, 025h, 012h
|
||||||
|
db 013h, 014h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch
|
||||||
|
db 00Ch, 00Fh, 025h, 028h, 019h, 015h, 00Fh, 012h
|
||||||
|
db 013h, 028h, 023h, 017h, 025h, 013h, 020h, 027h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 023h, 00Eh, 020h, 02Ch
|
||||||
|
db 028h, 00Fh, 016h, 01Ch, 012h, 017h, 02Dh, 028h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 023h, 00Eh, 020h, 02Ch
|
||||||
|
db 028h, 00Fh, 016h, 01Ch, 012h, 017h, 02Dh, 028h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 016h, 02Dh, 014h, 012h
|
||||||
|
db 013h, 00Fh, 017h, 00Eh, 027h, 025h, 016h, 02Dh
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 026h, 020h, 013h, 014h
|
||||||
|
db 016h, 020h, 02Dh, 028h, 014h, 01Dh, 013h, 012h
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage14
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata14 & 0ffh
|
||||||
|
intpage14
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage14
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata14:
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 026h, 020h, 013h, 014h
|
||||||
|
db 016h, 020h, 02Dh, 028h, 014h, 01Dh, 013h, 012h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 026h, 016h, 019h, 019h
|
||||||
|
db 016h, 017h, 02Dh, 028h, 016h, 026h, 00Fh, 017h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 02Dh, 016h, 01Ch, 01Dh
|
||||||
|
db 014h, 01Bh, 016h, 01Ch, 01Dh, 014h, 012h, 013h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 00Fh, 016h, 02Dh, 025h
|
||||||
|
db 020h, 00Eh, 00Eh, 027h, 025h, 016h, 02Dh, 00Ch
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 00Fh, 00Eh, 020h, 02Ch
|
||||||
|
db 014h, 020h, 01Ch, 027h, 025h, 016h, 02Dh, 00Ch
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 013h, 012h, 01Ah, 028h
|
||||||
|
db 025h, 020h, 013h, 017h, 02Dh, 027h, 025h, 016h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 013h, 012h, 01Ah, 028h
|
||||||
|
db 025h, 020h, 013h, 017h, 02Dh, 028h, 020h, 00Eh
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 013h, 017h, 025h, 017h
|
||||||
|
db 014h, 028h, 023h, 016h, 014h, 02Ch, 027h, 025h
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage15
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata15 & 0ffh
|
||||||
|
intpage15
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage15
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata15:
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 019h, 01Dh, 020h, 013h
|
||||||
|
db 01Fh, 028h, 01Dh, 015h, 02Dh, 014h, 012h, 013h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 019h, 00Fh, 016h, 01Ah
|
||||||
|
db 012h, 013h, 026h, 020h, 02Dh, 027h, 025h, 016h
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 019h, 00Fh, 016h, 01Ah
|
||||||
|
db 012h, 013h, 026h, 020h, 02Dh, 028h, 020h, 00Eh
|
||||||
|
db 00Ch, 00Fh, 013h, 028h, 014h, 015h, 014h, 020h
|
||||||
|
db 02Dh, 01Fh, 01Dh, 020h, 026h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 001h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 001h, 01Dh, 020h
|
||||||
|
db 023h, 01Fh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 001h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 002h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage16
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata16 & 0ffh
|
||||||
|
intpage16
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage16
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata16:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 003h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 004h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 005h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 006h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 006h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 007h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 008h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 000h, 009h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage17
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata17 & 0ffh
|
||||||
|
intpage17
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage17
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata17:
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 000h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 001h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 001h, 020h, 00Eh
|
||||||
|
db 014h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 001h, 00Fh, 00Eh
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 002h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 003h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 004h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 024h, 00Fh, 028h, 001h, 005h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
396
selectgame/text-engine_bank2.asm
Normal file
396
selectgame/text-engine_bank2.asm
Normal file
@ -0,0 +1,396 @@
|
|||||||
|
|
||||||
|
; INTRAM
|
||||||
|
; 20-2f = char temp space
|
||||||
|
; 30 = temp exram pointer
|
||||||
|
; 31 = PAL/NTSC
|
||||||
|
; 32-35 = line colors
|
||||||
|
|
||||||
|
; only alterable during assemble-time: y0, gridfill
|
||||||
|
; alterable during runtime: x0, backcol
|
||||||
|
|
||||||
|
cpu 8048
|
||||||
|
|
||||||
|
include "g7000.h"
|
||||||
|
|
||||||
|
iram_disp_type equ 031h
|
||||||
|
iram_line_selected equ 37h
|
||||||
|
iram_mempage equ 36h
|
||||||
|
iram_timer equ 78h
|
||||||
|
|
||||||
|
x0 equ 018h ; between 000h and 024h
|
||||||
|
y0 equ 01ch ; multiple of 4, between 014h and 038h
|
||||||
|
gridfill equ 080h ; 000h or 080h
|
||||||
|
backcol equ 002h ; grid and background color
|
||||||
|
|
||||||
|
org 400h
|
||||||
|
|
||||||
|
jmp selectgame
|
||||||
|
jmp irq
|
||||||
|
retr
|
||||||
|
nop
|
||||||
|
; jmp vsyncirq ; VSYNC-interrupt
|
||||||
|
jmp vsync
|
||||||
|
jmp start
|
||||||
|
jmp soundirq
|
||||||
|
|
||||||
|
vsync
|
||||||
|
clr f1
|
||||||
|
cpl f1
|
||||||
|
mov r1,#0a2h
|
||||||
|
movx a,@r1
|
||||||
|
mov r0,#03fh
|
||||||
|
jmp 0030h
|
||||||
|
|
||||||
|
change_bank
|
||||||
|
dis i
|
||||||
|
anl p1,#0feh ; change to bank 2
|
||||||
|
call startchkpages
|
||||||
|
orl p1,#003h ;
|
||||||
|
anl p1,#0fdh ; change to bank 1
|
||||||
|
call startchkpages
|
||||||
|
anl p1,#0fch ; change to bank 0
|
||||||
|
call startchkpages
|
||||||
|
orl p1,#003h ; change to bank 3
|
||||||
|
en i
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
start
|
||||||
|
startchkpages
|
||||||
|
mov r1,#iram_mempage
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#4
|
||||||
|
jnz chkpage5
|
||||||
|
call initpage4
|
||||||
|
ret
|
||||||
|
chkpage5
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#5
|
||||||
|
jnz chkpage6
|
||||||
|
call initpage5
|
||||||
|
ret
|
||||||
|
chkpage6
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#6
|
||||||
|
jnz chkpage7
|
||||||
|
call initpage6
|
||||||
|
ret
|
||||||
|
chkpage7
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#7
|
||||||
|
jnz chkpage8
|
||||||
|
call initpage7
|
||||||
|
ret
|
||||||
|
chkpage8
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#8
|
||||||
|
jnz chkpage9
|
||||||
|
call initpage8
|
||||||
|
ret
|
||||||
|
chkpage9
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#9
|
||||||
|
jnz chkpage10
|
||||||
|
call initpage9
|
||||||
|
ret
|
||||||
|
chkpage10
|
||||||
|
mov a,@r1
|
||||||
|
xrl a,#10
|
||||||
|
jnz chkpage11
|
||||||
|
call initpage10
|
||||||
|
ret
|
||||||
|
chkpage11
|
||||||
|
ret
|
||||||
|
|
||||||
|
initend
|
||||||
|
|
||||||
|
; --> color data (used for "initchars" and "initpage")
|
||||||
|
|
||||||
|
mov r0,#032h ; set text colors
|
||||||
|
mov @r0,#001h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#023h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#045h
|
||||||
|
inc r0
|
||||||
|
mov @r0,#067h
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
calcchar
|
||||||
|
; call calcY
|
||||||
|
mov a,r5
|
||||||
|
rl a
|
||||||
|
rl a
|
||||||
|
mov r5,a
|
||||||
|
; mov a,r4
|
||||||
|
; rr a
|
||||||
|
; rr a
|
||||||
|
; cpl a
|
||||||
|
; inc a
|
||||||
|
; add a,r5
|
||||||
|
ret
|
||||||
|
putchar
|
||||||
|
call calcchar
|
||||||
|
movx @r1,a
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
align 256
|
||||||
|
initpage4
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata4 & 0ffh
|
||||||
|
intpage4
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage4
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata4:
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 000h, 006h, 00Fh
|
||||||
|
db 00Eh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 001h, 001h, 00Fh
|
||||||
|
db 00Eh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 001h, 004h, 01Bh
|
||||||
|
db 016h, 022h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 001h, 009h, 028h
|
||||||
|
db 01Ch, 007h, 004h, 000h, 000h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 002h, 000h, 00Fh
|
||||||
|
db 00Eh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 002h, 004h, 00Fh
|
||||||
|
db 00Eh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 002h, 008h, 01Bh
|
||||||
|
db 016h, 022h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 003h, 000h, 01Bh
|
||||||
|
db 016h, 022h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage5
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata5 & 0ffh
|
||||||
|
intpage5
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage5
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata5:
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 003h, 001h, 028h
|
||||||
|
db 01Ch, 007h, 004h, 000h, 000h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 003h, 005h, 00Fh
|
||||||
|
db 00Eh, 028h, 01Bh, 016h, 022h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 003h, 006h, 01Bh
|
||||||
|
db 016h, 022h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 004h, 000h, 028h
|
||||||
|
db 01Ch, 007h, 004h, 000h, 000h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 004h, 003h, 00Fh
|
||||||
|
db 00Eh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 005h, 005h, 00Fh
|
||||||
|
db 00Eh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 025h, 013h, 002h
|
||||||
|
db 001h, 028h, 01Bh, 016h, 022h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 01Ah, 012h, 026h
|
||||||
|
db 017h, 02Dh, 028h, 020h, 014h, 014h, 020h, 023h
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage6
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata6 & 0ffh
|
||||||
|
intpage6
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage6
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata6:
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 026h, 017h, 014h
|
||||||
|
db 017h, 028h, 023h, 013h, 020h, 019h, 01Dh, 028h
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 00Fh, 00Eh, 020h
|
||||||
|
db 02Ch, 014h, 020h, 01Ch, 028h, 01Bh, 016h, 022h
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 014h, 015h, 014h
|
||||||
|
db 020h, 02Dh, 01Fh, 01Dh, 020h, 026h, 028h, 01Bh
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 024h, 00Fh, 009h
|
||||||
|
db 028h, 012h, 022h, 020h, 026h, 00Fh, 00Eh, 012h
|
||||||
|
db 00Ch, 026h, 017h, 01Ah, 028h, 024h, 00Fh, 003h
|
||||||
|
db 001h, 028h, 012h, 022h, 020h, 026h, 00Fh, 00Eh
|
||||||
|
db 00Ch, 026h, 017h, 015h, 019h, 012h, 023h, 020h
|
||||||
|
db 014h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 020h, 026h, 017h
|
||||||
|
db 01Fh, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 020h, 026h, 017h
|
||||||
|
db 01Fh, 028h, 020h, 00Eh, 014h, 027h, 025h, 016h
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage7
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata7 & 0ffh
|
||||||
|
intpage7
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage7
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata7:
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 023h, 020h, 00Eh
|
||||||
|
db 023h, 015h, 00Eh, 020h, 014h, 017h, 013h, 027h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 01Dh, 012h, 00Eh
|
||||||
|
db 016h, 023h, 017h, 00Fh, 014h, 012h, 013h, 028h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 01Eh, 01Ch, 028h
|
||||||
|
db 026h, 015h, 02Dh, 023h, 01Dh, 01Fh, 016h, 02Dh
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 01Fh, 023h, 028h
|
||||||
|
db 00Fh, 020h, 023h, 026h, 020h, 02Dh, 027h, 025h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 01Fh, 023h, 028h
|
||||||
|
db 00Fh, 020h, 023h, 024h, 016h, 01Ah, 027h, 025h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 01Fh, 014h, 020h
|
||||||
|
db 020h, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 01Fh, 014h, 020h
|
||||||
|
db 020h, 028h, 01Ah, 012h, 026h, 017h, 001h, 027h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 01Fh, 014h, 020h
|
||||||
|
db 020h, 028h, 01Ah, 012h, 026h, 017h, 002h, 027h
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage8
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata8 & 0ffh
|
||||||
|
intpage8
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage8
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata8:
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 026h, 013h, 013h
|
||||||
|
db 017h, 025h, 017h, 014h, 017h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 00Fh, 00Eh, 020h
|
||||||
|
db 02Dh, 012h, 014h, 028h, 00Eh, 020h, 02Dh, 01Ah
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 00Fh, 017h, 02Dh
|
||||||
|
db 01Ch, 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 00Fh, 017h, 02Dh
|
||||||
|
db 01Ch, 028h, 020h, 00Eh, 00Eh, 027h, 025h, 016h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 00Fh, 00Fh, 00Fh
|
||||||
|
db 028h, 017h, 002h, 012h, 026h, 027h, 025h, 016h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 00Fh, 015h, 021h
|
||||||
|
db 021h, 00Eh, 012h, 028h, 00Fh, 016h, 012h, 023h
|
||||||
|
db 00Ch, 02Dh, 012h, 011h, 028h, 013h, 017h, 015h
|
||||||
|
db 014h, 012h, 006h, 006h, 027h, 025h, 016h, 02Dh
|
||||||
|
db 00Ch, 02Dh, 017h, 013h, 019h, 012h, 026h, 020h
|
||||||
|
db 02Dh, 00Ch, 02Eh, 012h, 015h, 013h, 017h, 00Fh
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage9
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata9 & 0ffh
|
||||||
|
intpage9
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage9
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata9:
|
||||||
|
db 00Ch, 02Dh, 014h, 019h, 023h, 028h, 005h, 007h
|
||||||
|
db 027h, 025h, 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 02Dh, 014h, 019h, 023h, 028h, 023h, 01Dh
|
||||||
|
db 012h, 021h, 028h, 026h, 020h, 022h, 016h, 026h
|
||||||
|
db 00Ch, 02Dh, 014h, 019h, 023h, 028h, 012h, 022h
|
||||||
|
db 017h, 01Eh, 012h, 014h, 028h, 00Fh, 00Eh, 027h
|
||||||
|
db 00Ch, 02Dh, 014h, 019h, 023h, 028h, 016h, 02Dh
|
||||||
|
db 014h, 012h, 013h, 00Fh, 017h, 00Eh, 027h, 025h
|
||||||
|
db 00Ch, 02Dh, 014h, 019h, 023h, 028h, 026h, 017h
|
||||||
|
db 014h, 017h, 028h, 023h, 013h, 020h, 019h, 01Dh
|
||||||
|
db 00Ch, 02Dh, 014h, 019h, 023h, 028h, 019h, 01Dh
|
||||||
|
db 020h, 013h, 01Fh, 028h, 01Dh, 015h, 02Dh, 014h
|
||||||
|
db 00Ch, 02Dh, 014h, 019h, 023h, 028h, 014h, 015h
|
||||||
|
db 014h, 020h, 02Dh, 01Fh, 01Dh, 020h, 026h, 027h
|
||||||
|
db 00Ch, 017h, 002h, 028h, 000h, 006h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
|
||||||
|
align 128
|
||||||
|
initpage10
|
||||||
|
call extramenable
|
||||||
|
mov r1,#0
|
||||||
|
mov r7,#pagedata10 & 0ffh
|
||||||
|
intpage10
|
||||||
|
mov a,r7
|
||||||
|
movp a,@a
|
||||||
|
mov r5,a
|
||||||
|
call putchar
|
||||||
|
inc r7
|
||||||
|
inc r1
|
||||||
|
mov a,r1
|
||||||
|
cpl a
|
||||||
|
jb7 intpage10
|
||||||
|
jmp initend
|
||||||
|
|
||||||
|
align 128
|
||||||
|
|
||||||
|
pagedata10:
|
||||||
|
db 00Ch, 017h, 002h, 028h, 000h, 007h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 001h, 000h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 001h, 001h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 001h, 004h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 001h, 006h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 001h, 009h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 002h, 001h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
||||||
|
db 00Ch, 017h, 002h, 028h, 003h, 000h, 027h, 025h
|
||||||
|
db 016h, 02Dh, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch, 00Ch
|
Loading…
Reference in New Issue
Block a user