Writing binary data to disk.

Basic and Machine Language

Moderator: Moderators

User avatar
eslapion
ultimate expander
Posts: 5458
Joined: Fri Jun 23, 2006 7:50 pm
Location: Canada
Occupation: 8bit addict

Writing binary data to disk.

Post by eslapion »

I'm converting a Behr-Bonz cart into an omnitype device reader.

I'll use it to either dump the content of a large ROM or read the truth table of various logic devices to a 1581.

This is generally the basic routine I use:
11 OPEN2,8,2,"DATA.SEQ,S,W":FORT=1TO262144:GOSUB100:A=PEEK(38915):PRINT#2,CHR$(A);:NEXT:CLOSE2:END
However, this is incredibly slow. Even with JiffyDOS, it writes the data on the 1581 at about 15 bytes per second and it keeps the disk spinning all the while.

Quite a demanding job for the little drive.

Anybody can turn this into an ML routine or suggest a faster BASIC code?
Be normal.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Writing binary data to disk.

Post by Mike »

What is done in the subroutine at line 100?
User avatar
srowe
Vic 20 Scientist
Posts: 1325
Joined: Mon Jun 16, 2014 3:19 pm

Re: Writing binary data to disk.

Post by srowe »

It will be slow: there's going to be a CHKOUT, CHROUT, CLRCHN for every byte. That maps on to a LISTEN, CIOUT, UNLSN on the serial bus.

You could try building a BASIC string up to 255 bytes and then PRINT#ing that but you will still have the overhead of BASIC string concatenation.

I think the only way to speed this up is in machine code where you can set up the channel once and then send the data in one unit.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Writing binary data to disk.

Post by Mike »

Yes, me thought the same. Furthermore, JiffyDOS actually slows down more than the standard IEC protocol on single byte transfers, as it has to negotiate repeatedly with the drive, that it still can use the JiffyDOS protocol.

With machine language, you'd have a single CHKOUT/CLRCHN pair for the entire SEQ file, and would transfer around 300 to 400 bytes/second with the standard IEC protocol, and around 2.5 to 4 Kbytes/second with JiffyDOS.

However, the single line program only provided the information, that the data is being transferred from the single port address at $9803. The real meat is in the subroutine at 100, which supposedly controls what appears in $9803.
groepaz
Vic 20 Scientist
Posts: 1180
Joined: Wed Aug 25, 2010 5:30 pm

Re: Writing binary data to disk.

Post by groepaz »

i'd copy blocks into ram, then use SAVE (or even save the banked in blocks directly) - that would be about a gazillion times faster than per byte transfers. you can append the blocks to each other with a seperate tool then (directly on the 1581 if you really want - or simply copy/cat them together on pc)
I'm just a Software Guy who has no Idea how the Hardware works. Don't listen to me.
User avatar
eslapion
ultimate expander
Posts: 5458
Joined: Fri Jun 23, 2006 7:50 pm
Location: Canada
Occupation: 8bit addict

Re: Writing binary data to disk.

Post by eslapion »

Mike wrote:What is done in the subroutine at line 100?
A cluster of latches are set; they correspond to the addresses exposed to the device. I have set this method aside.

I did one routine which reads a series of values from the device and copies it directly to RAM at BLK 5 ($A000-$BFFF).

I then save the data in chunks of 8k.

The routine is as follows:

Code: Select all

60 OPEN2,11,2,"TRIAL.SEQ,S,W"
70 FORT=40960TO49151:PRINT#2,CHR$(PEEK(T)):NEXT
80 CLOSE2
(NOTE: the 1581 is device 11)

This routine now saves at a rate of 64 bytes per second which is an improvement but nowhere near the speed I would like to have.

This "trial" routine saves only 8 kB but of course the total size of the device to be dumped has 256kB.

Only the save routine is a problem to me because dumping the data at BLK 5 is done by a small ML routine I placed in the tape buffer.
Yes, me thought the same. Furthermore, JiffyDOS actually slows down more than the standard IEC protocol on single byte transfers, as it has to negotiate repeatedly with the drive, that it still can use the JiffyDOS protocol.

With machine language, you'd have a single CHKOUT/CLRCHN pair for the entire SEQ file, and would transfer around 300 to 400 bytes/second with the standard IEC protocol, and around 2.5 to 4 Kbytes/second with JiffyDOS.
The routine at 100 is now gone. Think you can help me with an ML routine?
Be normal.
User avatar
eslapion
ultimate expander
Posts: 5458
Joined: Fri Jun 23, 2006 7:50 pm
Location: Canada
Occupation: 8bit addict

