Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
PRINT AT 23,0 and FOR NEXT Loop not working after Fastcall
#1
Hi,

I´ve tried but now yet find the issue for this:

I´m writing a BASIC program (with help of LCDs BorIDE) with a FASTCALL Function ASM
which itself calls a machine code routine in Spectrum Betadisk / TR-DOS ROM.

If have the FASTCALL NOT active in my BASIC program then these BASIC line work:
PRINT AT 23,0;"XXX"
and
DIM A AS UINTEGER
FOR A=59999 TO 60008
PRINT A, PEEK(A); " "
NEXT A

BUT if I activate the FASTCALL
and then run those BASIC lines
I get error: 5 Out of Screen on: PRINT AT 23,0;"XXX"
and I get output 60000 to 60008 on the loop (instead of output 59999 to 60008)

Because of it´s complexity I won´t post my whole source here,
as you need BorIDE and an emulator like Fuse and some additional files (like TRDOS-Disk-Image) to test it completly.
I you like, I can send this all packed together directly to you.

But maybe on reading the above you have an Idea what could be the reason ?

Regards,

Luzie
Reply
#2
Unfortunately, I don't know what could be happening.
Usually, if you get an error with FastCall in an ASM routine, it means that you're not returning well.
You need to preserve the IX register upon return (check if any of your routines modifies it).
I would need to have a look at the subroutine(s) using fastcall.
Reply
#3
OK.

I´ll paste the called FASTCALL down under.

I´ve tried to save IX register by a PUSH IX and restore it with POP IX, but this changed nothing,

The problem seems to me the TR-DOS-ROM (=Spectrum Betadisk-System) Routine
which is called with the FASTCALL.

But I cannot imagine yet, why this can bring your ZX Basic "out of running correct".

Here´s my used FASTCALL:
Code:
FUNCTION FASTCALL MCodeDIRDOSv4 (number as uByte) as uInteger

ASM

;BDUC-Newsletter No.5 Page 5 Brothaers TR-DOS v4.XX Example for CAT to SCREEN
CALL 15366                        ;TR-DOS v4 #3C06 = 15366 dez = DOS ON
PUSH HL                            ;Put the DOS OFF return adress on the stack - Needed by TR-DOS v4
LD A,2                            ;Select Stream 2 (screen)
LD C,7                            ;Set DOS Routine 7 (catalogue)
CALL 15357                        ;Call TR-DOS v4 Central Functions adress #3BFD = 15357 dez
RET                                        ;This one jumps to the adress PUSHed with PUSH HL, put DOS Off and returns

END ASM
END FUNCTION
Reply
#4
Luzie Wrote:OK.

I´ll paste the called FASTCALL down under.

I´ve tried to save IX register by a PUSH IX and restore it with POP IX, but this changed nothing,

The problem seems to me the TR-DOS-ROM (=Spectrum Betadisk-System) Routine
which is called with the FASTCALL.

But I cannot imagine yet, why this can bring your ZX Basic "out of running correct".

Here´s my used FASTCALL:
Code:
FUNCTION FASTCALL MCodeDIRDOSv4 (number as uByte) as uInteger

ASM

;BDUC-Newsletter No.5 Page 5 Brothaers TR-DOS v4.XX Example for CAT to SCREEN
CALL 15366                        ;TR-DOS v4 #3C06 = 15366 dez = DOS ON
PUSH HL                            ;Put the DOS OFF return adress on the stack - Needed by TR-DOS v4
LD A,2                            ;Select Stream 2 (screen)
LD C,7                            ;Set DOS Routine 7 (catalogue)
CALL 15357                        ;Call TR-DOS v4 Central Functions adress #3BFD = 15357 dez
RET                                        ;This one jumps to the adress PUSHed with PUSH HL, put DOS Off and returns

END ASM
END FUNCTION
You have to save both the SP (stack) and the IX register. FASTCALL is faster and does nothing of this, it's just a pure ASM code (the ubyte parameter is passed in the A register).
I haven't examined what TR-DOS do. Also, ZX BASIC uses the classic 48k ROM variables (i.e.236XX addresses). It might also be that.
Where can I find the TR-DOS asm listings? maybe I can have a look.
Reply
#5
boriel Wrote:You have to save both the SP (stack) and the IX register. FASTCALL is faster and does nothing of this, it's just a pure ASM code (the ubyte parameter is passed in the A register).
I haven't examined what TR-DOS do. Also, ZX BASIC uses the classic 48k ROM variables (i.e.236XX addresses). It might also be that.
I think you maybe right with this. I have to try a little further.

OK. As I´m not very experimented with ASM, can you please show me the way ? Do you think this should be enough (=save IX and SP):

On <!-- m --><a class="postlink" href="http://jgmalcolm.com/z80/intermediate/pcsp.htm#gsc.tab=0">http://jgmalcolm.com/z80/intermediate/p ... #gsc.tab=0</a><!-- m -->
I found this one:
;SafeExit:
ld sp,(SavedSP) ;get back saved sp
ret ;exit
;SaveSP:
ld (SavedSP),sp ;save sp
ret ;go back
;SavedSP: .dw 0 ;memory to save sp

I tried this with:

Code:
LD (SavedSP),SP
PUSH IX
...
CALL 15357                        ;TR-DOS v4 #3BFD = 15357 dez
POP IX
LD SP,(SavedSP)
RET

