[PC-8801] New C chain, possible integration?

Post Reply
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

[PC-8801] New C chain, possible integration?

Post by shram86 »

Hi,

I sent this to the mailing list but the official forums is probably a better place.

To recap:

I checked out z88dk a while ago (3-4 months) and decided since it wasn't super fleshed out that I would just start my own. (I didn't delve in too deeply, and I'm not super familiar with z88dk as a whole, but I didn't see methods for drawing in V2 or disk loading, and it didn't seem like anyone was working on it at the time.)

I started using SDCC, and now it's in a stable, but feature-wanting state:
https://github.com/bferguson3/pc88-c

In src/pc88-c.h I have fully documented all of the hardware registers in English. There is a hardware vsync, and and a hardware key-reading routine - I actually didn't have a resource for the BASIC disassembly and hadn't investigated it on my own, so I went ahead and wrote one. The sprite example is rock-solid on hardware, and there is also a proper fast-handshake disk loading routine (save routine and a tilemap example are WIP).

I researched and translated this all on my own, so I'm pretty well-versed in the graphic functionality now. I can certainly help contribute in this regard.

(Mansplaining a bit, but this is pretty important for PC-88 dev and should be explicit:)
When a PC-8801 boots, it checks dipswitch status. If "boot from floppy" is enabled, it does the following:
1. Initialize ROM BASIC. Stack pointer is around $e4xx depending on the model.
2. Copy the first 256 bytes from drive 1, track 0, sector 1 to RAM at address $c000, then jumps to $c000. <- This is called the IPL, and should take the place of crt0. This usually sets up the stack and software environment and loads in the main program.

My toolchain adds the compiled main.bin to sector 2 and the IPL copies the whole thing into RAM. By default it's set to full color graphic mode with ROM basic bankswapped out for 64k ram mode. It mostly uses python and does some brute-force stuff to match the IPL bytes to the compiled binary.

The makefile looks like this:

Code: Select all

# Very simple makefile for PC88-C.
#  Please use official GNU make installer 3.81!
#  i.e. do not use the one distributed with SGDK etc.

CC=sdcc
CFLAGS=-Isrc
PY=python3
DEL=rm

## USED SECTORS ON DISC ##
USEDSEC=0x5f
# If this number isn't correct, 
# the app won't load right!
# Make sure it's big enough!

## PROJECT FOLDER ##
PROJECT=examples/helloworld
# This can also be explicit on the commandline i.e.
# $ make PROJECT=myproj

## MEMORY LOCATIONS ##
STACK=0x80
DATA=0x100
CODE=0x4000
# Stack should stay in ZP.
# This is due to VRAM being in C000~.

88FLAGS=-mz80 --stack-loc $(STACK) --data-loc $(DATA) --code-loc $(CODE) --fomit-frame-pointer --no-std-crt0 

## DISC FILE NAME ##
APPNAME=app.d88

## EMULATOR EXECUTABLE ##
EMUEXE=C:\Users\Bent\Downloads\m88\m88x5.exe 

default: $(PROJECT)
	$(PY) tools/maked88.py $(APPNAME)
	$(PY) tools/hexer.py src/ipl.bin 0x2f $(USEDSEC)
	$(CC) $(88FLAGS) $(CFLAGS) $(PROJECT)/main.c
	$(PY) tools/fixboot.py src/ipl.bin 
	$(PY) tools/hex2bin.py main.ihx main.bin
	$(PY) tools/maked88.py $(APPNAME) src/ipl.bin 0 0 1
	$(PY) tools/maked88.py $(APPNAME) main.bin 0 0 2	
	$(DEL) *.ihx
	$(DEL) *.lk
	$(DEL) *.lst
	$(DEL) *.map
	$(DEL) *.noi
	$(DEL) *.rel
	$(DEL) *.sym
	$(EMUEXE)
so it should be pretty easy to swap out with z88dk - I hope.

Obviously I don't want to step on any toes here, but it seemed like nobody was working on this part of the chain. I would love to integrate what I can that will help out and please feel free to use all of my documentation and tooling to help out.

