z88dk-lib +scz180 -f ff
zcc +scz180 -subtype=cpm -clib=sdcc_iy -llib/scz180/ff -v -m -SO3 --math32_z180 --max-allocs-per-node80000 diskio_check.c -o diskchk
CP/M-80 v2.2, 54.0K TPA
B>a:
A>b:xm r diskchk.com
XMODEM v12.5 - 07/13/86
RBC, 28-Aug-2019 [WBW], ASCI
Receiving: A0:DISKCHK.COM
376k available for uploads
File open - ready to receive
To cancel: Ctrl-X, pause, Ctrl-X
CKCK
A>diskchk
test_diskio(0, 3, 0x2C7C, 0x1000)
**** Test cycle 1 of 3 start ****
disk_initalize(0) - ok.
**** Get drive serial number ****
disk_ioctl(0, ATA_GET_SN, 0x2C7C) - failed 4.
Serial number of the drive 0 is .
**** Get drive size ****
disk_ioctl(0, GET_SECTOR_COUNT, 0xD7D1) - ok.
Number of sectors on the drive 0 is 7837696.
**** Get sector size ****
disk_ioctl(0, GET_SECTOR_SIZE, 0xD7D7) - ok.
Size of sector is 512 bytes.
**** Get block size ****
disk_ioctl(0, GET_BLOCK_SIZE, 0xD7D5) - ok.
Size of the erase block is 160 sectors.
**** Single sector write test ****
disk_write(0, 0x2C7C, 0, 1) - ok.
disk_ioctl(0, CTRL_SYNC, NULL) - ok.
disk_read(0, 0x2C7C, 0, 1) - ok.
Data matched.
**** Multiple sector write test ****
disk_write(0, 0x2C7C, 1, 4) - ok.
disk_ioctl(0, CTRL_SYNC, NULL) - ok.
disk_read(0, 0x2C7C, 1, 4) - ok.
Data matched.
**** Single sector write test (misaligned address) ****
disk_write(0, 0x2C7F, 5, 1) - ok.
disk_ioctl(0, CTRL_SYNC, NULL) - ok.
disk_read(0, 0x2C81, 5, 1) - ok.
Data matched.
**** 4GB barrier test ****
disk_write(0, 0x2C7C, 6, 1) - ok.
disk_write(0, 0x2C7C, 5, 1) - ok.
disk_ioctl(0, CTRL_SYNC, NULL) - ok.
disk_read(0, 0x2C7C, 6, 1) - ok.
disk_read(0, 0x2C7C, 5, 1) - ok.
Data matched.
**** Test cycle 1 of 3 completed ****
--- snip ---
Congratulations! The disk driver works well.
A>
Been fairly productive over the past week, and have added the SC130 (and partial SC126) to the z88dk platform list as scz180.
- rom - which implies that the code relies on no other code, and is usually used to build a bios or monitor.
- app - which will be a native app model that (if it existed) would call the SCM entry points.
- cpm - which is the only useful model currently, with applications running on either of ROMWBW CP/M or Z-System booted from ROM.
- none - which is no drivers.
The only useful model currently is the cpm startup model. Using this model allows you access to all the z88dk C libraries written for the z180.
Including a pretty effective set of math libraries (even if I have to say so myself).
I've finished a working (but still a bit rough and not properly tested) version of the SD FATFS support. Therefore, you can boot from ROM into CP/M, and then access FATFS formatted SD cards completely normally (as if you were on a PC).
To use this... you can... install the ff library from z88dk-libs, into your z88dk repository.
z88dk-lib +scz180 -f ff
Then your applications can be compiled with this incantation,...
zcc +scz180 -subtype=cpm -clib=sdcc_iy -llib/scz180/ff -v -m -SO3 --math32_z180 --max-allocs-per-node80000 @diskio_check.c -o diskchk
Hi Phillip,
RomWBW does have an API. It is documented in Doc\RomWBW Architecture.pdf in the RomWBW download.
Been fairly productive over the past week, and have added the SC130 (and partial SC126) to the z88dk platform list as scz180.
Support will eventually cover four startup models.
- rom - which implies that the code relies on no other code, and is usually used to build a bios or monitor.
- hbios - which will be a native app model that will call the ROMWBW HBIOS entry points.
- cpm - which is the only useful model currently, with applications running on either of ROMWBW CP/M or Z-System booted from ROM.
- none - which is no drivers.
The only useful model currently is the cpm startup model. Using this model allows you access to all the z88dk C libraries written for the z180. Including a pretty efficient set of math libraries, optimised for z180 (even if I have to say so myself).
Next step is to support an application startup model.
That's nice stuff ! Thank you very much. What are the differences between the support for SC126 and SC130 ?
Limitations ? Missing features ?
Phillip Stevens wrote:Been fairly productive over the past week, and have added the SC130 (and partial SC126) to the z88dk platform list as scz180.
Ok, well the next step is now well underway. I've committed the app subtype, which now has direct connectivity to the HBIOS serial drivers for the SC126 and SC130.
This subtype utilises the ROMWBW HBIOS system calls (call 0xFFF0) to provide two terminals stdin, stdout, stderr, and ttyin, ttyout, and ttyerr, on asci0 and asci1 respectively.
A resulting application example_CODE.bin (or example.bin) can be uploaded using the CP/M xmodem function and then run. If it doesn't overwrite the CP/M BDOS/BIOS when the data and bss sections are expanded and with its heap and stack usage, when the application exits it will return to CP/M, otherwise the hardware will be restarted, and reboots into dgbmon.
Alternatively an Intel Hex file can be uploaded by the dgbmon directly (although this is much slower in practice).The application is loaded at 0x0100 and initially places its stack at 0xF000, which is the base of the dbgmon. Wayne has moved the dbgmon to 0xF000 to provide uninterrupted space for the z88dk app subtype from 0x0100 through to 0xF000.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#include <arch/scz180/system_time.h>
#pragma printf = "%li %lu %s %u" // enables printf format conversion for %li %lu %s, %u only, to save space
#define UNIX_OFFSET 946684800UL
void main(void)
{
struct timespec startTime, endTime, resTime;
resTime.tv_sec = 1573555318 - UNIX_OFFSET; // it was about this time when I tested. to get timestamp: date +%s
// clock_settime(CLOCK_REALTIME,&resTime); // set the real time once, and it will be maintained through reboots
clock_gettime(CLOCK_REALTIME,&startTime);
printf("Start: %li sec %lu msec\n", startTime.tv_sec, startTime.tv_nsec/1000000 );
fprintf(stdout,"Hello World R\nHello World C\nHello World 2\nHello World 0\nHello World 1\nHello World 4\n");
for (uint16_t i= 0; i < 512; ++i) {
clock_gettime(CLOCK_REALTIME,&endTime);
printf("End: %li sec %lu msec\n", endTime.tv_sec, endTime.tv_nsec/1000000 );
timersub(&endTime, &startTime, &resTime);
printf("Elapsed: %li sec %lu msec\n", resTime.tv_sec, resTime.tv_nsec/1000000 );
}
}
zcc +scz180 -subtype=app -SO3 -clib=sdcc_iy -v -m --list --math32_z180 --c-code-in-asm --max-allocs-per-node40000 test.c -o test -create-app
A> b:xm r test.com
zcc <- the z88dk preprocessor. this calls everything
+scz180 <- the target in this case the SC130, but it will also work for SC126 (limited hardware support though)
-subtype=app <- the specific goal for the compilation, whether app for HBIOS or cpm for CPM or rom for raw hardware
-SO3 <- optimise strongly, always do this, unless you suspect a compiler bug
-clib=sdcc_iy <- use the zsdcc (sdcc) compiler, together with the new library in iy variant vs. -clib=new for sccz80 and new libarary
-v <- verbose
-m <- provide a map file, needed to create the app
--list <- provide listings
--math32_z180 <- use the 32 bit IEEE z180 specific library
--c-code-in-asm <- provide C comments in assembly (easier to read listings), but breaks some optimisation for sccz80
--max-allocs-per-node40000 <- optimise register allocation for sdcc reasonably strongly 1000000 to 10000 are sensible values
test.c <- the input file, can also be a number of files if proceeded by @. i.e. @test.lst
-o test <- output file root name
-create-app <- build an intel hex application
I've committed the hbios subtype, which now has direct connectivity to the HBIOS serial drivers for the SC126 and SC130.
This subtype utilises the ROMWBW HBIOS system calls (call 0xFFF0) to provide two terminals stdin, stdout, stderr, and ttyin, ttyout, and ttyerr, on asci0 and asci1 respectively.
Now the 'nix like <sys/time.h> functions have been completed. This means that a standard 'nix time stamp can be loaded into a 32 bit time_t register, and real time will be maintained. There is a 20ms resolution on the timer, which is reported in nanoseconds as per the standard. The Y2K epoch is offset from the 'nix epoch by the UNIX_OFFSET of 946684800 seconds.
Tue Nov 12 10:41:58 2019
#include <lib/scz180/time.h>
void main(void)
{
time_t theTime;
struct tm CurrTimeDate; // set up an array for the time info.
char timeStore[26];
// snip
time(&theTime);
localtime_r(&theTime, &CurrTimeDate);
asctime_r(&CurrTimeDate, timeStore);
fprintf(stdout, "%s\n", timeStore);
// snip
fprintf(ttyout, "SYSTEM Time: %s\r\n", ctime( (time_t *)&theTime)); // optionally all in one line, on the second serial port
}
> z88dk-lib +scz180 -f time
> zcc +scz180 -subtype=app -SO3 -v -m -clib=sdcc_iy -llib/scz180/time --math32_z180 --max-allocs-per-node40000 test.c -o test
I have added the SC130 (and partial SC126) to the z88dk platform list as scz180.
Support will eventually cover four startup models.
- rom - which implies that the code relies on no other code, and is usually used to build a bios or monitor.
- hbios - which is a native app model that will call the ROMWBW HBIOS entry points.
- cpm - which is for applications running on either of ROMWBW CP/M or Z-System booted from ROM.
- none - which is no drivers.
The most useful models currently are the hbios and cpm startup models. Using these models allows you access to all the z88dk C libraries written for the z180. Including a pretty efficient set of math libraries, optimised for z180 (even if I have to say so myself).
I've committed the hbios subtype, which now has direct connectivity to the HBIOS serial drivers for the SC126 and SC130.
ROMWBW has a debug monitor dbgmon that can load Intel Hex from serial, and it has two versions of CP/M and other programs also in ROM.
This subtype utilises the ROMWBW HBIOS system calls (call 0xFFF0) to provide two terminals stdin, stdout, stderr, and ttyin, ttyout, and ttyerr, on asci0 and asci1 respectively.
A resulting application example.bin can be uploaded using the CP/M xmodem function and then run as EXAMPLE.COM. If it doesn't overwrite the CP/M BDOS/BIOS when the data and bss sections are expanded and with its heap and stack usage, then when the application exits it will return to CP/M, otherwise the hardware will be restarted, and reboots into dgbmon.
Alternatively an Intel Hex file (example.ihx) can be uploaded by the dgbmon directly using the L function. So reboot and then M L to load a new version of your program. I use cat on linux to simply upload the hex file. Now that dbgmon has been optimised a little, I find it can keep up with 115200 baud cat with the scz180 platform.The application is loaded at 0x0100 and initially places its stack at 0xF000, which is the base of the dbgmon. Wayne has moved the dbgmon to 0xF000 to provide more uninterrupted space for the z88dk hbios subtype.
TO DO (in later smaller commits).
- connect the sys/time.h functions, pending PR #54 at ROMWBW. - DONE- connect the hbios disk functions to FatFs, so long as z88dk newlib doesn't have file acccess functions. - DONE
- bank switching so app can expand beyond one page.
// return DEHL, function BC
uint32_t hbios(uint16_t func);
// return A, function BC
uint8_t hbios_a(uint16_t func);
// return A, function BC, arg DE
uint8_t hbios_a_de(uint16_t func, uint16_t arg);
// return A, function BC, arg DEHL
uint8_t hbios_a_dehl(uint16_t func, uint32_t arg);
// return A, function BC, arg DE, void * HL
uint8_t hbios_a_de_hl(uint16_t func, uint16_t arg, void * buffer);
// return E, function BC
extern uint8_t hbios_e(uint16_t func);
// return E, function BC, arg DE
extern uint8_t hbios_e_de(uint16_t func, uint16_t arg);
// return E, function BC, arg DEHL
uint8_t hbios_e_dehl(uint16_t func, uint32_t arg);
// return E, function BC, arg DE, void * HL
uint8_t hbios_e_de_hl(uint16_t func, uint16_t arg, void * buffer);
/*-----------------------------------------------------------------------*/
/* Write Sector(s) */
/*-----------------------------------------------------------------------*/
DRESULT disk_write (
BYTE pdrv, /* Physical drive number */
const BYTE *buff, /* Pointer to the data to be written */
LBA_t sector, /* Start sector number (LBA) */
UINT count /* Sector count (1..128) */
)
{
uint8_t wattempt = WRITE_ATTEMPTS; /* Write attempts */
uint8_t resp = 0;
if (count == 0 ) return RES_PARERR; /* sector count can't be zero */
do {
if ( hbios_a_dehl( BF_DIOSEEK<<8|pdrv, sector|LBA_ADDRESS ) == 0) {
resp = hbios_e_de_hl( BF_DIOWRITE<<8|pdrv, count, buff );
if ( resp == count ) resp = RES_OK;
}
} while ((--wattempt != 0) && (resp != RES_OK) );
return resp;
}
/*----------------------------------------------------------------------*/
/* Foolproof FatFs sample project for Z80 (C)feilipu, 2019 */
/*----------------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ffconf.h" /* FatFs configuration. Use same file as you used to compile library */
#if __YAZ180
#include <arch/yaz180.h>
#include <lib/yaz180/ff.h> /* Declarations of FatFs API */
#elif __SCZ180
#include <arch/scz180.h>
#include <lib/scz180/ff.h> /* Declarations of FatFs API */
#elif __RC2014
#include <arch/rc2014.h>
#include <lib/rc2014/ff.h> /* Declarations of FatFs API */
#else
#warning - no FatFs library available
#endif
#pragma printf = "%s %u" /* Reduce program size by removing unneeded format converters */
#pragma output CRT_ORG_BSS = 0x9000 /* move bss origin to address 0x9000 (check map for overlap between data and bss) */
// zcc +rc2014 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/hbios/diskio_hbios -llib/rc2014/ff ffmain.c -o ffmain -create-app
// zcc +scz180 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/scz180/time -llib/scz180/diskio_sd -llib/scz180/ff ffmain.c -o ffmain -create-app
// zcc +scz180 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/scz180/time -llib/hbios/diskio_hbios -llib/hbios/ff ffmain.c -o ffmain -create-app
// zcc +hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/hbios/time -llib/hbios/diskio_hbios -llib/hbios/ff ffmain.c -o ffmain -create-app
// cat > /dev/ttyUSB0 < fftest.ihx
static FATFS FatFs; /* FatFs work area needed for each volume */
static FIL Fil; /* File object needed for each open file */
static char buffer[128]; /* must be in bss (which is above 0x8000) for romwbw hbios */
void main (void)
{
UINT bw;
UINT br;
FRESULT res;
res = f_mount(&FatFs, "2:", 1); /* Give a work area to the SD drive */
if(res != FR_OK) printf("\nf_mount error #%u\r\n", res);
if (f_open(&Fil, "2:bfile.txt", FA_CREATE_ALWAYS | FA_WRITE | FA_READ ) == FR_OK)
{ /* Create a file if needed */
res = f_write(&Fil, "It works!\r\n", 11, &bw); /* Write data to the file */
if(res != FR_OK) printf("\nf_write error #%u\r\n", res);
br = 0;
res = f_read(&Fil, buffer, 128, &br); /* Read data from the file */
if(res != FR_OK) printf("\f_read error #%u\r\n", res);
res = f_close(&Fil); /* Close the file */
if(res != FR_OK) printf("\nf_close error #%u\r\n", res);
printf("\r\n%u bytes: %s\r\n", br, buffer);
if(br > 0) printf("It works!\r\n");
}
else
{
printf("\nf_open error #%u\r\n", res);
}
f_mount(0, "2:", 0); /* Unmount and free work area */
}
Phillip Stevens wrote:I have added the SC130 (and partial SC126) to the z88dk platform list as scz180.Support will eventually cover four startup models.
- rom - which implies that the code relies on no other code, and is usually used to build a bios or monitor.
- hbios - which is a native app model that will call the ROMWBW HBIOS entry points.
- cpm - which is for applications running on either of ROMWBW CP/M or Z-System booted from ROM.
- none - which is no drivers.
The most useful models currently are the hbios and cpm startup models. Using these models allows you access to all the z88dk C libraries written for the z180. Including a pretty efficient set of math libraries, optimised for z180 (even if I have to say so myself).I've committed the hbios subtype, which now has direct connectivity to the HBIOS serial drivers for the SC126 and SC130.ROMWBW has a debug monitor dbgmon that can load Intel Hex from serial, and it has two versions of CP/M and other programs also in ROM.This subtype utilises the ROMWBW HBIOS system calls (call 0xFFF0) to provide two terminals stdin, stdout, stderr, and ttyin, ttyout, and ttyerr, on asci0 and asci1 respectively.A resulting application example.bin can be uploaded using the CP/M xmodem function and then run as EXAMPLE.COM. If it doesn't overwrite the CP/M BDOS/BIOS when the data and bss sections are expanded and with its heap and stack usage, then when the application exits it will return to CP/M, otherwise the hardware will be restarted, and reboots into dgbmon.Alternatively an Intel Hex file (example.ihx) can be uploaded by the dgbmon directly using the L function. So reboot and then M L to load a new version of your program. I use cat on linux to simply upload the hex file. Now that dbgmon has been optimised a little, I find it can keep up with 115200 baud cat with the scz180 platform.The application is loaded at 0x0100 and initially places its stack at 0xF000, which is the base of the dbgmon. Wayne has moved the dbgmon to 0xF000 to provide more uninterrupted space for the z88dk hbios subtype.TO DO (in later smaller commits).- connect the sys/time.h functions, pending PR #54 at ROMWBW. - DONE- connect the hbios disk functions to FatFs, so long as z88dk newlib doesn't have file acccess functions. - DONE- bank switching so app can expand beyond one page.Now the final piece of support has been added to the ROMWBW HBIOS to allow the use of applications that need to have FAT32 formatted SD cards.This -subtype=hbios model uses the drivers present in the HBIOS to provide the largest possible application space, and direct access to all HBIOS functions.
The hbios subtype assumes you will run code from 0x0100, and doesn't overwrite the monitor at 0xF000. Although really, all that is needed to be preserved is the hbios stubs in the upper few bytes, if you're pushed for space.
// zcc +scz180 -subtype=hbios -v -m -SO3 -clib=sdcc_iy -llib/scz180/time -llib/scz180/ff --math32_z180 --list --max-allocs-per-node100000 fftest.c -o fftest -create-app
// cat > /dev/ttyUSB0 < fftest.ihx
static FATFS FatFs; /* FatFs work area needed for each volume */
static FIL Fil; /* File object needed for each open file */
static char buffer[128]; /* must be in bss (which is above 0x8000) for romwbw hbios */
void main (void)
{
UINT bw;
UINT br;
FRESULT res;
res = f_mount(&FatFs, "2:", 1); /* Give a work area to the SD drive */
if(res != FR_OK) printf("\nf_mount error #%u\r\n", res);
if (f_open(&Fil, "2:bfile.txt", FA_OPEN_ALWAYS | FA_WRITE | FA_READ ) == FR_OK)
{ /* Create a file if needed */
res = f_write(&Fil, "It works!\r\n", 11, &bw); /* Write data to the file */
if(res != FR_OK) printf("\nf_write error #%u\r\n", res);
br = 0;
res = f_read(&Fil, buffer, 128, &br); /* Read data from the file */
if(res != FR_OK) printf("\f_read error #%u\r\n", res);
res = f_close(&Fil); /* Close the file */
if(res != FR_OK) printf("\nf_close error #%u\r\n", res);
printf("\r\n%u bytes: %s\r\n", br, buffer);
if(br > 0) printf("It works!\r\n");
}
else
{
printf("\nf_open error #%u\r\n", res);
}
f_mount(0, "2:", 0); /* Unmount and free work area */
}
I am very pleased to see this integration of RomWBW HBIOS into z88dk.
Phillip Stevens wrote:I have added the SC130 (and partial SC126) to the z88dk platform list as scz180.Support will eventually cover four startup models.
- rom - which implies that the code relies on no other code, and is usually used to build a bios or monitor.
- hbios - which is a native app model that will call the ROMWBW HBIOS entry points.
- cpm - which is for applications running on either of ROMWBW CP/M or Z-System booted from ROM.
- none - which is no drivers.
The most useful models currently are the hbios and cpm startup models. Using these models allows you access to all the z88dk C libraries written for the z180.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#if __YAZ180
#include <arch/yaz180.h>
#include <lib/yaz180/time.h> /* Declaration of system time */
#elif __SCZ180
#include <arch/scz180.h>
#include <lib/scz180/time.h> /* Declaration of system time */
#elif __HBIOS
#include <lib/scz180/time.h> /* Declaration of system time */
#elif __RC2014#include <lib/rc2014/time.h> /* Declaration of system time */
#warning No time measurement possible.
#else
#error Do you have time?
#endif
#include "ffconf.h"
#if __YAZ180
#include <lib/yaz180/ff.h> /* Declarations of FatFs API */
#include <arch/yaz180/diskio.h> /* Declarations of diskio & IDE functions */
//#elif __RC2014
//#include <lib/rc2014/ff.h> /* Declarations of FatFs API */
//#include <arch/rc2014/diskio.h> /* Declarations of diskio & IDE functions */
#elif __RC2014
#include <lib/hbios/ff.h> /* Declarations of FatFs API */
#include <lib/hbios/diskio_hbios.h> /* Declarations of diskio functions */
#include <arch/hbios.h> /* Declarations of HBIOS functions */
#elif __SCZ180
#include <lib/scz180/ff.h> /* Declarations of FatFs API */
#include <lib/scz180/diskio_sd.h> /* Declarations of diskio functions */
#include <arch/scz180.h> /* Declarations of SD functions */
//#elif __SCZ180
//#include <lib/hbios/ff.h> /* Declarations of FatFs API */
//#include <lib/hbios/diskio_hbios.h> /* Declarations of diskio functions */
//#include <arch/hbios.h> /* Declarations of HBIOS functions */
#elif __HBIOS
#include <lib/hbios/ff.h> /* Declarations of FatFs API */
#include <lib/hbios/diskio_hbios.h> /* Declarations of diskio functions */
#include <arch/hbios.h> /* Declarations of HBIOS functions */
#else
#warning - no FatFs library available
#endif
#pragma output CRT_ORG_BSS = 0x9000 // move bss origin to address 0x9000 (check map to confirm there is no overlap between data and bss sections)
#pragma printf = "%s %c %u %li %lu" // enables %s, %c, %u, %li, %lu only
// zcc +yaz180 -subtype=app -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/yaz180/time -llib/yaz180/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +rc2014 -subtype=cpm -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/rc2014/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +rc2014 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/hbios/time -llib/hbios/diskio_hbios -llib/hbios/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +scz180 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/scz180/time -llib/scz180/diskio_sd -llib/scz180/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +scz180 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/hbios/time -llib/hbios/diskio_hbios -llib/hbios/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/hbios/time -llib/hbios/diskio_hbios -llib/hbios/ff fileCopyTest.c -o fileCopyTest -create-app
static FILINFO Finfo;
static FATFS FatFs; /* FatFs work area needed for each volume */
static FIL FileIn, FileOut; /* File object needed for each open file */
static BYTE buffer[4096]; /* 4kB working buffer */
int main (void)
{
UINT bw;
UINT br;
DWORD bwt = 0;
FRESULT res;
struct timespec startTime, endTime, resTime;
startTime.tv_sec = 1577836800 - UNIX_OFFSET;
clock_settime(CLOCK_REALTIME, &startTime); /* Set the time of day, y2k epoch */
if ((res = f_mount(&FatFs, "2:", 1)) == FR_OK) { /* Give a work area to the 0th or 2nd drive */
printf("\r\n\nFatFs.fs_type %u\nFatFs.fsize %lu\n", FatFs.fs_type, FatFs.fsize);
printf("\r\nOpening random1.txt");
if ((res = f_open(&FileIn, "2:random1.txt", FA_READ)) == FR_OK) { /* "0:random1.txt" for SD drivers */
printf(" - Opened");
if ((res = f_lseek(&FileIn, 0)) == FR_OK) {
printf("\r\nCreating random2.txt");
if ((res = f_open(&FileOut, "2:random2.txt", FA_CREATE_ALWAYS | FA_WRITE)) == FR_OK) { /* "0:random2.txt" for SD drivers */
printf(" - Created\r\n\nCopying...");
clock_gettime(CLOCK_REALTIME,&startTime);
for (;;) {
res = f_read(&FileIn, buffer, sizeof(buffer), &br);
if (res != FR_OK || br == 0) break; // eof or error
res = f_write(&FileOut, buffer, br, &bw);
bwt += bw;
if (res != FR_OK || bw < br) break; // error or disk full
}
clock_gettime(CLOCK_REALTIME,&endTime);
f_close(&FileOut);
if ((res = f_unlink("2:random2.txt")) != FR_OK) {
printf("\r\nCouldn't delete random2.txt - f_unlink error #%u\r\n", res);
}
} else {
printf("\r\nCouldn't open random2.txt - f_open error #%u\r\n", res);
}
} else {
printf("\r\nCouldn't seek random1.txt - f_lseek error #%u\r\n", res);
}
f_close(&FileIn);
} else {
printf("\r\nCouldn't open random1.txt - f_open error #%u\r\n", res);
}
timersub(&endTime, &startTime, &resTime);
printf("\r\nCopied %lu bytes", bwt ); printf(", the time taken was %li.%.4lu seconds\n", resTime.tv_sec, resTime.tv_nsec/100000 );
f_mount(0, "2:", 0); /* Free work area */
} else {
printf("\r\nCouldn't mount drive - f_mount error #%u\r\n", res);
}
return 0;
}
RetroBrew HBIOS v2.9.2-pre.22, 2019-11-30
SC130 Z8S180-N @ 36.864MHz IO=0xC0
1 MEM W/S, 2 I/O W/S, INT MODE 2
512KB ROM, 512KB RAM
ASCI0: IO=0xC0 ASCI W/BRG MODE=115200,8,N,1
ASCI1: IO=0xC1 ASCI W/BRG MODE=115200,8,N,1
DSRTC: MODE=STD IO=0x0C NOT PRESENT
MD: UNITS=2 ROMDISK=384KB RAMDISK=384KB
PPIDE: IO=0x20 NOT PRESENT
SD: MODE=SC OPR=0x0C CNTR=0xCA TRDR=0xCB DEVICES=1
SD0: SDHC NAME=NCard BLOCKS=0x00779800 SIZE=3827MB
Unit Device Type Capacity/Mode
---------- ---------- ---------------- --------------------
Char 0 ASCI0: RS-232 115200,8,N,1
Char 1 ASCI1: RS-232 115200,8,N,1
Disk 0 MD1: RAM Disk 384KB,LBA
Disk 1 MD0: ROM Disk 384KB,LBA
Disk 2 SD0: SD Card 3827MB,LBA
SC130 Boot Loader
ROM: (M)onitor (C)P/M (Z)-System (F)orth (B)ASIC (T)-BASIC
Disk: (0)MD1 (1)MD0 (2)SD0
Boot Selection? M
Loading Monitor...
Monitor Ready (H for Help)
>L
Loaded
>R100
FatFs.fs_type 3
FatFs.fsize 7640
Opening random1.txt - Opened
Creating random2.txt - Created
Copying...
Copied 1048576 bytes, the time taken was 18.3800 seconds
Monitor Ready (H for Help)
>L
Loaded
>R100
FatFs.fs_type 3
FatFs.fsize 7640
Opening random1.txt - Opened
Creating random2.txt - Created
Copying...
Copied 1048576 bytes, the time taken was 44.4400 seconds
Monitor Ready (H for Help)
>
YAZ180 - yabios - CRT
> :? :-)
> loadh 3
::####################
Done!
Loaded Bank: 3
> mkb 3
Initialised Bank: 3
> initb 3
FatFs.fs_type 3
FatFs.fsize 1816
Opening random1.txt - Opened
Creating random2.txt - Created
Copying...
Copied 1048576 bytes, the time taken was 7.0429 seconds
>
YAZ180 - yabios - CRT
> :? :-)
> loadh 3
::############################
Done!
Loaded Bank: 3
> mkb 3
Initialised Bank: 3
> initb 3
FatFs.fs_type 3
FatFs.fsize 15161
Opening random1.txt - Opened
Creating random2.txt - Created
Copying...
Copied 1048576 bytes, the time taken was 5.0625 seconds
>
In summary, the SCZ180 platform just has CISO SD drivers included in z88dk. An additional library to provide the diskio layer for the CISO SD Card has been created. In parallel a library to provide diskio off the back of the HBIOS API has also been created. When building applications, either CSIO SD or HBIOS SD (or any other hardware) interfaces can then be chosen at build time, by linking from the command line.
The RC2014 platform has an 82C55 IDE based diskio platform included in z88dk. But if needed any another diskio layer can be linked from the command line, and this will override the integrated version.Any other HBIOS equipped platform can use the hbios target, together with the diskio layer using the HBIOS API, to access the ChaN FAT file system library code.So what does the user code look like? Glad you asked... this is to copy one file "random1.txt" to another file "random2.txt".
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/time.h>
#if __YAZ180
#include <arch/yaz180.h>
#include <lib/yaz180/time.h> /* Declaration of system time */
#elif __SCZ180
#include <arch/scz180.h>
#include <lib/scz180/time.h> /* Declaration of system time */
#elif __HBIOS
#include <lib/scz180/time.h> /* Declaration of system time */
#elif __RC2014
#warning No time possible
#include "ffconf.h"
#pragma output CRT_ORG_BSS = 0x9000 // move bss origin to address 0x9000 (check map to confirm there is no overlap between data and bss sections)
#pragma printf = "%s %c %u %li %lu" // enables %s, %c, %u, %li, %lu only
// zcc +yaz180 -subtype=app -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/yaz180/time -llib/yaz180/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +rc2014 -subtype=cpm -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/rc2014/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +rc2014 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/hbios/diskio_hbios -llib/rc2014/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +scz180 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/scz180/time -llib/scz180/diskio_sd -llib/scz180/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +scz180 -subtype=hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/scz180/time -llib/hbios/diskio_hbios -llib/hbios/ff fileCopyTest.c -o fileCopyTest -create-app
// zcc +hbios -clib=sdcc_iy -SO3 -v -m --list --max-allocs-per-node100000 -llib/scz180/time -llib/hbios/diskio_hbios -llib/hbios/ff fileCopyTest.c -o fileCopyTest -create-app
printf("\r\nCopied %lu bytes, the time taken was %li.%.4lu seconds\n", bwt, resTime.tv_sec, resTime.tv_nsec/100000 );
f_mount(0, "2:", 0); /* Free work area */
} else {
printf("Couldn't mount drive - f_mount error #%u\r\n", res);
}
return 0;
}
The above is an example of two separate builds. Firstly using the CISO SD Card drivers, and secondly using the HBIOS API.