Gemini and others
Gemini and others
I recently hacked (a bit too aggressively) the xbeaver emulator to get it running on Windows.
The resulting program has a limited set of the original features and simply crashes if someone tries to use them, but it's enough for progressing with the z88dk tools and hopefully the libraries.
Today I've extended appmake to write the Galaxy Gemini 35 tracks disk format.
Here's how xbeaver looks like on Windows.
The resulting program has a limited set of the original features and simply crashes if someone tries to use them, but it's enough for progressing with the z88dk tools and hopefully the libraries.
Today I've extended appmake to write the Galaxy Gemini 35 tracks disk format.
Here's how xbeaver looks like on Windows.
You do not have the required permissions to view the files attached to this post.
Re: Gemini and others
Console support is ready, I'm not pulling in yet, I'm still trying to understand how to deal with the graphics.
Probably 2 modes are enough, a mid-rez of 160x75 plus a 256x256 graphics mode with partial coverage of the z88dk libraries and valid only on the later graphics boards.
I managed to get the exact font/udg structure already available for the MicroBEE, including the 2x2 blocky graphics characters in Sinclair style.
I also fixed the "inverse font" option on the MicroBEE (valid only in ANSI VT mode).
VTSTONE uses it, I'm attaching some picture.
The Gemini configured to use the Amstrad CPC font (ANSI VT emulation): Loading a font: The Gemini in mode2, generic console driver, with the ZX Spectrum font: The console code runs well (32x25 characters) also in high rez graphics mode, which could be useful. The emulation of the graphics board is partial, so I'm not squeezing this monster computer at its maximum: the real hardware permits a different service/terminal program to be loaded on the graphics board and run locally by its internal CPU (a Z80B) !
Probably 2 modes are enough, a mid-rez of 160x75 plus a 256x256 graphics mode with partial coverage of the z88dk libraries and valid only on the later graphics boards.
I managed to get the exact font/udg structure already available for the MicroBEE, including the 2x2 blocky graphics characters in Sinclair style.
I also fixed the "inverse font" option on the MicroBEE (valid only in ANSI VT mode).
VTSTONE uses it, I'm attaching some picture.
The Gemini configured to use the Amstrad CPC font (ANSI VT emulation): Loading a font: The Gemini in mode2, generic console driver, with the ZX Spectrum font: The console code runs well (32x25 characters) also in high rez graphics mode, which could be useful. The emulation of the graphics board is partial, so I'm not squeezing this monster computer at its maximum: the real hardware permits a different service/terminal program to be loaded on the graphics board and run locally by its internal CPU (a Z80B) !
You do not have the required permissions to view the files attached to this post.
Re: Gemini and others
Lo rez graphics (160x75).
You do not have the required permissions to view the files attached to this post.
Re: Gemini and others
Xbeaver helped me in extending the support for the Alphatronic-PC (a.k.a. MATMOS).
The new disk format is still not recognized by MAME, the reason is still obscure to me, it could depend on a different SKEW table or on a special way to create the boot tracks.
By the way Xbeaver works already with the resulting raw disk images.
I extended the console library, now the ANSI-VT mode is supported. I suspect the max rows should be limited, because it prints blindly before scrolling.
The new disk format is still not recognized by MAME, the reason is still obscure to me, it could depend on a different SKEW table or on a special way to create the boot tracks.
By the way Xbeaver works already with the resulting raw disk images.
I extended the console library, now the ANSI-VT mode is supported. I suspect the max rows should be limited, because it prints blindly before scrolling.
You do not have the required permissions to view the files attached to this post.
Re: Gemini and others
I finally understood what was wrong with the disk images !!!
Besides a wrong track numbering (now fixed), the MAME emulator required a disk image to be "run" at the proper drive speed.
I improved the appmake conversion tool by adding a disk_spec option named "disk_mode", used only with the IMD format.
For the Alphatronic it is now set to "MFM300", while the default value for the other targets is (at the moment) left at the original default of "MFM500". I think that this trick could fix other targets as well, currently working on MAME only in other disk formats or not working at all.
Besides a wrong track numbering (now fixed), the MAME emulator required a disk image to be "run" at the proper drive speed.
I improved the appmake conversion tool by adding a disk_spec option named "disk_mode", used only with the IMD format.
For the Alphatronic it is now set to "MFM300", while the default value for the other targets is (at the moment) left at the original default of "MFM500". I think that this trick could fix other targets as well, currently working on MAME only in other disk formats or not working at all.
Re: Gemini and others
I took the opportunity to check the existing cp/m disk options with MAME and adjusted the results to make the IMD format work in many cases.
While doing so I noticed a bug in the nascom cp/m format, now fixed.
While doing so I noticed a bug in the nascom cp/m format, now fixed.
Re: Gemini and others
CP/M option for the NASCOM is now in working order, in classic, generic or ANSI console mode, plus graphics.
Now the disk image works correctly in both the raw and IMD formats.
I also fixed a minor problem on the non-CP/M console library (the top row was shifed while scrolling in the generic console mode).
Now the disk image works correctly in both the raw and IMD formats.
I also fixed a minor problem on the non-CP/M console library (the top row was shifed while scrolling in the generic console mode).
You do not have the required permissions to view the files attached to this post.
Re: Gemini and others
Thanks for all your work!
On the Alphatronic, there seems to be a bug when using screen mode 1 in cartridge mode. The screen stays in 40 column mode, and every line feed gets doubled.
You can test it with my Deepspace game by adding the last || defined(__ALPHATRO__) condition here:
And it seems that your having great fun with your Windows-compiled Xbeaver emulator. Can you make it available to us even if its still not fully functional? Just declare it as an Alpha Release...
On the Alphatronic, there seems to be a bug when using screen mode 1 in cartridge mode. The screen stays in 40 column mode, and every line feed gets doubled.
You can test it with my Deepspace game by adding the last || defined(__ALPHATRO__) condition here:
Code: Select all
// Define screen modes
// If no modes are defined here, then the system does not require any mode switching to display hires graphics
#if defined(__GALPLUSHIRES__) || defined(__VZ200__) || defined(__PC6001__) || defined(__SPC1000__) || defined(__Z9001_KRT__) || defined(__Z1013_KRT__) || defined(__ALPHATRO__)
#define SCREEN_MODE_STANDARD 0
#define SCREEN_MODE_GAME 1
Re: Gemini and others
Sure, I haven't done it yet only because I haven't found a good home for it.
Even contacting the original author is troublesome because of the antispam of his email server (I'm lucky the server warns me) .
Even contacting the original author is troublesome because of the antispam of his email server (I'm lucky the server warns me) .
Code: Select all
diff original/advantage.cfg new/advantage.cfg
1a2
> if D echo Option D - Demo Disk Boot
2a4
> if L echo Option L - Use large hard disk (30MB)
8c10
< board 0x90 nsavdu 0x20000 Advantage options BDK
---
> board 0x90 nsavdu 0x20000 Advantage options BDK green
11c13,22
< board 0x00 nsambd -opt DA ~/NorthStarAdvantage/system.nsi
---
> if H board 0x00 nsambd -opt DA NorthStarAdvantage/system_hd.nsi
> if !H if !D board 0x00 nsambd -opt DA NorthStarAdvantage/system_flp.nsi NorthStarAdvantage/disks/Utilities.NSI
> if !H if D board 0x00 nsambd -geometry RNS35.2.10.0.512 -opt DA NorthStarAdvantage/disks/demodiag.nsi
>
> #size:179200
> #board 0x00 nsambd -geometry RNS35.1.10.0.512 -opt DA /c/z80/northstar/XITANCPM.NSI
> #size:358400
> #board 0x00 nsambd -geometry RNS35.2.10.0.512 -opt DA /c/z80/northstar/V2212_56.NSI
> #board 0x00 nsambd -geometry RNS35.2.10.0.512 -opt DA /NorthStarAdvantage/system_flp.nsi
>
14d24
< board 0x30 nsaser tty /dev/ttyS0
16d25
< if H board 0x00 nsahd ~/NorthStarAdvantage/ADV_SG5A.NHD
18c27
< binload 0 ~/NorthStarAdvantage/Advantage_Boot_Rom.bin
---
> binload 0 NorthStarAdvantage/Advantage_Boot_Rom.bin
19a29,55
> #Define optional boards here
> #
> #Board Address Slot
> # 0x50 1 -< Use this for the printer
> # 0x40 2 -< Use this for punch/reader
> # 0x30 3 -< Use with network (t-net.com)
> # 0x20 4
> # 0x10 5
> # 0x00 6 -< Use this for the hard disk
>
>
> #Board 1 - printer
> board 0x50 nsaser trace tty tty COM2
>
> #Board 2 for rdr, pun
>
> #moved from board 2 to board 3 to avoid clash with pun/rdr
> #Board 3 - network interface
> board 0x30 nsaser bvrnet &
> beaver/network & #Common network drive
> NorthStarAdvantage/network & #North Star Advantage Work
> /saturn/cpmapps/beaver/diska/user0 #Gemini system files (for import)
>
>
> #Board 6 - hard disk
> if H if !L board 0x00 nsahd NorthStarAdvantage/ADV_SG5A.NHD
> if H if L board 0x00 nsahd NorthStarAdvantage/MS30D-30MB.NHD
diff original/advantage_harddisk.c new/advantage_harddisk.c
31c31
< #define FALSE (0)
---
> #ifndef TRUE
32a33,37
> #endif
>
> #ifndef FALSE
> #define FALSE (0)
> #endif
diff original/advantage_mboard.c new/advantage_mboard.c
10a11
> #ifndef _WIN32
11a13
> #endif
diff original/advantage_parity.c new/advantage_parity.c
8a9
> #ifndef _WIN32
9a11
> #endif
diff original/advantage_video.c new/advantage_video.c
10a11
> #ifndef _WIN32
11a13
> #endif
27c29
< #define FALSE (0)
---
> #ifndef TRUE
28a31,35
> #endif
>
> #ifndef FALSE
> #define FALSE (0)
> #endif
63a71,74
>
> #ifdef _WIN32
> long execution_clock;
> #else
64a76,77
> #endif
>
253,254d265
< struct tms cpu_time;
< clock_t new_clock;
257a269,293
> #ifdef _WIN32
>
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER ticks;
> LARGE_INTEGER tms;
> long new_clock;
>
> if (QueryPerformanceFrequency(&ticks))
> {
> //ticks_per_second = (PointerSizeUInt) ticks.QuadPart;
> ticks_per_second = ticks.QuadPart;
> }
> else
> {
> ticks_per_second = 1L;
> }
> QueryPerformanceCounter(&tms);
>
> new_clock = tms.QuadPart;
>
> #else
>
> struct tms cpu_time;
> clock_t new_clock;
>
259a296,299
>
> #endif
>
>
diff original/agb_video.c new/agb_video.c
66a67
> #ifndef _WIN32
67a69
> #endif
83c85
< #define FALSE (0)
---
> #ifndef TRUE
84a87,91
> #endif
>
> #ifndef FALSE
> #define FALSE (0)
> #endif
276c283,289
< clock_t execution_clock;
---
>
> #ifdef _WIN32
> long execution_clock;
> #else
> clock_t execution_clock;
> #endif
>
1048,1049d1060
< struct tms cpu_time;
< clock_t new_clock;
1052a1064,1088
> #ifdef _WIN32
>
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER ticks;
> LARGE_INTEGER tms;
> long new_clock;
>
> if (QueryPerformanceFrequency(&ticks))
> {
> //ticks_per_second = (PointerSizeUInt) ticks.QuadPart;
> ticks_per_second = ticks.QuadPart;
> }
> else
> {
> ticks_per_second = 1L;
> }
> QueryPerformanceCounter(&tms);
>
> new_clock = tms.QuadPart;
>
> #else
>
> struct tms cpu_time;
> clock_t new_clock;
>
1054a1091,1094
>
> #endif
>
>
diff original/alphatronic_mboard.c new/alphatronic_mboard.c
19a20
> #ifndef _WIN32
20a22
> #endif
diff original/alphatronic_video.c new/alphatronic_video.c
10a11
> #ifndef _WIN32
11a13
> #endif
34c36
< #define FALSE (0)
---
> #ifndef TRUE
35a38
> #endif
36a40,42
> #ifndef FALSE
> #define FALSE (0)
> #endif
311a318,321
>
> #ifdef _WIN32
> long execution_clock;
> #else
312a323,324
> #endif
>
1081,1082c1093
< struct tms cpu_time;
< clock_t new_clock;
---
>
1085a1097,1121
> #ifdef _WIN32
>
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER ticks;
> LARGE_INTEGER tms;
> long new_clock;
>
> if (QueryPerformanceFrequency(&ticks))
> {
> //ticks_per_second = (PointerSizeUInt) ticks.QuadPart;
> ticks_per_second = ticks.QuadPart;
> }
> else
> {
> ticks_per_second = 1L;
> }
> QueryPerformanceCounter(&tms);
>
> new_clock = tms.QuadPart;
>
> #else
>
> struct tms cpu_time;
> clock_t new_clock;
>
1087a1124,1127
>
> #endif
>
>
diff original/baudot_modem.c new/baudot_modem.c
62a63
> #include "pcol_utils.h"
diff original/beaver_net.c new/beaver_net.c
691c691,695
< fd = open( mydata->unix_filename, O_WRONLY | O_TRUNC | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
---
> #ifdef _WIN32
> fd = open( mydata->unix_filename, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
> #else
> fd = open( mydata->unix_filename, O_WRONLY | O_BINARY | O_TRUNC | O_CREAT | O_SYNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
> #endif
697c701
< fd = open( mydata->unix_filename, O_RDONLY );
---
> fd = open( mydata->unix_filename, O_RDONLY | O_BINARY );
737c741
< fd = open( mydata->unix_filename, O_RDONLY);
---
> fd = open( mydata->unix_filename, O_RDONLY | O_BINARY);
764a769,771
> #ifdef _WIN32
> fd = open( mydata->unix_filename, O_RDWR);
> #else
765a773
> #endif
791c799
< fd = open( mydata->unix_filename, O_RDONLY);
---
> fd = open( mydata->unix_filename, O_RDONLY | O_BINARY);
808a817,819
> #ifdef _WIN32
> fd = open( mydata->unix_filename, O_RDWR);
> #else
809a821
> #endif
diff original/bus_bridge.c new/bus_bridge.c
27a28
> #include <string.h>
52a54,86
>
> #ifdef _WIN32
>
> static char * ppt_busname( void * handle )
> {
> return ("-");
> }
>
> BUSBRIDGE_CLASS_T ppt_bus =
> {
> "parport",
> ppt_busname,
> NULL,
> NULL,
> NULL,
> NULL,
> NULL, /* input_multiple */
> NULL /* output_multiple */
> };
>
> BUSBRIDGE_CLASS_T spo_bus =
> {
> "spioutput",
> ppt_busname,
> NULL,
> NULL,
> NULL,
> NULL,
> NULL, /* input_multiple */
> NULL /* output_multiple */
> };
>
> #endif
Only in original: changes.pl
Only in original: CHANGES.txt
Only in original: check_documentation.pl
diff original/cmdparse.c new/cmdparse.c
194a195
> fflush(stdout);
221a223
> fflush(stdout);
diff original/commands.c new/commands.c
49a50,98
> #ifdef _WIN32
>
> /*
> * The definition of the led card
> */
> IOCARD_CARD_DEFN_T hwfp_display =
> {
> "hwfp",
> "Hardware front panel (Blinkenlight API client)",
> 0,
> 0
> };
>
>
> /*
> * The definition of the telent server
> */
> IOCARD_CARD_DEFN_T telnet_server =
> {
> "telnetd",
> "Telnet Server",
> 0,
> 0
> };
>
> /*
> * The definition of the telent server
> */
> IOCARD_CARD_DEFN_T tcpraw_server =
> {
> "tcprawd",
> "TCP Raw Server",
> 0,
> 0
> };
>
> /*
> * The definition of the shell server
> */
> IOCARD_CARD_DEFN_T shell_server =
> {
> "shellserv",
> "Unix Shell Server",
> 0,
> 0
> };
>
>
> #endif
531c580
< fd = open(file, O_RDONLY);
---
> fd = open(file, O_RDONLY | O_BINARY);
535a585
> //if ( read( fd, &byte, 1 ) < 0 ) break;
Only in original: COPYING
diff original/exit_handler.c new/exit_handler.c
2a3
> #include <stddef.h>
Only in original: fileserver.cfg
diff original/floppy.c new/floppy.c
601c601
< fd = open( drive->host_filename, O_RDONLY ); /* See if the file exists */
---
> fd = open( drive->host_filename, O_RDONLY | O_BINARY ); /* See if the file exists */
607c607
< fd = open( drive->host_filename, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR );
---
> fd = open( drive->host_filename, O_WRONLY | O_BINARY | O_CREAT, S_IRUSR | S_IWUSR );
760c760
< fd = open( drive->host_filename, O_RDONLY );
---
> fd = open( drive->host_filename, O_RDONLY | O_BINARY );
843a844,846
> #ifdef _WIN32
> fd = open( drive->host_filename, O_RDWR );
> #else
845c848,849
< lseek( fd, sector_entry->file_position, SEEK_SET );
---
> #endif
> lseek( fd, sector_entry->file_position, SEEK_SET );
870a875,877
> #ifdef _WIN32
> fd = open( drive->host_filename, O_RDWR );
> #else
871a879
> #endif
1116c1124
< fd = open( drive->host_filename, O_RDONLY );
---
> fd = open( drive->host_filename, O_RDONLY | O_BINARY );
1329c1337
< fd = open( drive->host_filename, O_RDONLY );
---
> fd = open( drive->host_filename, O_RDONLY | O_BINARY );
Only in original: gemini.cfg
diff original/gemini_ramdisk.c new/gemini_ramdisk.c
372c372
< fd = open( filename, O_RDONLY );
---
> fd = open( filename, O_RDONLY | O_BINARY );
diff original/gemini_scsi.c new/gemini_scsi.c
241c241
< fd = open( mydata->harddisk_name, O_RDONLY );
---
> fd = open( mydata->harddisk_name, O_RDONLY | O_BINARY );
271a272,274
> #ifdef _WIN32
> fd = open( mydata->harddisk_name, O_RDWR );
> #else
272a276
> #endif
diff original/gemini_svc.c new/gemini_svc.c
59a60
> #ifndef _WIN32
60a62,63
> #endif
> #include <time.h>
79a83,84
> typedef uint16_t u_int16_t;
> //typedef size_t size_type;
338a344,346
> #ifdef _WIN32
> long execution_clock;
> #else
339a348
> #endif
1479,1480d1487
< struct tms cpu_time;
< clock_t new_clock;
1483a1491,1515
> #ifdef _WIN32
>
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER ticks;
> LARGE_INTEGER tms;
> long new_clock;
>
> if (QueryPerformanceFrequency(&ticks))
> {
> //ticks_per_second = (PointerSizeUInt) ticks.QuadPart;
> ticks_per_second = ticks.QuadPart;
> }
> else
> {
> ticks_per_second = 1L;
> }
> QueryPerformanceCounter(&tms);
>
> new_clock = tms.QuadPart;
>
> #else
>
> struct tms cpu_time;
> clock_t new_clock;
>
1486d1517
< clock_delta = new_clock - mydata->execution_clock;
1487a1519,1522
> #endif
>
>
> clock_delta = new_clock - mydata->execution_clock;
1497a1533
>
2075c2111
< fd = open( "system.kst", O_RDONLY );
---
> fd = open( "system.kst", O_RDONLY | O_BINARY );
4132a4169,4171
> #ifdef _WIN32
> LARGE_INTEGER cpu_time;
> #else
4133a4173
> #endif
4185c4225,4233
< mydata->execution_clock = times( &cpu_time);
---
>
> #ifdef _WIN32
> QueryPerformanceCounter(&cpu_time);
> mydata->execution_clock = cpu_time.QuadPart;
>
> #else
> mydata->execution_clock = times(&cpu_time);
> #endif
>
Only in original: harddisk.dsk
diff original/hcms_panel.c new/hcms_panel.c
25a26
> #ifndef _WIN32
26a28
> #endif
diff original/hw_panel.c new/hw_panel.c
7a8
> #ifndef _WIN32
8a10
> #endif
13a16,18
> #ifdef _WIN32
> #include <rpc.h> /* always needed */
> #else
14a20,21
> #endif
>
diff original/led_display.c new/led_display.c
7a8
> #ifndef _WIN32
8a10
> #endif
diff original/led_panel.c new/led_panel.c
7a8
> #ifndef _WIN32
8a10
> #endif
diff original/Makefile new/Makefile
17c17
< CFLAGS = $(OPTIMIZE) # $(CWARN)
---
> CFLAGS = -I/mingw64/include/ncurses $(OPTIMIZE) # $(CWARN)
20a21,24
> tty_host.o \
> beaver_net.o \
> pcol_trace.o \
> pcol_append.o \
25,28c29,32
< gemini_clock.o \
< gemini_ramdisk.o \
< gemini_serial.o \
< gemini_printer.o \
---
> gemini_clock.o \
> gemini_ramdisk.o \
> gemini_serial.o \
> gemini_printer.o \
31d34
< hw_panel.o \
52c55
< tnetserv.o shellserv.o clock_count.o \
---
> clock_count.o \
62d64
< ppt_extender.o \
71,72c73
< tty_host.o pipe_host.o pcol_trace.o pcol_tcp.o pcol_append.o \
< beaver_net.o ay8912chip.o \
---
> ay8912chip.o \
76,77c77,82
< exit_handler.o poll.o strutils.o \
< rpcgen_linux/rpc_blinkenlight_api_clnt.o rpcgen_linux/rpc_blinkenlight_api_xdr.o
---
> exit_handler.o poll.o strutils.o
>
> # ppt_extender.o tnetserv.o hw_panel.o shellserv.o \
> # tty_host.o pipe_host.o pcol_tcp.o \
>
> # rpcgen_linux/rpc_blinkenlight_api_clnt.o rpcgen_linux/rpc_blinkenlight_api_xdr.o
88c93
< make xbeaver
---
> # make xbeaver
97,98c102,104
< $(CC) $(CFLAGS) $(VIRTUALBEAVER_OBJS) textwin_SDL.o -o xbeaver_SDL \
< $(shell sdl-config --libs) -lncurses -lm -lutil -lpthread -lasound
---
> $(CC) $(CFLAGS) $(VIRTUALBEAVER_OBJS) textwin_SDL.o -o xbeaver_SDL -static-libgcc -static-libstdc++ \
> -Wl,-Bstatic $(shell sdl-config --static-libs) -Wl,-Bstatic -lncurses -Wl,-Bstatic -lm -lutildll -lpthread -lws2_32
> -Wl,-Bstatic $(shell sdl-config --static-libs) -Wl,-Bstatic -lncurses -Wl,-Bstatic -lm -lutil -lpthread -lasound
101,102c107,109
< $(CC) $(CFLAGS) $(VIRTUALBEAVER_OBJS) textwin_SDL2.o -o xbeaver_SDL2 \
< $(shell sdl2-config --libs) -lncurses -lm -lutil -lpthread -lasound
---
> $(CC) $(CFLAGS) $(VIRTUALBEAVER_OBJS) textwin_SDL2.o -o xbeaver_SDL2 -static-libgcc -static-libstdc++ \
> -Wl,-Bstatic $(shell sdl2-config --static-libs) -Wl,-Bstatic -lncurses -lm -lutildll -lpthread -lws2_32
> -Wl,-Bstatic $(shell sdl2-config --static-libs) -Wl,-Bstatic -lncurses -lm -lutil -lpthread -lasound
162,163c169,170
< rpcgen_linux/rpc_blinkenlight_api_clnt.o: rpcgen_linux/rpc_blinkenlight_api_clnt.c
< rpcgen_linux/rpc_blinkenlight_api_xdr.o: rpcgen_linux/rpc_blinkenlight_api_xdr.c
---
> #rpcgen_linux/rpc_blinkenlight_api_clnt.o: rpcgen_linux/rpc_blinkenlight_api_clnt.c
> #rpcgen_linux/rpc_blinkenlight_api_xdr.o: rpcgen_linux/rpc_blinkenlight_api_xdr.c
Only in original: Makefile_Arch.zip
Only in original: map_vfc_cpm.cfg
diff original/map_video.c new/map_video.c
21a22
> #ifndef _WIN32
22a24
> #endif
160a163,166
>
> #ifdef _WIN32
> long execution_clock;
> #else
161a168,169
> #endif
>
410,411d417
< struct tms cpu_time;
< clock_t new_clock;
414a421,445
> #ifdef _WIN32
>
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER ticks;
> LARGE_INTEGER tms;
> long new_clock;
>
> if (QueryPerformanceFrequency(&ticks))
> {
> //ticks_per_second = (PointerSizeUInt) ticks.QuadPart;
> ticks_per_second = ticks.QuadPart;
> }
> else
> {
> ticks_per_second = 1L;
> }
> QueryPerformanceCounter(&tms);
>
> new_clock = tms.QuadPart;
>
> #else
>
> struct tms cpu_time;
> clock_t new_clock;
>
416a448,450
>
> #endif
>
Only in original: matmos.cfg
diff original/midi_keyboard.c new/midi_keyboard.c
12a13
> #ifndef _WIN32
13a15
> #endif
336c338
< mydata->fd = open( cmd_part, O_RDONLY );
---
> mydata->fd = open( cmd_part, O_RDONLY | O_BINARY );
Only in original: mkfont.pl
Only in original: nascom.cfg
Only in original: needswhat.pl
diff original/pcol_utils.c new/pcol_utils.c
9a10,95
>
> #ifdef _WIN32
> /*
> * This is the definition of the protocol
> */
> PCOL_CLASS_T ptcp_pcol =
> {
> "tcp", /* The name of the protocol is a tcp */
> "tcp connection (incomming/outgoing)", /* The description of the protocol */
> NULL, /* Create routine */
> NULL, /* No delete routine */
> NULL, /* Baud rate routine */
> NULL, /* Modem status routine */
> NULL, /* Modem control routine */
> NULL, /* Line status routine */
> NULL, /* Line control routine */
> NULL, /* Poll routine */
> NULL, /* TX routine */
> 0 /* Size of class private data area */
> };
>
>
> /*
> * This is the definition of the protocol
> */
> PCOL_CLASS_T tnet_pcol_tnet_server =
> {
> "telnet_server", /* The name of the protocol for telnet server */
> "Telnet Server", /* The description of the protocol */
> NULL, /* Create routine */
> NULL, /* No delete routine */
> NULL, /* Baud rate routine */
> NULL, /* Modem status routine */
> NULL, /* Modem control routine */
> NULL, /* Line status routine */
> NULL, /* Line control routine */
> NULL, /* Poll routine */
> NULL, /* TX routine */
> 0 /* Size of class private data area */
> };
>
>
> /*
> * This is the definition of the protocol
> */
> PCOL_CLASS_T tnet_pcol_tcpraw_server =
> {
> "tcp_server", /* The name of the protocol for telnet server */
> "TCP Raw Server", /* The description of the protocol */
> NULL, /* Create routine */
> NULL, /* No delete routine */
> NULL, /* Baud rate routine */
> NULL, /* Modem status routine */
> NULL, /* Modem control routine */
> NULL, /* Line status routine */
> NULL, /* Line control routine */
> NULL, /* Poll routine */
> NULL, /* TX routine */
> 0 /* Size of class private data area */
> };
>
>
>
> /*
> * This is the definition of the protocol
> */
> PCOL_CLASS_T pipehst_pcol =
> {
> "pipe", /* The name of the protocol is a tty */
> "pipe", /* The description of the protocol */
> NULL, /* Create routine */
> NULL, /* No delete routine */
> NULL, /* Baud rate routine */
> NULL, /* Modem status routine */
> NULL, /* Modem control routine */
> NULL, /* Line status routine */
> NULL, /* Line control routine */
> NULL, /* Poll routine */
> NULL, /* TX routine */
> 0 /* Size of class private data area */
> };
>
>
> #endif
>
>
diff original/pipe_host.c new/pipe_host.c
314c314
< mydata->pipe_in_fd = open( cmd_arg, O_RDONLY | O_NOCTTY | O_NONBLOCK);
---
> mydata->pipe_in_fd = open( cmd_arg, O_RDONLY | O_BINARY | O_NOCTTY | O_NONBLOCK);
318c318
< mydata->pipe_out_fd = open( cmd_arg, O_WRONLY | O_NOCTTY | O_NONBLOCK);
---
> mydata->pipe_out_fd = open( cmd_arg, O_WRONLY | O_BINARY | O_NOCTTY | O_NONBLOCK);
diff original/poll.h new/poll.h
11c11,13
<
---
> #ifdef _WIN32
> #include <windows.h>
> #endif
diff original/ppt_extender.c new/ppt_extender.c
40a41,45
>
> #ifdef _WIN32
> #include <windows.h>
> #include <winioctl.h>
> #else
43a49,50
> #endif
>
427a435
> #ifndef _WIN32
436a445
> #endif
456a466,467
>
> #ifndef _WIN32
461a473
> #endif
485a498,499
> #ifndef _WIN32
>
502a517
> #endif
Only in original: README.arch
Only in original: README.beaver
Only in original: README.libs
Only in original: README.yaze
Only in original: rpcgen_linux
diff original/shellserv.c new/shellserv.c
57a58
> #ifndef _WIN32
59a61
> #endif
67a70
> #ifndef _WIN32
69a73
> #endif
77a82
> #ifndef _WIN32
78a84
> #endif
203a210
> #ifndef _WIN32
208a216
> #endif
Only in original: simz80.pl
Only in original: sintab.pl
diff original/sound.c new/sound.c
2a3,7
>
> #ifdef _WIN32
> #include <windows.h>
> #include <winioctl.h>
> #else
4a10,12
> #include<alsa/asoundlib.h>
> #endif
>
7d14
< #include<alsa/asoundlib.h>
23c30
< #define SND_USE_ALSA (1) /* Use ALSA sound interface */
---
> #define SND_USE_ALSA (0) /* Use ALSA sound interface */
Only in original: terminal.cfg
Only in new: termiwin.h
diff original/textwin_X.c new/textwin_X.c
643c643
< case 1: fd = open( font_data, O_RDONLY );
---
> case 1: fd = open( font_data, O_RDONLY | O_BINARY );
diff original/tnetserv.c new/tnetserv.c
113a114,116
> #include <time.h>
>
> #ifndef _WIN32
118a122
> #endif
128a133
> #ifndef _WIN32
129a135
> #endif
271a278,280
> #ifdef _WIN32
>
> #else
279a289
> #endif
299a310,311
> #ifdef _WIN32
>
390a403,404
> #endif
>
796a811,812
>
> #ifndef WIN32
798a815
> #endif
804a822
> #ifndef WIN32
805a824
> #endif
diff original/tty_host.c new/tty_host.c
24c24
< #define LINUX_TTY 1
---
> #define LINUX_TTY 0
31a32,33
>
> #ifndef _WIN32
33d34
< #include <unistd.h>
35a37
> #include <clock.h>
36a39,46
> #endif
>
> #include <unistd.h>
>
> #ifdef _WIN32
> #include <windows.h>
> #include <winioctl.h>
> #else
38a49,50
> #endif
>
84a97,107
> #ifdef _WIN32
> typedef struct COM {
> HANDLE hComm;
> int fd; //Actually it's completely useless
> char port[128];
> } COM;
>
> DCB SerialParams = { 0 }; //Initializing DCB structure
> struct COM com;
> #endif
>
86a110,114
>
> #ifdef _WIN32
> long tx_timestamp;
> #else
> clock_t tx_timestamp; /* Timestamp of first tx byte of consecutive bytes */
88c116,117
< clock_t tx_timestamp; /* Timestamp of first tx byte of consecutive bytes */
---
> #endif
>
119a149,164
> #ifdef _WIN32
> //Baud speed
> #define B0 0 // Dirty fix
> #define B110 CBR_110
> #define B300 CBR_300
> #define B600 CBR_600
> #define B1200 CBR_2400
> #define B2400 CBR_2400
> #define B4800 CBR_4800
> #define B9600 CBR_9600
> #define B19200 CBR_19200
> #define B38400 CBR_38400
> #define B57600 CBR_57600
> #define B115200 CBR_115200
> #endif
>
296a342
> #ifndef _WIN32
297a344
> #endif
312a360,364
> #ifdef _WIN32
> GetCommState(com.hComm, &SerialParams);
> SerialParams.BaudRate = baudrate_encoded;
> SetCommState(com.hComm, &SerialParams);
> #else
318a371,372
> #endif
>
335a390,394
> #ifdef _WIN32
> GetCommState(com.hComm, &SerialParams);
> SerialParams.BaudRate = baudrate;
> SetCommState(com.hComm, &SerialParams);
> #else
340a400
> #endif
344a405,410
>
> #ifdef _WIN32
> GetCommState(com.hComm, &SerialParams);
> SerialParams.BaudRate = B38400;
> SetCommState(com.hComm, &SerialParams);
> #else
350a417
> #endif
395,396c462,468
< tcgetattr(mydata->serial_port_fd, &tio); /* get current serial port settings */
< return_code = ttyhst_baudrate_decode( tio.c_cflag & CBAUD );
---
> #if _WIN32
> // return_code=cfgetispeed(&tio);
> GetCommState(com.hComm, &SerialParams);
> return_code=SerialParams.BaudRate;
> #else
> tcgetattr(mydata->serial_port_fd,&tio); /* get current serial port settings */
> #endif
404a477,478
>
> #ifndef _WIN32
422a497,498
>
> #endif
482a559,560
>
> #ifndef _WIN32
487a566
> #endif
513a593,595
> #ifdef _WIN32
> return_code = 0;
> #else
534a617,618
> #endif
>
562c646
< ioctl(mydata->serial_port_fd, TIOCOUTQ, &outq);
---
> #ifdef _WIN32
563a648,649
> DWORD errors;
> COMSTAT comstat;
565c651,662
< /* If anything in the outut queue then transmitter is active */
---
> ClearCommError(com.hComm, &errors, &comstat);
> outq=comstat.cbInQue;
>
> #else
>
> ioctl(mydata->serial_port_fd, TIOCOUTQ, &outq);
>
> #endif
>
>
>
> /* If anything in the output queue then transmitter is active */
588c685,698
< { int clock_delta;
---
> {
> int clock_delta;
>
> #ifdef _WIN32
>
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER tms;
> long new_clock;
>
> QueryPerformanceCounter(&tms);
> new_clock = tms.QuadPart;
>
> #else
>
591a702,703
>
> #endif
635a748
> #ifndef _WIN32
636a750,756
> #endif
>
> #ifdef _WIN32
>
> GetCommState(com.hComm, &SerialParams);
>
> #else
639a760,761
> #endif
>
641a764
> #ifndef _WIN32
642a766
> #endif
644a769,774
> #ifdef _WIN32
> case 5: SerialParams.ByteSize = 5;break;
> case 6: SerialParams.ByteSize = 6;break;
> case 7: SerialParams.ByteSize = 7;break;
> case 8: SerialParams.ByteSize = 8;break;
> #else
648a779
> #endif
650a782,789
>
> #ifdef _WIN32
> if ( control_mask & PCOL_LINE_CONTROL_PARENBL )
> {
> if (!( control_data & PCOL_LINE_CONTROL_PARENBL ))
> SerialParams.Parity = NOPARITY;
> }
> #else
655a795
> #endif
656a797,805
> #ifdef _WIN32
> if ( control_mask & PCOL_LINE_CONTROL_PAREVEN )
> {
> if (!( control_data & PCOL_LINE_CONTROL_PAREVEN ))
> SerialParams.Parity = EVENPARITY;
> else
> SerialParams.Parity = ODDPARITY;
> }
> #else
661a811
> #endif
670a821,830
>
> #ifdef _WIN32
> if ( control_mask & PCOL_LINE_CONTROL_STOPBITS )
> {
> if ( control_data & PCOL_LINE_CONTROL_STOPBITS )
> SerialParams.StopBits = TWOSTOPBITS;
> else
> SerialParams.StopBits = ONESTOPBIT;
> }
> #else
678a839
> #endif
679a841,843
> #ifdef _WIN32
> SetCommState(com.hComm, &SerialParams);
> #else
680a845
> #endif
682a848,857
>
> #ifdef _WIN32
> switch ( SerialParams.ByteSize )
> {
> case 5: return_code = PCOL_LINE_CONTROL_BITS5;break;
> case 6: return_code = PCOL_LINE_CONTROL_BITS6;break;
> case 7: return_code = PCOL_LINE_CONTROL_BITS7;break;
> case 8: return_code = PCOL_LINE_CONTROL_BITS8;break;
> }
> #else
689a865
> #endif
692a869,878
>
>
> #ifdef _WIN32
> if ( SerialParams.Parity != NOPARITY ) mydata->tx_bits_per_frame++; /* Add extra bit for parity bit */
> if ( SerialParams.StopBits == TWOSTOPBITS ) mydata->tx_bits_per_frame++; /* Add extra bit if two stop bits */
>
> if ( SerialParams.Parity != NOPARITY ) return_code |= PCOL_LINE_CONTROL_PARENBL;
> if ( SerialParams.Parity != ODDPARITY ) return_code |= PCOL_LINE_CONTROL_PAREVEN;
> if ( SerialParams.StopBits == TWOSTOPBITS ) return_code |= PCOL_LINE_CONTROL_STOPBITS;
> #else
696d881
<
699a885,886
> #endif
>
735a923,929
> #ifdef _WIN32
> //if (select_serial(mydata->serial_port_fd+1,&s,(fd_set*)0,(fd_set*)0,&t)==1) /* Check for new character */
> SetCommMask(com.hComm, EV_RXCHAR);
> DWORD dwEventMask;
> if (WaitCommEvent(com.hComm, &dwEventMask, NULL) != 0)
> if (dwEventMask == EV_RXCHAR)
> #else
738a933
> #endif
741a937,941
> #ifdef _WIN32
> int rc = 0;
> bytes_in = ReadFile(com.hComm, buffer, 1, &rc, NULL);
> if (bytes_in != 0) bytes_in = 1;
> #else
742a943
> #endif
773a975,979
> #ifdef _WIN32
> //write_serial(mydata->serial_port_fd, &tx_byte, sizeof(tx_byte) );
> int rc = 0;
> WriteFile(com.hComm, &tx_byte, 1, &rc, NULL);
> #else
774a981
> #endif
780,783c987,1005
< struct tms cpu_time;
< clock_t new_clock;
< int delta_ticks;
< mydata->tx_timestamp = times( &cpu_time );
---
>
>
> #ifdef _WIN32
>
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER tms;
> //long new_clock;
>
> QueryPerformanceCounter(&tms);
> mydata->tx_timestamp = tms.QuadPart;
>
> #else
>
> struct tms cpu_time;
> // clock_t new_clock;
> mydata->tx_timestamp = times( &cpu_time );
>
> #endif
>
826a1049
> #ifndef _WIN32
827a1051
> #endif
830a1055,1093
> #ifdef _WIN32
> // mydata->serial_port_fd = open_serial( cmd_arg, O_RDWR);
>
> if (strlen(cmd_arg) < 4) return -1;
> // Set to zero
> memset(com.port, 0x00, 128);
>
> //COMxx
> size_t portSize = 0;
> if (strlen(cmd_arg) > 4) {
> portSize = sizeof(char) * strlen("\\\\.\\COM10") + 1;
> #ifdef _MSC_VER
> strncat_s(com.port, portSize, "\\\\.\\", strlen("\\\\.\\"));
> #else
> strncat(com.port, "\\\\.\\", strlen("\\\\.\\"));
> #endif
> }
> //COMx
> else {
> portSize = sizeof(char) * 5;
> }
>
> #ifdef _MSC_VER
> strncat_s(com.port, portSize, cmd_arg, 4);
> #else
> strncat(com.port, cmd_arg, 4);
> #endif
> com.port[portSize] = 0x00;
>
> com.hComm = CreateFile(com.port, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
>
> if (com.hComm == INVALID_HANDLE_VALUE) {
> return -1;
> }
> com.fd = atoi(cmd_arg + 3); // COMx and COMxx
> SerialParams.DCBlength = sizeof(SerialParams);
>
> #else
>
833a1097,1113
> #endif
>
> #ifdef _WIN32
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER ticks;
> if (QueryPerformanceFrequency(&ticks))
> {
> //ticks_per_second = (PointerSizeUInt) ticks.QuadPart;
> mydata->ticks_per_second = ticks.QuadPart;
> }
> else
> {
> mydata->ticks_per_second = 1L;
> }
>
>
> #else
836c1116
< tcgetattr(mydata->serial_port_fd, &tio); /* save current serial port settings */
---
> #endif
838d1117
< tio.c_cflag &= ~( CSIZE | CLOCAL | CREAD | PARENB | CSTOPB );
840a1120,1138
> #ifdef _WIN32
>
> GetCommState(com.hComm, &SerialParams);
>
> SerialParams.Parity = NOPARITY; /* 8n1 */
> SerialParams.StopBits = ONESTOPBIT;
> SerialParams.ByteSize = 8;
>
> SerialParams.fBinary = TRUE;
> SerialParams.fDsrSensitivity = FALSE;
> SerialParams.fErrorChar = FALSE;
> SerialParams.fNull = FALSE;
> SerialParams.fAbortOnError = FALSE;
>
> #else
>
> tcgetattr(mydata->serial_port_fd, &tio); /* save current serial port settings */
>
> tio.c_cflag &= ~( CSIZE | CLOCAL | CREAD | PARENB | CSTOPB );
843c1141,1142
< tio.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IUCLC | IXOFF | IXON | ISTRIP | IUCLC ); /* Dont do any input processing */
---
> tio.c_iflag &= ~(ICRNL | INLCR | ISTRIP | IUCLC | IXOFF | IXON | ISTRIP ); /* Dont do any input processing */
>
845a1145
>
851a1152,1157
> #endif
>
>
> #ifdef _WIN32
> PurgeComm(com.hComm, PURGE_RXCLEAR);
> #else
853a1160
> #endif
diff original/vct_extender.c new/vct_extender.c
51a52,53
> #include "cmdparse.h"
>
diff original/viewdata_video.c new/viewdata_video.c
15a16
> #ifndef _WIN32
16a18
> #endif
165c167,171
< clock_t execution_clock;
---
> #ifdef _WIN32
> long execution_clock;
> #else
> clock_t execution_clock;
> #endif
582,583d587
< struct tms cpu_time;
< clock_t new_clock;
586a591,615
> #ifdef _WIN32
>
> //static PointerSizeUInt clock_speed_;
> LARGE_INTEGER ticks;
> LARGE_INTEGER tms;
> long new_clock;
>
> if (QueryPerformanceFrequency(&ticks))
> {
> //ticks_per_second = (PointerSizeUInt) ticks.QuadPart;
> ticks_per_second = ticks.QuadPart;
> }
> else
> {
> ticks_per_second = 1L;
> }
> QueryPerformanceCounter(&tms);
>
> new_clock = tms.QuadPart;
>
> #else
>
> struct tms cpu_time;
> clock_t new_clock;
>
588a618,620
>
> #endif
>
Only in original: xbeaver
diff original/xbeaver.c new/xbeaver.c
12a13
> #include <time.h>
28a30
>
210d211
<
Only in original: xbeaver.cfg
Only in original: xbeaver_SDL
Re: Gemini and others
Hi from me... The author of xbeaver!
Just a note, the above post is extracts from the xbeaver emulation of the northstar advantage.
Documentation is available from http://www.cccplusplus.co.uk/xbeaver
PS - I would love a copy of the adventure program with the graphics shown in
gemini_adva_lr2.png (6.84 KiB) Viewed 65 times
I had no idea that xbeaver had generated so much interest!
Just a note, the above post is extracts from the xbeaver emulation of the northstar advantage.
Documentation is available from http://www.cccplusplus.co.uk/xbeaver
PS - I would love a copy of the adventure program with the graphics shown in
gemini_adva_lr2.png (6.84 KiB) Viewed 65 times
I had no idea that xbeaver had generated so much interest!
Re: Gemini and others
> I had no idea that xbeaver had generated so much interest!
why not? it's a rather accurate work, requiring a lot of information gathering and reverse engineering.
Without you guys doing this passionate research and without the emulators the z88dk project couldn't probably exist or was still limited to the Cambridge Z88.
I'll do my best to reach you out after the weekend.
why not? it's a rather accurate work, requiring a lot of information gathering and reverse engineering.
Without you guys doing this passionate research and without the emulators the z88dk project couldn't probably exist or was still limited to the Cambridge Z88.
I'll do my best to reach you out after the weekend.
Re: Gemini and others
It was started in about 2007 as a reliable replacement for my machine based on Gemini cards. During Covid I had a lot of time on my hands and so expanded it to cover as many cards as possible in a modular fashion. The matmos/alphatronic support was added as I owned one of those machines
and decided to restore it. Part of the "restoration" was to replace the 400k 5.25 inch drives with 1.44MByte drives. This involved replacing the onboard boot rom which retains the ability to boot from DD drives but also allows boot from HD 1.44MByte drives. At the same time I added a 5.25 inch 1.2MByte drive (Easy having modified the hard disk controller to support 500kbps transfer rate in addition to the 250kbps transfer rate. The North Star advantage support was added to re-create a machine I used during my PhD. The hard disk code for the advantage was largely a copy of an already existing North Star advantage emulator, thus allowing the use of those hard disk images. Isis was another operating system I used on an Intel MDS and I realised that VPM/M created a system with 64k of memory (minus 768 bytes required for CP/M emulation). VPM/M is a program I ran on my gemini system which uses the memory management to allow multiple consoles - each console taking 64k of memory. By a bit of cleverness I was able to overlay the virtual CP/M system with an ISIS system which allowed z80 Isis programs, and also allowed these programs to make both CP/M, VPM/M and ISIS system
calls! This means the ISIS system can use VPM/M character I/O drivers but needs control of its own filesystem via an MDS compatible disk controllers.
On route I have found that the datasheets do not always give all the features that are used. For example during booting, the Gemini boot roms read
the first half of the boot sector and then jump to the loaded code! This had to be catered for. In some cases I have given a nod to efficiency, for example the SVC video card is actually controlled by its own Z80/Software. I made the choice not to run that code, but to emulate the interface to the card as I thought that trying to use a Z80 emulation to run the SVC card would be too limiting/slow. Another feature not in any of the manuals is that there is an
extra bit used in the SVC status register (undocumented) which allows software to check if a keyboard character is available.
Another difficulty was getting the Gemini Multi Format Bios (MFB) system to boot. This had one of the chips on the floppy disk controller replaced with
a different 74 series chip which had its number scratched out. This served as a dongle to the MFB software. Luckily someone on the Nascom/Gemini board had been given one of these machines and when he got it working would run a couple of programs for me to explore the MFB floppy disk controller.
(see glasstty.com for infomation of this. He has also exported it to docker, and supplied me with the changes to make it work as a 64 bit program.
- note using the "shell" command provides a menu driven interface if you want to explore the CP/M software that comes with the image. Also worthy of
note is that the NUL character (ascii code 0, keyboard control+@ or control+space) allows a console to switch between upto 8 programs. VPM/M
did indeed run on a real Z80 machine and allowed 8 programs per console, and each console needed its own 64k of ram, with 64k of ram for operating system which included a network. The network was basic, and worked on the rs232 interface of the real machine (called t-net).
Some of the programs were written during my time as a PhD student. For example MEDIT which was a mid-1980s attempt at an IDE before the concept was known which allowed assembler code to be edited/assembled - the editor even had a screen mode as well as a character mode. The screen mode
was/is largely wordstar compatible while the character mode was based on RT11 edit. This was for a home computer a group of us were building using
wirewrap. So there is a lot of personal history in Xbeaver. The font editor program shown earlier in the post was written by me in 1985.
and decided to restore it. Part of the "restoration" was to replace the 400k 5.25 inch drives with 1.44MByte drives. This involved replacing the onboard boot rom which retains the ability to boot from DD drives but also allows boot from HD 1.44MByte drives. At the same time I added a 5.25 inch 1.2MByte drive (Easy having modified the hard disk controller to support 500kbps transfer rate in addition to the 250kbps transfer rate. The North Star advantage support was added to re-create a machine I used during my PhD. The hard disk code for the advantage was largely a copy of an already existing North Star advantage emulator, thus allowing the use of those hard disk images. Isis was another operating system I used on an Intel MDS and I realised that VPM/M created a system with 64k of memory (minus 768 bytes required for CP/M emulation). VPM/M is a program I ran on my gemini system which uses the memory management to allow multiple consoles - each console taking 64k of memory. By a bit of cleverness I was able to overlay the virtual CP/M system with an ISIS system which allowed z80 Isis programs, and also allowed these programs to make both CP/M, VPM/M and ISIS system
calls! This means the ISIS system can use VPM/M character I/O drivers but needs control of its own filesystem via an MDS compatible disk controllers.
On route I have found that the datasheets do not always give all the features that are used. For example during booting, the Gemini boot roms read
the first half of the boot sector and then jump to the loaded code! This had to be catered for. In some cases I have given a nod to efficiency, for example the SVC video card is actually controlled by its own Z80/Software. I made the choice not to run that code, but to emulate the interface to the card as I thought that trying to use a Z80 emulation to run the SVC card would be too limiting/slow. Another feature not in any of the manuals is that there is an
extra bit used in the SVC status register (undocumented) which allows software to check if a keyboard character is available.
Another difficulty was getting the Gemini Multi Format Bios (MFB) system to boot. This had one of the chips on the floppy disk controller replaced with
a different 74 series chip which had its number scratched out. This served as a dongle to the MFB software. Luckily someone on the Nascom/Gemini board had been given one of these machines and when he got it working would run a couple of programs for me to explore the MFB floppy disk controller.
(see glasstty.com for infomation of this. He has also exported it to docker, and supplied me with the changes to make it work as a 64 bit program.
- note using the "shell" command provides a menu driven interface if you want to explore the CP/M software that comes with the image. Also worthy of
note is that the NUL character (ascii code 0, keyboard control+@ or control+space) allows a console to switch between upto 8 programs. VPM/M
did indeed run on a real Z80 machine and allowed 8 programs per console, and each console needed its own 64k of ram, with 64k of ram for operating system which included a network. The network was basic, and worked on the rs232 interface of the real machine (called t-net).
Some of the programs were written during my time as a PhD student. For example MEDIT which was a mid-1980s attempt at an IDE before the concept was known which allowed assembler code to be edited/assembled - the editor even had a screen mode as well as a character mode. The screen mode
was/is largely wordstar compatible while the character mode was based on RT11 edit. This was for a home computer a group of us were building using
wirewrap. So there is a lot of personal history in Xbeaver. The font editor program shown earlier in the post was written by me in 1985.
Last edited by JBH on Sat Dec 07, 2024 10:27 pm, edited 1 time in total.
Re: Gemini and others
Stefano, you never sent me your Windows version of the emulator - maybe you and JBH can now make an official Windows version. :-)
Re: Gemini and others
@JBH: It was easy to guess you had fond memories and real life experience with those systems, we still miss lot of for the period of "those systems with hard sectored disk hardware", mostly because of lack of original software to study and poor or no emulation. The NorthStar models would be a great add, in example. I'm trying to extend appmake to support the H17 disk image format, I think I'm close but something is still wrong.
> note using the "shell" command provides a menu driven interface...
Under some aspect it recalls the Otrona Attachè BIOS, which provided a "valet" program showing up by pressing a special key. The vendors were trying hard to extend the CP/M 2.2 or similar systems with some customisation. When CP/M 3 appeared on the market, it was too late.
@RobertK, I will dump what I've got in a zip file, beware it's a rather experimental build.
> note using the "shell" command provides a menu driven interface...
Under some aspect it recalls the Otrona Attachè BIOS, which provided a "valet" program showing up by pressing a special key. The vendors were trying hard to extend the CP/M 2.2 or similar systems with some customisation. When CP/M 3 appeared on the market, it was too late.
@RobertK, I will dump what I've got in a zip file, beware it's a rather experimental build.
Re: Gemini and others
The latest linux source is at http://www.cccplusplus.co.uk/download/xbeaver.tgz
maybe worth taking this and merging in the changes. Most of the changes I have made is in adding additional boards, I suspect your
win mods are mostly in textwin, the xbeaver.c and maybe fileio? Is this correct?
maybe worth taking this and merging in the changes. Most of the changes I have made is in adding additional boards, I suspect your
win mods are mostly in textwin, the xbeaver.c and maybe fileio? Is this correct?
Re: Gemini and others
> I suspect your win mods are mostly in textwin, the xbeaver.c and maybe fileio? Is this correct?
The timers (interfacing to the system clock). I see I tried to connect to the system's serial ports, but for sure I've never tested it.
Some feature removed to get it built.
And the file I/O, it is simplified due to the mingw library emulation limits. I've just discovered it probably was too much simplified, when a program writes an IMD disk image, the image file gets corrupt on program exit (perhaps a missing close()?).
Hacked configuration sampes:
matmos.cfg
gemini.cfg
The timers (interfacing to the system clock). I see I tried to connect to the system's serial ports, but for sure I've never tested it.
Some feature removed to get it built.
And the file I/O, it is simplified due to the mingw library emulation limits. I've just discovered it probably was too much simplified, when a program writes an IMD disk image, the image file gets corrupt on program exit (perhaps a missing close()?).
Hacked configuration sampes:
matmos.cfg
Code: Select all
#Options - set using -o <options> on the command line
echo option B - Boot Basic
echo option F - Boot from disk
echo option G - Use BiCom Roms with graphics card support
echo option L - Use large disk (80 track CP/M format)
echo option N - Use CP/M network
echo option R - Include Rom Packs
#verbose
#Remove network if not using CP/M
if B optionclr N
if !F optionclr N
if R optionclr N
#Set for basic if no disk controller
if !F optionclr B
#Display booting action
if !F if !R echo Booting ROM Basic
if F if !R if B echo Booting Disk Basic
if F if !R if !B echo Booting CP/M
if R echo Booting ROM Cartridge
if N echo Network to linux on serial port (use t-net nop to access)
#Set CPU Clock speed
cpuclock 4
#
#Load the ROMS
#NB
#1. These statements must be before the mother board definition
#2. The load at address 0 must be the last
#Include the rom cartridges (Load at 8000 for pack1, a000 for pack2)
if R binload 0xa000 matmos/rompacks/escape_be_d2_rom_pack_1.bin
if R binload 0xc000 matmos/rompacks/escape_be_d2_rom_pack_2.bin
#Now load the main roms
binload 0x6000 matmos/roms/2764.ic-1038
if G binload 0x0000 matmos/roms/HN613256P_24k.bin
if !G binload 0x0000 matmos/roms/613256.ic-1058
#Create the matmos mother board - ports 10,20,30
#indicate floppy controller present
#if F board 0x10 aptmbd F
#indicate no floppy controller present
#if !F board 0x10 aptmbd
#Create the matmos serial port (speed = 16 * baudrate)
if !N board 0x40 serial_8251 153600 trace tty tty /dev/tty8
if N board 0x40 serial_8251 153600 bvrnet beaver/network matmos/network/system matmos/network/work
#Create the matmos vdu (Option k defines the keyboard at address 0x20-0x2b)
board 0x50 aptvdu 0x0f000 Alphatronic options K green
#Create the DMA Controller
#NB - This must preceed any lines that use the DMA controller (eg floppy disk controller)
board 0x60 dma_8257
#And the floppy disk controller (If required to be present)
#if B board 0xf0 aptflp -geometry I matmos/diskimages/matmos_disk_basic.imd -geometry 40.2.16.1.256 matmos/diskimages/basic_work.dsk
#if !B if !L board 0xf0 aptflp -geometry 40.2.16.1.256 matmos/diskimages/new_system.dsk matmos/diskimages/work.dsk -geometry 80.2.16.1.256 matmos/diskimages/newsys80.dsk
#if !B if L board 0xf0 aptflp -geometry 80.2.16.1.256 matmos/diskimages/newsys80.dsk
#board 0xf0 aptflp -geometry 40.2.16.1.256 matmos/diskimages/new_system.dsk -geometry 40.2.16.1.256 a.dsk
#board 0xf0 aptflp -geometry 40.2.16.1.256 alpha4.raw
board 0x10 aptmbd F
board 0xf0 aptflp -geometry 40.2.16.1.256 matmos/diskimages/new_system.dsk -geometry 40.2.16.1.256 test.img
Code: Select all
if D echo Option D - Use distribuion disk
if E echo Option E - External SVC Card
if V echo Option V - Use Virtual Console as serial port
if X echo Option X - Experimental Version
#verbose
cpuclock 4
board 0xfe gm813_mmu
if !E board 0xb0 gm832 Gemini green keyboard gemini
if E board 0xb1 extbus 0x0a1 0x03 rw /dev/z80xbus
if E output 0xb3 0
if V board 0xb8 serial_8250 trace tty tty /dev/tty11
if !V board 0xb8 serial_8250 bvrnet &
beaver/network & #Common network drive
NorthStarAdvantage/network & #North Star Advantage Work
/saturn/cpmapps/beaver/diska/user0 & #Gemini system files (for import)
/home/john/Dropbox/Documents/CPM/Gemini80/Emulator/xbeaver/network
#board 0xc0 gm849_floppy /dev/fd0
#if !D board 0xe0 gm829_floppy -geometry D35.2.10.0.512 beaver/gm512/GM512_64_CCP.DMP beaver/gm512/GM512WRK.DMP
#if D board 0xe0 gm829_floppy -geometry D35.2.10.0.512 beaver/gm512/GM512_ORIGINAL.DMP beaver/gm512/GM512_64_CCP.DMP
#if D board 0xe0 gm829_floppy -geometry D35.2.10.0.512 beaver/gm512/GM512_ORIGINAL.DMP -geometry D35.2.10.0.512 beaver/gm512/GM512_64_CCP.DMP
#board 0xe0 gm829_floppy -geometry D35.2.10.0.512 beaver/gm512/GM512_ORIGINAL.DMP -geometry I a.imd
board 0xe0 gm829_floppy -geometry D35.2.10.0.512 beaver/gm512/GM512_ORIGINAL.DMP -geometry I globe.imd
#board 0xfb gm833
if X binload 0xf000 beaver/rpm-v2p2.rom
#Patch top of ram for RPM
if X byte 0f0a8 21 00 f0
#select boot sector
if X byte 0fc36 0
#patch disk code GG for floppy boot id
if X byte 0fc59 47 47
#patch in jump to patch routine
if X byte 0fc72 e0 ff
#patch routine - copy sector from 80h to 0h
if X byte 0ffe0 21 80 00 11 00 00 01 80 00 ed b0 f3 c3 02 00
#if !X binload 0xf000 beaver/rpm-v2p1.rom
#if !X binload 0xf000 beaver/SIMON_V4.1_MFB.ROM
if !X binload 0xf000 beaver/SIMON44.ROM
#if !X byte 0f0a8 21 00 f0 #Patch top of ram for RPM
#byte 0000 c3 00 f0
Re: Gemini and others
I had a look at the diff i've created time ago, probably the changes to fopen aren't any longer needed if the mingw64 environment is set to UCRT64.
Re: Gemini and others
Looking at the floppy.c code, the imd code reads in the entire floppy disk into memory, noting the file position for each sector. When writing a sector
it looks at the saved file position for that sector and writes to that part of the file. An open/close is done around every sector write. Corruption maybe
due to seek not working correctly (Text mode??).
1. Try using geometry IR (R gives read only)
2. Use T flag on geometry (gives tracing) geometry IT
Note - read only option is automatically added if the .imd file contains any compressed sectors - as they cannot be patched with new data.
it looks at the saved file position for that sector and writes to that part of the file. An open/close is done around every sector write. Corruption maybe
due to seek not working correctly (Text mode??).
1. Try using geometry IR (R gives read only)
2. Use T flag on geometry (gives tracing) geometry IT
Note - read only option is automatically added if the .imd file contains any compressed sectors - as they cannot be patched with new data.
Re: Gemini and others
On the matmos, the ROM screen bios adds extra new lines. I wrote my own (crt.com) which gives a more traditional handling of the console for cp/m and does
hardware scroll. The ROM character handling was hard to follow, and is patched depending on the machine running basic or CP/M.
hardware scroll. The ROM character handling was hard to follow, and is patched depending on the machine running basic or CP/M.
Re: Gemini and others
>due to seek not working correctly (Text mode??
Most probably.
I'm trying to redo my crap port on your recent work, trying not to affect the Linux version. (conditional #ifdefs but rather spaghetti code ) and I noticed it is better to explicitly O_BINARY everywhere, with Windows.
Most probably.
I'm trying to redo my crap port on your recent work, trying not to affect the Linux version. (conditional #ifdefs but rather spaghetti code ) and I noticed it is better to explicitly O_BINARY everywhere, with Windows.
Re: Gemini and others
Adding O_BINARY everywhere solves the file problems!
I merged the changes and got it "running".
As I said already it's not a perfect port, some module simply doesn't work and I even excluded some entire portions (TCP/IP related stuff). I hadn't noticed the textwin mode, apparently it just works but I'm not sure about the keyboard in textwin mode.
I could paste a diff here, I understand the binaries can be of some interest but they are still rather delicate, a missing module makes the emulator crash.. and sending them as email attachments is often triggering the antiviruses.
Is there a reason for you avoiding GitHub or similar repos?
BTW I should have let the Linux part consistent but I'm embarrassed in sharing my spaghetti adjustments, you have a clever programming style.
I merged the changes and got it "running".
As I said already it's not a perfect port, some module simply doesn't work and I even excluded some entire portions (TCP/IP related stuff). I hadn't noticed the textwin mode, apparently it just works but I'm not sure about the keyboard in textwin mode.
I could paste a diff here, I understand the binaries can be of some interest but they are still rather delicate, a missing module makes the emulator crash.. and sending them as email attachments is often triggering the antiviruses.
Is there a reason for you avoiding GitHub or similar repos?
BTW I should have let the Linux part consistent but I'm embarrassed in sharing my spaghetti adjustments, you have a clever programming style.
Re: Gemini and others
Well done....
Which bits do you consider clever..., but thank you for the comment.
Which bits do you consider clever..., but thank you for the comment.
Re: Gemini and others
This is what I've got. It really just demonstrates that a windows port is possible, is runs consistently most of the computer models at the wrong speed, the network depending parts are disabled as well as ioctl controlled peripherals (parallel ports, etc). The code to reach the serial interfaces is totally untested an probably not working.
Yet, this emulator included so many features that the remaining elements are rather enjoyable.
Hope you (all) appreciate my Christmas wish.
Yet, this emulator included so many features that the remaining elements are rather enjoyable.
Hope you (all) appreciate my Christmas wish.
You do not have the required permissions to view the files attached to this post.
Re: Gemini and others
Thanks, now I've got the Gemini working.
I assume that there is no speed throttling yet in the emulator - I don't think that the machine was that fast.
There is a small bug in the emulation that when switching to mode 2, clrscr() does not clear the characters from mode 0 - although they disappar when resizing the emulator window. Calling clg() does not help.
UDGs in mode 2 (using a custom font) start from code 160, as I have found out by printing the entire set.
I assume that there is no speed throttling yet in the emulator - I don't think that the machine was that fast.
There is a small bug in the emulation that when switching to mode 2, clrscr() does not clear the characters from mode 0 - although they disappar when resizing the emulator window. Calling clg() does not help.
UDGs in mode 2 (using a custom font) start from code 160, as I have found out by printing the entire set.
You do not have the required permissions to view the files attached to this post.
Re: Gemini and others
clg() and clrscr() should trigger the same code, which (if I properly checked the library) simply sends the control character for CLS directly to the I/O port of the video board.
Some kind of speed throttling should be in, but clearly I haven't done it right
I tried to slow it down arbitrairly but it is still too fast, it can be just the wrong time measuring scale but it could also be a bigger mistake on the way I'm interfacing to the Windows APIs. With the last MinGW64 versions it should be possible to bind everything to more POSIX-like libraries.
Some kind of speed throttling should be in, but clearly I haven't done it right
I tried to slow it down arbitrairly but it is still too fast, it can be just the wrong time measuring scale but it could also be a bigger mistake on the way I'm interfacing to the Windows APIs. With the last MinGW64 versions it should be possible to bind everything to more POSIX-like libraries.