If anyone is interested please reach out! :cool:
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

Re: [PC-8801] New C chain, possible integration?

Post by shram86 »

I forgot to mention, I tested all my examples on my own hardware (PC8801-mkII-FR) and I'm more than willing to do hardware tests for z88dk.
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

In terms of tooling I think we're okay, it's literally a case of "zcc +pc88 -subtype=disk -create-app [files]" and a bootable disc pops out at the end - it's not been tested on real hardware though.

Since you posted over on GitHub I've been looking at the port and can see a few things that make it a bit clunky:

1. Reliance on the ROM, this means that allram mode can't be used
2. The ALU isn't used at all, everything is brute forced bank switching
3. Switching graphics modes is a compile time option, not runtime
4. I think both myself and Stefano needed a bit of a break from the pc88, but we forgot to return! Which is a shame since it's capable piece of hardware

I'd like to switch over to allram first of all, leaving aside the BASIC style loading, I can see the we use the ROM to set the screen mode. IIRC (probably not!), the firmware interrupt does something to the display? Obviously if you ignore the firmware then that won't happen, but is anything actually mandatory on the interrupt or is it just the regular 50/60Hz tick?

2. Should give a nice performance boost: it's not the easiest to see how to add a completely custom plot routine on the pc88 at the moment since a lot of default functionality is being inherited (see 3). But, it should resemble something like the smc777: https://github.com/z88dk/z88dk/tree/mas ... 7/graphics where there's clear entry points for plot/res/xor/point which then branch to cover the various screen modes.

That covers plotting, but we're still using the software line drawing routines here: https://github.com/z88dk/z88dk/tree/mas ... c/gfx/wide, if there's a an easy way to draw a line using the ALU then we can just create an override for it in the target/pc88 hierarchy (*)

File loading for targets that support it usually relies on the firmware/OS to provide that functionality and wrap them up in <fcntl.h> - I don't think we've dived enough into the firmware to see if there's convenient routines. Likewise, we don't have a filesystem implementation, so there's not yet a generalised raw disk access API - I can see that some of the targets have custom routines to do that though.

(*) You may be thinking "but then I've got two functions named the same, how does that work?" - The linker works on a first match and the library files are arranged as such, the default linking order is:

pc88_clib.lib
z80_crt0.lib

Which allows the target to override any of the standard C library (eg strings, but more likely arithmetic)

Within pc88_clib.lib we've arranged it so that the order is:

pc88 routines
shared routines compiled for the pc88

Which keeps the library construction simple and allows the overriding of line/circle etc

To be complete, when you add a library on the command line (eg -lxyz) then the search path becomes:

xyz.lib
pc88_clib.lib
z80_crt0.lib

Which then allows anything in xyz.lib to override anything lower down
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

Re: [PC-8801] New C chain, possible integration?

Post by shram86 »

Sorry it took me so long to respond, I kept hitting the sign-in timeout and my post kept getting erased!
dom wrote: Mon Mar 08, 2021 9:18 am In terms of tooling I think we're okay, it's literally a case of "zcc +pc88 -subtype=disk -create-app [files]" and a bootable disc pops out at the end - it's not been tested on real hardware though.
I must have checked out z88dk right before disk support was added. D88 is pretty lenient, when I get a chance I will write a z88dk disk and test it on my hardware :)
Since you posted over on GitHub I've been looking at the port and can see a few things that make it a bit clunky:

1. Reliance on the ROM, this means that allram mode can't be used
2. The ALU isn't used at all, everything is brute forced bank switching
3. Switching graphics modes is a compile time option, not runtime
4. I think both myself and Stefano needed a bit of a break from the pc88, but we forgot to return! Which is a shame since it's capable piece of hardware
1. Removing support on the ROM should be pretty easy. I don't use the BASIC ROM right now, but I am still missing disk save and sound support. (I really want OPN/A before I consider it feature-complete).
Other things like grabbing strings instead of a single kb scancode I don't have but shouldn't be too hard to finish (I'm pretty happy with the GetKeyDown method).

2. This also isn't too bad, I tried to simplify it a bit below...

3. I can aid in full documenting the registers so that this can be added to simple methods, it's pretty easy

4. Oh no! =D
I'd like to switch over to allram first of all, leaving aside the BASIC style loading, I can see the we use the ROM to set the screen mode. IIRC (probably not!), the firmware interrupt does something to the display? Obviously if you ignore the firmware then that won't happen, but is anything actually mandatory on the interrupt or is it just the regular 50/60Hz tick?
Should be super easy to do - you don't need too much from the ROM after all. I have a lot of the hardware register info translated in src/pc88-c.h, but I'm lacking actual "documentation" besides my blog posts.

My IPL actually disables all the IRQ masks in registers $e6/$e4, so the IRQ_ON and IRQ_OFF macros are just safety for now. Thanks for reminding me to implement them!
In case this isn't documented in English some quick info (http://mydocuments.g2.xrea.com/html/p8/soundinfo.html) :
The interrupt table is in F300-F30F, and by default points to BASIC routines around $e7xx. On boot these vectors point to:
Serial IRQ - $e7ea
CRTC (vblank) - $e808
Clock (1/600) - $e80e (SR+ only)
Sound 1/Sound 2/User - $e814

I didn't disassemble what BASIC has these do, but they aren't very long.

I'm pretty sure that nothing special is done to the screen, but that can depend on your app, I suppose. G2 recommends using a vblank wait, but that could just be his preferred practice of avoiding interrupts. Setting the vbl irq high and loading in a routine to the CRTC address should be all that is required - I'll test this asap.
2. Should give a nice performance boost: it's not the easiest to see how to add a completely custom plot routine on the pc88 at the moment since a lot of default functionality is being inherited (see 3). But, it should resemble something like the smc777: https://github.com/z88dk/z88dk/tree/mas ... 7/graphics where there's clear entry points for plot/res/xor/point which then branch to cover the various screen modes.

That covers plotting, but we're still using the software line drawing routines here: https://github.com/z88dk/z88dk/tree/mas ... c/gfx/wide, if there's a an easy way to draw a line using the ALU then we can just create an override for it in the target/pc88 hierarchy (*)
I glanced over the draw routines and without parsing them completely they look pretty good as standard plot routines to me. Honestly the BASIC routines for drawing are probably best to use for a generic graphic plotting library. Given how kind of wierd dealing with VRAM on the 88 is, people will probably end up writing their own. Keeping this in mind, my 'drawpixel' example uses 3-4 methods of drawing a single pixel to the screen to try and illustrate this...

I tend to make things complicated, but I tried to simplify ALU writing as:

Code: Select all

    ExpandedGVRAM_On();                 // Expanded mode GVRAM on, comp data off 
    EnableALU();                        // ALU on - must be performed AFTER GVRAM on!
    SetIOReg(EXPANDED_ALU_CTRL, CLR_CYAN); 
    vu8* vp = (vu8*)0xc100;
    *vp = 0xff;             // write a line of pixels
    DisableALU();           // don't forget!
    ExpandedGVRAM_Off();    // required after V2 draw
You can think of R34 (Expanded ALU control) register as the ALU "pen". The bottom nibble holds the "write" color, and the upper nibble holds the "erase" color. This is actually a bitwise op on all 3 planes, but if you think of it this way instead, it makes a lot more sense.
File loading for targets that support it usually relies on the firmware/OS to provide that functionality and wrap them up in <fcntl.h> - I don't think we've dived enough into the firmware to see if there's convenient routines. Likewise, we don't have a filesystem implementation, so there's not yet a generalised raw disk access API - I can see that some of the targets have custom routines to do that though.
We can definitely shunt that into hardware routines. The DiskLoad() function should actually be easy to copy directly into z88dk as-is.
File access on PC88 is kind of annoying. Disk BASIC provides a file structure, but only one file per sector can exist on a disk, for a maximum of 78 files. This is fine when you're doing this and that, but games generally didn't use a file index, and just used logical loading - its pretty easy, and the version in source (thanks G2, haha) uses a the fast-handshake.
(*) You may be thinking "but then I've got two functions named the same, how does that work?" - The linker works on a first match and the library files are arranged as such, the default linking order is:

pc88_clib.lib
z80_crt0.lib

Which allows the target to override any of the standard C library (eg strings, but more likely arithmetic)

Within pc88_clib.lib we've arranged it so that the order is:

pc88 routines
shared routines compiled for the pc88

Which keeps the library construction simple and allows the overriding of line/circle etc

To be complete, when you add a library on the command line (eg -lxyz) then the search path becomes:

xyz.lib
pc88_clib.lib
z80_crt0.lib

Which then allows anything in xyz.lib to override anything lower down
Thanks for explaining this, I was wondering how this worked. For the 88, the IPL is effectively the crt0 as it performs the basic function, so I just let that do the lifting and use --no-std-crt0.

What did I miss? :lol: :lol:
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

Re: [PC-8801] New C chain, possible integration?

Post by shram86 »

So, here's a vertical blank interrupt project that works (see below for wonkyness):

Code: Select all

#include "pc88-c.h"

void Vblank();
void SetVBLIRQ();

void SetVBLIRQ()
{
    __asm 
        ld hl, #_Vblank
        ld (0xf302),hl
    __endasm;
    SetIOReg(0xe4, 2);
    SetIOReg(0xe6, 0b10);
}

void Vblank()
{
    IRQ_OFF 
    SetVBLIRQ();
    print("Hi!");
    IRQ_ON 
}

void main()
{

    IRQ_OFF 
    SetVBLIRQ();
    IRQ_ON 

    while(1){ }
}
Good news - You don't need the BASIC ROM to poll interrupts - hooray! The confusing news is when the IRQ goes low, it seems to reset completely. Right now, you have to copy in the vector and rewrite both interrupt registers in vblank when the interrupt is called (as SetVBLIRQ()) or else it won't call vsync next blank.

However, this project works - real interrupts with little hassle, yay :)
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

