Jump to content
IGNORED

function DSRLNK error... someone can help ?


Recommended Posts

Hi !

a friend of mine posted on the italian ti99iuc forum a question about an error during the programming in assembler...

i can't help, maybe know how to solve this problem ?

 

Thankyou ! :D

 

TI 99 Freeze when i call the Function DSRLNK?

I done the examples on the manual, and looking for a solution on this prolem...

i tried to change flag, record lenght but it's not working...

 

the same problem using the emulator ...

on the real TI the DSK2 power on the red light but freeze.

 

This is the source code:

...

PAB EQU >F80

PABBUF EQU >1000

PNTR EQU >8356

...

PDATA BYTE >00 I/O OPCODE

BYTE >0A FLAG/STATUS

DATA PABBUF DATA BUFFER ADDRESS

BYTE >80 LOGICAL RECORD LENGTH

CCOUNT BYTE >00 CHARACTER COUNT

DATA >0000 RECORD NUMBER (RELATIVE RECORD FILES)

BYTE >00 SCREEN OFFSET

NLEN BYTE NAMEND-FNAME NAME LENGTH

FNAME TEXT 'DSK2.RS232ROM'

NAMEND EQU $

EVEN

...

LI R0,PAB

LI R1,PDATA

LI R2,NAMEND-PDATA

BLWP @VMBW

LI R6,PAB-PDATA+NLEN

MOV R6,@PNTR

 

BLWP @DSRLNK

DATA 8

Link to comment
https://forums.atariage.com/topic/197270-function-dsrlnk-error-someone-can-help/
Share on other sites

No. This doesn't look correct to me. I think the first problem is this line:

 

LI R6,PAB-PDATA+NLEN

 

PDATA and NLEN are symbolic addresses *IN CPU MEMORY* (probably in the >A000 range). However, the value loaded into PNTR (>8356) must be a *VDP* address.

 

The value loaded into CPU memory address >8356 should be the VDP address of the name byte in the PAB. In the above code, that is simply PAB+>0A (or PAB+10 in decimal).

 

So, the code should be changed to read as follows:

 

PAB	EQU >F80
PABBUF EQU >1000
PNTR   EQU >8356

PDATA  BYTE >00	i/o opcode
  BYTE >0A	flag/status
  DATA PABBUF data buffer address
  BYTE >80	logical record length
CCOUNT BYTE >00	character count
   DATA >0000  record number (relative record files)
   BYTE >00	screen offset
NLEN   BYTE NAMEND-FNAME	name length
FNAME  TEXT 'DSK2.RS232ROM'
NAMEND EQU $
   EVEN

   LI R0,PAB
   LI R1,PDATA
   LI R2,NAMEND-PDATA
   BLWP @VMBW
   LI R6,PAB+10	 <---- changed here
   MOV R6,@PNTR

   BLWP @DSRLNK
   DATA 8

 

I assume the user wants to open the file DSK2.RS232ROM for OUTPUT as a FIXED INTERNAL 128 file? That is what the PAB says (if I decoded it correctly!)

 

I have attached a PAB info cheat sheet that I made about two years ago; it saves me having to find the correct page in the editor assembler manual!

 

Please pass my best regards on to our Italian friends.

 

Mark

PAB Info.pdf

No. This doesn't look correct to me.

 

No. I think it is correct. The address written at >8356 must point to the name length, not the first character of the name. So, it's PAB+9, not PAB+10. Or PAB+(NLEN-PDATA) as written in the original post. ;)

 

I tested the code from the original post with classic99 and it creates a file "DSK2.RS232ROM" of type INT/FIX 128.

No. This doesn't look correct to me.

 

No. I think it is correct. The address written at >8356 must point to the name length, not the first character of the name. So, it's PAB+9, not PAB+10. Or PAB+(NLEN-PDATA) as written in the original post. ;)

 

I tested the code from the original post with classic99 and it creates a file "DSK2.RS232ROM" of type INT/FIX 128.

 

Mark indeed referenced the wrong byte; however, the name length is always byte 9 of the PAB as you point out, so the calculation, NLEN-PDATA, of the position within the PAB of the namelength byte, though fortunately correct, is unnecessarily complex (sort of like this sentence :P ). Were NLEN other than 9 bytes after PDATA, the branch to DSRLNK would not work in either case.

 

