No return to BASIC with inline assembled parts

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
cha05e90
Member
Posts: 23
Joined: Fri Jan 04, 2019 11:06 am

No return to BASIC with inline assembled parts

Post by cha05e90 »

Hello there!

I'm trying to include some inline-assembler to one of my little C-try-outs. while *simple* "self-contained" assembler works nicely as expected I have problems with the shown source here:
It's Andrew Pennell's assembler routine for establishing stream #14/channel "Z" for reading #14 outputs to z$. Whatever I try (even compiling it a a "normal" machine code and "call" it from my C program doesn't work. In most of the cases it never returns from the (C) machine code after the second "printf()". So I'm doing something wrong, but I could not figure out what exactly.

Is it maybe the fact that Andrews code extends the CHAN area and therefore moves the BASIC space? If I RANDOMIZE USR the compiled assembler part directly (address looked up via Spectaculator debugger) everthing works like it should - therefore I assume the culprit is something other than that...

Code: Select all

/*
Z80 asm for z88dk.
A. Pennell's "z$-channel-#14-routine"
*/

#include <conio.h>
#include <stdio.h>
#include <spectrum.h>
#include <zxinterface1.h>

#define PROG 0x5c53
#define VARS 0x5c4b

int ch14z(void)
{
#asm
SETUP:          
                ld  hl, (PROG)
                dec hl 
                push bc
                push hl 
                ld bc,11
                call 0x1655
                pop de 
                ld hl, OUTCH-SETUP 
                pop bc 
                add hl,bc 
                push de 
                ex de,hl
                ld (hl),e 
                inc hl 
                ld (hl),d 
                inc hl 
                ex de,hl 
                ld bc,LABEL-OUTCH 
                add hl,bc 
                ld bc,9
                ldir
                pop hl 
                inc hl 
                ld bc,(0x5c4f)
                and a 
                sbc hl,bc 
                ld (0x5c32),hl 
                ld bc,0 
                ret
LABEL:          
                defw 0x15c4
                defm "Z"
                defw 0x28
                defw 0x28
                defw 11
OUTCH:          
                push af 
                ld hl,(VARS)
L1:             
                ld a,(hl) 
                cp 0x5a
                jr z,FOUND
                cp 0x80
                jp z,0x0670
                call 0x19b8
                ex de,hl 
                jr L1                
FOUND:          
                inc hl 
                ld c,(hl) 
                inc hl 
                ld b,(hl) 
                inc bc 
                push bc 
                push hl 
                add hl,bc 
                call 0x1652
                inc hl 
                ex de,hl 
                pop hl 
                pop bc 
                ld (hl),b 
                dec hl 
                ld (hl),c 
                pop af 
                ld (de),a 
                and a  
                ret                  
#endasm    
}
int main(void)
{
    printf("Start Of Routine!\n");
    ch14z();
    printf("End Of Routine!\n");
    return (0);	
}
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: No return to BASIC with inline assembled parts

Post by dom »

Sorry It looks like I’m taking a little break at the moment.

However, does a normal z88dk program return cleanly to basic? It should, but if it doesn’t that that’s probably the problem.

If it does, does this program work without the printfs?
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: No return to BASIC with inline assembled parts

Post by dom »

To answer my own questions, using Fuse/48k (no interface1 since I've not downloaded the ROMs).

1. Yes, programs can return to basic
2. Yes, it also works with the printfs

So, at the moment I can't reproduce this issue, can you let me know what version of z88dk you're using and the compile flags you're using?
cha05e90
Member
Posts: 23
Joined: Fri Jan 04, 2019 11:06 am

Re: No return to BASIC with inline assembled parts

Post by cha05e90 »

Hi, thanks for caring! :-)

For emulation I use a setup with Fuse or Spectaculator with a ZX Spectrum 48k/128k and an Interface 1 v2-Rom. It's interesting that the code seems to work for you...

ATM I'm using the nightly build from 04.02.2020 (should be one day (?) after the official v2.0 release) and this is my compile line:

Code: Select all

zcc +zx -lm -lndos ch14_z.c -och14_z.bin -zorg60000
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: No return to BASIC with inline assembled parts

Post by dom »

I've downloaded if2-1.rom so I can now test with if1 and it's still working.

So, I can only presume there was an issue back in February that's now fixed, so please grab a newer nightly - you'll get interbank calls, 128k TAP file and 128k +3 disc creation as additional bonuses!
cha05e90
Member
Posts: 23
Joined: Fri Jan 04, 2019 11:06 am

Re: No return to BASIC with inline assembled parts

Post by cha05e90 »

Sounds promising - I'll download a new nightly, fingers crossed. :-)
cha05e90
Member
Posts: 23
Joined: Fri Jan 04, 2019 11:06 am

Re: No return to BASIC with inline assembled parts

Post by cha05e90 »

Hm, I were not able to get the newest z88dk nightly build running - going backwards revealed that a nb from July is the last which works here. I suppose something changed in the build pipeline. The culprit might be the fact that I'm running a 32Bit Windows 10 on a 64Bit processor (due to a rather devoured upgrade path from Windows Vista). I had the same problem with Mike's CSpect. Nevertheless that older version of z88dk at least solved the "no-return-to-BASIC" problem and, indeed, it behaves like you described, both "printf()" are executed and I'm back to "K" cursor.

But: The asm code part still don't work when called from the c part of the code. If I call that asm part directly from BASIC with (in my compile) RANDOMIZE USR 60265) it works perfectly as expected, sets up the channel/stream data for #14/"Z" and establishes the code to push #14-output to z$. So the assembler itself is allright.

I still assume that the manipulation of the channel (and therefore BASIC area) area from the asm part is something that the surrounding c (library) parts doesn't like...
User avatar
dom
Well known member
Posts: 2076
Joined: Sun Jul 15, 2007 10:01 pm

Re: No return to BASIC with inline assembled parts

Post by dom »

The culprit might be the fact that I'm running a 32Bit Windows 10 on a 64Bit processor (due to a rather devoured upgrade path from Windows Vista).
Ah, yes: https://z88dk.org/forum/viewtopic.php?f=18&t=11381
cha05e90
Member
Posts: 23
Joined: Fri Jan 04, 2019 11:06 am

Re: No return to BASIC with inline assembled parts

Post by cha05e90 »

dom wrote: Sun Dec 13, 2020 9:42 am Ah, yes: https://z88dk.org/forum/viewtopic.php?f=18&t=11381
Ok - understood! :-)
cha05e90
Member
Posts: 23
Joined: Fri Jan 04, 2019 11:06 am

Re: No return to BASIC with inline assembled parts

Post by cha05e90 »

cha05e90 wrote: Sun Dec 13, 2020 9:19 am ...
I still assume that the manipulation of the channel (and therefore BASIC area) area from the asm part is something that the surrounding c (library) parts doesn't like...
Just did a quick test with something like this:

Code: Select all

org 50000
call 0xeb69 	; Start of (asm) Code: 60265 - see above
ret 
and it doesn't work, either. So everything than calling Pennell's code directly from BASIC does not work. Hmm...maybe someone has a hint what's so special here...
Timmy
Well known member
Posts: 392
Joined: Sat Mar 10, 2012 4:18 pm

Re: No return to BASIC with inline assembled parts

Post by Timmy »

I just compiled and ran the code of the very first post with no problems.

I was using a build from the beginning of this year, so you can probably just an earlier build too that works for you.

Of course, the channel z thing can be called and return to basic to me, but that's because you don't use it in any way, right?