That's the exact same vector as is used in z88dk - https://github.com/z88dk/z88dk/blob/mas ... 1_init.asm - and for it fires multiple times: I've had interrupt based music playing.

The key difference looks like the treatment of your VBlank() function - I think you may need to annotate the function to get the compiler to generate the correct interrupt magic, the annotation isn't exactly obvious, but to match up with what we do it's: void VBlank() __critical __interrupt(0)

EDIT: Actually we daisy chain onto the basic handler so that probably does the reset.
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

I'm working in this branch at the moment: https://github.com/z88dk/z88dk/tree/fea ... 88_cleanup

I've now got allram mode working and the screen mode can be changed from 80 -> 40 columns without calling the ROM.

Next few steps will be: cleaning up any other ROM calls, testing/getting interrupts working again and getting plot etc into the main library rather than being separate.

At that point it should be enough to add in optimisations, new features etc
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

Re: [PC-8801] New C chain, possible integration?

Post by shram86 »

That's the exact same vector as is used in z88dk - https://github.com/z88dk/z88dk/blob/mas ... 1_init.asm - and for it fires multiple times: I've had interrupt based music playing.

The key difference looks like the treatment of your VBlank() function - I think you may need to annotate the function to get the compiler to generate the correct interrupt magic, the annotation isn't exactly obvious, but to match up with what we do it's: void VBlank() __critical __interrupt(0)

EDIT: Actually we daisy chain onto the basic handler so that probably does the reset.
Awesome!

Thanks for pointing out the __interrupt qualifier. It pushes the registers to the stack and uses reti as expected, but for some reason this doesn't reset the interrupt - I was mistaken that you have to write the vector each time (duh), but it does seem that unless I reset the irq high _and_ reset the mask it won't trigger again. I'll look more into this.

