-
Notifications
You must be signed in to change notification settings - Fork 93
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic card reading in I650 #392
base: master
Are you sure you want to change the base?
Conversation
45d9571
to
ac767b6
Compare
The diffs for I650/i650_sys.c are unfortunately difficult to read if you show them "inline" or "unified" as github calls it. Side-by-side (or "split") works better but needs a wider window. |
ac767b6
to
dcecaff
Compare
Other than these changes I like it. |
Further opinions and/or arguments? |
For 2 I think it might make things clearer if you move the check for EOF and EMPTY to where you call deck_read_card... also now that I think of it, I would rename this to read_card since you are not reading in a deck but a single card. |
Oh, what I wanted to ask: In deck_split_cmd() I commented a line with XXX. We need to count the number of cards in the input deck, and then we need to read them for real. (Strictly speaking we only need to count them if the user gives a negative number cards, because then we need to leave the last nCards1 cards for the second output file, but the first copy loop is a bit easier if we always know the right number). |
There is already a function in sim_card to return the number of cards in the deck. |
8bd7484
to
e36f30d
Compare
Ah very good! I changed the code to use that. |
On the other hand, if there is a card with EOF marking in the input, the original code would use only the cards before the EOF, but when using sim_card_input_hopper_count(), it would count the EOF card and the following ones too (and expect to copy them). What would be expected behaviour for such a case? |
When you attach to a deck, if you don't specify a EOF option you will not get one added to the deck. |
What I meant was the following. Suppose you have the following deck:
I took these cards from one of the *.dck files under the I650 directory, and added the EOF marker
The report about 20 cards comes from sim_card but deck_load() only loads 10. However when using sim_card_input_hopper_count() it considers 20 usable cards to be in the hopper, and thus wants to put 15 cards into the first output deck. Which fails because after 10 it receives CDSE_EOF.
(the output decks now contain wildly different numbers of cards, not the ones requested, nor the ones reported; 1.dck contains the 10 cards before the EOF and 2.dck contains the remaining 9) I think the only thing that makes sense is to simply ignore every card after the EOF, just like before. To that end I'm introducing a function similar to sim_card_input_hopper_count() that only counts cards until EOF. If we wanted to do something more "intelligent" with decks containing EOF markers, there are so many different ways to do that, that a one-size-fits-all approach doesn't really fit with these split and join commands as they are. I propose to leave that to someone who has a concrete need in the future. |
e36f30d
to
e507cd3
Compare
You probably do not want to add a ~ to end of deck. I could add a function to return number of cards until next EOF or ERR card. Just let me know what you would like it called. It does sound like useful function. |
I already made one and included it in the changed merge request - have a look at sim_card_input_hopper_count_before_eof() in sim_card.c |
I might also stop counting of (card & (CARD_EOF|CARD_ERR) != 0. Also could you put this in it's own commit under SIM_CARD: And can you also post it to my sims repository. This is not really part of i650. |
e507cd3
to
f15366d
Compare
I did some git surgery and there are now 3 commits. Two preparatory ones, where 5b47799 is the one that introduces the new card function. It can be used separately. The last one is the meat of the change. I combined my original version of that with the changes since then, since I changed the order of commits and would not really make sense any more. |
I am not sure of the use of the card counting routine. I would just use the hopper size function and allocate enough space to cover that. Then read the deck into your space. If you get error or EOF, stop and return number of cards read. Errors will only occur if there is an untranslatable line in input. Since you attaching your file to the reader, you don't have to worry about stacking. I am also wondering if these card management functions don't belong in a stand alone utility. |
It has been a while since I looked at this so I have to page everything back in... I guess that with "the card counting routine" you mean The thing is that there is no longer a "space" to "read the deck into your space.". That has been eliminated. If I recall right, in an earlier version of the merge request, I did have a local buffer with a dynamic size. But it was pointed out to me that all cards are already stored anyway and making another copy is wasteful. So now the modified functions have just one card in memory at any time which is much nicer. Unfortunately there is a case where the deck is split in two parts, and the number of cards for the second output is given. |
As for whether these functions belong in a stand-alone utility, I offer no opinion other than that I was encouraged to do this refactoring, and that the functionality is used in the self-test scripts. |
so that they don't use the same file as source and destination.
f15366d
to
9a3be89
Compare
What is unclear to me is why you need to read the complete deck into memory and not just process cards one at a time? Also what kind of processing are you doing on these decks. I have not looked at code in a long time, so don't remember. |
The potential value of reading all cards at attach time validates th data correctly being good and if there are issues with the data, the user gets to see it directly later than having the running program stumble in who knows what way. |
This is not the issue here. Sim_Card currently verifies cards as they are loaded, and will print out error messages if something is wrong. Here he is doing processing on the cards to generate decks. It is unclear why he has to process the decks all at once. |
I am getting very confused. The whole point of this merge request is to do processing using only one card at a time. That the already pre-existing sim_card code buffers all cards in memory is something I wasn't even aware of, at the start. In any case there is no change in that, so it seems irrelevant to me. |
Ok, why do you need to add a routine to count number of cards up to first error or end of file? |
To keep the semantics of the changed commands the same. They were reading the input deck up to that point: https://github.com/open-simh/simh/blob/master/I650/i650_sys.c#L751-L770 |
In the github CI, the i650 test fails like this, but for me locally it passes.
for me locally:
Maybe the compiler used at github has some new exciting code breaking optimisations that need to be disabled? |
Why do these commands need to load the full deck into memory then do the operations and then dump out the results? Why not process one card at a time? Also if you are not dealing with binary decks, these can be done with simple commands. Deck Join is also probably no longer needed as sim_card supports stacking of decks. |
Again: After incorporating this merge request, the code in The code that loads a full deck into memory is then only still in |
I wrote pretty much all of sim_card. Originally it did not read the decks into memory and only read one card at a time. However @markpizz wanted me to validate the deck. This also allows for support of stacking of decks on the reader. This allows for you to read in several different format decks and process them as one deck. |
This is a first go at dynamically reading cards for the use of the
carddeck
command. Discussion on how to do this better is invited.There are some ugly bits in this. To read a card you need a UNIT and a UNIT needs a DEVICE. So we allocate and free those dynamically. But it seems to be a bit too intimate in the implementation of devices. Also they don't seem to be meant to be very dynamic, so maybe there are bugs because of that.
Possibly some of this code better belongs in sim_card but then it may need some generalisation.
The original code already used a CDR (card reader) to punch cards, even though there is also a CDP device available (however it has no cdp_attach() function, so you cannot currently create more of them). I'm not sure how to use a CDP to write files or if it would even work; sim_card internally has no problems to write via a CDR.
The test code used overlapping input and output file names when splitting or joining card decks. I am forbidding that (and issue an error message). I don't think this is a great limitation since there is a command to rename files.
I adjusted the ini files used for the self test to correct for this.
I left the binary .doc file as it is; binary files are not very suited for tracking in version systems like git.