...lee

No. This doesn't look correct to me.

 

No. I think it is correct. The address written at >8356 must point to the name length, not the first character of the name. So, it's PAB+9, not PAB+10. Or PAB+(NLEN-PDATA) as written in the original post. ;)

 

I tested the code from the original post with classic99 and it creates a file "DSK2.RS232ROM" of type INT/FIX 128.

 

Mark indeed referenced the wrong byte; however, the name length is always byte 9 of the PAB as you point out, so the calculation, NLEN-PDATA, of the position within the PAB of the namelength byte, though fortunately correct, is unnecessarily complex (sort of like this sentence :P ). Were NLEN other than 9 bytes after PDATA, the branch to DSRLNK would not work in either case.

 

...lee

Not to muddy the waters but be careful: It is true that the name length is byte 9 when using level 3 file IO routines (ie, open/read/write/close/restore/delete) however the length byte, PAB, and scratchpad RAM requirements change when using the direct sector/file access routines (ie, read sector, write direct file, rename file).

Sorry! My bad. Even my own cheat sheet shows the correct byte (9) for the name length.

 

However, please take a look at the code as originally posted. The address MOVd to >8356 is incorrect, because it is computed from *CPU* memory addresses, which are determined at load time by the option 3 loader. The address in >8356 should be a VDP address, and is computed from the equate PAB (>F80), which is a VDP address. Therefore, I believe my original observation to be correct, albeit with the wrong byte offset.

 

So, to be clear, the corrected line of code should be:

 

LI R6,PAB+9

 

Please refer to ED/AS manual, page 303. I had to go look myself, as I rarely get involved with DSRLNK; I wrote the disk handling code for TurboForth in 2009 and haven't touched it since (in fact, it's just about the only bit of code that hasn't changed!!)

 

Apologies for the confusion - I will endeavour to check first! That's what happens when you post from your work desk, trying to look like your doing real work!

Sorry! My bad. Even my own cheat sheet shows the correct byte (9) for the name length.

 

However, please take a look at the code as originally posted. The address MOVd to >8356 is incorrect, because it is computed from *CPU* memory addresses, which are determined at load time by the option 3 loader. The address in >8356 should be a VDP address, and is computed from the equate PAB (>F80), which is a VDP address. Therefore, I believe my original observation to be correct, albeit with the wrong byte offset.

 

So, to be clear, the corrected line of code should be:

 

LI R6,PAB+9

 

Please refer to ED/AS manual, page 303. I had to go look myself, as I rarely get involved with DSRLNK; I wrote the disk handling code for TurboForth in 2009 and haven't touched it since (in fact, it's just about the only bit of code that hasn't changed!!)

 

Apologies for the confusion - I will endeavour to check first! That's what happens when you post from your work desk, trying to look like your doing real work!

 

Begging your pardon, Mark, but the original code is the same as yours, but with an address calculation for the offset instead of a literal value: NLEN-PDATA, though operating on CPU address space, nonetheless, computes to the proper offset, viz., 9.

 

...lee

Hello everybody,

 

I'm the original user that posted the question to the Italian TI-99 user club forum. I wasn't registered as an AtariAge user, so Ciro kindly posted the question here for me.

 

At first I would like to thank everybody for all the feedback, I wasn't expecting so much ;)

 

In particular, I would like to thank Mark for his cheat sheet, very useful to have it handy!

 

Returning to the argument of the post, I'm really stumped because I think the code is right. Yes, those are CPU addresses, but computing the difference between the two simply gives you an offset that is added to a VDP address, so at last the assembler geenrates a valid VDP address (I hate having "magic numbers" around my code and il ti easier for my mind to understand what that means. Complex? Maybe. We all are somehow... Let's the assembler work for us)

 

I really don't understand what's up with this code. On the physical console, all I have is a DSK2 led turned on (and a few seek noises), but than everything hangs. On the MESS, I don't have leds and noises, just hang :-(

 

I don't have at the moment a Classic99 at hand, but I understand that there the same code works. I'm glad, but I neet it to work on the real console...

 