EDIT: ohh! That makes a lot of sense. I bet we would see that if we disas'd the basic routine.
I'm working in this branch at the moment: https://github.com/z88dk/z88dk/tree/fea ... 88_cleanup

I've now got allram mode working and the screen mode can be changed from 80 -> 40 columns without calling the ROM.

Next few steps will be: cleaning up any other ROM calls, testing/getting interrupts working again and getting plot etc into the main library rather than being separate.

At that point it should be enough to add in optimisations, new features etc
Nice!

I did want to share that you inspired me to factor out the big h file on my repo and tweak the Make so that the resultant bin isn't needlessly huge :) I'm still a little clumsy with putchr/print since I've never had to write a "stdio" before.

I also read through the github thread and it seems z81 is quite knowledgeable, but it's pretty difficult to tell where the coding left off without being familiar with the code base.

If there is anything in particular you think would benefit researching please let me know.
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

I'm starting to remember why I needed a break from the pc88 in the first place!

I've ended up a little distracted and starting playing with text attributes (why, oh why are they implemented that way?) and have got the decorators to work:
PC88 text decorators
Bold is under + overlined for want of anything better.

But no colours yet - which is quite vexing - I must be doing something silly but I can't see it at the moment.
You do not have the required permissions to view the files attached to this post.
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

Re: [PC-8801] New C chain, possible integration?

Post by shram86 »

Text color mode is actually off on boot, could that be it? Try clearing bit 1 of io port 30h... Unintuitively, setting bit 1 is B&W mode.
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

Yup, that was it, I just had to track where it was being overwritten.

I then fell into the trap where the attributes are actually 80 column based. We now have colour and 40 column mode working
40 column colour
Though obviously it's not as useful as on other targets as a result of the line based nature of the attributes as a result it's easy for the screen to end up in a bit of a mess if you're randomly printing at coordinates as in this test. Should be perfectly usable for adventure games though. To quote the G2 page "To be honest, it's a hassle." :)

I've given the M88 emulator a try as well - what do I need to do to get it to display all 25 lines on screen? At the moment it's just showing 20 despite the port being set to show the 25?

Next: graphics. I'm going to make the default graphics mode hires since the attribute design makes lores graphics "awkward" to mix with text without careful crafting. I'll probably add support in for the 400 high monochrome screen.

I suspect the end state of the libraries will be:

- By default I'll attempt to make it work broadly the same as other machines which helps non-specialists get software onto the machine
- Collection of utility routines/sfr/#defines to allow the oddities to be used - so this would be similar to your pc88.h

That should keep everyone happy!
You do not have the required permissions to view the files attached to this post.
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

Re: [PC-8801] New C chain, possible integration?

Post by shram86 »

dom wrote: Wed Mar 10, 2021 8:51 am Yup, that was it, I just had to track where it was being overwritten.

I then fell into the trap where the attributes are actually 80 column based. We now have colour and 40 column mode working

40 column colour

Though obviously it's not as useful as on other targets as a result of the line based nature of the attributes as a result it's easy for the screen to end up in a bit of a mess if you're randomly printing at coordinates as in this test. Should be perfectly usable for adventure games though. To quote the G2 page "To be honest, it's a hassle." :)

I've given the M88 emulator a try as well - what do I need to do to get it to display all 25 lines on screen? At the moment it's just showing 20 despite the port being set to show the 25?
M88 might forcibly use its DIP-SW settings, I'm not 100% sure, but this works on boot:
Image
It looks like you're in 25 row mode, because there's only 1 px between text rows, so the bottom row is probably hidden somehow. If your attributes table is all 00, that could be why they aren't showing up? Additionally, if you are using BASIC hooks still, it might use the CONSOLE parameters as limitations to printing. From G2:
起動直後のアトリビュートは [0x80][0x00] で初期化されているようです(白黒モード)。
BASIC で CONSOLE 0,25,0,1 (1=カラーモード)とすると [0x80][0xE8] で初期化されます。
After boot, attributes are initialized to 0x80 0x00 (BW mode). If you enter CONSOLE 0,25,0,1 in BASIC (1 = color mode) then they will initialize to 0x80 0xe8.
I would also suggest trying it in all 3 modes - (V1/S V1/H and V2)I noticed some odd glitches in my sprite example when on hardware on V1 mode in that bottom "text RAM" area.
Next: graphics. I'm going to make the default graphics mode hires since the attribute design makes lores graphics "awkward" to mix with text without careful crafting. I'll probably add support in for the 400 high monochrome screen.

