Posts: 35
Threads: 8
Joined: Nov 2015
Reputation:
0
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
Posts: 1,763
Threads: 55
Joined: Aug 2019
Reputation:
24
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.
Posts: 35
Threads: 8
Joined: Nov 2015
Reputation:
0
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
Posts: 1,763
Threads: 55
Joined: Aug 2019
Reputation:
24
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.
Posts: 35
Threads: 8
Joined: Nov 2015
Reputation:
0
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.
Posts: 1,763
Threads: 55
Joined: Aug 2019
Reputation:
24
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:
Posts: 35
Threads: 8
Joined: Nov 2015
Reputation:
0
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.
Posts: 1,763
Threads: 55
Joined: Aug 2019
Reputation:
24
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.
Posts: 35
Threads: 8
Joined: Nov 2015
Reputation:
0
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
Posts: 1,763
Threads: 55
Joined: Aug 2019
Reputation:
24
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.
Posts: 1,763
Threads: 55
Joined: Aug 2019
Reputation:
24
But I can implement a way to optionally resignal "OK" if you want.
Posts: 35
Threads: 8
Joined: Nov 2015
Reputation:
0
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"
Posts: 1,763
Threads: 55
Joined: Aug 2019
Reputation:
24
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 Big Grin](https://www.boriel.com/forum/images/smilies/biggrin.png) 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.
Posts: 35
Threads: 8
Joined: Nov 2015
Reputation:
0
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!
Posts: 1,763
Threads: 55
Joined: Aug 2019
Reputation:
24
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...)
|