Is there some black magic to do before invoking DSRLNK? I beg you aprdon, but this is my very first assembler program on the TI, so please consider that I may have missed also obvoius things.

 

Once more thanks to everybody, and happy 1st May (for the ones that are in holiday like us in Italy).

 

Ciao,

Ugo

Well, your code does look correct (apologies to Lee! Woops!)

 

Is this the complete code, or is there more code?

 

For example, I am wondering if you are using your own workspace, or the GPL workspace? Are you running this code from the editor assembler option 3 loader? We could do with a little more information.

 

You should also issue a CLOSE command to the disk system to close the file, but I don't think that would crash the computer.

 

How are you returning to the Editor Assembler environment? With an RT (B *R11) instruction?

 

Mark

Here is program that is complete - it sets up the workspace, creates the file, indicates if there was an error or not, and then returns to the editor assembler.

 

Load with editor assembler option 3. For program name, enter START.

 

   REF VMBW,VSBW,DSRLNK
   DEF START

PAB	EQU >F80
PABBUF EQU >1000
PNTR   EQU >8356

PDATA  BYTE >00 I/O OPCODE
   BYTE >0A FLAG/STATUS
   DATA PABBUF DATA BUFFER ADDRESS
   BYTE >80 LOGICAL RECORD LENGTH
CCOUNT BYTE >00 CHARACTER COUNT
   DATA >0000 RECORD NUMBER (RELATIVE RECORD FILES)
   BYTE >00 SCREEN OFFSET
NLEN   BYTE NAMEND-FNAME NAME LENGTH
FNAME  TEXT 'DSK2.RS232ROM'
NAMEND EQU $
   EVEN

MYWS   BSS 32


START  LWPI MYWS
   LI R0,PAB
   LI R1,PDATA
   LI R2,NAMEND-PDATA
   BLWP @VMBW
   LI R6,PAB-PDATA+NLEN
   MOV R6,@PNTR

   BLWP @DSRLNK
   DATA 8

   JEQ ERR			 JUMP IF IO ERROR DETECTED


* NO ERROR DETECTED
   CLR R0			  SCREEN ADDRESS
   LI R1,OKTXT		 ADDRESS OF TEXT
   LI R2,5			 LENGTH OF TEXT
   BLWP @VMBW		  WRITE TO SCREEN
   JMP EXIT

* ERROR DETECTED
ERR	MOV R0,R2		   SAVE ERROR CODE IN R2
   CLR R0			  SCREEN ADDRESS
   LI R1,ERRTXT		ADDRESS OF TEXT
   LI R2,4			 LENGTH OF TEXT
   BLWP @VMBW		  WRITE TO SCREEN

EXIT   LI R0,3			 OUTER COUNTER
   LI R1,>FFFF		 INNER COUNTER
LOOP   DEC R1
   JNE LOOP
   DEC R0
   JNE LOOP
   RT				  RETURN TO EDITOR ASSEMBLER

ERRTXT TEXT 'ERROR'
   EVEN
OKTXT  TEXT 'OKAY'
   EVEN

   END

 

 

It uses a simple JEQ instruction to see if there is an error or not. According to section 16.2.4 (page 262) in the ED/AS manual:

 

If no errors occur, the equal bit in the Status Register is reset on return from DSRLNK. If an I/0 error occurs, the equal bit is set, and the error code is stored in the most-significant byte of Register 0 of the calling program's Workspace.

 

Please try this on a real 4A (it works okay in Classic99). If you see ERROR on the screen please let me know and I will add code to display the error code.

 

Mark

Thanks Mark, of course there is other code, there is always other code, other code that make things go wrong... :-(

 

I'm saying this because I tried your example on the MESS emulator and it worked. Then I examined your code and compared with my own, and I saw that it was almost the same (AORG >A000 being the only difference). I "just" have some more code before the DSRLNK. I remmed that core out, and, guess it?, DSRLNK started working. So i understood that the culprit is not DSRLNK itself, nor the PAB, but the copy loop right before, that is going to dirty teh PAB copy in CPU RAM and I really don't understand what's going on there.

 

I attach the whole code of my fabolous program ;) I'm trying to make a backup of my CorComp RS232 ROM, as I'm willing to replace it with a Flash EEPROM adding (maybe) some features in it (HDX). So the (bugged) logic of the program is: enable RS232 rom, make a backup of the ROM in CPU RAM, disable ROM, open file, write file, close file.

 