I suspect the end state of the libraries will be:

- By default I'll attempt to make it work broadly the same as other machines which helps non-specialists get software onto the machine
- Collection of utility routines/sfr/#defines to allow the oddities to be used - so this would be similar to your pc88.h

That should keep everyone happy!
Awesome! There is some cool stuff you can do with ALU copy mode and the like which might be very useful.
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

The dip switch was the problem it seems, I'll stick with Takeda though since the debugger is capable.

So, I've now got hires graphics working quite nicely (no ALU yet) nicely in colour and it's a runtime switch between hires and semigraphics.

I am however, fighting (despairing, cursing, crying...) at handling the text attributes to make them usable. I'm on the 3rd(?) iteration of the code to deal with them and I'm almost, but not quite there.

Sadly, each iteration which makes it work a little better, just gets slower. I'm now at the point where I uncompress and then compress the attributes every time a character is printed. It still doesn't work properly and I end up a curious display when I mix text and semi-graphics:
Semigraphics gone bad
So I've obviously got a bug (or two) - I'm nowhere near the 20 changes per line in this test. It was looking quite nice until the border was drawn. I don't suppose you've come across a routine on your travels?

EDIT: Now working in 80 column mode, just need to figure out why 40 column mode behaves differently with semigraphics.
You do not have the required permissions to view the files attached to this post.
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

Re: [PC-8801] New C chain, possible integration?

Post by shram86 »

Nothing as such to deal with text attributes... You can tell I am lazy, because I stack them in an array and let the user worry about not effing up.

It looks pretty good to me to be honest - I don't think the different modes are really meant to be mixed that much, if that is any consolation.

A few things to maybe check:
1. The first attribute on any line HAS TO START at X=0. The first 'position' byte of every attribute row is actually ignored by the hardware and is just assumed to be 0.
2. You can't have multiple attributes sharing a location byte. The location bytes have to be in order and cannot repeat, i.e. 0, 1, 4, 7, 9, 12... You will see glitches if you don't do this, and don't reset the attribute at the end of the line
3. Given 1 and 2, you might see bugs being 'fixed' by spreading out the attributes and text on-screen.

I am excited to try out your graphics - I've been messing with old adventure games, and so many use Turtle it is frustrating. A lot of these games could have actually been playable :rolleyes:
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

It turns out the problem was the opposite - the attributes ended up being spaced too far apart and the repeated compression cycles worsened the case.

The cross example above now has character perfect colour which is great because it’s less explanation for me to put in the wiki!

I didn’t know about the end of line reset being required - I can’t immediately spot that in emulator source code.

Given how awful they are to use I guessed that mixing modes wasn’t really thought of. I have to admit that I don’t entirely understand the usecase for overline nor hidden really - without them then you’d get perfect settings for 40 column. Ah well.

I can see some screenshots that do mix them but they look like art rather than action shots so to speak.

I’ll push the branch this weekend to let you have a play.
stefano
Well known member
Posts: 1663
Joined: Mon Jul 16, 2007 7:39 pm

Re: [PC-8801] New C chain, possible integration?

Post by stefano »

wonderful job ! it saves me time in looking in the BASIC disassembly for something possibly pertaining :)
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

I've pushed my changes, hopefully it'll build ok. The code is in the feature/pc88_cleanup branch, hopefully it'll build. It's probably easiest to quote the commit message:
(pc88) Checkpoint a chunk of work.

1. Rewrite the graphics code so it's in the library. Default is
hires graphics. To use lores graphics switch mode with
console_ioctl() and add 32