Re: Writing binary data to disk.

Post by eslapion »

I disabled JiffyDOS and the save rate improved to 71 Bytes per second. Indeed, JiffyDOS slows down.

At that rate, saving a 256k device should take one hour.
I'd copy blocks into ram, then use SAVE (or even save the banked in blocks directly) - that would be about a gazillion times faster than per byte transfers. you can append the blocks to each other with a seperate tool then
I'm gonna have to do this a good number of times. I'd really prefer an automated solution.
Be normal.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Writing binary data to disk.

Post by Mike »

eslapion wrote:Think you can help me with an ML routine?
Just saving the contents in BLK5 is easily done with the SYS calls I wrote in the topic 'ROM calls and other tricks'.

Specifically for BLK5 and your file name and device no.:

SYS57809"TRIAL.SEQ,S",11:POKE193,0:POKE194,160:POKE780,193:POKE781,0:POKE782,192:SYS65496

However, if you want the contents in one big file, and don't want to concatenate them, you'll have to tell me where the banking register resides, and what range of values I'd have to POKE there. Then I can devise a small ML routine that'd do the job.
User avatar
eslapion
ultimate expander
Posts: 5458
Joined: Fri Jun 23, 2006 7:50 pm
Location: Canada
Occupation: 8bit addict

Re: Writing binary data to disk.

Post by eslapion »

Mike wrote:Specifically for BLK5 and your file name and device no.:

SYS57809"TRIAL.SEQ,S",11:POKE193,0:POKE194,160:POKE780,193:POKE781,0:POKE782,192:SYS65496
This routine is nice and fast but it closes the file and I can't run it multiple time to add - add - add data to the file everytime the content of BLK 5 is filled with new data.
However, if you want the contents in one big file, and don't want to concatenate them, you'll have to tell me where the banking register resides, and what range of values I'd have to POKE there. Then I can devise a small ML routine that'd do the job.
Yes, I want one single big file but there is no such thing as a "banking register" at all. It works with cascaded counters that increase automatically everytime a byte is read.

However, I may settle for 16k banks that appear at BLK2-3. If I go about it that way then poking a value to the first byte of IO2 range chooses the 4 higher address lines.
Be normal.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Writing binary data to disk.

Post by Mike »

eslapion wrote:This routine is nice and fast but it closes the file and I can't run it multiple time to add - add - add data to the file everytime the content of BLK 5 is filled with new data.
Sigh. Francois, it would be possible to concatenate those blocks *after* they've all be written, into one big file, either directly on the drive, or on the PC - as groepaz also already stated.
Yes, I want one single big file but there is no such thing as a "banking register" at all. It works with cascaded counters that increase automatically everytime a byte is read.
O.K. - then there's no banking register but this counter. And the data can be read off $9803 as in your first example.

How is this counter initialised?
User avatar
eslapion
ultimate expander
Posts: 5458
Joined: Fri Jun 23, 2006 7:50 pm
Location: Canada
Occupation: 8bit addict

Re: Writing binary data to disk.

Post by eslapion »

:roll:

I just worked on reconfiguring the thing for banking selectable through poking at the first byte of IO2.

I then went to the post office (received new chips for another batch of Behr-Bonz) and now that I am done, I read your message.

I guess an automated concatenation program could be done on the VIC.

The counter was initiated by poking $9800-$9801-$9802. Now its gone.

Poking $9800 now sets address lines 14-17, the 16k cells of data can be read from $4000-$7FFF.

This is the same way the Scott Adams games are presented to the VIC by a normally operating Behr-Bonz.
Be normal.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Writing binary data to disk.

Post by Mike »

Just to clarify things:

If you had presented a *complete* BASIC program in the first post of this thread, able to dump the entire 256K, even if a little bit slow, I'd have been more than happy just to jump into things and convert the main loop into ML.

However, judging from the code alone I knew it wasn't complete. I suspected that a pointer into the address range was set in the subroutine in line 100, and then the byte was read off in that port register in $9803.

Instead of keeping it this way, and clarifying things, you suddenly shifted the target by implying a banked solution in BLK5, and opening a sideshow:

With a complete block being banked in BLK5, I could rightfully assume there was something like a banking register.

Then you *again* changed the view, and told me that the first solution actually didn't require updating the pointer from the BASIC program, rather the pointer was self-incrementing - so, whatever was in line 100 ultimately was not relevant anyhow. Yet, you'd still had to initialise that pointer, and that was the reason of the question in my last response.