I'm almost sure that there is a bug in the write loop too, but I will address that later if I survive this one.

 

And yes, I'm sure I could find a CorComp ROM somewhere in the net, but forgive me I have to finish this now, simply cannot give up without understanding my own errors.

 

You will see strange things in the code, like BL @PDEBUG or JMP BAILOU or BL @PRINTR, but those are only debug istructions and you can safely ignore them. I added them when I saw that the code was hanging at the DSRLNK call, and keep adding debug also after understanding that the loop was the guilty.

 

BTW, how do you debug such a beast? The only method I found is tou use MESS with -debug switch to enable debugger, but that's sooooo slooooowwwwwww... :(

 

   DEF  START

   REF  VMBW,DSRLNK,VSBW,VSBR

   AORG >A000

PAB    EQU  >F80
PABBUF EQU  >1000
PNTR   EQU  >8356
CRU    EQU  >1300
ROMSRC EQU  >4000
ROMSIZ EQU  >2000

PFFIX  EQU  >00
PFVAR  EQU  >10
PFDIS  EQU  >00
PFINT  EQU  >08
PFUPD  EQU  >00
PFOUT  EQU  >02
PFINP  EQU  >04
PFAPP  EQU  >06
PFSEQ  EQU  >00
PFRAN  EQU  >01

REGS   BSS  32
RTNADR BSS  2

CPUDAT BSS  ROMSIZ

PDATA  BYTE >00    I/O OPCODE
   BYTE PFFIX+PFINT+PFOUT+PFSEQ FLAG/STATUS
   DATA PABBUF DATA BUFFER ADDRESS
   BYTE >80    LOGICAL RECORD LENGTH
CCOUNT BYTE >00    CHARACTER COUNT
   DATA >0000  RECORD NUMBER (RELATIVE RECORD FILES)
   BYTE >00    SCREEN OFFSET
NLEN   BYTE NAMEND-FNAME NAME LENGTH
FNAME  TEXT 'DSK2.RS232ROM'
NAMEND EQU  $
   EVEN

WRITE  BYTE >03
CLOSE  BYTE >01
DTEXT  TEXT 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
   EVEN

START  MOV  R11,@RTNADR
   LWPI REGS

   CLR  R13
   BL   @PDEBUG

   LI   R0,367
   LI   R1,CPUDAT
   BL   @PRINTR

   LIMI 0
   LI   R12,CRU
   SBO  0

   LI   R0,ROMSRC
   LI   R1,CPUDAT
   LI   R2,ROMSIZ
COPYLP MOV  *R0+,*R1+
   DECT R2
  JNE  COPYLP

   SBZ  0
   LIMI 2

   BL   @PDEBUG

   MOV  R1,R3
   MOV  R0,R1
   LI   R0,299
   BL   @PRINTR

   MOV  R3,R1
   LI   R0,304
   BL   @PRINTR

   MOV  R2,R1
   LI   R0,309
   BL   @PRINTR

   LI   R0,PAB
   LI   R1,PDATA
   LI   R2,NAMEND-PDATA
   BLWP @VMBW

   BL   @PDEBUG

   JMP  BAILOU

   BL   @DSR

   BL   @PDEBUG

*	  JMP  BAILOU

   MOVB @WRITE,R1

   BLWP @VSBW

   LI   R1,>8000
   LI   R0,PAB+CCOUNT-PDATA
   BLWP @VSBW

   BL   @PDEBUG

   LI   R0,PABBUF
   LI   R1,CPUDAT
   LI   R2,>80
LOOP   BLWP @VMBW

   BL   @PDEBUG

   BL   @DSR

   BL   @PDEBUG
*	  JMP  BAILOU

   A    R2,R1
   CI   R1,CPUDAT+ROMSIZ
   JNE  LOOP

   BL   @PDEBUG

   MOVB @CLOSE,R1
   LI   R0,PAB
   BLWP @VSBW

   BL   @PDEBUG

   BL   @DSR

   BL   @PDEBUG

   JMP  BAILOU

