Tursi Posted December 5, 2019 Share Posted December 5, 2019 (edited) 8 hours ago, senior_falcon said: If I understand this correctly, you can do the equivalent of CALL FILES(1) and put all the disk information so that nothing above >1FFF is used at all. The downside to this is that the stack space will be reduced by 529 bytes. Normally there are 1460 bytes of stack space available; reducing that by 529 is a deal breaker. That's just a number I chose - choose whatever values work for you. (edit: most of the CF7 is the standard TI DSR... so these statements are also true for it. They start with whatever is in >8370 when the powerup routine is called. This allows for multiple cards to reserve VDP RAM space. It just so happens that we all took what the TI Disk Controller did as the only gospel ) Edited December 5, 2019 by Tursi Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 6, 2019 Author Share Posted December 6, 2019 (edited) 7 hours ago, Lee Stewart said: The TI disk controller specs require(?) an additional buffer for one Volume Information Block (VIB) + other stuff for a total of 534 bytes. That plus one buffer (518 bytes) for one open file would seem to require starting one byte above >3BE3 - (>3FFF - >1FFF) = >3BE3 - >2000 = >1BE3 rather than >1DF3. How do you get away with room for only one buffer? ...lee The VDP stack area, (252 bytes) Disk drive info (4 bytes) , ??(6 bytes),Volume information block(256 bytes) and file name compare buffer (11 bytes) normally start at >3DEF and run to >3FFF. These are perfectly happy when left in their original location. Only the 5 byte header and 518 byte buffers have to be moved. I have no idea why this works, but it does, at least on the TI controller. As I remember, this technique did not work so well with the Myarc controller. The locations seemed to be hard coded. But it was still usable for 1 disk file and with some VDP shuffling I could get 2 disk files. Edited December 6, 2019 by senior_falcon 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 6, 2019 Author Share Posted December 6, 2019 If I understand the previous comments, there are 8 bytes inserted at >3FF8 to >3FFF used by the CF7. Then (for CALL FILES(3)) everything that is normally loaded from >37D8 to >3FFF is loaded 8 bytes lower in memory. So at >37D0 are the bytes >AA,>3F,>FF,>11,>03 Is this correct? 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted December 6, 2019 Share Posted December 6, 2019 2 hours ago, senior_falcon said: If I understand the previous comments, there are 8 bytes inserted at >3FF8 to >3FFF used by the CF7. Then (for CALL FILES(3)) everything that is normally loaded from >37D8 to >3FFF is loaded 8 bytes lower in memory. So at >37D0 are the bytes >AA,>3F,>FF,>11,>03 Is this correct? Yes (though the >11 is >10 in Classic99, as that's the CRU base of the disk device that created the buffer). 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 6, 2019 Author Share Posted December 6, 2019 I may have found the reason the CF7 doesn't work with The Missing Link. Upon startup, TML moves the disk buffer(s) and then clears the VDP graphics tables above the disk buffers. I don't remember why I did it this way, but VDP is cleared all the way up to >3FFA. This overwrites the >AA03 header at >3FF8. Tursi didn't see that the header was checked by the DSR, but if it is, then that would explain why the CF7 does not work. I will have a new test program to post in the next day or two. The answer is binary-either it works or it does not. If not then I don't think there is anything else that can be done. 4 Quote Link to comment Share on other sites More sharing options...
Tursi Posted December 7, 2019 Share Posted December 7, 2019 (edited) 3 hours ago, senior_falcon said: I may have found the reason the CF7 doesn't work with The Missing Link. Upon startup, TML moves the disk buffer(s) and then clears the VDP graphics tables above the disk buffers. I don't remember why I did it this way, but VDP is cleared all the way up to >3FFA. This overwrites the >AA03 header at >3FF8. Tursi didn't see that the header was checked by the DSR, but if it is, then that would explain why the CF7 does not work. I will have a new test program to post in the next day or two. The answer is binary-either it works or it does not. If not then I don't think there is anything else that can be done. It'll be interesting if that's it, but I suspect not. When the CF7 DSR needs to access a disk, it needs to FIND that 8 byte header, and it does that (as far as I can tell) starting with >8370, which TML changes. I suppose what we could do is work backwards, set up the system for TML, do a disk access, and see where it reads to find the disk volume. That may give the missing insight. Edited December 7, 2019 by Tursi 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted December 7, 2019 Share Posted December 7, 2019 First, I ran the CF7 normally with a breakpoint on VDP reads from >3FFA, so I could see where the DSR does the lookup for DSK1. I don't follow the code that does the calculation, unfortunately, we'd have to work backwards, but the code that uses the calculation is here: 55DE D220 movb @>834c,R8 834C 55E2 0988 srl R8,8 55E4 0608 dec R8 55E6 0A18 sla R8,1 55E8 A220 a @>8358,R8 8358 55EC 0228 ai R8,>010d 010D > 55F0 06A0 bl @>4628 This puts the base address (>3FFA) into R8. The BL sets the VDP address and reads two bytes for return in R0. So with that in mind, I started up TML and put a breakpoint at >55F0. When I run TML with the CF7 in Classic99, I see all eight bytes at >3ff8 have been zeroed. That would of course be a problem... so in the debugger I manually added them back before the test. I should breakpoint anyway... and the address is >3FFA! and the disk access worked (remember I manually poked the values back in). So, I can take it back.. it likely IS the loss of those top bytes -- but they are all lost, not just the two header bytes. 2 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted December 7, 2019 Share Posted December 7, 2019 14 minutes ago, Tursi said: I suppose what we could do is work backwards, set up the system for TML, do a disk access, and see where it reads to find the disk volume. That may give the missing insight. Your setup/test will most likely confirm once and for all if the volume ID byte location is static or if it is dependent upon 8370. Debugging CALL MOUNT might provide insight, too, as you should be able to tell where that subprogram is writing the new volume IDs. 2 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 7, 2019 Author Share Posted December 7, 2019 One more question just to be sure I have all the information I need. Is the CF7 the only device that moves the top of the stack pointed to by >8370? 1 Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted December 7, 2019 Share Posted December 7, 2019 I searched my work folder and found some info I pulled together a few years ago. I can't be certain it is 100% accurate and if I remember correctly, this research came out of my work with the Horizon RAMdisk ROS. ROS was using VDP to store the last accessed filename and some other misc. info (for boot tracking). However, if there wasn't a floppy controller in the system, the normal disk buffers were not reserved. Thus XB programs were able to use that normally-reserved disk controller buffer space but ROS assumed there was a disk controller in the system, corrupting the XB program in the process. TI, CorComp, and BwG disk controllers reserve VDP RAM during powerup. 0x8370 is set to 0x37D7. (BwG may reserve additional bytes?) Myarc disk controllers set 0x8370 to 0x37D7 for compatibility with the above cards. VDP usage is minimal. For example, disk # boot tracking does not work in the same manner as the TI and CorComp. Myarc Hard/floppy controllers set 0x8370 to 0x37D7 for legacy controller compatibility when used at CRU 0x1100; otherwise, the pointer is left untouched. VDP usage is minimal. SCSI cards do not manipulate 0x8370. IDE cards do not manipulate 0x8370. The AVPC video card reserves 16 bytes from 0x3FF0 to 0x3FFF, based on a review of the OPA 3.0 DSR. The EVPC video card reserves 2 bytes at 0x3FFE-0x3FFF EVPC2 - untested/unknown The NanoPEB/CF7 devices reserve 8 bytes of video RAM from 0x3FF8-0x3FFF to store pointers and information related to the mounted diskettes. 0x8370 is set to 0x37CF. (edit: I found a copy of the same info with a few comments referencing Lee and Atrax helping with the research; I'm guessing there is an AA thread and/or wiki entry containing some of this intel.) 2 1 Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted December 7, 2019 Share Posted December 7, 2019 6 hours ago, InsaneMultitasker said: I found a copy of the same info with a few comments referencing Lee and Atrax helping with the research; I'm guessing there is an AA thread and/or wiki entry containing some of this intel. This topic: Programming challenge (started by Tony Knerr @Gazoo) and a PM you started with me: 37d2 (7/5/2015) ...lee 2 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 8, 2019 Author Share Posted December 8, 2019 Here is a test program to test whether the CF7 can be compatible with TML. Just run it like any XB program and follow the prompts. Don't use my file names; be sure your file names are compatible with the CF7. If all goes well you get the message "CF7 will be functional with The Missing Link" Let me know the results... TESTCF7.zip 1 1 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted December 8, 2019 Share Posted December 8, 2019 Testing this in about an hour. Quote Link to comment Share on other sites More sharing options...
Opry99er Posted December 8, 2019 Share Posted December 8, 2019 Well, not sure if I did this properly, but here are the results I got. On the "Disk buffer not OK" pic, that was after I reset the TI and tried again. Quote Link to comment Share on other sites More sharing options...
Opry99er Posted December 8, 2019 Share Posted December 8, 2019 Sorry... something went screwy. Second try: Quote Link to comment Share on other sites More sharing options...
Tursi Posted December 8, 2019 Share Posted December 8, 2019 (edited) I'm just sticking my nose in here, but.. why are you doing RUN 500 instead of just RUN? (Oh, I see, it's part of the test ) Edited December 8, 2019 by Tursi Quote Link to comment Share on other sites More sharing options...
Opry99er Posted December 8, 2019 Share Posted December 8, 2019 If there's anything else I can do to help, please let me know! I'm starting to get the feel for CF7 work again... it is not an intuitive system, but once you get the hang of it, it's not so bad. 2 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted December 9, 2019 Author Share Posted December 9, 2019 6 hours ago, Tursi said: I'm just sticking my nose in here, but.. why are you doing RUN 500 instead of just RUN? The test first checks that the disk buffer has been moved. It then erases vdp memory in the areas used by TML (v2000 to v3DB6) It tries to open a DV80 file, write a line to it and close it. It then tries to open the file again and read the line. If successful it checks if the reserved vram has been corrupted. It then prompts you to save the program, erase it and load it. If you can run line 500 it shows that the program could be saved and loaded. Line 500 reports that, then checks whether the reserved vram is corrupted. Since it passes these tests it shows that TML and the CF7 should be compatible. Tursi asked "Can you just set >8370 to the address that you want everything to be located under, then call the disk powerup routine followed by the equivalent of CALL FILES(1)?" TML uses this code to do CALL FILES(n) MOVB @NFILES+1,@>834C 834C gets the # of files in MSB LI R0,>03E8 Unused area of VDP RAM LI R1,HMWS+6 R3-R5 used LI R2,5 5 bytes to write (only need 2 here next) LI R3,>0116 opcode for Allocate Disk Buffer Space BLWP @VMBW Write PAB MOV R0,@>8356 >8356 gets address of PAB BLWP @DSRLNK DATA >000A a subprogram This doesn't seem to need a value in >8370. If >37d7 is there, then this routine with number of files=3 puts >37D7 into >8370. Maybe there is a lower level program that expects a value in >8370? Thanks to all who helped troubleshoot this problem, Tursi and Opry99 in particular. I should be posting a revised version of TML that is CF7 compatible in the next few days. Even better, this information will make it possible to have a very nice Christmas present for those of you who are XB programmers... 4 Quote Link to comment Share on other sites More sharing options...
Opry99er Posted December 9, 2019 Share Posted December 9, 2019 Exciting! Quote Link to comment Share on other sites More sharing options...
+Lee Stewart Posted December 9, 2019 Share Posted December 9, 2019 (edited) 10 hours ago, senior_falcon said: This doesn't seem to need a value in >8370. If >37d7 is there, then this routine with number of files=3 puts >37D7 into >8370. Maybe there is a lower level program that expects a value in >8370? There is, indeed, a lower level program that expects a value in >8370. It is the “subprogram” (>16) in the DSR that you call with DSRLNK. This routine starts at A5DAE in the DSR code disassembled by Thierry Nouspikel from the TI disk controller’s ROM (see spoiler below): Spoiler *==================================== * * TI DISK CONTROLLER ROM >4000-5FFF * *==================================== * AORG >4000 * A4000 BYTE >AA standard header mark BYTE >02 version 2 DATA >0000 no programs DATA A4044 power-up chain ptr DATA >0000 programs chain ptr (none) DATA A404A DSR chain ptr DATA A4010 subprograms chain ptr DATA >0000 ISR chain ptr (none) DATA >0000 A4010 DATA A4016 link to next subprogram DATA A5B38 address of that one DATA >0110 subprogram name: >10 (sector R/W) A4016 DATA A401C DATA A5B48 DATA >0111 subprogram >11 (format disk) A401C DATA A4022 DATA A5B52 DATA >0112 subprogram >12 (file un/protect) A4022 DATA A4028 DATA A5BAC DATA >0113 subprogram >13 (file rename) A4028 DATA A402E DATA A5C78 DATA >0114 subprogram >14 (file direct input) A402E DATA A4034 DATA A5CE8 DATA >0115 subprogram >15 (file direct output) A4034 DATA A403A DATA A5DAE DATA >0116 subprogram >16 (number of files) A403A DATA >0000 no more DATA A5D5A BYTE >05 TEXT 'FILES' same as >16, called from Basic A4044 DATA >0000 power-up chain (no more) DATA A4070 address of power-up routine DATA >0000 no name A404A DATA A4052 DSR chain DATA A504E address of DSR BYTE >03 name size TEXT 'DSK' DSR name A4052 DATA A405C DATA A505C BYTE >04 TEXT 'DSK1' EVEN A405C DATA A4066 DATA A5062 BYTE >04 TEXT 'DSK2' EVEN A4066 DATA >0000 no more DATA A5068 BYTE >04 TEXT 'DSK3' EVEN *===================================== * Power-up routine *===================================== A4070 MOV 11,7 save return address STWP 9 get workspace (should be >83E0) AI 9,>FF20 point to top of scratch-pad mem (>8300) MOV @>0070(9),0 highest free address in vdp mem (>8370) MOV 0,2 save it AI 0,>F7D8 we'll need >828 bytes MOV 0,@>0070(9) update address INC 0 BL @A40DA set VDP address LI 1,>0828 A4090 CLR @>FFFE(15) clear these >828 bytes DEC 1 JNE A4090 BL @A40DA set VDP address (same) LI 3,>AA03 MOVB 3,@>FFFE(15) write buffer ID mark NOP MOVB 2,@>FFFE(15) write old highest free address SWPB 2 MOVB 2,@>FFFE(15) NOP MOVB 12,@>FFFE(15) write CRU base of disk controller (1 byte) SWPB 3 MOVB 3,@>FFFE(15) write number of files (3) BL @A4726 preparation routine BL @A4658 call subroutine DATA A4554 reset all drives CLR @>0054(9) name length = 0 for power-up BLWP @>005A(9) retrieve R7 (saved by A4726) DATA >0011 put it into R11 MOV @A40D8,@>006C(9) ??? B *11 return A40D8 DATA >0404 * A40DA ORI 0,>4000 set VDP for a write SWPB 0 ------------------- MOVB 0,*15 pass address SWPB 0 MOVB 0,*15 B *11 *--------------------------------------- * Sector read/write *--------------------------------------- A40E8 LI 4,>000A try ten times A40EC MOVB @A4630,@>0050(9) no error BL @A4496 select drive BL @A45F0 point to # of last track CLR 0 MOVB @>FBFE(15),0 get # of last track accessed CI 0,>D700 JH A410C too high: drive was reset BL @A4524 seek track 0 SETO 0 inverted data bus" >FF will be >00 A410C MOVB 0,@>5FFA place >00 in track register MOV @>004A(9),1 sector # SBZ 7 side 0 CLR 7 CI 1,>02D0 max 720 (DS/SD) JHE A41B6 error 7 CI 1,>0168 on which side is it? JL A413E 0-359: on side 0 AI 1,-719 on side 1: sector # grow from in to out ABS 1 719 - sector # CLR 0 DIV @A4632,0 sect/track (=9) AI 1,-8 invert: 8=0, 0=8, 7=1, etc ABS 1 SBO 7 side 1 LI 7,>0100 side number = >01 JMP A414E A413E CI 1,>0001 is it sector 0 or 1? JH A4148 no BL @A4524 yes: seek track 0 A4148 CLR 0 DIV @A4632,0 R0=track #, R1=sector # A414E SWPB 0 INV 0 BL @A4614 set VDP to write MOVB 0,@>FFFE(15) save # of last track accessed MOVB 0,@>5FFE pass to data register SWPB 1 INV 1 MOVB 1,@>5FFC pass new sector # to sector register CB 0,@>5FF2 new track # same as current? JEQ A417A yes BL @A45CA send command DATA >E100 "seek" h=1 V=1 r1r0=10 BL @A4482 wait for command completion SLA 0,13 test "seek error" bit JOC A41B0 try again, then error 11 A417A BL @A45CA send command DATA >3F00 "read ID" E=0 SBO 2 enable hold MOVB @>5FF6,0 skip track # LI 6,>0004 MOVB @>5FF6,5 side # INV 5 A4190 MOVB @>5FF6,0 skip next 4 bytes DEC 6 JNE A4190 BL @A4480 SBZ 2, wait for command completion SLA 0,13 test status bits JOC A41BC "not found": try again, then error 21 JLT A41C2 "crc error": try again, then error 22 SLA 0,2 JOC A41C8 "lost data": try again, then error 23 CB 7,5 side # matches? JEQ A41CE yes: sector found, now access it A41AA BL @A45AC no: error 6 DATA >0600 A41B0 BL @A4590 gracefull error 11 DATA >1100 A41B6 BL @A45AC error 7 DATA >0700 A41BC BL @A4590 gracefull error 21 DATA >2100 A41C2 BL @A4590 gracefull error 22 DATA >2200 A41C8 BL @A4590 gracefull error 23 DATA >2300 A41CE MOVB 1,@>5FFC load sector register MOV @>004E(9),2 data buffer address MOVB @>004D(9),0 read or write ? JEQ A425C write BL @A4614 read: set VDP to write A41E0 BL @A45CA ---- send command DATA >7700 "read sector" m=0 S=1 E=0 C=0 LI 6,>0100 256 bytes / sector SETO 5 SBO 2 MOVB @>004D(9),0 read or write? JNE A4214 read CLR 0 write: now we must verify A41F6 MOVB @>5FF6,0 get a byte from FDC ------ AB @>FBFE(15),0 compare with byte in data buffer CI 0,>FF00 JNE A422E mismatch SZCB @>5FF6,0 again SB @>FBFE(15),0 JNE A422E mismatch DECT 6 JNE A41F6 next byte JMP A422C done A4214 MOVB @>5FF6,0 get 1 byte from FDC INV 0 MOVB 0,@>FFFE(15) save it to VDP MOVB @>5FF6,0 again INV 0 MOVB 0,@>FFFE(15) DECT 6 JNE A4214 next byte A422C CLR 5 clear flag A422E BL @A4480 SBZ 2, wait for command completion SLA 0,13 test status bits JOC A4244 "not found": try again, then error 21 JLT A424A "crc error": try again, then error 22 MOV 5,5 JNE A4256 try again, then error 28 SLA 0,2 JOC A4250 "lost data": try again, then error 23 B @A4676 return A4244 BL @A4590 gracefull error 21 DATA >2100 A424A BL @A4590 gracefull error 22 DATA >2200 A4250 BL @A4590 gracefull error 23 DATA >2300 A4256 BL @A4590 gracefull error 28 DATA >2800 A425C BL @A461E write: set VDP to read BL @A45CA ----- send command DATA >5700 "write sector" m=0 S=1 E=0 C=0 a=0 LI 6,>0100 256 bytes / sector SBO 2 enable holds A426C MOVB @>FBFE(15),0 get a byte from data buffer INV 0 MOVB 0,@>5FFE pass it to data register MOVB @>FBFE(15),0 again INV 0 MOVB 0,@>5FFE DECT 6 JNE A426C next BL @A4480 SBZ 2, wait for command completion SLA 0,11 test status bits JOC A429A "write protect": error 34 SLA 0,2 JOC A42A0 "not found": try again, then error 31 SLA 0,2 JOC A42A6 "lost data": try again, then error 33 BL @A461E now, set VDP to read JMP A41E0 and verify sector A429A BL @A45AC error 34 DATA >3400 A42A0 BL @A4590 gracefull error 31 DATA >3100 A42A6 BL @A4590 gracefull error 33 DATA >3300 *--------------------------------------- * Format disk *--------------------------------------- A42AC CLR @>004A(9) called by subprogram >11 MOVB @>004C(9),8 DSR version + drive # SRL 8,12 keep version only JEQ A42C4 0: standard format C 8,@A4630 JEQ A42C4 1: needs DSR version 2 (this one) BL @A45AC 2: needs another version DATA >0700 returns with error 7 A42C4 SZCB @A4638,@>004C(9) clear DSR version flags CB @>0051(9),@A4657 double sided? JNE A42D6 no SETO @>004A(9) yes: set flag A42D6 MOVB @A4630,@>0050(9) no error BL @A4496 select drive BL @A4524 seek track 0 CLR 3 init track counter A42E6 MOV @>004A(9),@>004A(9) check # of sides flag JEQ A42F8 single-side SBO 7 set CRU bit for side 1 LI 7,>0100 value for side 1 in sector ID BL @A43AA format one track A42F8 SBZ 7 set CRU bit for side 0 CLR 7 >00 = value for side 0 in sector ID BL @A43AA format one track BL @A45CA send command DATA >A500 "step-in" (T=1, h=1, V=0, r0r1=10) BL @A4482 wait for command completion AI 3,>0100 one more track CB 3,@>004D(9) all done? JNE A42E6 no: format next one MOV @>004A(9),@>004A(9) check # of sides JEQ A437A single-side SBO 7 LI 4,>000A try 10 times A4322 BL @A4524 seek track 0 MOV @>004E(9),2 data buffer address BL @A4614 set VDP to write BL @A45CA send command DATA >3F00 "read ID" (E=0) LI 6,>0006 read 6 bytes SBO 2 enable wait states A433A MOVB @>5FF6,0 read data register INV 0 FDC has inverted data bus MOVB 0,@>FFFE(15) write it to data buffer MOVB @>5FF6,0 again, why write this twice ? INV 0 MOVB 0,@>FFFE(15) DECT 6 JNE A433A BL @A4480 SBZ 2 then wait for command completion SLA 0,13 check status bits JOC A4398 "not found" JLT A439E "CRC error" SLA 0,2 JOC A43A4 "lost data" MOV @>004E(9),2 address of data buffer INC 2 skip track # BL @A461E set VDP to read from it CLR 0 MOVB @>FBFE(15),0 read one byte JEQ A437A side 0 MOVB @>004D(9),0 side 1: get tracks/side SLA 0,1 times two (since 2 sides) JMP A4384 A437A MOVB @A4631,@>0051(9) error code 1 MOVB @>004D(9),0 get # of tracks A4384 SRL 0,8 make it a word MPY @A4632,0 times # of sectors per track MOV 1,@>004A(9) pass total # of sectors per disk MOVB @A4633,@>004D(9) pass # of sectors per track B @A4676 return * A4398 BL @A4590 try again, or error >21 DATA >2101 A439E BL @A4590 try again, or error >22 DATA >2201 A43A4 BL @A4590 try again, or error >23 DATA >2301 * A43AA MOV 11,8 format a track MOV @>004E(9),2 -------------- BL @A4614 set VDP to write to data buffer LI 6,>0016 write 24 sync bytes >00 CLR 2 sector counter JMP A43C0 A43BC LI 6,>0006 write 6 sync bytes >00 A43C0 MOVB @A4630,@>FFFE(15) DEC 6 JNE A43C0 MOVB @A4639,@>FFFE(15) write >FE (will be ID mark) NOP MOVB 3,@>FFFE(15) write track # NOP MOVB 7,@>FFFE(15) write side # MOVB 3,0 track number SRL 0,8 make it a word SWPB 7 MPY @A4635(7),0 times >00 for side 1, >06 for side 0 SWPB 7 A 2,1 add # of sectors prepared DIV @A4632,0 divide by sectors/track MOVB @A464F(1),@>FFFE(15) sector #, according to interlacing pattern LI 6,>FFEC write 20 times A43F8 MOVB @A464E(6),@>FFFE(15) code for a CRC INC 6 JNE A43F8 one more LI 0,>E5E5 data to put in empty sectors BL @A4474 write it 256 times DATA >0100 MOVB @A464E,@>FFFE(15) write code to CRC SETO 0 >FF filler bytes BL @A4474 write it 45 times DATA >002D INC 2 # of sectors prepared CI 2,>0009 JNE A43BC one more BL @A4474 write 231 more >FF at end of track DATA >00E7 LI 4,>0003 try 3 times A442C MOVB @>004E(9),2 top of data buffer BL @A461E set VDP to read from it BL @A45CA send command DATA >0B00 "write track" (E=1) LI 6,>0CA3 SBO 2 enable wait states A4440 MOVB @>FBFE(15),0 read one byte from buffer INV 0 FDC has an inverted data bus MOVB 0,@>5FFE send it to data register MOVB @>FBFE(15),0 why on earth is it done like that??? INV 0 MOVB 0,@>5FFE send next byte DECT 6 JGT A4440 next pair of bytes BL @A4480 SBZ 2, then wait for command completion SLA 0,11 check "write protect" bit JNC A4464 B @A429A error code >34 ?? A4464 SLA 0,4 test "lost data" bit JNC A4472 ok: return DEC 4 shall we try again? JNE A442C yes BL @A45AC no: error code >33 DATA >3300 A4472 B *8 return A4474 MOV *11+,6 VDP repeated write A4476 MOVB 0,@>FFFE(15) ------------------ DEC 6 byte in R0 JNE A4476 number of repeats in data word B *11 * A4480 SBZ 2 wait for command completion A4482 MOVB @>5FF0,0 --------------------------- get status INV 0 FDC has an inverted data bus JLT A4490 drive not ready SRC 0,9 JOC A4482 FDC busy: keep waiting B *11 A4490 BL @A45AC exit with error code 6, reseting all drives DATA >0600 * A4496 MOV 11,7 select a drive MOV @>0058(9),2 -------------- AI 2,>FFF6 point to drive info BL @A461E set VDP to read MOVB @>FBFE(15),0 get # of last drive accessed CLR 5 clear flag CB 0,@>004C(9) same as the one to be formated? JEQ A44B2 yes SETO 5 no: set flag A44B2 CLR 0 MOVB @>004C(9),0 get drive # JEQ A451E can't be >00: error #7 BL @A4614 set VDP to write, address in R2 MOVB 0,@>FFFE(15) modify last drive accessed SWPB 0 CI 0,>0003 JH A451E drive number can't be higher than 3: error #7 LI 2,>0080 SLA 2,0 proper drive selection bit: >01 >02 or >04 AI 12,>0008 CRU address of drive selection bits (4-6) MOV 5,5 test "same drive" flag JEQ A4506 LDCR @A4505,3 deselect all drives AI 12,>FFFA selection bits are echoed in CRU bits 1-3 STCR 0,3 load CRU bits 2-4 AI 12,>0006 back to bits 4-6 CZC 2,0 echoed properly? JEQ A4506 yes: go on CLR 0 MOV @>0058(9),2 point to drive info AI 2,>FFF6 BL @A4614 set VDP to write to address in R2 MOVB 0,@>FFFE(15) clear "last drive accessed" AI 12,>FFF8 back to CRU base BL @A45AC exit with "device error" BYTE >06 A4505 BYTE >00 A4506 LDCR 2,3 select drive AI 12,>FFF8 back to cru base MOV 5,5 test "same drive" flag JEQ A451C same: return LI 0,>0BB8 different: wait while drive gets ready A4514 SRC 5,4 SRC 5,4 DEC 0 JNE A4514 keep waiting A451C B *7 A451E BL @A45AC exit with error #7 DATA >0700 * A4524 MOV 11,8 seek track 0 BL @A45CA ------------ DATA >F500 send "restore" command (h=1, V=0, r0r1=10) BL @A4482 wait for command completion BL @A4544 test if track 0 reached, error it not BL @A45F0 set VDP to read "last track #" BL @A4614 set VDP to write at same address MOVB @A4640,@>FFFE(15) set "last track #" as >FF for this drive B *8 * A4544 MOVB @>5FF0,0 check if track 0 reached INV 0 ------------------------ SLA 0,6 test the "track 0" bit JOC A4552 B @A4490 exit with error code 6, reseting all drives A4552 B *11 * A4554 AI 12,>0008 reset all drives LDCR @A4630,4 ---------------- no drive selected AI 12,>FFF8 SBZ 1 motor strobe SBO 1 MOVB @A45BC,@>5FF8 send "Force interrupt" with no interrupt flag set MOV @>0058(9),2 ptr to VIB buffer AI 2,>FFF6 now points to drive info buffer BL @A4614 set VDP to write to address in R2 LI 0,>0004 A457A MOVB 0,@>FFFE(15) write four >00 (i.e. clear drive info) DEC 0 JNE A457A BL @A4480 test status, reset drives if not ready MOVB @A4630,@>0050(9) no error B @A4676 get return address from stack A4590 DEC 4 gracefull error JEQ A45AC --------------- no more tries: error MOV *11,11 try again: get data word SRC 11,1 test return flag JNC A459E B @A4322 back to "read ID" in format routine A459E CI 4,>0005 JH A45A8 BL @A4524 last 5 tries: seek track 0 A45A8 B @A40EC back to sector r/w routine * A45AC MOV *11,0 exit with error MOVB 0,@>0050(9) --------------- place err code in >8350 CI 0,>0600 check if "device error" JNE A45C6 no: exit BL @A45CA yes: reset drives A45BC DATA >2F00 send force interrupt, no ints A45BE MOVB @>5FF0,0 get status SRC 0,9 test "busy" flag JNC A45BE wait until done A45C6 B @A4676 return to caller (address from stack) * A45CA MOV *11+,0 send command to FDC from data word MOVB @>5FF0,6 ------------- get status SLA 6,1 test "ready" bit SBZ 1 strobe motor SBO 1 JOC A45E4 ready (inverted) LI 6,>7530 wait a long time A45DC SRC 5,4 SRC 5,4 DEC 6 JNE A45DC A45E4 MOVB 0,@>5FF8 send command SBO 3 signal head loaded (HLT pin) SRC 5,8 kill time SRC 5,8 B *11 A45F0 CLR 0 get last track # for this drive MOVB @>004C(9),0 ---------------- get drive # JEQ A460E can't be 0 SWPB 0 CI 0,>0003 JH A460E can't be higher than 3 MOV @>0058(9),2 AI 2,>FFF6 point to "last drive accessed" A 0,2 point to "last track" for this drive B @A461E prepare VDP to read from address in R2 A460E BL @A45AC exit with error code 7 DATA >0700 * A4614 ORI 2,>4000 set VDP address to write ANDI 2,>7FFF ------------------------ not to a register JMP A4622 A461E ANDI 2,>3FFF set VDP address to read A4622 SWPB 2 ----------------------- MOVB 2,*15 write address SWPB 2 MOVB 2,*15 ANDI 2,>3FFF B *11 * A4630 BYTE >00 A4631 BYTE >01 A4632 BYTE >00 sectors per track A4633 BYTE >09 " BYTE >00 A4635 BYTE >06 DATA >0003 A4638 BYTE >F0 A4639 BYTE >FE DATA >01F7 DATA >FFFF DATA >FFFF A4640 DATA >FFFF DATA >FFFF DATA >FFFF DATA >FF00 DATA >0000 DATA >0000 DATA >00FB A464E BYTE >F7 code for CRC A464F BYTE 0,7,5,3,1,8,6,4 sector interlace pattern A4657 BYTE 2 * A4658 DECT @>0066(9) call subroutine, return address in stack MOV @>0066(9),10 --------------- BLWP @>005A(9) set VDP to write to address in R10 DATA >0143 MOV *11+,10 get next data word SWPB 11 write return address to VDP MOVB 11,@>FFFE(15) SWPB 11 MOVB 11,@>FFFE(15) B *10 branch to address in data word * A4676 MOV @>0066(9),11 get return address from VDP stack BLWP @>005A(9) --------------------------------- DATA >0162 set VDP to read from address in R11 MOVB @>FBFE(15),11 SWPB 11 MOVB @>FBFE(15),11 INCT @>0066(9) B *11 *--------------------------------------- * Custom routines, dealing with VDP memory * Format is >pppr where r is routine number (0-3) * and ppp contains parameters * The workspace it >8300. Called by BLWP @>005A(9). *--------------------------------------- A4690 MOV 13,10 save wregs ptr MOV *14+,8 get next data word MOV 8,9 save it SRL 9,4 keep parameter ANDI 8,>0003 four possible operations A 8,8 make it a word ptr MOV @>001E(13),11 get old R15, i.e. VDP port (>8C02) MOV @A46A8(8),8 get vector for operation B *8 branch to it A46A8 DATA A46B0 save registers to VDP stack DATA A46DC retrieve registers DATA A4712 set VDP address to read DATA A4708 set VDP address to write * A46B0 AI 10,>0016 0: save registers in VDP mem A46B4 SRL 9,1 -------------- start with R12 JNC A46D8 bits in >ppp tell which register to save (R0-R11) DECT 12 previous address in VDP stack (grows down) MOV *10,8 get register contents SWPB 12 set VDP address to write MOVB 12,*11 R12 is >8366: VDP stack ptr SWPB 12 ORI 12,>4000 MOVB 12,*11 SWPB 8 save register to VDP mem MOVB 8,@>FFFE(11) SWPB 8 MOVB 8,@>FFFE(11) MOV 9,9 more to come? JEQ A4706 no:return A46D8 DECT 10 point to previous register JMP A46B4 * A46DC SLA 9,4 1: retrieve registers from VDP mem A46DE SLA 9,1 ------------------ each bit tells whether to load JNC A4702 don't retrieve that one SWPB 12 set VDP address to read MOVB 12,*11 R12 is >8366: VDP stack ptr SWPB 12 ANDI 12,>3FFF MOVB 12,*11 NOP MOVB @>FBFE(11),8 get a 2-byte value from VDP SWPB 8 MOVB @>FBFE(11),8 MOV 8,*10 save it to register INCT 12 increment ptr (stack grows downwards) MOV 9,9 more to come? JEQ A4706 no: return A4702 INCT 10 next register JMP A46DE A4706 RTWP * A4708 A 13,9 2: set VDP for a write MOV *9,8 ------------------- ORI 8,>4000 get address from reg in >..p2 (*2) JMP A471A A4712 A 13,9 3: set VDP for a read MOV *9,8 ------------------ ANDI 8,>3FFF get register from reg in >..p3 (*2) A471A SWPB 8 set VDP address MOVB 8,*11 SWPB 8 MOVB 8,*11 RTWP *--------------------------------------- * Preparation subroutine * Sets up the 4 custom subroutines * Gets a few pointers to VDP buffers * >8358: copy of VIB >8366: VDP stack ptr (grows down from drive info) * >8354: PAB >8356: ptr to end-of-buffer *--------------------------------------- A4724 INCT 7 stop scanning upon return A4726 MOV 11,10 save return address STWP 9 get workspace (should be >83E0) AI 9,>FF20 top of scratch/pad mem (>8300) LI 0,A4690 entry to 4 custom routines MOV 0,@>005C(9) put it in >835C MOV 9,0 AI 0,>004E workspace for these four (>834E) MOV 0,@>005A(9) put it in >835A MOV @>0070(9),8 highest free address in VDP mem A4744 INCT 8 point to "end-of-buffer" word BL @A4B76 read 2 bytes from VDP address R8, into R0 MOV 8,2 save current R8 MOV 0,8 get end-of-buffer word MOVB @>FBFE(15),1 get CRU of controller that reserved this mem CB 12,1 same as ours? JNE A4744 no: use end-of-buffer to link to next buffer AI 8,>FEF6 yes: point to volume information block MOV 8,@>0058(9) save it in >8358 AI 8,>FFF6 point to disk drive info (drive #, last tracks) MOV 8,@>0066(9) save in >8366: VDP stack ptr (DECT before writing) BLWP @>005A(9) save R7 (return address) DATA >0100 MOV @>0056(9),7 ptr to PAB: end of DSR name MOV 7,3 save it S @>0054(9),7 beg of DSR name MOV 2,@>0056(9) >8356: ptr to "end-of-buffer" word in VDP mem DEC 7 point to name length byte CLR 2 BLWP @>005A(9) set VDP to read from address in R2 DATA >00E2 MOVB @>FBFE(15),2 get name length byte SWPB 2 make it a word S @>0054(9),2 minus DSR name size: lenght of .parameters AI 7,>FFF7 point to top of PAB MOV 7,@>0054(9) save it in >8354 B *10 * * A4798 BL @A4658 create file DATA A4E02 ----------- find a FDR in disk A479E MOV 4,4 found? JNE A47AA no BL @A4658 yes: delete old file DATA A48DE free file sector in VIB bitmap JMP A4834 clear its FDR A47AA BL @A4B0A new file: insert a FDR in sector 1 SETO 1 BL @A4658 call subroutine DATA A4EF6 find a free sector in VIB bitmap MOV 0,0 found? JNE A47C0 yes: # in R0 BL @A4C72 no: update data, then return with error DATA >8000 "memory full" A47C0 BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 0,@>FFFE(15) write sector # for FDR in sector 1 SWPB 0 MOVB 0,@>FFFE(15) SWPB 0 MOV @>0056(9),1 ptr to FDR in VDP buffers AI 1,>FFFC ptr to sector # for FDR BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) write sector # for FDR in VDP buffer SWPB 0 MOVB 0,@>FFFE(15) AI 1,>0003 ptr to drive # BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 6,@>FFFE(15) write drive # before FDR in VDP buffer CLR 2 code for write INC 1 BL @A4658 call subroutine DATA A4D36 write sector 1 MOV @>0058(9),5 ptr to VIB in VDP buffers CLR 4 sector 0 BL @A4658 call subroutine DATA A4D4E write VIB to sector 0 MOV 5,3 copy filename from compare buffer to FDR AI 3,>0101 ptr to file compare buffer LI 2,>000A 10 chars per filename A4818 BLWP @>005A(9) set VDP to read DATA >0062 address in R3 MOVB @>FBFE(15),0 get 1 char INC 3 increment source ptr BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) copy 1 char INC 1 increment destination ptr DEC 2 # of chars in R2 JNE A4818 next A4834 MOV @>0056(9),1 FDR ptr AI 1,>000A skip filename LI 2,>00F6 remaining bytes in FDR BLWP @>005A(9) set VDP to write DATA >0023 address in R1 A4846 MOVB 2,@>FFFE(15) write >00 DEC 2 clear remainder of new FDR JNE A4846 next byte JMP A4870 write FDR to disk return to caller * A4850 MOV @>0056(9),5 check if FDR must be updated BLWP @>005A(9) ---------------------------- set VDP to read DATA >00A2 address in R5 MOVB @>FBFE(15),4 get filename in file ctrl block JLT A4862 flag: FDR was modified, update it JMP A4876 A4862 ANDI 4,>7F00 clear flag bit BLWP @>005A(9) st VDP to write DATA >00A3 address in R5 MOVB 4,@>FFFE(15) write back filename without flag bit A4870 CLR 2 code for write B @A4D40 write FDR to disk A4876 B @A4676 return to caller * A487A BL @A4658 update FDR + data DATA A489A ----------------- update data buffer if necessary BL @A4658 call subroutine DATA A4850 update FDR if necessary A4886 MOV @>0056(9),5 CLR 6 BLWP @>005A(9) set VDP to write DATA >00A3 address in R5 MOVB 6,@>FFFE(15) clr first byte of filename in FDR B @A4CD2 * A489A MOV @>0056(9),4 check if data buffer must be updated DEC 4 ------------------------------------ BLWP @>005A(9) set VDP to read DATA >0082 address in R4 MOVB @>FBFE(15),1 get drive # JLT A48AE flag: must be updated JMP A48DA no need to update: return A48AE ANDI 1,>7F00 erase flag BLWP @>005A(9) set VDP to write DATA >0083 address in R4 MOVB 1,@>FFFE(15) write back drive # without flag AI 4,>FFFB point to current logical record offset BLWP @>005A(9) set VDP to read DATA >0082 address in R4 MOVB @>FBFE(15),3 get current logical record offset SWPB 3 MOVB @>FBFE(15),3 SWPB 3 MOV 4,7 AI 7,>0106 point to data buffer area JMP A494E A48DA B @A4676 return to caller * A48DE MOV @>0056(9),2 free file sectors in VIB bitmap AI 2,>000C ------------------------------- BLWP @>005A(9) set VDP to read DATA >0042 address in R2 MOVB @>FBFE(15),0 get file status byte from FDR ANDI 0,>0800 write protected? JEQ A48FC no BL @A4C72 update data if needed, the return with error DATA >2000 "write protected" A48FC MOV @>0056(9),8 get ptr to FDR AI 8,>001C point to clusters list SETO 4 previous offset A4906 BL @A4EB6 decode cluster info: sector in R1, offset in R2 AI 8,>0003 next cluster ptr MOV 1,1 JEQ A492A sector 0 = no more clusters MOV 2,0 total offset S 4,2 minus previous cluster offset = cluster size MOV 0,4 new "previous cluster offset" BL @A4658 call subroutine DATA A4FC2 free sectors in bitmap (from R1, # in R2) MOV 8,1 S @>0056(9),1 CI 1,>0100 end of FDR reached? JNE A4906 not yet A492A B @A4676 return to caller * A492E BL @A4B70 read a sector from offset in file DATA >000E --------------------------------- get # of sectors C 0,3 is desired sector in file? JH A493E yes BL @A4C72 no: update data, then return with error DATA >A000 "past end-of-file" A493E BL @A4658 call subroutine DATA A4A4E find sector from cluster list A 1,4 put sector in R4 SETO 2 code for read A4948 MOV 7,5 buffer ptr B @A4D4E read/write sector * A494E BLWP @>005A(9) write sector to offset in file offset in R3 DATA >8100 ------------------------------ save R0 and R7 BL @A4658 call subroutine DATA A4964 append enough sectors to reach that offset BLWP @>005A(9) retrieve R0 and R7 DATA >8101 CLR 2 code for write JMP A4948 write sector * A4964 BL @A4B70 append sector(s) to a file to get offset in R3 DATA >000E -------------------------- get # of sect from FDR A496A C 0,3 is desired sector in file? JH A49FC yes: find it and return MOV 0,0 JEQ A4974 empty file DEC 0 last sector # A4974 MOV 3,5 save desired sector offset MOV 0,3 last sector in file BL @A4658 call subroutine DATA A4A4E find sector # from offset in file BLWP @>005A(9) save R1 (sector #) DATA >4000 A 4,1 # of last sector in cluster MOV 5,4 offset of desired sector A4988 BL @A4658 call subroutine DATA A4EF6 find free sector in bitmap, starting from R1 MOV 0,0 found? JNE A499A yes: # in R0 MOV 2,5 no: save # of sectors BL @A4A08 update FDR JMP A49D0 return with "memory full" A499A MOV 1,1 JEQ A49DE empty cluster INC 1 one more sector in cluster C 0,1 same as the one found in bitmap? JEQ A49DC yes: just increase cluster size BLWP @>005A(9) no: retrieve R1 (sector #) DATA >4001 BLWP @>005A(9) save R0 + R2 DATA >A000 BL @A4ED2 update current cluster info BLWP @>005A(9) retrieve R0 + R2 DATA >A001 AI 8,>0003 ptr to next cluster info MOV 8,1 S @>0056(9),1 current FDR size CI 1,>0100 room enough? JNE A49D4 yes BL @A4658 no: call subroutine DATA A4FBC free sector in bitmap A49D0 B @A4E28 return with "memory full" A49D4 MOV 0,1 new sector # BLWP @>005A(9) save R1 DATA >4000 A49DC JMP A49EC make a new cluster A49DE BLWP @>005A(9) retrieve R1 DATA >4001 BLWP @>005A(9) save R0 DATA >8000 SETO 2 empty file: start from offset 0 A49EC MOV 0,1 sector # INC 2 increment cluster size C 2,4 enough? JNE A4988 no: get one more sector MOV 4,5 BL @A4A08 add sector to FDR JMP A4A04 done A49FC BL @A4658 call subroutine DATA A4A4E find a sector from offset in file A 1,4 last sector in cluster A4A04 B @A4676 return to caller * A4A08 MOV 11,10 add sector to FDR MOV 1,4 ----------------- BLWP @>005A(9) retrieve R1 DATA >4001 MOV 1,1 sector # JEQ A4A4C none: return BL @A4ED2 write info for 1 cluster MOV @>0056(9),2 pointer to FDR BLWP @>005A(9) set VDP to read DATA >0042 address in R2 MOVB @>FBFE(15),1 first char of filename ORI 1,>8000 flag BLWP @>005A(9) set VDP to write DATA >0043 address in R2 MOVB 1,@>FFFE(15) AI 2,>000E ptr to # of sectors INC 5 new # of sectors BLWP @>005A(9) set VDP to write DATA >0043 address in R2 MOVB 5,@>FFFE(15) update # of sectors SWPB 5 MOVB 5,@>FFFE(15) A4A4C B *10 * A4A4E MOV @>0056(9),8 find sector from offset in file AI 8,>001C ------------------------------- cluster list MOV 3,4 desired sector offset is in R3 A4A58 BL @A4EB6 decode info: sector in R1, offset in R2 C 2,3 reached yet? JLT A4A62 no JMP A4A6E yes: return A4A62 AI 8,>0003 point to next cluster info MOV 3,4 S 2,4 DEC 4 size of the desired cluster (if it's the next) JMP A4A58 keep trying A4A6E B @A4676 return to caller * *--------------------------------- * Opcode 7: Delete * ---------------- * PAB 0: >07 * 1: <--- error code * 2-3: * 4: * 5: * 6-7: * 8: *--------------------------------- A4A72 BL @A4658 delete file DATA A4DA4 ----------- find file FDR in VDP buffers MOV 4,4 found? JEQ A4A8A yes BL @A4658 no: call subroutine DATA A4E0C find FDR on disk MOV 4,4 found? JEQ A4AAC yes B @A4676 no: return to caller A4A8A INC 1 FDR found, point to it MOV 1,@>0056(9) save it for other routines BL @A4658 call subroutine DATA A4D34 read sector 1 BL @A4B70 read 2 bytes from VDP at >8356+offset DATA >FFFC i.e. get sector # of FRD in R0 MOV 0,3 save it for later MOV 5,8 ptr to top of sector 1 A4AA0 BL @A4B76 read 2 bytes from VDP at R8 into R0 INCT 8 next FDR ptr in sector 1 C 0,3 is this the one we want? JNE A4AA0 not yet DECT 8 yes: point back to it A4AAC BLWP @>005A(9) save R8 DATA >0080 BL @A4658 call subroutine DATA A48DE free file sectors in VIB bitmap BLWP @>005A(9) retrieve R8 DATA >0081 BL @A4ADA remove FDR ptr from sector 1 CLR 2 code for write BL @A4658 call subroutine DATA A4D36 write sector 1 BL @A4B70 get 2 bytes from VDP at >8356+offset in R0 DATA >FFFC i.e. sector # of FDR BL @A4658 call subroutine DATA A4FBC free sector in R0 in VIB bitmap B @A4886 clear 1rst byte of filename in VDP * * Sector 1 contains an alphabetically sorted list of FDR pointers * Each pointer is 2 bytes long and contains the sector # of this FDR * The list must end with a >0000 mark. Thus there can be 127 files at most * A4ADA MOV @>0056(9),5 remove FDR ptr from sector 1 AI 5,>0100 ---------------------------- MOV 5,3 pointer to data buffer AI 3,>0100 point to next ctrl block MOV 8,2 shift up FDR list, erasing FDR pointed by R8 INCT 2 point to next FDR ptr in sector 1 A4AEC BLWP @>005A(9) set VDP to read DATA >0042 address in R2 MOVB @>FBFE(15),0 get 1 byte INC 2 inc source ptr BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 0,@>FFFE(15) copy 1 byte INC 8 inc dest pointer C 2,3 done? JNE A4AEC not yet B *11 * A4B0A MOV 11,10 insert a FDR in sector 1 MOV 8,1 ------------------------ BL @A4B70 get 2 bytes from VDP at >8356+offset DATA >01FC i.e. last FDR slot in sector 1 (list ends with 0) MOV 0,0 JEQ A4B1C B @A4E28 "memory full" error A4B1C DEC 8 previous byte BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),0 get 1 byte INCT 8 BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 0,@>FFFE(15) copy byte two bytes further down DECT 8 C 8,1 done ? JNE A4B1C not yet B *10 * A4B3C MOV @>0058(9),2 compare filenames AI 2,>0100 ----------------- A4B44 BLWP @>005A(9) set VDP to read DATA >0022 address in R1 (ptr to filename) MOVB @>FBFE(15),0 get 1 char ANDI 0,>7FFF clear flag (on drive #) BLWP @>005A(9) set VDP to read DATA >0042 address in R2 (filename compare buffer) MOVB @>FBFE(15),3 get 1 char CB 0,3 compare chars JNE A4B68 mismatch INC 1 match: increment pointers INC 2 DEC 4 JNE A4B44 next char A4B68 B *11 if complete match: ret with EQ set * A4B6A MOV @>0054(9),8 get two bytes from PAB JMP A4B74 ---------------------- A4B70 MOV @>0056(9),8 get two bytes from FDR A4B74 A *11+,8 ---------------------- offset in data word A4B76 BLWP @>005A(9) get two byte from VDP at R8 DATA >0102 --------------------------- set VDP to read at R8 MOVB @>FBFE(15),0 get two bytes of data SWPB 0 MOVB @>FBFE(15),0 SRC 0,8 why not swpb ? B *11 A4B8A MOV @>0058(9),1 find disk from name (ptr in R3) AI 1,>0100 ------------------- BL @A4C14 copy filename from VDP at R3 to compare buffer BLWP @>005A(9) save R2 + R3 DATA >3000 MOV 0,0 last char copied JLT A4BA2 flagged JMP A4BAC A4BA2 MOV 0,6 ANDI 6,>0300 JEQ A4C18 return with "file error" JMP A4C0A return to caller A4BAC CLR 6 don't read any drive BL @A4658 call subroutine DATA A4CD2 save current VIB A4BB4 AI 6,>0100 next drive SETO 7 error flags SETO 2 code for read CLR 4 sector 0 BL @A4658 call subroutine DATA A4D50 read sector 0 MOV 7,7 ok? JNE A4C02 no: try next drive LI 4,>000A yes: diskname size MOV @>0058(9),1 VIB ptr BLWP @>005A(9) save R1-R3 DATA >7000 BL @A4B3C compare names (ptr in R1 + compare buffer) BLWP @>005A(9) DATA >7001 retrieve R1-R3 MOV 4,4 name matched? JNE A4C02 no: try next drive MOV 6,0 drive # ORI 0,>8000 add "update" flag BLWP @>005A(9) set VDP to write DATA >0063 address in R3 MOVB 0,@>FFFE(15) copy drive+flag before diskname in source DEC 5 before sector 0 copy BLWP @>005A(9) set VDP to write DATA >00A3 address in R5 MOVB 6,@>FFFE(15) copy drive # before VIB JMP A4C0A done A4C02 CI 6,>0300 did we do all drives? JNE A4BB4 no: try next on JMP A4C18 return with "file error" A4C0A BLWP @>005A(9) retrieve R2 + R3 DATA >3001 B @A4676 return to caller * A4C14 DEC 2 JH A4C1E A4C18 BL @A4C9E return with error DATA >E000 "file error" A4C1E LI 0,>2000 copy (+check) filename in VDP from R3 to R1 BLWP @>005A(9) ---------------------- set VDP to write DATA >0023 address in R1 LI 8,>000A 10 chars per filename A4C2C MOVB 0,@>FFFE(15) fill filename with spaces DEC 8 JNE A4C2C LI 8,>000B 11 chars countring drive # A4C38 INC 3 increment source ptr BLWP @>005A(9) set VDP to read DATA >0062 address in R3 MOVB @>FBFE(15),0 get a char JEQ A4C18 >00: return with "file error" JLT A4C68 flag bit set CI 0,>2E00 JEQ A4C68 '.' DEC 8 JEQ A4C18 name to long: return with "file error" CI 0,>2000 JEQ A4C18 name can't contain spaces: "file error" again BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) copy 1 char INC 1 increment destination pointer DEC 2 more? JNE A4C38 yes A4C68 CI 8,>000B name can't be 0 chars long JEQ A4C18 else return with "file error" B *11 A4C70 DATA >AA00 A4C72 MOV 11,0 update data, then error MOV @>0056(9),3 ----------------------- DEC 3 see what >8356 is pointing at BLWP @>005A(9) set VDP to read DATA >0062 address in R3 MOVB @>FBFE(15),2 get 1 byte CB 2,@A4C70 is it >AA (disk buffer area mark) JEQ A4C9C yes: announce error (code in data word) BLWP @>005A(9) no: >8356 points to a FDR. Save R0 DATA >8000 BL @A4658 call subroutine DATA A487A update FRD and data buffer if needed BLWP @>005A(9) retrieve R0 DATA >8001 A4C9C MOV 0,11 A4C9E MOV @>0054(9),1 annouce error JEQ A4CBE ------------- no PAB INC 1 for DSRs: ptr to status byte BLWP @>005A(9) set VDP to read DATA >0022 address in R2 MOVB @>FBFE(15),2 get file status byte SOC *11+,2 add error code BLWP @>005A(9) set VDP to write DATA >0023 address in R2 MOVB 2,@>FFFE(15) write back status byte JMP A4CC2 A4CBE MOV *11+,@>0050(9) for subs: error code in >8350 A4CC2 MOV @>0058(9),8 get stack ptr AI 8,-12 point back to initial caller MOV 8,@>0066(9) update pointer B @A4676 return to caller * A4CD2 BLWP @>005A(9) read VIB (drive # in R6) DATA >3000 -------- save R2 + R3 MOV @>0058(9),5 pointer to VIB in ctrl block DEC 5 ptr to drive # BLWP @>005A(9) set VDP for read DATA >00A2 address in R5 MOVB @>FBFE(15),2 get drive # MOV 2,3 CLR 4 sector 0 for VIB ANDI 2,>0300 clear flag (>80 = update data) CB 2,6 wanted drive? JEQ A4D28 yes: return MOV 3,3 no: shall we update VIB? JLT A4CFA yes JMP A4D0E no A4CFA BLWP @>005A(9) set VDP to write DATA >00A3 address in R5 MOVB 4,@>FFFE(15) clr drive # INC 5 point back to VIB buffer BL @A4658 call subroutine DATA A4D52 write sector 0 to old drive (in R2) DEC 5 point to drive # A4D0E SETO 2 flag for read MOVB 6,2 add wanted drive JEQ A4D1E none INC 5 point at VIB buffer BL @A4658 call subroutine DATA A4D50 read sector (in R4) to buffer (in R5) DEC 5 point at drive # A4D1E BLWP @>005A(9) set VDP to write DATA >00A3 address in R5 MOVB 6,@>FFFE(15) write drive # in control block, before FDR A4D28 INC 5 point back to FDR BLWP @>005A(9) DATA >3001 retrieve R2 + R3 from stack B @A4676 branch to address on stack * A4D34 SETO 2 read sector 1 A4D36 LI 4,>0001 ------------- LI 5,>0100 into data buffer area of current ctrl block JMP A4D4A A4D40 BL @A4B70 read FDR DATA >FFFC -------- get sector # of FDR from control block A4D46 MOV 0,4 sector read/write CLR 5 ----------------- A4D4A A @>0056(9),5 point to FDR or data buffer A4D4E CLR 7 A4D50 MOVB 6,2 add drive # for r/w flag A4D52 BLWP @>005A(9) save R0-R8 DATA >FF80 MOV 4,@>004A(9) sector # MOV 2,@>004C(9) drive | r/w flag MOV 5,@>004E(9) buffer ptr BL @A4658 call subroutine DATA A40E8 sector read/write BLWP @>005A(9) retrieve R0-R8 DATA >FF81 MOVB @>0050(9),7 get error code | flags SWPB 7 JEQ A4D9C MOV 7,7 JGT A4D7E JMP A4D94 A4D7E ANDI 7,>00FF CI 7,>0034 JNE A4D8E BL @A4C72 DATA >2000 "write protected" A4D8E BL @A4C72 DATA >C000 "device error" A4D94 MOVB @>004D(9),@>004D(9) read or write? JEQ A4D7E write A4D9C ANDI 7,>00FF B @A4676 return to caller * A4DA4 MOV @>0058(9),1 save filename in compare buffer and find its FDR AI 1,>0100 ------------------------------------------------ BLWP @>005A(9) set VDP to write DATA >0023 address in R1: filename compare buffer MOVB 6,@>FFFE(15) write drive # INC 1 BL @A4C14 copy (+ check) filename from R3 to R1 MOV 2,2 all chars copied (or was there a "." or a >00 ?) JEQ A4DC4 A4DC0 B @A4C18 return with "file error" * A4DC4 MOV @>0056(9),1 find filename in buffered FDRs AI 1,>0003 ------------------------------ BLWP @>005A(9) set VDP to read DATA >0022 address in R1 MOVB @>FBFE(15),2 get # of files SRL 2,8 make it a word MOV 2,3 save it AI 1,>0006 ptr to drive # A4DDE LI 4,>000B compare 11 bytes (drive + filename) BLWP @>005A(9) save R1-R3 DATA >7000 BL @A4B3C compare with name in compare buffer BLWP @>005A(9) retrieve R1-R3 DATA >7001 MOV 4,4 fully compared? JEQ A4DFE yes: done AI 1,>0206 move to next FDR in VDP mem DEC 2 JNE A4DDE next file A4DFE B @A4676 return to caller (R4=0 if successfull) * A4E02 BL @A4658 DATA A4DA4 save name in comp buffer, find FDR in VDP buffers A4E08 MOV 4,4 find FDR on disk (from filename) JEQ A4DC0 ---------------- "file error" A4E0C MOV @>0056(9),5 ptr to top of disk buffer in VDP mem AI 5,>000A ptr to drive # in first file control block A4E14 BLWP @>005A(9) set VDP to read DATA >00A2 address in R5 MOVB @>FBFE(15),2 get drive # JEQ A4E2E free control block found AI 5,>0206 ptr to file control block DEC 3 JNE A4E14 more files ? A4E28 BL @A4C72 no: DATA >8000 "memory full" A4E2E MOV 5,@>0056(9) save ptr to free ctrl block (drive #) BL @A4658 call subroutine DATA A4D34 read sector 1 A4E38 MOV @>0056(9),8 entry point if sector 1 already read AI 8,>017E point to middle of sector 1 LI 2,>0040 distance: start with 1/4 sector A4E44 SETO 4 BL @A4B76 read 2 bytes in R0 from VDP address in R8 MOV 0,0 JEQ A4EAA no file here: move up BLWP @>005A(9) save R2 DATA >2000 SETO 2 code for read BL @A4658 call subroutine DATA A4D46 read FDR, sector # in R0 MOV 5,1 A4D46 sets R5 as FDR ptr AI 5,>FFFC point to "sector # of FDR" in ctrl block BLWP @>005A(9) set VDP to write DATA >00A3 address in R5 MOVB 4,@>FFFE(15) A4D46 puts sector # in R4 SWPB 4 copy it to ctrl block MOVB 4,@>FFFE(15) MOV 1,5 FDR ptr DEC 1 now point to drive # BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 6,@>FFFE(15) save drive # LI 4,>000B size to compare (drive # + filename) BL @A4B3C compare filenames BLWP @>005A(9) retrieve R2 DATA >2001 JEQ A4EA6 compared ok: return BLWP @>005A(9) set VDP to write DATA >00A3 address in R5 MOVB 4,@>FFFE(15) remaining chars to compare C 0,3 what kind of mismatch occured? JH A4EAA too far down the alphabet A 2,8 too far up: move half-way down MOV 2,2 JNE A4EB0 then divide distance by 2 INCT 8 already checked: reset EQ A4EA6 B @A4676 return (from stack) A4EAA S 2,8 move half-way up MOV 2,2 JEQ A4EA6 can't: already checked A4EB0 SRL 2,2 divide distance by 2 A 2,2 but keep it even JMP A4E44 * * The cluster info list is located in the FDR, bytes >1C to >FF * A cluster info consists in 3 bytes, i.e 6 nibbles * 3 nibbles specify the beginning sector for that cluster, and * 3 nibbles specify the total file offset in sectors, including this cluster. * The nibbles are arranged as EG SB OF, to be combined as BEG OFS * A4EB6 MOV 11,10 decode cluster info BL @A4B76 ------------------- read 2 bytes VDP at R8 in R0 SWPB 0 MOVB @>FBFE(15),2 get third byte from cluster list MOV 0,1 ANDI 1,>0FFF start sector in R1 SZC 1,0 remove it from R0 SRL 2,8 SOC 0,2 combine offset nibbles SRC 2,12 offset in R2 B *10 * A4ED2 SRC 2,4 write info for 1 cluster MOV 2,0 ------------------------ ANDI 0,>F000 sector in R1, offset in R2 SOC 0,1 copy nibble 3 of offset before nibble 1 of sector A4EDC BLWP @>005A(9) set VDP to write DATA >0103 address in R8 SWPB 1 write cluster info MOVB 1,@>FFFE(15) as 3 bytes SWPB 1 MOVB 1,@>FFFE(15) SWPB 2 MOVB 2,@>FFFE(15) B *11 * * The sector bitmap is located in the VIB (i.e. sector 0) at bytes >38 to >FF * In each byte a bit defines a sector, from right to left: "0"=free, "1"=used * A4EF6 BLWP @>005A(9) find a free sector in bitmap DATA >7800 ---------------------------- BL @A4658 call subroutine DATA A4CD2 load VIB for drive in R6 MOV 1,1 first sector specified in R1 ? JNE A4F0A yes LI 1,>0021 no: start with sector 34 A4F0A INC 1 MOV 1,0 SRL 1,3 div by 8 since 8 sect/byte in bitmap LI 2,>00FF ANDI 0,>0007 bit number in bitmap byte JEQ A4F1C SLA 2,0 get that bit A4F1C MOV 1,3 byte # A 5,3 add VIB ptr AI 3,>0038 ptr to sector in bitmap CI 1,>00C8 end of VIB? JLT A4F2C no CLR 1 yes: top of bitmap A4F2C A 5,1 AI 1,>0038 make another bitmap ptr BLWP @>005A(9) set VDP to read DATA >0022 address in R1 A4F38 SETO 0 MOVB @>FBFE(15),0 get bitmap byte MOV 0,4 save it SOC 2,0 mask previous sectors CLR 2 INC 0 get 1 more sector JNE A4F68 ok INC 1 byte full: try next MOV 1,0 AI 0,>FF00 won't change if byte # became >100 C 0,5 still in VIB? JNE A4F5E yes AI 1,>FF38 no: to top of bitmap BLWP @>005A(9) set VDP to read DATA >0022 address in R1 A4F5E C 1,3 are we back to where we started? JNE A4F38 no: seach that byte for a free sector MOV 4,0 get original byte INC 0 try sectors just before ours (no mask this time) JEQ A4FB2 full: return with EQ A4F68 DEC 0 restore original byte MOV 0,2 CLR 0 bit counter SWPB 2 A4F70 INC 0 increment bit count SRC 2,1 find first "0" bit from the right JOC A4F70 not yet LI 2,>0080 SLA 2,0 make a mask for that bit DEC 0 bit # (0-7) SOC 2,4 mark sector as used in bitmap byte BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 4,@>FFFE(15) update bitmap AI 1,>FFC8 S 5,1 byte # in bitmap SLA 1,3 times 8 (8 sect per byte) SOC 0,1 add bit #: = sector # MOV 1,0 save it A4F96 DEC 5 point to drive # BLWP @>005A(9) set VDP to read DATA >00A2 address in R5 MOVB @>FBFE(15),1 get drive # ORI 1,>8000 add flag: update VIB BLWP @>005A(9) set VDP to write DATA >00A3 address in R5 MOVB 1,@>FFFE(15) write back flagged drive # INC 5 point to VIB (& return with NEQ) A4FB2 BLWP @>005A(9) retrieve R1-R4 DATA >7801 B @A4676 return to caller * A4FBC MOV 0,1 free sector(s) in bitmap LI 2,>0001 ------------------------ 1 sector only A4FC2 BLWP @>005A(9) entry point if more than 1 sector DATA >7800 save R1-R4 BL @A4658 call subroutine DATA A4CD2 load VIB for drive in R6 MOV 1,0 sector # ANDI 0,>0007 bit in bitmap byte (8 per byte) SRL 1,3 byte in bitmap A 5,1 add VIB buffer AI 1,>0038 add bitmap offset in VIB MOV 0,3 NEG 0 AI 0,>0008 change 0-7 into 8-1 LI 4,>00FF mask to erase C 2,0 how many to erase? JLT A4FEE less than in that byte JMP A5004 A4FEE LI 0,>0008 free sectors in first byte S 2,0 SRC 4,0 adjust mask MOV 3,0 original bit # of starting sector JEQ A4FFC SLA 4,0 don't erase before starting sector A4FFC JMP A5000 A4FFE SRL 9,3 what the heck is that??? A5000 SWPB 4 JMP A5036 goto erase last byte A5004 SRC 4,0 adjust mask A5006 S 0,2 that many will be freed BLWP @>005A(9) set VDP to read DATA >0022 address in R1 MOVB @>FBFE(15),0 get bitmap byte SZC 4,0 mark sectors as free BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) write it back LI 4,>FF00 clear full byte INC 1 next byte LI 0,>0008 i.e. 8 sectors C 2,0 how many more setors? JLT A502E less than 8 JMP A5006 8 or more: next byte A502E MOV 2,0 remaining sectors LI 4,>00FF SLA 4,0 coin mask A5036 BLWP @>005A(9) set VDP to read DATA >0022 address in R1 MOVB @>FBFE(15),0 get bitmap byte SZC 4,0 mark sectors as free BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) write it back JMP A4F96 done: flag drive # and return * *=================================== * DSR entry points *=================================== A504E MOV 11,7 DSK BL @A4724 --- prepare file operations BL @A4658 call subroutine DATA A4B8A find disk in drive (name ptr in R3) JMP A5072 A505C LI 6,>0100 DSK1 JMP A506C ---- A5062 LI 6,>0200 DSK2 JMP A506C ---- A5068 LI 6,>0300 DSK3 * ---- A506C MOV 11,7 save return address BL @A4724 prepare file operations A5072 MOV @>0054(9),0 PAB ptr BLWP @>005A(9) set VDP to read DATA >0002 address in R0 MOVB @>FBFE(15),1 get opcode SRL 1,8 CI 1,>0009 check range JH A50BA illegal opcode CI 2,>0001 filename lenght (including . ) JNE A5098 no filename: dir AI 1,>000A only allow open, close and read CI 1,>000C JH A50BA others are illegal A5098 A 1,1 make it a word ptr MOV @A50A0(1),1 get vector B *1 branch to it * A50A0 DATA A50C0 open DATA A52D2 close DATA A52DC read DATA A53C6 write DATA A567A rewind DATA A56CE load DATA A5770 save DATA A4A72 delete DATA A4C9E scratch record: return with "bad attribute" error DATA A57F4 status DATA A58B4 open directory DATA A5912 close directory DATA A5928 read directory * A50BA BL @A4C72 return with error DATA >6000 "illegal opcode" *--------------------------------- * Opcode 0: Open * -------------- * PAB 0: >00 * 1: file type <--- error code * 2-3: * 4: record length * 5: * 6-7: # of records (if output) * 8: *--------------------------------- A50C0 CLR 0 MOVB @>FBFE(15),0 get file attributes BLWP @>005A(9) DATA >8000 save R0 ANDI 0,>1600 keep fix/var and access mode CI 0,>0600 JNE A50DC A50D6 BL @A4C72 dis/fix, open as append: return with error DATA >4000 "bad attribute" A50DC JLE A50F2 MOV 0,1 var BL @A4B6A get 2 bytes from PAB into R0 DATA >0004 rec len and char count CI 0,>FF00 is rec len 255? JHE A50D6 yes: bad attribute MOV 1,0 retrieve attributes ANDI 0,>0600 keep only access mode A50F2 CI 0,>0200 is it output? JNE A51A6 no BL @A4658 call subroutine DATA A4798 create file A50FE BL @A5280 coin status byte in FDR style BLWP @>005A(9) set VDP to write DATA >0083 address in R4: status byte in FDR buffer MOVB 2,@>FFFE(15) write file status in FDR MOV @>0054(9),3 PAB ptr AI 3,>0004 ptr to rec len CLR 5 BLWP @>005A(9) set VDP to read DATA >0062 address in R3 MOVB @>FBFE(15),5 get record length JNE A5130 LI 5,>5000 >00: default it 80 BLWP @>005A(9) set VDP to write DATA >0063 address in R3 MOVB 5,@>FFFE(15) write default rec len A5130 AI 4,>0005 point to rec len byte in FDR BLWP @>005A(9) set VDP to write DATA >0083 address in R4 MOVB 5,@>FFFE(15) write rec len in FDR buffer LI 1,>0100 256 bytes/sector MOV 2,2 var or dis? JLT A5148 var JMP A514C dis A5148 A 1,5 var: rec len +1 DEC 1 254 bytes only (needs size byte) A514C SWPB 5 make it a word CLR 0 DIV 5,0 how many times in 254/255 bytes? AI 4,>FFFC point to # of rec/sect in FDR MOV 0,1 save result for later SWPB 0 BLWP @>005A(9) set VDP to write DATA >0083 address in R4 MOVB 0,@>FFFE(15) write # of rec/sect in FDR MOV @>0056(9),8 point to filename in FDR BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),0 get first char ORI 0,>8000 flag it: update FDR before leaving BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 0,@>FFFE(15) write it back BLWP @>005A(9) DATA >8001 retrieve R0 (access mode) BL @A4B6A get 2 bytes from PAB into R0 DATA >0006 required size in records MOV 0,4 JEQ A51A2 no size specified JLT A50D6 return with "bad attribute" error A 1,4 round up to record size DEC 4 CLR 3 DIV 1,3 how many sectors will this be? DEC 3 offset start from 0 BL @A4658 call subroutine DATA A4964 add sectors to FDR to match offset in R3 A51A2 B @A56A8 initialise file control block and return to caller A51A6 BLWP @>005A(9) not output DATA >8000 save R0 BL @A4658 call subroutine DATA A4E02 find FDR on disk BLWP @>005A(9) DATA >8001 retrieve R0 (access mode) MOV 4,4 found FDR? JEQ A51CE yes CI 0,>0400 no: is file open as input? JEQ A51CA yes: must exist BL @A4658 no: call subroutine DATA A47AA create file JMP A50FE A51CA B @A50D6 return with "bad attribute" error A51CE MOV 0,7 save access mode BL @A5280 prepare status byte for FDR BLWP @>005A(9) set VDP to read DATA >0082 address in R4 (status byte in FDR) MOVB @>FBFE(15),0 get current file status MOV 0,3 save it ANDI 3,>0800 is file write protected? JEQ A51F2 no CI 7,>0400 yes: is it open as input? JEQ A51F2 no BL @A4C72 yes: return with error DATA >2000 "write protected" A51F2 ANDI 0,>8300 keep only file type bits (V/F, D/I, Prg/Data) XOR 2,0 compare with new (coined by A5280) JNE A51CA different: bad attribute MOV @>0054(9),3 PAB ptr AI 3,>0004 ptr to rec len in PAB AI 4,>0005 ptr to rec len in FDR BLWP @>005A(9) set VDP to read DATA >0082 address in R4 MOVB @>FBFE(15),0 get rec len from FDR BLWP @>005A(9) set VDP to read DATA >0062 address in R3 MOVB @>FBFE(15),2 get rec len from PAB JEQ A5220 0 = keep current one CB 0,2 are they identical? JNE A51CA no: "bad attribute" A5220 BLWP @>005A(9) set VDP to write DATA >0063 address in R3 MOVB 0,@>FFFE(15) update rec len in PAB (in case it was 0) BLWP @>005A(9) retrieve R0 (open mode) DATA >8001 ANDI 0,>0600 keep only access mode CLR 2 SETO 3 CI 0,>0600 is it "append" JNE A5278 no MOV @>0056(9),4 yes: get FDR ptr MOV 4,7 save it AI 4,>000E ptr to # of sectors BLWP @>005A(9) set VDP to read DATA >0082 address in R4 MOVB @>FBFE(15),3 get # of sectors in file SWPB 3 MOVB @>FBFE(15),3 SWPB 3 MOVB @>FBFE(15),2 get eof offset DEC 3 offset starts from 0 JLT A5278 file is empty (0 sectors) BLWP @>005A(9) DATA >3000 save R2 + R3 AI 7,>0100 ptr to data buffer area for this file BL @A4658 call subroutine DATA A492E read a sector, from offset in R3 BLWP @>005A(9) DATA >3001 retrieve R2 + R3 A5278 BL @A52AA update current record offset in file ctrl block B @A4676 return to caller * A5280 BLWP @>005A(9) prepare file status byte for FDR DATA >8001 -------------------------------- access mode in R0 BLWP @>005A(9) DATA >8000 save it back LI 2,>0002 "int" in FDR status byte MOV @>0056(9),4 FDR pointer SLA 0,4 fix or var? JNC A529E fix LI 2,>0082 "int var" in FDR MOV 0,0 dis or int? A529E JLT A52A2 int DECT 2 dis: remove the "int" from FDR status A52A2 AI 4,>000C point at file status byte in FDR SWPB 2 B *11 * A52AA MOV @>0056(9),4 update sect + rec offsets in file control block AI 4,>FFFA ----------------------------------------------- BLWP @>005A(9) set VDP to write DATA >0083 address in R4 MOVB 3,@>FFFE(15) write current sect offset SWPB 3 MOVB 3,@>FFFE(15) AI 4,>0004 point to logical rec offset (for var files) BLWP @>005A(9) set VDP to write DATA >0083 address in R4 MOVB 2,@>FFFE(15) write record offset B *11 * *---------------------------------- * Opcode 1: Close * -------------- * PAB 0: >01 * 1: <--- error code * 2-3: * 4: * 5: * 6-7: * 8: *---------------------------------- A52D2 BL @A4658 call subroutine DATA A54D0 find file FDR B @A487A update FDR + data area, get VIB, return to caller * *---------------------------------- * Opcode 2: Read * -------------- * PAB 0: >02 * 1: file type <--- error code * 2-3: data buffer address in VDP mem * 4: * 5: bytes read * 6-7: record # * 8: * * Logical records organisation whithin sectors * * Fixed records (e.g. rec length = 6) * 11 11 11 11 11 11 22 22 22 22 22 22 33 33 33 33 33 33 xx xx xx * Where 11=data for record 1, 22=record 2, 33=record 3, xx=junk bytes * * Variable records: * sz 11 11 11 11 11 11 11 sz 22 22 22 22 22 sz 33 33 FF xx xx xx * Where sz=record size, 11,22,33=record data, FF=end-of-sector mark, xx=junk *---------------------------------- * A52DC BL @A4658 call subroutine DATA A54D0 find FDR in VDP buffers, get status from PAB ANDI 0,>0200 what type of access? JEQ A52EC "update" or "input": ok A52E8 B @A50BA "append" or "output": error "illegal opcode" A52EC BL @A54FC get status byte in R0, from FDR JLT A5306 var BL @A5510 fix: get rec # compare to # of recs/file JL A52FE ok: in file A52F8 BL @A4C72 update data and return with error DATA >A000 "eof reached" A52FE BL @A4658 call subroutine DATA A5576 load record from disk into FDR data buffer area JMP A5328 A5306 BL @A4658 var: call subroutine DATA A5362 load proper sector, point to rec in it JMP A52F8 skipped if ok: return with "eof reached" INC 2 next byte in data buffer A 4,0 add rec size to offset INC 0 room for end-of-sector mark MOV @>0056(9),5 FDR ptr DECT 5 point to var record offset in sector SWPB 0 BLWP @>005A(9) set VDP to write DATA >00A3 address in R5 MOVB 0,@>FFFE(15) update var record offset in sector MOV 4,0 save # of bytes to be read A5328 MOV @>0054(9),4 PAB ptr AI 4,>0005 point to char count SWPB 0 BLWP @>005A(9) set VDP to write DATA >0083 address in R4 MOVB 0,@>FFFE(15) write # of char to be read SWPB 0 make it a word A533E MOV 0,0 check it JEQ A535E none: return A5342 BLWP @>005A(9) set VDP to read DATA >0042 address in R2 MOVB @>FBFE(15),3 read 1 byte from FDR data buffer area INC 2 increment source ptr BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 3,@>FFFE(15) write the byte in PAB data buffer INC 1 increment destination ptr DEC 0 more to read? JNE A5342 yes A535E B @A4676 return to caller * A5362 BL @A5650 load sector, point to record in it MOV 3,3 ----------------------------------- sector offset JLT A536C -1: top of file JMP A5390 in file A536C MOV 3,0 INC 0 next sector C 0,2 compare to # of sect/file JEQ A535E end-of-file reached: return to caller (JMP to err) BL @A4658 call subroutine DATA A489A update data buffer, if needed MOV 0,3 desired offset CLR 5 BL @A55EE update sect + rec offsets in control block AI 7,>0100 point to data buffer area (R7 set by A55EE) BL @A4658 call subroutine DATA A492E read a sector, from offset in file (in R3) CLR 0 JMP A5398 A5390 MOV 0,0 in file: test var rec offset (from A5650) JNE A5398 inside sector C 0,2 at beg of sector JEQ A535E file is empty: return A5398 MOV 0,2 FDR data buffer will be added to R2 by A55CA BL @A4658 call subroutine DATA A55CA R2=byte in FDR data buf, R1=top of PAB data buf BLWP @>005A(9) set VDP to read DATA >0042 address in R2 MOVB @>FBFE(15),4 get first byte (rec length) SRL 4,8 make it a word MOV 0,0 var rec offset JEQ A53BC CI 4,>00FF is it >FF (end of sector mark) ? JNE A53BC no BL @A5650 yes: get sect + rec offsets from control block JMP A536C try again with next sector A53BC BLWP @>005A(9) DATA >0011 retrieve return address from stack in R11 INCT 11 skip the JMP to "eof reached" error B *11 * *------------------------------------ * Opcode 3: Write * -------------- * PAB 0: >03 * 1: file type <--- error code * 2-3: data buffer address in VDP mem * 4: * 5: bytes to write * 6-7: record # * 8: *------------------------------------ A53C6 BL @A4658 call subroutine DATA A54D0 find FDR in VDP buffers ANDI 0,>0600 keep only access mode CI 0,>0400 is it "input" JEQ A52E8 yes: return with error "illegal opcode" BL @A54FC get file status byte from FDR JLT A5402 var BL @A5510 fix: get rec # from PAB, sect # in R0 JL A53FA less that total rec/file BLWP @>005A(9) past eof: expand file DATA >D800 save R0, R1, R3, R4 MOV 0,3 desired sector offset BL @A4658 call subroutine DATA A4964 append enough sectors to reach offset in R3 BLWP @>005A(9) DATA >D801 restore R0, R1, R3, R4 BL @A561A update # of rec/file in FDR A53FA BL @A4658 in file: call subroutine DATA A5576 fetch rec from disk into FDR data buffer area JMP A54A8 set "update data" flag, write data, return A5402 BL @A5650 var: R2=sect/file R3=sect offset R0=rec offset MOV 3,3 sector offset in file JLT A540C -1: top of file JMP A5422 in file A540C BLWP @>005A(9) "next sector" loop DATA >3000 save R2 + R3 BL @A4658 call subroutine DATA A489A update data buffer if needed BLWP @>005A(9) DATA >3001 retrieve R2 + R3 INC 3 next sector CLR 0 init char offset in sector A5422 C 3,2 did we reach last sector? JNE A5438 no BLWP @>005A(9) yes: expand file DATA >9000 save R0 + R4 BL @A4658 call subroutine DATA A4964 get last sector then append sectors to reach R3 BLWP @>005A(9) DATA >9001 retrieve R0 + R4 A5438 MOV @>0054(9),5 PAB ptr AI 5,>0005 point to char count BLWP @>005A(9) set VDP to read DATA >00A2 address in R5 MOVB @>FBFE(15),4 get # of chars to write SRL 4,8 make it a word MOV 4,5 A 0,5 add current char offset in sector INC 5 make room for size byte CI 5,>00FF past end of sector? JH A540C yes: not enough room, try next sector SETO 2 ok: rec will fit in sector MOV @>0056(9),1 FDR ptr A 5,1 past-last-byte offset AI 1,>0100 ptr to data buffer area BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 2,@>FFFE(15) write end-of-sect mark to FDR data buffer area BLWP @>005A(9) DATA >8000 save R0 (current byte offset in sector) MOV 3,0 BL @A55EE update sect + rec offsets in control block AI 1,>0012 point to eof offset in FDR (R1 modified by A55EE) BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 5,@>FFFE(15) update eof offset in last sector, in FDR BL @A561A update # of rec/file in FDR BLWP @>005A(9) DATA >2001 retrieve old R0 in R2 (current byte offset) MOV 4,0 record size BL @A4658 call subroutine DATA A55CA get FDR data buffer in R2, PAB data buffer in R1 SWPB 4 BLWP @>005A(9) set VDP to write DATA >0043 address in R2 MOVB 4,@>FFFE(15) write size byte to FDR data buffer INC 2 increment dest pointer A54A8 MOV 2,3 invert source and dest MOV 1,2 so we can use the same read-write loop MOV 3,1 than the "read" opcode MOV @>0056(9),4 FDR ptr DEC 4 pointer to drive # for that file BLWP @>005A(9) set VDP to read DATA >0082 address in R4 MOVB @>FBFE(15),5 get drive # ORI 5,>8000 add "update data area" flag BLWP @>005A(9) set VDP to write DATA >0083 address in R4 MOVB 5,@>FFFE(15) write back flagged byte B @A533E to read-write loop * A54D0 BL @A4658 find FDR in VDP buffer DATA A4DA4 ---------------------- find file FDR MOV 4,4 found? JEQ A54E0 yes BL @A4C72 no: return with error DATA >E000 "file error" A54E0 INC 1 point to filename in FDR MOV 1,@>0056(9) new FDR ptr MOV @>0054(9),4 get PAB ptr INC 4 point to status byte CLR 0 BLWP @>005A(9) set VDP to read DATA >0082 address in R4 MOVB @>FBFE(15),0 get file status B @A4676 return to caller * A54FC MOV @>0056(9),4 get status byte from FDR AI 4,>000C ------------------------ point to status byte BLWP @>005A(9) set VDP to read DATA >0082 address in R4 MOVB @>FBFE(15),0 read status byte B *11 * A5510 MOVB @>FBFE(15),5 get record # from PAB, check if valid SRL 5,8 ------------------------------------- JNE A551C get # of rec/sector from FDR LI 5,>0100 0: default to 256 A551C MOV @>0054(9),3 PAB ptr AI 3,>0006 point to rec # BLWP @>005A(9) set VDP to read DATA >0062 address in R3 MOVB @>FBFE(15),1 get record # from PAB SWPB 1 MOVB @>FBFE(15),1 SWPB 1 MOV 1,0 save it JLT A553C too big JMP A5542 ok A553C BL @A4C72 update data then return with error DATA >8000 "memory full" A5542 INC 0 next record BLWP @>005A(9) set VDP to write DATA >0063 address in R3 MOVB 0,@>FFFE(15) write back # of future record SWPB 0 MOVB 0,@>FFFE(15) CLR 0 MOV 1,3 save # of desired rec DIV 5,0 divide by # of rec/sector = sect # in R0 A555A MOV @>0056(9),2 FDR ptr AI 2,>0012 point to total # of rec (# of sectors for var) BLWP @>005A(9) set VDP to read DATA >0042 address in R2 MOVB @>FBFE(15),2 get total # of recs/file (sect/file for var) SWPB 2 MOVB @>FBFE(15),2 remember: bytes are swapped C 3,2 compare with desired record (ignored by var) B *11 * A5576 BLWP @>005A(9) fetch record into FDR data buffer area DATA >4000 -------------------------------------- save R1 AI 4,>FFEE ptr to top of control block BLWP @>005A(9) set VDP to read DATA >0082 address in R4 MOVB @>FBFE(15),5 get current sector offset in file SWPB 5 MOVB @>FBFE(15),5 SRC 5,8 JLT A559E -1: top of file C 5,0 compare with desired offset (from A5510) JEQ A55AE same BL @A4658 call subroutine DATA A489A update data buffer if needed A559E MOV 0,3 desired sector offset in file BL @A55EE update sect + rec offsets in control block AI 7,>0100 point to data buffer area (R7 set by A55EE) BL @A4658 call subroutine DATA A492E read a sector from offset in file (in R3) A55AE BLWP @>005A(9) DATA >4001 retrieve R1 MOV @>0056(9),3 FDR ptr AI 3,>0011 point to record length BLWP @>005A(9) set VDP to read DATA >0062 address in R3 MOVB @>FBFE(15),0 get rec length in bytes SRL 0,8 make it a word MPY 0,1 calc file offset in bytes A55CA A @>0056(9),2 add FDR ptr AI 2,>0100 point inside data buffer area MOV @>0054(9),3 PAB ptr INCT 3 point to data buffer address BLWP @>005A(9) set VDP to read DATA >0062 address in R3 MOVB @>FBFE(15),1 get PAB data buffer address SWPB 1 MOVB @>FBFE(15),1 SWPB 1 B @A4676 return * A55EE MOV @>0056(9),7 update sect + rec offsets in control block MOV 7,1 ------------------------------------------ FDR ptr AI 1,>FFFA top of file control block BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) current sector offset in file SWPB 0 MOVB 0,@>FFFE(15) AI 1,>0004 point to var rec offset in sector SWPB 5 BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 5,@>FFFE(15) first free byte in current sector B *11 * A561A MOV @>0056(9),2 update # of rec/file in FDR BLWP @>005A(9) --------------------------- set VDP to read DATA >0042 address in R2 (FDR ptr) MOVB @>FBFE(15),10 get first char of filename ORI 10,>8000 set "was modified" flag BLWP @>005A(9) set VDP to write DATA >0043 address in R2 MOVB 10,@>FFFE(15) write flagged char back AI 2,>0012 point to # of recs/file in FDR INC 3 one more BLWP @>005A(9) set VDP to write DATA >0043 address in R2 SWPB 3 update # of recs/file MOVB 3,@>FFFE(15) SWPB 3 MOVB 3,@>FFFE(15) B *11 * A5650 MOV @>0056(9),8 get rec offset, compare sect with total MOV 8,4 --------------------------------------- FDR ptr AI 4,>0100 point to data buffer area DECT 8 point to var record offset BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),2 get var rec offset in current sector SRL 2,8 make it a word MOV 11,10 save return point BL @A4B74 get 2 bytes from FDR (at R8-4) into R0 DATA -4 current sector offset in file MOV 0,3 save it MOV 10,11 restore return point MOV 2,0 var record offset B @A555A get # of sect/file from FDR, return * *------------------------------------ * Opcode 4: Rewind * -------------- * PAB 0: >04 * 1: file type <--- error code * 2-3: * 4: * 5: * 6-7: record # <--- >0000 if sequential * 8: *------------------------------------ A567A BL @A4658 call subroutine DATA A54D0 find FDR in VDP buffers, read status from PAB BLWP @>005A(9) DATA >8000 save R0 (status from PAB) ANDI 0,>0600 keep only access mode JEQ A5696 "update" is ok CI 0,>0400 is it "input"? JEQ A5696 yes: ok B @A50BA "output" or "append": return with "illegal opcode" A5696 BL @A4658 call subroutine DATA A489A update data buffer if needed BLWP @>005A(9) DATA >8001 retrieve R0 (status from PAB) ANDI 0,>0100 sequential or reloc? JNE A56CA reloc: don't do anything, return A56A8 CLR 2 rewind file: record offset = 0 SETO 3 ----------- current record = -1 (none) BL @A52AA update file control block CLR 0 record 0 MOV @>0054(9),8 get PAB ptr AI 8,>0006 point to record # BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 0,@>FFFE(15) write record # NOP MOVB 0,@>FFFE(15) A56CA B @A4676 return to caller * *------------------------------------ * Opcode 5: Load * -------------- * PAB 0: >05 * 1: file type <--- error code * 2-3: data buffer address in VDP mem * 4: * 5: * 6-7: maximum # of bytes (size of buffer) * 8: *------------------------------------ A56CE BL @A4658 call subroutine DATA A4E02 find FDR on disk MOV 4,4 found? JEQ A56DE yes A56D8 BL @A4C72 no: return with error DATA >E000 "file error" A56DE BL @A4B70 get 2 bytes from FDR into R0 DATA >000C file status byte ANDI 0,>0100 is it "program"? JEQ A56D8 no: file error INCT 8 point to # of sect/file in FDR BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),1 get # of sectors in file SWPB 1 MOVB @>FBFE(15),1 SRC 1,8 JEQ A56D8 0=empty file: return with "file error" BL @A57C0 get data buffer address in R7, # of sectors in R2 INCT 8 point to eof offset in FDR CLR 4 BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),4 get # of bytes in last sector C 1,2 compare # of sect with max in PAB JH A56D8 file is too big: return with "file error" JNE A571C file is smaller C 0,4 same # of sect: check bytes in last sector JL A56D8 file is too big: "file error" A571C CLR 3 sector offset in file SWPB 4 A5720 DEC 1 next sector JEQ A573E done BLWP @>005A(9) DATA >D900 save R0, R1, R3, R4, R7 BL @A4658 call subroutine DATA A492E read a sector from offset in R3 BLWP @>005A(9) restore R0, R1, R3, R4, R7 DATA >D901 INC R3 next sector AI 7,>0100 256 bytes further in PAB buffer JMP A5720 keep going A573E MOV 4,4 JNE A574A BL @A4658 call subroutine DATA A492E read a sector from offset in R3 JMP A576C done A574A MOV 7,5 save PAB data buffer ptr MOV @>0056(9),7 FDR ptr AI 7,>0100 point to FDR data area BLWP @>005A(9) DATA >0D00 save R4, R5, R7 BL @A4658 call subroutine DATA A492E read a sector from offset in R3 BLWP @>005A(9) restore R4 in R0, R5 in R1, R7 in R2 DATA >E001 BL @A4658 call subroutine DATA A533E write bytes from FDR data buffer to PAB data buf A576C B @A487A update FDR, data buffer, VIB and return to caller * *------------------------------------ * Opcode 6: Save * -------------- * PAB 0: >06 * 1: file type <--- error code * 2-3: data buffer address in VDP mem * 4: * 5: * 6-7: # of bytes to save * 8: *------------------------------------ A5770 BL @A4658 call subroutine DATA A4798 create file BL @A57C0 get PAB buffer ptr + # of bytes CLR 3 sector offset 0 A577C BLWP @>005A(9) DATA >B100 save R0, R2, R3, R7 BL @A4658 call subroutine DATA A494E write sector to offset in R3 BLWP @>005A(9) DATA >B101 retrieve R0, R2, R3, R7 INC 3 next sector AI 7,>0100 256 bytes further in PAB data buffer DEC 2 next sector JNE A577C more to do MOV @>0056(9),1 FDR ptr AI 1,>000C point to file status byte LI 2,>0100 value for "program" file BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 2,@>FFFE(15) write file status byte in FDR AI 1,>0004 point to eof offset byte in FDR BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) # of bytes in last sector B @A487A update FDR, data buffer, VIB then return to caller * A57C0 MOV @>0054(9),0 get buffer address + # of bytes INCT 0 ------------------------------- data buffer in PAB BLWP @>005A(9) set VDP to read DATA >0002 address in R0 MOVB @>FBFE(15),7 get data buffer address SWPB 7 MOVB @>FBFE(15),7 SWPB 7 AI 0,>0004 point to # of bytes to transfer BLWP @>005A(9) set VDP to read DATA >0002 address in R0 MOVB @>FBFE(15),2 get # of bytes to be transfered SRL 2,8 make it # of sectors (256 bytes each) CLR 0 MOVB @>FBFE(15),0 see if one more is needed JEQ A57F2 no INC 2 yes: one more sector A57F2 B *11 * *------------------------------------- * Opcode 9: Status * -------------- * PAB 0: >09 * 1: * 2-3: * 4: * 5: * 6-7: record # * 8: <--- file status * * Status bits, returned in PAB byte 8: * >80: file not found * >40: file is protected * >20: * >10: internal (else display or program) * >08: program file * >04: variable (else fixed or program) * >02: memory full * >01: end-of-file reached *------------------------------------- A57F4 BL @A4658 call subroutine DATA A4DA4 save filename in comp buf, then find FDR in VDP A57FA MOV 4,4 found? JEQ A581E yes BL @A4658 no: call subroutine DATA A4E0C find FDR on disk LI 0,>8000 value for "file not found" MOV 4,4 found? JNE A589E no: return with that value MOV @>0056(9),1 yes: ptr to FDR CLR 2 BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 2,@>FFFE(15) invalidate that FDR (file not open) JMP A588A transfer FDR status to PAB status byte A581E BL @A4658 file is open: call subroutine DATA A54E0 adjust FDR ptr, get PAB file type into R4 BL @A54FC get status byte from FDR JLT A582C var JMP A5838 fix A582C BL @A4658 var: call subroutine DATA A5362 load wanted sector, point to wanted rec in buffer JMP A585A out of range CLR 2 ok: clear flag JMP A588A copy status byte from FDR into PAB, return A5838 MOVB @>FBFE(15),5 fix: get rec/sect byte SRL 5,8 make it a word JNE A5844 LI 5,>0100 00 (program files) means 256 A5844 BL @A4B6A get 2 bytes from PAB into R0 DATA >0006 # of wanted record MOV 0,3 save it JLT A5886 too big: set memory full bit in PAB status byte BL @A555A get # recs/file into R2, comp with R3 CLR 2 JL A588A in file: copy file type bits, return DIV 5,2 how many sectors do we need? MOV 2,3 save result A585A BL @A4B70 get 2 bytes from FDR into R0 DATA >000E # of sectors/file INC 3 plus 1 sector for FDR LI 2,>0100 value for "eof reached" in PAB status S 0,3 are there enough sectors in file for these recs? JGT A586C JMP A588A yes: we reached the eof A586C BL @A4658 call subroutine DATA A4CD2 load VIB (sector 0) MOV 3,4 number of sectors that will be needed MOV 5,8 VIB ptr AI 8,>000A skip 10 bytes (required by A5A68) BL @A5A68 count free sectors in bitmap, into R3 LI 2,>0100 value for "eof reached" C 3,4 are there that many free sectors? JHE A588A yes A5886 LI 2,>0200 value for "memory full" A588A BL @A4B70 get 2 bytes from FDR into R0 DATA >000C file status byte ANDI 0,>8F00 mask irrelevant bits JGT A589A ORI 0,>0080 var: put var bit in PAB status style A589A SLA 0,3 get rid of var bit in FDR style SOCB 2,0 add "eof" and "mem full" bits A589E MOV @>0054(9),1 PAB ptr AI 1,>0008 point to bias/status return byte BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) write file status to PAB B @A4676 return to caller * *--------------------------------- * Disk directory access * --------------------- * The directory is accessed by omiting the filename in the DSR name: "DSK1." * It must be opened for input only, as an Int/Fix 38 file. * It consists in upto 128 records, the first one contains the disk informations, * the others the informations for upto 127 files (in alphabetical order). * Each record consists in an ascii string and three floating point numbers. * * Record 0 contains: * - Diskname (an ascii string of upto 10 chars). * - The number zero. * - The number of sectors on disk. * - The number of free sectors on disk. * * Other records contain: * - Filename (an ascii string of upto 10 chars). * - Filetype: 1=D/F, 2=D/V, 3=I/F, 4=I/V, 5=Prog, 0=end of directory. * If the file is protected, this number is negative (-1=D/F, etc). * - File size in sectors (including the FDR itself). * - File record length (0 for programs). *--------------------------------- *--------------------------------- * Open disk directory pseudo-file *--------------------------------- A58B4 MOVB @>FBFE(15),0 get file type from PAB ANDI 0,>1E00 mask irrelavant bits (rel/seq) CI 0,>0C00 is it "int/fix" in "output" mode? JEQ A58C8 yes A58C2 BL @A4C9E return with error DATA >4000 "bad attributes" A58C8 BL @A4B6A get 2 bytes from PAB into R0 DATA >0004 rec length SRL 0,8 make it a word JEQ A58D8 >00= default: set it to 38 CI 0,>0026 is it 38? JNE A58C2 no: return with "bad attributes" error A58D8 LI 0,>2600 set rec len to 38 BLWP @>005A(9) set VDP to write DATA >0103 address in R8 (from A4B6A) MOVB 0,@>FFFE(15) write rec len to PAB CLR 7 BL @A5AA2 find matching drive in file control blocks DATA A58F4 go there if not found A58EE BL @A4C72 update data then return with error DATA >E000 "file error" A58F4 MOV 7,7 did we find a free slot? JNE A58FE yes BL @A4C9E no: return with error DATA >8000 "memory full" A58FE BLWP @>005A(9) set VDP to write DATA >00E3 address in R7 MOVB 3,@>FFFE(15) write drive # SWPB 3 MOVB 3,@>FFFE(15) and a space as filename (illegal, indicates dir) B @A4676 return to caller * *--------------------------------- * Close disk directory *--------------------------------- A5912 BL @A5AA2 find matching drive in file control blocks DATA A58EE go there if not found: return with "file error" CLR 0 BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 0,@>FFFE(15) clear drive # B @A4676 return to caller * *--------------------------------- * Read a record from disk directory *--------------------------------- A5928 BL @A5AA2 find matching drive in file control blocks DATA A58EE go ther it not found: return with "file error" INC 8 MOV 8,5 save ptr to FDR BL @A4B6A get 2 bytes from PAB into R0 DATA >0006 record # MOV 0,2 save it INC 2 BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 2,@>FFFE(15) write record number in FDR SWPB 2 after first char of filename! MOVB 2,@>FFFE(15) SLA 0,1 since two byte per file ptr MOVB 0,0 is rec # greater than 128? JEQ A5958 no BL @A4C72 yes: update data then return with error DATA >A000 "past eof" A5958 SETO 2 code for read MOV 0,4 record # JEQ A59D4 0=disk parameters LI 4,>0001 sector #1 BL @A4658 call subroutine DATA A4D4E read sector into buffer in R5 MOV 5,8 buffer ptr AI 5,>00FF point to data buffer area in this ctrl block DECT 0 don't count record 0 A 0,8 point to desired file ptr BL @A4B76 get two byte from VDP at R8 into R0 MOV 0,4 sector where that FDR is to be found JEQ A59CA no more BL @A4658 call subroutine DATA A4D4E read FDR sector into data buffer area BL @A4B70 get 2 bytes from FDR into R0 DATA >010E # of sect/file MOV 0,6 save it to output file size INC 6 include the FDR itself MOVB @>FBFE(15),3 ignore eof offset LI 2,>0A00 10 chars per filename MOVB @>FBFE(15),3 get rec length SRL 3,8 make it a word DECT 8 point to status byte in FDR BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),0 get file status byte MOV 0,7 ANDI 0,>0800 keep only "write protected" bit SZCB 0,7 clear "write protected" bit (if it was set) SRL 7,8 make it a word INC 7 types are numbered from 1 CI 7,>0002 is it a "program" file? JNE A59BA no AI 7,>0003 yes: make it type 5 A59BA CI 7,>0008 is it var? JL A59C4 no AI 7,>FF81 yes: add 1 and clear "var" bit A59C4 SLA 0,4 "write protect" bit will be >80 SOC 0,7 add it to file type JMP A59D2 A59CA CLR 2 no more files: filename size = 0 CLR 6 file size = 0 CLR 3 rec length = 0 CLR 7 type = 0 A59D2 JMP A59F2 output that A59D4 AI 5,>00FF disk info: point to data buffer area in ctrl block BL @A4658 call subroutine DATA A4D4E read sector 0 BL @A4B70 get 2 bytes from FDR into R0 DATA >010A # of sectors on disk MOV 0,6 duplicate it DECT 6 minus directory itself (sect 0 + 1) BL @A5A68 count free sectors in bitmap, result in R3 CLR 7 filetype is not used LI 2,>0A00 diskname is 10 chars A59F2 BL @A4B6A get 2 bytes from PAB into R0 DATA >0002 data buffer address MOV 0,8 duplicate it INC 8 skip first byte SRL 2,8 filename length (or diskname) JEQ A5A2C 0: skip filename copying CLR 1 A5A02 BLWP @>005A(9) set VDP to read DATA >00A2 address in R5 (FDR ptr) MOVB @>FBFE(15),1 get 1 char from filename in FDR CI 1,>2000 is it a space? JEQ A5A24 yes: end of name BLWP @>005A(9) no: set VDP to write DATA >0103 address in R8 (PAB data buffer ptr) MOVB 1,@>FFFE(15) copy char in PAB data buffer INC 5 increment source ptr INC 8 increment destination ptr DEC 2 next char JNE A5A02 A5A24 NEG 2 number of trailing spaces AI 2,>000A number of chars in filename SWPB 2 A5A2C BLWP @>005A(9) set VDP to write DATA >0003 address in R0 (beg of PAB data buffer) MOVB 2,@>FFFE(15) write string length byte BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOV 7,1 file type + protection BL @A5AE6 make it a float number MOV 6,1 file size in sectors, including FDR BL @A5AE6 make it a float number MOV 3,1 record length BL @A5AE6 make it a float number MOV @>0054(9),8 get PAB ptr AI 8,>0005 point to character count LI 0,>2600 always 38 bytes BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 0,@>FFFE(15) write # of characters in record B @A4676 return to caller * A5A68 AI 8,>002E count free sectors in VIB bitmap LI 2,>00C8 -------------------------------- bitmap size CLR 3 free sectors counter BLWP @>005A(9) set VDP to read DATA >0102 address in R8 A5A78 MOVB @>FBFE(15),1 get a byte from bitmap AI 1,>0100 SRL 1,8 JEQ A5A9C was >FF: no free sectors, next byte DEC 1 was it >00? JNE A5A8E no: count bits AI 3,>0008 yes: 8 more free sectors JMP A5A9C next byte A5A8E LI 0,>0008 8 bits per byte A5A92 SRL 1,1 test a bit JOC A5A98 was 1: sector is used INC 3 was 0: one more free sector A5A98 DEC 0 next bit in byte JNE A5A92 more to come A5A9C DEC 2 next bitmap byte JNE A5A78 more to come B *11 * A5AA2 MOV *11+,10 find drive in file control blocks MOV 11,5 --------------------------------- save 2 returns MOV @>0056(9),8 "top of mem" word in VDP buffers header AI 8,>0003 point to max # of files BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),2 get # of files SRA 2,8 make it a word AI 8,>0006 point to drive # in file ctrl block LI 3,>0020 filename begin with space (illegal: flag for dir) MOVB 6,3 add drive # A5AC4 BL @A4B76 read 2 bytes from VDP at R8 into R0 C 3,0 match with that control block? JEQ A5ADE yes ANDI 0,>00FF keep only first char of filename JNE A5AD4 valid filename: a FDR is loaded here MOV 8,7 this space is free: save ptr A5AD4 AI 8,>0206 point to next file control block DEC 2 next file JNE A5AC4 more to come B *10 not found: return to address passed in data word A5ADE INC 8 drive matches: point to FDR MOV 8,@>0056(9) save ptr B *5 return to caller after data word * A5AE6 LI 2,>0800 write an integer in floating point format MOVB 2,@>FFFE(15) ----------------------------------------- size=8 MOV 1,5 integer is in R1: save it for sign processing ANDI 1,>7FFF clear sign bit CI 1,100 is it less than 100? JL A5B08 yes CLR 0 100 or over LI 4,100 DIV 4,0 divide by 100 ORI 0,>4100 add exponent 2 to hundreths JMP A5B12 A5B08 MOV 1,0 is it 0? JEQ A5B10 yes: exponent is 0 ORI 0,>4000 no: add exponent 1 A5B10 CLR 1 next digits will be 0 A5B12 MOV 5,5 test sign bit JLT A5B18 negative JMP A5B1A positive or zero A5B18 NEG 0 negate first word A5B1A MOVB 0,@>FFFE(15) write exponent to VDP at preset address SWPB 0 MOVB 0,@>FFFE(15) write first first 2 digits (or hundreths) SWPB 1 MOVB 1,@>FFFE(15) write last 2 digits (if any) LI 2,>0005 the remaining bytes are all 0 with integers A5B2E MOVB 2,@>FFFE(15) write 0 to VDP DEC 2 next byte JNE A5B2E more to do B *11 *-------------------------------------- * Floating point format * --------------------- * Float numbers are 8 bytes long: EE 12 34 56 78 9A BC * EE is the exponent in radix 100 (not in radix 10 as usual!). It is biased * by 64: >40=0, 41=1 (i.e *100), >42=2 (i.e * 10,000) >3F= -1 (i.e /100), etc * * 12 ... BC are the mantissa in binary coded decimal: each byte encodes two * decimal digits from 00 to 99 * * For negative numbers, the first word is negated * For zero, the first word is >0000 the others are irrelevant * * Examples: 40 08 00 00 00 00 00 00 is 8.0 * 41 02 37 00 00 00 00 00 is 255.0 (>37 hex = 55 decimal) * BF F8 00 00 00 00 00 00 is -8.0 * 43 01 02 03 04 05 06 07 is 1020304.050607 *-------------------------------------- * *--------------------------------------- * Subprogram >10: sector R/W * -------------- * >834A: (n/a) <--- sector # * >834C: drive # * >834D: R/W code (write if >00) * >834E: VDP buffer * >8350: sector # <--- error code *--------------------------------------- A5B38 MOV 11,7 BL @A4724 prepare disk operations MOV @>0050(9),@>004A(9) copy sector # B @A40E8 * *--------------------------------------- * Subprogram >11: format disk * -------------- * >834A: (n/a) <--- # of sectors on disk * >834C: DSR+drive # (DSR >0x old version >1x new, >2x unknown) * >834D: # of tracks * >834E: VDP buffer * >8350: density <--- error code * >8351: # of sides <--- ditto *--------------------------------------- A5B48 MOV 11,7 BL @A4724 prepare disk operations B @A42AC * *--------------------------------------- * Subprogram >12: file (un)protect * -------------- * >834C: drive # * >834D: protect code (>00 unprotect) * >834E: ptr to filename * >8350: (n/a) <--- error code *--------------------------------------- A5B52 MOV 11,7 BL @A4724 prepare disk operations MOVB @>004D(9),0 get protection code ANDI 0,>0800 keep the bit that will be needed BLWP @>005A(9) save R0 on stack DATA >8000 MOV @>004E(9),0 get pointer to filename BL @A4658 call subroutine DATA A5C54 load FDR in VDP buffer BLWP @>005A(9) retrieve old R0, in R2 DATA >2001 BL @A4B70 read two bytes in R0 from top of FDR + offset DATA >000C file status byte ANDI 0,>F700 clear protection flag SOCB 2,0 set it if needed BLWP @>005A(9) set VDP for write DATA >0103 address in R8 MOVB 0,@>FFFE(15) write back file status to FDR A5B8C MOV @>0056(9),8 FDR address in VDP mem BLWP @>005A(9) set VDP for read DATA >0102 address in R8 MOVB @>FBFE(15),0 get drive # in ctrl block ORI 0,>8000 flag it BLWP @>005A(9) set VDP for write DATA >0103 address in R8 MOVB 0,@>FFFE(15) write it back B @A487A update FDR, load VIB * *--------------------------------- * Subprogram >13: file rename * -------------- * >834C: drive # * >834E: ptr to new name * >8350: ptr to old name <--- error code *--------------------------------- A5BAC MOV 11,7 BL @A4724 prepare disk operations MOV @>004E(9),0 get ptr to new filename BLWP @>005A(9) save R0 on stack DATA >8000 MOV @>0050(9),0 get ptr to old filename BL @A4658 call subroutine DATA A5C54 put FDR in VDP buffer BL @A4ADA remove FDR ptr from sector 1 BL @A4B70 get 2 bytes from FDR DATA >000C file status byte ANDI 0,>0800 protected? JEQ A5BDC no BL @A4C72 yes: return with error DATA >2000 "write protected" A5BDC BL @A4B70 get 2 bytes from FDR DATA >FFFC sector # of FDR MOV 0,1 BLWP @>005A(9) retrieve R0 from stack DATA >8001 ptr to new filename BLWP @>005A(9) save R1 on stack DATA >4000 sector # of FDR BL @A5E9C write drive # and filename in compare buffer BL @A4658 call subroutine DATA A4E38 find FDR from filename MOV 4,4 found? JEQ A5C6E yes: return with "file error" (name already exist) BL @A4B0A insert a FDR in sector 1 BLWP @>005A(9) retrieve sect # of FDR in R4 DATA >0801 BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 4,@>FFFE(15) write sector # of FDR SWPB 4 MOVB 4,@>FFFE(15) SWPB 4 sector # SETO 2 code for read CLR 5 buffer offset: VDP at >8356 BL @A4658 call subroutine DATA A4D4A read FDR MOV 5,1 MOV @>0058(9),0 AI 0,>0101 DEC 1 BL @A5EB2 copy filename in compare buffer to FDR CLR 2 code for write BL @A4658 call subroutine DATA A4D4E write FDR (with new name in it) BL @A4658 call subroutine DATA A4D36 write sector 1 (with new FDR ptr in it) MOV @>0056(9),1 FDR ptr BLWP @>005A(9) prepare VDP to write DATA >0023 address in R1 MOVB 4,@>FFFE(15) clear first char of FDR in buffer B @A4676 return to caller * A5C54 CLR 6 put FDR in VDP buffer MOVB @>004C(9),6 --------------------- get drive # BL @A5E9C update filename compare buffer BL @A4658 call subroutine DATA A4DC4 look if FDR already in VDP buffer BL @A4658 call subroutine DATA A4E08 file FDR on disk MOV 4,4 found? JEQ A5C74 yes A5C6E BL @A4C9E no: return with error code in >8350 DATA >E000 "file error" A5C74 B @A4676 return to caller * *------------------------------------- * Subprogram >14: file raw read * -------------- * >834C: drive # <--- >00 * >834D: # of sectors (>00=get file info) <--- sectors read * >834E: ptr to filename * >8350: file info buffer (>83xx) <--- error code * | * >83xx : VDP buffer <--' * >83xx+2: first sector # (total # of sect when get file info) * >83xx+4: status flag * >83xx+5: recs/sector * >83xx+6: eof offset * >83xx+7: rec size * >83xx+8: # of recs *------------------------------------- A5C78 MOV 11,7 BL @A4724 prepare disk operations BL @A5ED4 load filename and ptrs BL @A5EFA find file FDR, load some info MOV 2,2 # of sectors to read JEQ A5CC6 >00: get file info S 3,0 sectors in file - first sector to read JGT A5C92 in file CLR 2 past eof JMP A5CC0 A5C92 C 2,0 sectors past first one vs sectors to load JL A5C98 MOV 0,2 load what's left A5C98 BLWP @>005A(9) DATA >2000 save R2 A5C9E BLWP @>005A(9) DATA >3100 save R2, R3, R7 BL @A4658 call subroutine DATA A492E read sector from offset in file BLWP @>005A(9) DATA >3101 retrieve R2, R3, R7 INC 3 next sector AI 7,>0100 increment VDP buffer ptr by 256 bytes DEC 2 more to do? JNE A5C9E yes A5CBA BLWP @>005A(9) DATA >2001 retrieve R2 (# of sectors read) A5CC0 MOV 2,@>004C(9) update # of sectors in parameters JMP A5CDA A5CC6 MOV 0,*4+ get file info: sectors in file DECT 8 INCT 2 copy 2 bytes (status + recs/sector) BL @A5F2E from VDP at R8 to file info structure LI 2,>0004 copy 4 bytes A 2,8 BL @A5F2E eof offset, rec len, # of recs (or # of sect) A5CDA BL @A4658 call subroutine DATA A487A updata FDR (+ data) if needed, read VIB CLR @>0050(9) clear error flag B @A4676 return to caller * *-------------------------------------- * Subprogram >15: file raw write * -------------- * >834C: drive # <--- >00 * >834D: # of sectors (>00=create file from info) <--- # of sectors written * >834E: ptr to filename * >8350: file info buffer (>83xx) <--- error code * | * >83xx : VDP buffer <--' * >83xx+2: first sector # (total # of sectors when creating file) * >83xx+4: status flag * >83xx+5: recs/sector * >83xx+6: eof offset * >83xx+7: rec size * >83xx+8: # of recs *-------------------------------------- A5CE8 MOV 11,7 BL @A4724 prepare disk operations BL @A5ED4 load drive + filename, + a few info JEQ A5D1C sectors to write=0: create file BL @A5EFA find file FDR BLWP @>005A(9) DATA >2000 save R2 (# of sectors to write) A5CFE BLWP @>005A(9) DATA >3100 save R2, R3, R7 BL @A4658 call subroutine DATA A494E write sector from offset in file BLWP @>005A(9) DATA >3101 retrieve R2, R3, R7 INC 3 next sector AI 7,>0100 increment VDP ptr by 256 bytes DEC 2 more to do? JNE A5CFE yes JMP A5CBA update # of sectors written, in param. Then return A5D1C BL @A4658 create file DATA A4DC4 find file FDR in VDP buffers BL @A4658 call subroutine DATA A4E08 find file FDR on disk BL @A4658 call subroutine DATA A479E create file BLWP @>005A(9) DATA >0801 retrieve R4 (file info ptr) MOV @>0056(9),8 FDR ptr INCT 4 skip 2 bytes MOV *4+,3 # of sector to create AI 8,>000A skip filename BL @A5F3E write 2 bytes in VDP at R8+2 DATA >0002 i.e. status + recs/sector BL @A5F3E write 4 bytes in VDP at new R8+4 DATA >0004 i.e. eof offset, rec len, # of recs (or # of sect) DEC 3 offset = # of sectors-1 (starts from 0) JLT A5D56 create an empty file, FDR only BL @A4658 DATA A4964 append enough sectors to reach offset A5D56 B @A5B8C modify FDR, write it, load VIB, return * *--------------------------------------- * Subprogram FILES: number of files *--------------------------------------- A5D5A MOV 11,7 BL @A4724 prepare disk operation MOV @>002C(9),8 ptr to next basic token AI 8,>0007 skip "FILES" BL @A4B76 get next two bytes in R0 CI 0,>C801 >C8=unquoted string, size=1 char JNE A5DAA return (with error) if different INCT 8 increment pointer BL @A4B76 get next two bytes SWPB 0 AI 0,>49D0 substact >B630: # of files >B6=closed parenthesis CI 0,>0009 only 9 files allowed in Basic ! JH A5DAA return with error if more SWPB 0 MOVB 0,@>004C(9) put new # of files in scratch-pad memory BL @A4658 call subroutine DATA A5DB4 subprogram >16 (private entry point) MOVB @>0050(9),@>0050(9) test result JNE A5DAA error MOV @>002C(9),8 ok: get ptr to Basic token AI 8,>000C skip the whole statement MOV 8,@>002C(9) update ptr SZCB @>0042(9),@>0042(9) clear current token A5DAA B @A4676 return to caller (i.e. Basic) * *--------------------------------------- * Subprogram >16: number of files * -------------- * >834C: # of files * >8350: (n/a) <--- error code *--------------------------------------- A5DAE MOV 11,7 entry point from assembly BL @A4724 prepare disk operations A5DB4 CLR 0 entry point from "call files" MOVB @>004C(9),0 get # of files JEQ A5E94 return with error MOV @>0056(9),8 ptr to "end of buffer" word AI 8,>0003 point to "# of files" byte CLR 3 BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),3 get current # of files LI 5,>0206 size of 1 file control block CB 0,3 compare required with current JEQ A5E8E same: return with no error JLE A5E30 less MOV 0,6 more files needed CI 0,>1000 maximum is 16 JH A5E94 return with error S 3,0 how many to add SRL 0,8 make it a word MPY 5,0 # of bytes to add MOV 1,4 result in R0:R1 NEG 4 MOV @>0070(9),2 highest free address in VDP mem MOV 2,0 S 1,0 what it would become CI 0,>0800 is there room enough for VDP? JLT A5E94 no: return with error MOV 0,1 ok: new base A5DFC INC 2 increment source ptr INC 0 increment destination ptr BLWP @>005A(9) set VDP to read DATA >0042 address in R2 MOVB @>FBFE(15),3 get a byte BLWP @>005A(9) set VDP to write DATA >0003 address in R0 MOVB 3,@>FFFE(15) copy a byte C 2,8 did we copy the whole header? JNE A5DFC not yet BLWP @>005A(9) set VDP to write DATA >0003 address in R0 MOVB 6,@>FFFE(15) new # of files CLR 6 S 0,2 A5E26 MOVB 6,@>FFFE(15) clear byte DEC 2 JNE A5E26 JMP A5E64 A5E30 BLWP @>005A(9) less files needed DATA >0103 set VDP to write to address in R8 MOVB 0,@>FFFE(15) new # of files in buffer header S 0,3 how many to remove SRL 3,8 make it a word MPY 5,3 # of bytes to remove MOV 4,1 result in R3:R4 A 8,1 new address for buffer header MOV @>0070(9),2 highest free address in VDP mem A5E48 BLWP @>005A(9) set VDP to read DATA >0102 address in R8 MOVB @>FBFE(15),0 read a byte BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 0,@>FFFE(15) write byte back DEC 1 decrement destination ptr DEC 8 decrement source ptr C 8,2 did we copy the whole header? JNE A5E48 not yet A5E64 MOV 1,@>0070(9) new first free address MOV 1,8 A5E6A INCT 8 point to "end of buffer" word BL @A4B76 read it in R0 MOVB @>FBFE(15),1 get CRU base byte CB 12,1 same as current controller? JEQ A5E8E yes: return with no error A 4,0 no: coin address of next buffer BLWP @>005A(9) set VDP to write DATA >0103 address in R8 MOVB 0,@>FFFE(15) write new "end of buffer" word MOV 0,8 and make it new address SWPB 0 MOVB 0,@>FFFE(15) JMP A5E6A now, try again A5E8E CLR @>0050(9) clear error flag JMP A5E98 A5E94 SETO @>0050(9) set error flag A5E98 B @A4676 return to caller * *----------------------------------------------------------- * A5E9C CLR @>0054(9) write drive # and filename in compare buffer MOV @>0058(9),1 -------------------------------------------- AI 1,>0100 ptr to filename compare buffer BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 6,@>FFFE(15) write drive # A5EB2 LI 2,>000A filename must be exactly 10 chars A5EB6 INC 1 next char in compare buffer BLWP @>005A(9) set VDP to read DATA >0002 address in R0 MOVB @>FBFE(15),3 get 1 char from filename INC 0 next char in provided filename BLWP @>005A(9) set VDP to write DATA >0023 address in R1 MOVB 3,@>FFFE(15) write 1 char to compare buffer DEC 2 JNE A5EB6 next char B *11 * A5ED4 MOV 11,10 load compare buffer and ptrs CLR 6 ---------------------------- MOVB @>004C(9),6 drive # MOV @>004E(9),0 ptr to filename BL @A5E9C write them in compare buffer MOVB @>0050(9),4 file info structure ptr SRL 4,8 A 9,4 make it a PAB address MOVB @>004D(9),0 # of sectors (>00=get file info) BLWP @>005A(9) DATA >0800 save R4 SRL 0,8 B *10 EQ set for get file info * A5EFA BLWP @>005A(9) find file FDR DATA >8010 ------------- save R0 + R11 BL @A4658 call subroutine DATA A4DC4 find file FDR in VDP buffers BL @A4658 call subroutine DATA A4E08 find FDR on disk MOV 4,4 found ? JEQ A5F16 yes BL @A4C72 no: return with error DATA >E000 "file error" A5F16 BL @A4B70 get two bytes from FDR into R0 DATA >000E # of sectors in file BLWP @>005A(9) DATA >2011 retrieve R0 in R2 (# of sect to read), and R11 BLWP @>005A(9) DATA >0801 retrieve R4 (ptr to file info structure) MOV *4+,7 VDP buffer MOV *4,3 first sector B *11 * A5F2E BLWP @>005A(9) copy VDP bytes to scratch-pad DATA >0102 ----------------------------- read from VDP at R8 A5F34 MOVB @>FBFE(15),*4+ read bytes into scratch-pad at R4 DEC 2 # of byte in R2 JNE A5F34 next byte B *11 * A5F3E MOV *11+,2 copy scratch-pad bytes to VDP A 2,8 ----------------------------- BLWP @>005A(9) set VDP to write DATA >0103 address in R8 + offset in data word A5F48 MOVB *4+,@>FFFE(15) write byte from scratch-pad at R4 DEC 2 # of bytes in R2, was in data word JNE A5F48 next byte B *11 *----------------------------------------- * * The remaining bytes (>5F52 to >5FEF) all contain >FFFF * Bytes >5FF0 to >5FFE map to the FDC registers * *----------------------------------------- * Th.N. April 1999 END The above code has registers listed as 0 – 15, which can be a bit difficult to read for those of us accustomed to seeing them as R0 – R15. [EDIT: It may be helpful to note that the >16 routine uses the GPL workspace, in which R9 has been set to the start of Scratchpad RAM (>8300) and R15 always contains the VRAM write address (>8C02).] ...lee Edited December 9, 2019 by Lee Stewart clarification 1 Quote Link to comment Share on other sites More sharing options...
Tursi Posted December 9, 2019 Share Posted December 9, 2019 I learned a little more about that crazy DSR... 5 Quote Link to comment Share on other sites More sharing options...
ruthven Posted March 29, 2020 Share Posted March 29, 2020 OK, forgive me--I'm coming to this a bit late but as I was reading though this thread it seemed to me that the incompatibility with TML running on the CF7 was finally solved... I downloaded TML from the pinned development thread on this forum very recently thinking it must be the updated version that is compatible with the CF7. However when I run it on my actual CF7 (mounted as DSK1), TML itself will load up but I am unable to save or load anything. I can't load bitmap graphics that are saved on my CF7; heck I can't even save the BASIC program I typed in--as soon as I try to save or load anything whether in immediate mode or from within the program, the computer crashes on a blank screen that I can't function-break or function-quit out of. So is TML not compatible with the CF7 or do I just have the wrong version (hopefully)? 1 Quote Link to comment Share on other sites More sharing options...
DavidC Posted March 29, 2020 Share Posted March 29, 2020 I don't think it has been released yet. I think this was testing for "XB *GEM*" that Senior Falcon has been working on. 1 Quote Link to comment Share on other sites More sharing options...
senior_falcon Posted March 30, 2020 Author Share Posted March 30, 2020 (edited) Here's something you can try, although I don't guarantee it will work. CALL INIT OLD DSK1.LOAD - this should load the XB program loader for TML. On my working disk it would be OLD DSK1.TML CALL PEEK(-7237,X)::PRINT X X should equal 6. If so, then: CALL LOAD(-7237,20) RUN Test to see whether the CF7 is working. If this fixes the problem, then: CALL INIT OLD DSK1.LOAD (or TML) CALL LOAD(-7237,20) SAVE DSK1.LOAD (or TML) And now it should be fixed permanently. Edited March 30, 2020 by senior_falcon 7 Quote Link to comment Share on other sites More sharing options...
ruthven Posted March 30, 2020 Share Posted March 30, 2020 Thanks so much! Yes that worked like a charm! Very much looking forward to creating something with TML now, it will be my first time using it. Also interested in your upcoming XB GEM cartridge now that I've just learned of it! 3 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.