2. Use the ALU for graphic mode gencon

3. Use the ALU for plot/unplot in hires mode

4. Rewrite the attribute handling. This does make text mode really
slow (relatively), but it's now usable without having to make
compensation for the "interesting way" it's implemented.

Everytime we print a char in text mode, we grab the appropriate
attribute row, decompress it, set the attributes for the print
position and then recompress. This allows us to mix lores graphics
and text fairly easily.

5. Lores graphics doesn't work in 40 column mode. I've no idea
what is going on if I'm honest.

TODO:

* vpeek() for hires console
* Fix up putsprite/stencil draw - these should use the ALU to speed things up nicely and simplify code
* C header file for pc88 hardware
* asm header file for pc88 hardware
* Fix up everything I've broken
Some more TODOs:

* Implement 640x400 mode
* Optimise the attribute compressor: https://github.com/z88dk/z88dk/blob/fea ... e.asm#L172 I know it can go faster since the use of ix isn't really needed
* Can we use the ALU for xorpixel/pointpixel?
* Autorepeat for keyboard reading

EDIT, more progress:

* ALU used for scrolling + CLS in mode 2. There's a remarkable speed up here!
* ALU used for stencil routine: these now reflect the textbackground/textcolour so it's in colour now as an added bonus
* vpeek() implemented
* Header files added (I've copied the doc from pc88-c.h) - all the ports are marked as __sfr which makes for nice inline code when compiled
User avatar
dom
Well known member
Posts: 1370
Joined: Sun Jul 15, 2007 10:01 pm

Re: [PC-8801] New C chain, possible integration?

Post by dom »

I've now merged this as it stands, I think it's an improvement on where we were before. You'll need to do a make clean after pulling or weird things will happen.

To compare non-ALU vs ALU accelerated code, compile with -clib=v1 - it's really noticeable when scrolling the hires screen and also allows us to stay compatible with the older two machines.

Some things that could still be done:

- Figure out why autorepeat doesn't work when reading the keyboard
- Optimise those attributes routines
- Support the 640x400 graphics screen
- Add diskio routines

But, I think all of those are incremental improvements.
shram86
Member
Posts: 13
Joined: Sun Mar 07, 2021 11:10 pm

Re: [PC-8801] New C chain, possible integration?

Post by shram86 »

Awesome job - I haven't had a chance to test it on hardware yet, but in my own experiments I found some things that might be worth looking into:

First, I think I found out why vsync interrupt isn't used, but I could be doing something wrong. When printing text it seems fine, but when hooking in a full draw routine like the example game I'm working on, it seems to run the hook too fast and can't seem to access GVRAM in the same way. When you switch from 15/24khz monitor modes this hook also changes its frequency.

To that end, the vsync wait seems to work better (for me - if you are performing full draws in both modes using vsync IRQ then I must be doing something wrong).

Second, I think I found the key difference between V1 and V2 - when you write to a GVRAM plane in V1 mode, it appears to require an additional cycle of sync to the CRT.
For example, in V1 mode:
Draw on 1 GVRAM plane - 60 FPS
Draw on 2 GVRAM planes - 30 FPS
Draw on all 3 GVRAM planes - 15 FPS
In V2 mode:
Draw on all 3 planes, same routine - 60 FPS

You should be able to see this yourself by making a simple project that draws a single pixel to all 3 planes.

Let me know if this matches your behavior, since its pretty fundamental to design on the hardware! :)

Edit: Xrea's info on 400-line mode:
bit0 の 640x400x1 の設定はグラフィックの B プレーンを上半分、R プレーンを下半分とする 400 ライン構成になります。G は表示されません。
この設定は高解像度(24KHz)モニターで、かつ bit4=0(白黒)設定でないと有効になりません.
With bit0 of IO 31h clear, you enable 400 line mode, where GVRAM plane B is the top half, and R is the bottom half. G is not displayed. This is only for 24khz monitors, and bit4 must be 0 or it will not be enabled.
Post Reply