PDEBUG MOVB @DTEXT(R13),R1
   MOV  R13,R0
   BLWP @VSBW
   INC  R13
   RT

DSR    LI   R6,PAB-PDATA+NLEN
   MOV  R6,@PNTR

   BLWP @DSRLNK
   DATA 8

   JEQ  DSRERR
   RT

DSRERR LI   R0,PAB+1
   BLWP @VSBR
   SRL  R1,13
   AI   R1,>30
   SLA  R1,8
   LI   R0,299
   BLWP @VSBW

BAILOU LI   R0,3
   LI   R1,>FFFF
WLOOP  DEC  R1
   JNE  WLOOP
   DEC  R0
   JNE  WLOOP

   MOV  @RTNADR,R11
   RT

DECODE TEXT '0123456789ABCDEF'
REGVAL BSS  2
PRNRET BSS  2

PRINTR MOV  R1,@REGVAL
   MOV  R11,@PRNRET
   SRL  R1,12
   BL   @PRINTC
   MOV  @REGVAL,R1
   SRL  R1,8
   ANDI R1,>000F
   BL   @PRINTC
   MOV  @REGVAL,R1
   SRL  R1,4
   ANDI R1,>000F
   BL   @PRINTC
   MOV  @REGVAL,R1
   ANDI R1,>000F
   BL   @PRINTC
   MOV  @PRNRET,R11
   RT

PRINTC MOVB @DECODE(R1),R1
   BLWP @VSBW
   INC  R0
   RT
   END

 

Thanks again.

 

Ciao,

 

Ugo

That LIMI 2 is ringing alarm bells in my head. There seems to be no reason for the interrupts to be enabled. You run the risk of the VDP address being changed while your screen writing routines are being executed, which can lead to trash being written into VDP (including the VDP registers which may corrupt the screen etc).

 

Give it a try without the LIMI 2.

 

The best program for debugging is Classic99 - it has an incredible debugger with breakpoints, break on read/write from/to memory, read/write from/to registers, read/write from/to VDP. It can even tell you if your code is reading from un-initialised areas of memory. It's easily the best debugger by a mile. I think a close second is TI994W by Fred Kaal.

 

If you have a TurboForth V1.1 cartridge I can write you some code to dump the RS232 ROM to a blocks file or any other type of file.

 

Mark

Also, it might be better to look at a different technique. You are copying the ROM to CPU memory. I wouldn't bother; I would copy it to VDP memory, as that's where it needs to be to write it out to disk.

 

I'll see if I can put something together this evening. I haven't done much assembly language disk access code; just the stuff for TurboForth so it should be fun!

 

Mark

Thanks King ;)

 

I thought I should copy ROM -> CPU RAM in order to use Disk Controller ROM to write to disk.

 

I didn't find any source stating that you can access devices (call @VSBW or @DSRLNK) with interrupts disabled, this is why I reenabled 'em just after copy.

 

Indeed, I could copy RS232 ROM -> VDP RAM directly, and maybe also in just one big chunk, so I will try this one tonight.

 

For the emulators: I'm on Linux, so I think I am stuck with MESS, am I not? Should I try the recursive emulator approach (Classic99 inside Virtualbox running Windows)? Still dreaming to use Linux native tools to develop (asm990 and so on)...

 

And no, I don't happen to have a TurboForth at hand. But started to read your site and seems interesting ;)

 

Please don't waste your time with this old noob :D

 

Once more thanks, and again congratulations for the title.

 

Ciao,

Ugo

And no, I don't happen to have a TurboForth at hand. But started to read your site and seems interesting ;)

 

Up !

you can found the TurboForth in Classic99 cartridge menu, it's ready to go !! :D

 

i have two original real carts but it's the v1.0, i should upgrade them to the new version...

Edited by ti99userclub

Still dreaming to use Linux native tools to develop (asm990 and so on)...

 

There is a port of the GNU assembler for the TI: http://www.atariage.com/forums/topic/164295-gcc-for-the-ti/page__st__75?do=findComment&comment=2484308

 