(Or perhaps you have some special setup that I can't see.)
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: No return to BASIC with inline assembled parts

Post by stefano »

cha05e90,
you chose quite a tricky piece of code for your experiments !

I wonder if the different results depend on whether the shadow ROM is being activated.

It is just my dumb guess, but consider that a freshly loaded auto-run program from tape won't enable the shadow rom. Most of the error conditions, will. You can force the IF1 activation with our functions, but you can't restore a clean memory condition (at the moment). The if1 status can be checked with "if1_installed()".
Manipulating channels for the Sinclair BASIC can be done in 2 ways IIRC, with and without the IF1 attached. I seem to remember that the latter requires a clean reset to be sure that the shadow ROM won't interfere.

I'm quite sure you are not trying to use that trick to pass parameters, but.. just in case, do you know you can store text in Z$ with the z88dk functions ?
zx_setstr ('z',"Adding text to Z$...");
cha05e90
Member
Posts: 23
Joined: Fri Jan 04, 2019 11:06 am

Re: No return to BASIC with inline assembled parts

Post by cha05e90 »

Ah, stefano, thanks for caring! Ehm, yes I know the zx_setstr() function - the above shown example from Andrew's ZX Microdrive magic is only for testing purposes from my side:

I would like to incorporate (foreign) assembler code (ZX MD/IF1 related) inside my own C stuff. So I assumed naively it could be done in the above shown way - but it quite did not work as expected (from me). Funny thing is when calling the assembler part directly from BASIC (IF1 active) everything's fine, when calling the C part from BASIC (IF1 active) which is calling the assembler part it doesn't work. Andrew's code is indeed manipulating the channel/stream SYSVAR area and expects the IF1 to activated. So I assume you're right - maybe somewhere around that corner is the culprit. It *feels* like calling the C part somehow resets the shadow ROM stuff to another state (at least different from the state the calling BASIC is in). But that's just a guess atm...
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: No return to BASIC with inline assembled parts

Post by stefano »

I recently put a lot of effort in the if1 stuff:
https://github.com/z88dk/z88dk/tree/mas ... get/zx/if1

.. which brought my attention to the many existing channel interfaces of the different BASIC implementations. Also the Newbrain, the TRS80 and the MSX had a similar device extension facility, all of them include a descriptor with the channel capabilities, and the addresses of the service routines.
Adding a sort of universal API to permit the file redirection on such channels could be interesting.
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: No return to BASIC with inline assembled parts

Post by cborn »

Hi
I did not test your routines but i want to remark that i re-wrote 64#4 to fit inside the CHANNEL area, including the font, just like this routine. But its pure MC.
An issue might be that the Microdrivemaps are placed BEFORE the channel table+extra thus moving addressing up in RAM
the standard CHANS length is 21 bytes but using #14 means a lot off extra (empty?) table space space of 5*11 bytes giving 21+55 bytes at least.
personaly i want to attempt to place the interrupt-table inside the channel area or maybe between the MicrodriveMaps and the Channeltable, but thats realy off topic

the next problem i work on and which might be an issue here is the check if the channel+stream are realy free. quite a lot of programs use #4 as a standard whithout checking the availabilyty of the channel it self.
this workfile re-installs the printroutine every time ON TOP of the last installed #4 routine:
http://www.cborn.nl/zxfiles/64-4chan.tap.zip
i hope it can it help a little bit
cheers
cborn
Well known member
Posts: 267
Joined: Tue Oct 06, 2020 7:45 pm

Re: No return to BASIC with inline assembled parts

Post by cborn »

PS:

Code: Select all

ld  hl, (PROG)
dec hl
It totaly assumes this will be the end toff the table without checking for 128 EOF mark

Code: Select all

LD a,128
cp (hl)
jr nz,EOF_error
the lack of this control show the lack of channel use and experience as a common problem.
AFAIK Tony Baker wrote a channel MANAGER which is able of removing an channel from the middle of the channel table.
CB
stefano
Well known member
Posts: 2137
Joined: Mon Jul 16, 2007 7:39 pm

Re: No return to BASIC with inline assembled parts

Post by stefano »

Well, on the microdrive part I did not use the channels at all. It's quite a low level approach :)
I think that understanding what's going on in interfacing z88dk with the channels would require a bit of hands-on. My first guess is a lack of the ix (iy?) registry protection, but I can be totally wrong.
Post Reply