Finally, once again a new target, this time a 16K bank in $4000 to $7FFF. And a banking register in $9800.

Actually, it would have been simpler to use that auto-incrementing pointer to dump the entire address range into a single file ... but now *please* *keep* the logic this way: a bank mapped to $4000 .. $7FFF and banking register in $9800.

Will follow up with the program later.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Writing binary data to disk.

Post by Mike »

Here we go. Sorry I can't upload files to my cloud space at OneDrive ATM, so you'll have to type in this for yourself. It's not that long anyhow:

Code: Select all

10 FORT=673TO712:READA:POKET,A:NEXT
11 DATA 32,241,215,32,201,255,169,0,133,251,168,169,64,133,252,170,138,72,152,72,177
12 DATA 251,32,210,255,104,168,104,170,200,208,240,230,252,202,208,235,76,204,255
13 :
14 OPEN2,11,2,"DUMP.BIN,S,W"
15 FORT=0TO15:POKE38912,T:SYS673,2:NEXT
16 CLOSE2
17 :
18 REM ** 256K DUMP.PRG WRITTEN 2015-07-18 BY MICHAEL KIRCHER
The file name in the OPEN statement adopts the convention of using the *.bin extension, in contrast to *.prg files which have the two-byte load address. The 1581 already knows it's a SEQ, so there... ;)

I only ported the main loop to ML. Here's the commented disassembly:

Code: Select all

.02A1             20 F1 D7  JSR $D7F1   ; read channel number from BASIC text into X
.02A4             20 C9 FF  JSR $FFC9   ; CHKOUT - set channel in X for output
.02A7             A9 00     LDA #$00
.02A9             85 FB     STA $FB
.02AB             A8        TAY
.02AC             A9 40     LDA #$40
.02AE             85 FC     STA $FC     ; set high byte of pointer to $40
.02B0             AA        TAX         ; ... incidentally also number of pages to write
.02B1  +---+--->  8A        TXA         ; put current X and Y on stack
.02B2  |   |      48        PHA
.02B3  |   |      98        TYA
.02B4  |   |      48        PHA
.02B5  |   |      B1 FB     LDA ($FB),Y ; read single RAM byte
.02B7  |   |      20 D2 FF  JSR $FFD2   ; CHROUT to file
.02BA  |   |      68        PLA         ; restore X and Y from stack
.02BB  |   |      A8        TAY
.02BC  |   |      68        PLA
.02BD  |   |      AA        TAX
.02BE  |   |      C8        INY         ; increment effective address within page
.02BF  |   +---<  D0 F0     BNE $02B1
.02C1  |          E6 FC     INC $FC     ; increment high byte of pointer
.02C3  |          CA        DEX         ; decrement remaining pages
.02C4  +-------<  D0 EB     BNE $02B1   ; until =0.
.02C6             4C CC FF  JMP $FFCC   ; CLRCHN - restore default output
User avatar
eslapion
ultimate expander
Posts: 5458
Joined: Fri Jun 23, 2006 7:50 pm
Location: Canada
Occupation: 8bit addict

Re: Writing binary data to disk.

Post by eslapion »

@Mike
eslapion wrote:I did one routine which reads a series of values from the device and copies it directly to RAM at BLK 5 ($A000-$BFFF).
Sorry for the confusion.

I did try to follow your indications with regards to banking...

Thank you very much for the posted code. You are a man of all solutions!

ADDED EDIT:
Correct me if I'm wrong but...
Isn't there supposed to be a RTS at the end of the small ML routine you created?

ADDED EDIT:
I was wrong...
Last edited by eslapion on Sat Jul 18, 2015 2:07 pm, edited 1 time in total.
Be normal.
User avatar
Mike
Herr VC
Posts: 4816
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: Writing binary data to disk.

Post by Mike »

eslapion wrote:Isn't there supposed to be a RTS at the end of the small ML routine you created?
Only if I had JSR'd to CLRCHN.

You can always *) contract the instruction sequence JSR/RTS to JMP. Then, it's the RTS in the jumped-to sub-routine, which returns to the caller *two* levels higher - in this case, the BASIC interpreter. :)


*) actually, "nearly always". This optimization is not possible, when the RTS instruction happens to be a labeled and/or jumped-to target.
Last edited by Mike on Sat Jul 18, 2015 2:09 pm, edited 1 time in total.
Post Reply