GCC still has some bugs, but the assembler works perfectly.

 

It's a patch for binutils-2.19.1, I don't know if it works with another version.

Well, I had to have a play!

 

I told myself I had to finish before my cup of tea went cold. I managed it!

 

Here is a program that I *think* works! I was only able to test it with classic99, and if I remember correctly, classic99 doesn't truly emulate the DSRs, so when you map the DSR ROM into memory they don't actually show up - so it saves 8K of zero's. If anyone spots anything wrong then please shout!

 

Anyway, I'm pretty sure this will work on a real TI. Please give it a shot.

 


   DEF START
   REF VMBR,VMBW,DSRLNK

SAVEOP  EQU 6		   memory image save opcode
VDPPAB  EQU >1000	   address of PAB in VDP
VDPBUF  EQU >1800	   address of rom image in VDP
LEV3IO  EQU 8		   code for standard level 3 disk io
PNTR    EQU >8356	   address of name length in VDP pab must be written here

MYPAB   BYTE SAVEOP,0
    DATA VDPBUF
    BYTE 0,0
    DATA 8192
    BYTE 0
    BYTE 13
    TEXT 'DSK2.RS232ROM'
    EVEN
ENDPAB  EQU $

* copy pab to vdp ram
START   LI R0,VDPPAB    vdp destination
    LI R1,MYPAB	 source
    LI R2,ENDPAB-MYPAB  # bytes to transfer
    BLWP @VMBW	  send PAB to VDP

* copy DSR ROM to VDP
    LI R12,>1300    cru address of card
    SBO 0		   turn on DSR ROMS

    LI R0,VDPBUF    we'll put DSR here
    LI R1,>4000	 address of DSR ROM
    LI R2,8192	  8K of ROM
    BLWP @VMBW	  send the dsr to VDP

    SBZ 0		   switch off DSR roms

* now execute a SAVE command using DSRLNK
    LI R0,VDPPAB+9  address of name byte in VDP pab
    MOV R0,@PNTR    required for DSRLNK
    BLWP @DSRLNK
    DATA LEV3IO	 standard level 3 disk io

    RT			  return to editor assembler environment

    END

 

It uses the SAVE command, which saves VDP memory to disk as a program image file; the most compact and fastest of the file formats for the TI. See editor assembler manual, section 18.2.1.7, page 297.

 

I've also attached the source as a text file.

 

Hope this helps.

 

Mark

SAVE-ROM.txt

The code is awesome, indeed. Very elegant. This proves that I have to RTFM a bit more ;)

 

But there is a little problem... it hangs my console with the floppy controller led lit. Both floppies are at IDLE (led turned off). I have to turn off the TI to resume, FNCT+= is not enough :(

 

I tried your original code (cut & paste from this web page into MESS, extracted from .DSK to TIFILES on Linux command line, transferred to TI via RS232 + MFM and compiled on the TI with no errors), and then I tried to add a private workspace and to disable interrupts, but nothing changes.

 

I cannot try anymore now, I'm risking a divorce right now ;)

 

Ciao

Ugo

Hmm... looks like the code us missing somewhere. Dunno. One for the experts I think. Anyone? Is SAVE level 3 operation? I'm a newbie at this disk io stuff.

I'd wager the problem is with the workspace (or lack thereof). Recommend you set up your environment and shut down the interrupts, ie. If the program is called from the GPLWS and DSRLNK uses that same workspace, you end up with a mess on your hands....

 

MYWS BSS >20
START LWPI MYWS
LIMI 0
continue code

Try returning with a BLWP @0  

 

I would also adjust the buffer start address from 0x1800 to 0x1200. Otherwise, you are mucking around with VDP space used by some of the disk controllers. For a good overview of the space, check out this doc pages 10 and 11 in particular.

ftp://whtech.com/magazines/smartprogrammer/sp8405.pdf

Edited by InsaneMultitasker
  • Like 2

Hmm... looks like the code us missing somewhere. Dunno. One for the experts I think. Anyone? Is SAVE level 3 operation? I'm a newbie at this disk io stuff.

 

SAVE is, indeed, a level 3 operation.

 

...lee

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...