SavedSP:
DEFB 0,0
but this doesn´t changed anything.
boriel Wrote:Where can I find the TR-DOS asm listings? maybe I can have a look.
You mean TR-DOS ROM-Listing ? I have one commented in portoguese for TR-DOS v4 compatible CBI-DOS v2.4
but I think it´s not yet worth to do time-consuming debugging on it.
Reply
#6
I think the order of the stack instructions is not right. Try this one:

Code:
PUSH IX
LD (SavedSP),SP
...
CALL 15357                  ;TR-DOS v4 #3BFD = 15357 dez
LD SP,(SavedSP)
POP IX
RET

Try this and tell me. :roll:
Reply
#7
boriel Wrote:I think the order of the stack instructions is not right. Try this one:

Code:
PUSH IX
LD (SavedSP),SP
...
CALL 15357                  ;TR-DOS v4 #3BFD = 15357 dez
LD SP,(SavedSP)
POP IX
RET

Try this and tell me. :roll:
This doesn´t changed anything.
I put the Fastcall / MCode out and get the "5 Out of screen" Error
while only running this BASIC lines:

Code:
FOR A=0 TO 40
PRINT AT A,15; INK 6; PAPER 0;A;"###"
NEXT A
END
This wraps around (e.g. AT 24,0 is printed on line 0). But these wrapped lines doesn´t print from column 15,
they are printed from column 0. And at program end, this rises the "5 Out of screen" error.
Reply
#8
Luzie Wrote:I put the Fastcall / MCode out and get the "5 Out of screen" Error
while only running this BASIC lines:

Code:
FOR A=0 TO 40
PRINT AT A,15; INK 6; PAPER 0;A;"###"
NEXT A
END
This wraps around (e.g. AT 24,0 is printed on line 0). But these wrapped lines don´t print from column 15,
they are printed from column 0. And at program end, this rises the "5 Out of screen" error.
This behaviour is expected.
The ZX Spectrum screen has only 24 physical rows (from 0 to 23). Printing beyond 23 just wraps around and resets the X coordinate (back to 0).

It also puts an "Out Of Screen" signal in the ROM Variable, hence when you exit back to Sinclair BASIC you get the 5 Out of Screen Error.
This is done this way because you can check if your latest print has been out of screen or not.
Also, if you enable ZX BASIC check error flag, printing or plotting out of screen will trigger an Out of Screen error and exit to BASIC.
Reply
#9
boriel Wrote:This behaviour is expected.
The ZX Spectrum screen has only 24 physical rows (from 0 to 23). Printing beyond 23 just wraps around and resets the X coordinate (back to 0).

It also puts an "Out Of Screen" signal in the ROM Variable, hence when you exit back to Sinclair BASIC you get the 5 Out of Screen Error.
This is done this way because you can check if your latest print has been out of screen or not.
I understand and have to check where my original BASIC program "runs out of screen".

However, one question:

When I have a program with this two lines:

PRINT AT 24,0;"24,0"
PRINT AT 10,0;"10,0"

I too get the 5 Out of Screen Error, and the second "regular" PRINT position
don´t reset the "Out Of Screen" signal ROM Variable (is this a Spectrum BASIC system variable ?).
I think a regular PRINT position should reset the "Out of Screen" flag ?

Regards,

Luzie
Reply
#10
Luzie Wrote:I understand and have to check where my original BASIC program "runs out of screen".
However, one question:
When I have a program with this two lines:

PRINT AT 24,0;"24,0"
PRINT AT 10,0;"10,0"

I think a regular PRINT position should reset the "Out of Screen" flag ?
Unfortunately not. For speed reasons, only errors are "signaled". If a PRINT is ok, no flag is reset.
Reply
#11
But I can implement a way to optionally resignal "OK" if you want.
Reply
#12
boriel Wrote:But I can implement a way to optionally resignal "OK" if you want.
I not fully understand what you mean with this. If you like, you can implement it. But as I now know the circumstances about it, I can also avoid "Printing out of screen" Big Grin
Reply
#13
Luzie Wrote:
boriel Wrote:But I can implement a way to optionally resignal "OK" if you want.
I not fully understand what you mean with this. If you like, you can implement it. But as I now know the circumstances about it, I can also avoid "Printing out of screen" Big Grin
you can also PEEK 23610 (ERR_NR). ZX Basic stores the error there. It should be the same number you get when you exit to basic minus 1, so for "0 OK 0:1" the code is 0, so poke it with 255 (which is -1 in 2 complement). That is POKE 23610, 255 before exiting to Sinclair BASIC will clear any error silently.
Reply
#14
boriel Wrote:you can also PEEK 23610 (ERR_NR). ZX Basic stores the error there. It should be the same number you get when you exit to basic minus 1, so for "0 OK 0:1" the code is 0, so poke it with 255 (which is -1 in 2 complement). That is POKE 23610, 255 before exiting to Sinclair BASIC will clear any error silently.
WOW! Nice trick! This helps me to avoid /clear the error "5 Out of screen". Thank you very much!
Reply
#15
You can also PEEK this address from time to time, to detect there has been an error, and do something (in old basic dialects, remember ON ERROR GOTO...)
Reply


Forum Jump:


Users browsing this thread: 3 Guest(s)