--
You received this message because you are subscribed to the Google Groups "C65GS Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to c65gs-developm...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Hi Paul,The VIC-20 with the 65CE02 chip outputs the number 57. I ran the program on a PET4008 and a C64 and they both report 51. I'm confused though. It looks like the program is subtracting 8 from 65 in decimal, isn't 57 the correct answer?Wayne
1800 SED ;Enter decimal mode1801 LDA #$41 ;Load the accumulator with initial value1803 SEC ;Set carry flag (so there is no "borrow" for SBC)1804 SBC #$08 ;Subtract an immediate value from .A1806 STA $1C00 ;Store the result1809 CLD ;Leave decimal mode180A RTS ;Return (to BASIC)
41 - 8 = 33
65 - 8 = 57
Hi Daniel,
I replied to Paul separately and he cleared everything up for me. The problem was, I used a tiny disassembler that was written in BASIC to look at the code. It didn’t do the conversions to hex, so I saw the program as:
6144 SED
6145 LDA #65
6147 SEC
6148 SDB #08
6150 STA 7168
6153 CLD
6154 RTS
So, in the midst of all these decimal to hex conversions and non-conversions, I got lost. I’m usually not this impaired. Honestly. :)
I think they’re just two aspects of the same bug. SBC only works in hex mode. It’s as if the SED never happened.
I’ve never used MESS so it must be someone else you’re thinking about. However, I do have a 4510 chip. If someone would like to help me build an adaptor to plug it into my VIC-20, C64 or even one of my PETs I’ll gladly play along and run whatever tests you’d like. I’ve got plenty of 84 pin PLCC sockets and a brand new roll of solder.
On Sunday, 23 November 2014 11:34:34 UTC+10, Wayne Sander wrote:Hi Daniel,
I replied to Paul separately and he cleared everything up for me. The problem was, I used a tiny disassembler that was written in BASIC to look at the code. It didn’t do the conversions to hex, so I saw the program as:
6144 SED
6145 LDA #65
6147 SEC
6148 SDB #08
6150 STA 7168
6153 CLD
6154 RTS
So, in the midst of all these decimal to hex conversions and non-conversions, I got lost. I’m usually not this impaired. Honestly. :)Hehe... SBC not SDB... :)I love it when I have those slightly skewed moments, too... Hmm...
I'd imagine that the 4510 won't work in the C64 because of the IO ports at $0000/$0001 and the PLA dependency. It will probably work in the VIC20? I read someone say that the 65CE02 is pin compatible with a 65C02 but the 4510 has a lot more going on and I don't know enough to say anything about how to make it work in the VIC20. It could be a problem if the 4510 relies on the operation of its internal 6526/8520s and that's all I know. I could read, speculate and experiment but with a part that rare and valuable you'd want to know for sure that it will be okay. Speaking of which, are you sure your 4510 is functional? Its a shame you don't have the other ICs in your C65.Its very interesting stuff, that this hasn't been found before. If the problem still exists in the 4510 then even Commodore hadn't tested its 65CE02 very well. Fascinating.
That's a very pretty looking VIC20.
Shame you couldn't get it to work. How were you powering the board? I wonder if you can use that widget board to detect some kind of life in the 4510 if you just try powering it up on its own?
Would you be able to run that test again as you did the first time but make it so that it does a SBC $10 for me (replacing the 8 in the data to 16?)? Just out of curiosity...
IMHO, the correct thing to do for Paul's 65GS02 is to implement the correct functionality. Since it is/was known to be broken in the 65CE02, anything expecting to be run on it shouldn't be using it so it should be okay to do it properly in the 65GS02.
--
? ILLEGAL QUANTITY ERROR
--
You received this message because you are subscribed to a topic in the Google Groups "C65GS Development" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/c65gs-development/ZNNF5nF_4Fo/unsubscribe.
To unsubscribe from this group and all its topics, send an email to c65gs-developm...@googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "C65GS Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email to c65gs-developm...@googlegroups.com.
--
Sounds like you have been busy!
For string compression, take a look at SMAZ as an example of a very simple but effective string compressor. Also consider something as simple as using a nybl to encode each character if it is in the most common 15 characters, else indicates that a whole byte follows. This should get you pretty close to 50% savings for common text, and with a very small routine for decompression.
Back to the tests, I think the only results we need to log are those that differ to what is expected for a 6502 or our understanding of the 65CE02 -- i.e., only log remarkable data.
;===============================================================================;Data for string dictionary: DMDTST;===============================================================================;Generated on: 09DEC2014 @ 23:51:13;;-------------------------------------------------------------------------------;Original text strings;-------------------------------------------------------------------------------; $00: "{CLEAR}{CYAN}DECIMAL MODE TEST{RETURN}"; $01: "{CYAN}6502{RETURN}"; $02: "{CYAN}65C02{RETURN}"; $03: "{CYAN}65816{RETURN}"; $04: "{CYAN}COMPLIANCE{RETURN}"; $05: "{CYAN}COMPREHENSIVE{RETURN}"; $06: "{CYAN}SPECIFIC CASE{RETURN}"; $07: "{BLUE} {RETURN}"; $08: "{BLUE}LEVEL SELECT: {RETURN}"; $09: "{BLUE} <{CYAN}1{BLUE}> - 6502{RETURN}"; $0A: "{BLUE} <{CYAN}2{BLUE}> - 65C02{RETURN}"; $0B: "{BLUE} <{CYAN}3{BLUE}> - 65816{RETURN}"; $0C: "{BLUE}TYPE SELECT: {RETURN}"; $0D: "{BLUE} <{CYAN}1{BLUE}> - COMPLIANCE{RETURN}"; $0E: "{BLUE} <{CYAN}2{BLUE}> - COMPREHENSIVE{RETURN}"; $0F: "{BLUE} <{CYAN}3{BLUE}> - SPECIFIC CASE{RETURN}"; $10: "{BLUE} <{CYAN}B{BLUE}> - BACK{RETURN}"; $11: "{BLUE} <{CYAN}Q{BLUE}> - QUIT{RETURN}"; $12: "{BLACK}INSERT DISK #"; $13: "S0:TESTDMODE";;-------------------------------------------------------------------------------;Compression lexicon;-------------------------------------------------------------------------------; $ 1: {SPACE} 43; $ 2: E 25; $ 3: {BLUE} 19; $ 4: C 18; $ 5: {RETURN} 18; $ 6: {CYAN} 15; $ 7: S 13; $ 8: I 12; $ 9: T 9; $ A: - 8; $ B: 6 8; $ C: < 8; $ D: > 8; $ E: L 7; $ F: M 7;;-------------------------------------------------------------------------------;Summary;-------------------------------------------------------------------------------;Used: 15, misses: 24, overhead: 38.31%;Original size: 316, compressed size: 268, ratio: 16.22%;;-------------------------------------------------------------------------------;Dictionary data;-------------------------------------------------------------------------------DMDTST WORD DMDTST + $25BYTE $20,$45,$1F,$43,$0D,$9F,$53,$49,$54,$2D,$36,$3C,$3E,$4C,$4DBYTE $0F,$15,$1C,$23,$2D,$3B,$46,$48,$52,$5E,$6B,$78,$83,$93,$A7,$B8BYTE $C4,$CF,$DC,$E7BYTE $09,$36,$04,$42,$48,$F0,$41,$E1,$F0,$4F,$04,$42,$19,$27,$95BYTE $6B,$03,$50,$30,$03,$25BYTE $6B,$03,$54,$03,$00,$32,$50BYTE $6B,$03,$50,$38,$03,$1B,$50BYTE $64,$04,$FF,$05,$0E,$80,$41,$04,$E4,$25BYTE $64,$04,$FF,$05,$00,$52,$20,$48,$20,$4E,$78,$05,$62,$50BYTE $67,$05,$02,$48,$04,$68,$41,$40,$41,$72,$50BYTE $31,$50BYTE $3E,$20,$56,$2E,$17,$2E,$24,$90,$3A,$15BYTE $31,$1C,$60,$31,$3D,$1A,$1B,$03,$50,$30,$03,$25BYTE $31,$1C,$60,$32,$3D,$1A,$1B,$03,$54,$03,$00,$32,$50BYTE $31,$1C,$60,$33,$3D,$1A,$1B,$03,$50,$38,$03,$1B,$50BYTE $39,$05,$90,$50,$21,$72,$E2,$49,$03,$A1,$50BYTE $31,$1C,$60,$31,$3D,$1A,$14,$04,$FF,$05,$0E,$80,$41,$04,$E4,$25BYTE $31,$1C,$60,$32,$3D,$1A,$14,$04,$FF,$05,$00,$52,$20,$48,$20,$4EBYTE $78,$05,$62,$50BYTE $31,$1C,$60,$33,$3D,$1A,$17,$05,$02,$48,$04,$68,$41,$40,$41,$72BYTE $50BYTE $31,$1C,$60,$42,$3D,$1A,$10,$42,$04,$14,$04,$B5BYTE $31,$1C,$60,$51,$3D,$1A,$10,$51,$05,$58,$95BYTE $09,$08,$04,$E7,$20,$52,$91,$04,$48,$70,$4B,$10,$23BYTE $70,$30,$03,$A9,$27,$90,$44,$F0,$4F,$04,$42;-------------------------------------------------------------------------------;;
StringDataPtr: Pointer;
--
Paul,How are you calculating that amount?
Also, how are the strings to be indexed or how do you seek a particular string in a table or list of strings?
I need a string table. Presently, without a compression scheme, I use two lists of bytes, one for the lo and another for the hi values for the pointers and index these lists by string number to get the address of the string and then pass the address to the BASIC print PChar routine.
However, with the compression, I have a list of length offsets which I index by string number and use then to seek in the string data itself to start the decompression to a buffer and pass the buffer pointer to the BASIC print PChar routine.
For my first pass of the NybMP algorithm, I store a list of the most frequently used characters (up to 15) for that string list as well as the offsets list and a pointer to the start of the string data. It achieves only, roughly, 16% compression ratio. I should note that version is obsolete now and I am getting a better than 21% ratio with the new version.
The ratio is calculated as per the common method for compression: the ratio of size delta to original size. So, (original size - compressed size) / original size * 100.I could, I suppose, get rid of the offset list and pass a pointer to the decompression routine that I get from a label. However, how would I know when to terminate the string? I would need to keep {NULL} ($00) as one of the dictionary characters reducing its effectiveness even further since it will match only once per string or store it as 3 nybbles which means it uses more data area than the lengths do (single byte per string). Even hard coding the value using generated macros perhaps, we are still talking about some kind of load instruction using an extra 2 bytes every time a string is referred to.
I could get rid of the string data pointer but it would make handling the block of strings more difficult, requiring about 6 lines more of LDA/STA code at least.
I could use a standard character dictionary and not have to include it with the string data but this will reduce the effectiveness of the compression. If I don't include it in the above sample, the rate is improved to a theoretical 20.57% but there is no way that in reality the ratio is going to be anywhere near that if I actually compress the string data using a standard character dictionary instead of the generated, optimal one.
In fact, I tried using the list of most frequent characters from the wiki page: <http://en.wikipedia.org/wiki/Letter_frequency>. I included space since they say it is the most common and in my own tests this proves to be true. The characters then are: {SPACE}, E, T, A, O, I, N, S, H, R, D, L, C, U, M. Compressing the test data above using this character set gave a ratio of 2.85%. This is a terrible result due, most likely, to the fact that punctuation characters (as noted on the wiki) are the fourth most commonly occurring characters and because we are effectively using two sets of punctuation in the test data with the colour codes.
For my new implementation, I began by producing tables of character affinity or association by proximity. I used a bit in the nybble to indicate whether it was a "control nybble" otherwise it was a character nybble. It it was a character nybble, it was a index into the current character table. If it was a control nybble it could be either to indicate a character embedded in the next byte of the stream or to switch the current character table to another one. This seemed promising to me at first but in the end, didn't work because of the limited number of characters that can be stored in the tables using only a nybble for indexing and control. I even "optimised" the compression process with a "peep hole" that tried to find the best table for the upcoming characters. Still, the results were terrible.
I went back to my original idea of using substitution flagging and instead of using a whole byte as I did at first, used only a nybble. So now I have a bit in the nybble to indicate if it is a word substitution or character substitution. If it is a character substitution it might also indicate a character directly in the stream. This is actually working out well.The problems really are that we have so few bits to work with as indexes using nybbles in the data stream. Additionally, we have no memory for extensive substitution or dictionary tables. Also, the strings are themselves relatively dissimilar.
I did some analysis of my test data using the PC "zip" and "7z" methods. I created a file with the equivalent test data in it. I named the file "t" to reduce the issue of file names stored in the compression since I could be bothered creating a program to produce a custom, data only stream. I couldn't set the dictionary size anywhere near equivalent to what we are working with. The "zip" method used 32KB, the "7z" method 64KB. My new NybMP has an effective dictionary size of 135bytes. I could control the word size, 16 bytes so that it is the same for my method but it wasn't going to make any difference with the dictionary sizes they use. The "zip" method internally gave a ratio of 47.11%. The "7z" internally 46.10%. However, the overheads were huge for these methods with 136 bytes of header for the "zip" method and 100 bytes for the "7z" one. Understandably, some of this overhead is for the file description but that would be small compared to the actual internal method signatures and checksums which they insist on having. In the end, the "zip" method gave a final ratio of 1.03% and "7z" 12.20%. Looking at these figures, I'm actually pleased with my NybMP method.
I would like to know more about your methods.
; SETUP THE FILE NAME STRINGS
UTILSFS LDA TSTBFDH
JSR TOHEX
STA TSTDSK0
STA TSTFIL0
STA TSTFIL1
LDA TSTBFDL
JSR TOHEX
STA TSTDSK0+1
STA TSTFIL0+1
STA TSTFIL1+1
How are you calculating that amount?The same way as you, i.e., 0% means no savings, and 100% means the string requires zero bytes.
Also, how are the strings to be indexed or how do you seek a particular string in a table or list of strings?You need the pointer to the start of the string. I haven't optimised that part yet, and am currently just using absolute,Y addressing mode, but could easily switch to (zp),Y which would shave a couple of bytes as well as allowing arbitrary string addresses.
I need a string table. Presently, without a compression scheme, I use two lists of bytes, one for the lo and another for the hi values for the pointers and index these lists by string number to get the address of the string and then pass the address to the BASIC print PChar routine.If the compressed strings all fit in a page you can use 1 byte each instead of 2 as addresses. If more than one page, I would split them into sets that fit in a page each.
Alternatively, you could just use a string number in the whole table, and count delimiter characters encountered, and only begin printing when you have reached the correct string, and stop after the delimiter for that string. This would trade some CPU time in return for being able to index up to 256 strings using just one byte.
However, with the compression, I have a list of length offsets which I index by string number and use then to seek in the string data itself to start the decompression to a buffer and pass the buffer pointer to the BASIC print PChar routine.See above, this can be completely avoided.
For my first pass of the NybMP algorithm, I store a list of the most frequently used characters (up to 15) for that string list as well as the offsets list and a pointer to the start of the string data. It achieves only, roughly, 16% compression ratio. I should note that version is obsolete now and I am getting a better than 21% ratio with the new version.This sounds in the right ball-park for this kind of compression.
If NULL (or CR as I use in my scheme) occurs once per string, it is by definition a fairly frequent character, and probably deserves to be in the table, unless there is a character that occurs more often. Just let the probabilities of occurrence govern this decision -- it is almost always the right decision for compression.
Also, chaining the strings this way saves you 1/2 a byte per string on average, because you can't waste the last nybl in strings anymore.
I don't think there is a good way to get away from including the letter frequencies for the strings you are encoding. The list needs to be there anyway, and only requires 15 bytes. But you should choose the characters to put in there based on absolute frequency.
What might make sense is to have separate lists for character prediction following vowels and non-vowels, but not sure if it will help.The other thing that might make sense, and it all depends on the character frequencies, is to make the common character lookup multi-stage:($1-F) = 15 most common characters.$0 + ($1-$F) = 15 next most common characters.$0 + $0 + ($1-F) = 15 next most common characters.and so on, until you have covered all characters that occur.
I went back to my original idea of using substitution flagging and instead of using a whole byte as I did at first, used only a nybble. So now I have a bit in the nybble to indicate if it is a word substitution or character substitution. If it is a character substitution it might also indicate a character directly in the stream. This is actually working out well.The problems really are that we have so few bits to work with as indexes using nybbles in the data stream. Additionally, we have no memory for extensive substitution or dictionary tables. Also, the strings are themselves relatively dissimilar.Yes, string-matching based compression is going to be problematic.You could consider bi-grams, tri-grams and n-grams as "common characters", and have a table with shifted characters as the terminator for each, and then have a "lookup n-gram" routine based on the "common n-gram" indicated in the stream.
Yes, compressing short strings is hard.Search for SMAC (Short Message Arithmetic Coder) for an example of how to do this, and the complexity trade-off that is incurred as a result.
If you can send me your string table, I can make some estimates of how well it can be compressed using the multi-stage n-gram based method I describe
{CLEAR}{CYAN}DECIMAL MODE TEST{RETURN}
{CYAN}6502{RETURN}{CYAN}65C02{RETURN}{CYAN}65816{RETURN}{CYAN}COMPLIANCE{RETURN}{CYAN}COMPREHENSIVE{RETURN}{CYAN}SPECIFIC CASE{RETURN}{BLUE} {RETURN}{BLUE}LEVEL SELECT: {RETURN}
{BLUE} <{CYAN}1{BLUE}> - 6502{RETURN}
{BLUE} <{CYAN}2{BLUE}> - 65C02{RETURN}
{BLUE} <{CYAN}3{BLUE}> - 65816{RETURN}
{BLUE}TYPE SELECT: {RETURN}
{BLUE} <{CYAN}1{BLUE}> - COMPLIANCE{RETURN}
{BLUE} <{CYAN}2{BLUE}> - COMPREHENSIVE{RETURN}
{BLUE} <{CYAN}3{BLUE}> - SPECIFIC CASE{RETURN}
{BLUE} <{CYAN}B{BLUE}> - BACK{RETURN}
{BLUE} <{CYAN}Q{BLUE}> - QUIT{RETURN}
{BLACK}INSERT DISK #S0:TESTDMODE
$93 {CLEAR}
$9C {CYAN}
$0D {RETURN}
$1F {BLUE}
$90 {BLACK}
Looking at your code: you are using 16 bytes for hex string conversion lookup table. You can save 6 bytes by removing the table, and adding the following routine:TOHEXcmp #$0abcs TOHEXhighadc #$30rtsTOHEXhighadc #$36rtsThen use:; SETUP THE FILE NAME STRINGS
UTILSFS LDA TSTBFDH
JSR TOHEX
STA TSTDSK0
STA TSTFIL0
STA TSTFIL1
LDA TSTBFDL
JSR TOHEX
STA TSTDSK0+1
STA TSTFIL0+1
STA TSTFIL1+1
Now to look at your table of strings for compression potential ...Paul.
--
Looking a savings from rephrasing strings without losing clarity of meaning:Change "APPROX. 30 BLANK DISKS" to "ABOUT 30 BLANK DISKS" to save 2 bytes.
Consider removing "BLANK " above to save a further 6 bytes.
Change "QUITE SOME TIME" to "A LONG TIME" to save 4 bytes.
Consider merging "LEVEL SELECT: " and "TYPE SELECT: " into a single "SELECT: " or "PICK: " to save 19 or 21 bytes.
Replace all strings like $1F," <",$9F,"B",$1F,"> ",$2D," with a single routine that prints $1F," <",$9F,{customcharacter},$1F,"> ",$2D. This will save a lot of bytes in a lot of strings. This could be done with a template string that gets modified, e.g.:
Hello
No problem. Compression can only help so much, it is generally better to remove the redundancy first if you can, because the compression scheme will almost invariable be less intelligent than the programmer. Substitution of words with shorter or lower scrabble scoring synonyms is a good place to start, thus my suggestions in the previous email.
Regarding the speed of printing strings if using the chained NULL terminated compressed string scheme I propose, I think you will find that the CPU time for the messages is insignificant. My decompression routine takes only a few rasters on a C64 to decode ~20 bytes. Multiply that by the ~40 messages you have, and it is still of the order of 1 message per frame, and that assumes that you don't put the most commonly used messages first, and errors that terminate last.
I need a nap now, but will try to generate a decompression routine that can lookup strings in this way when I get the chance. I'll also test the performance of my existing compressor on your string table to see if it still yields ~30%.
Finally, don't be worried about imperfection in your code, and don't worry about apologising for it. Just present what you can, and let the community work with you to improve it. Similarly, don't unnecessarily delay release under an open-source license: they are designed to allow fast collaboration on imperfect code!
;------------------------------------------------------------------------------- ;Test data location and count TSTDAT = $1E00 TSTCNT = $0C ;Routine to do the string updating TSTSTOR RTS ;------------------------------------------------------------------------------- ;Look-up table method TBLCNV BYTE "0123456789ABCDEF" TSTCNV1 LDX #TSTCNT @1 LDA TSTDAT,X PHA AND #$0F TAY LDA TBLCNV,Y JSR TSTSTOR PLA AND #$F0 LSR LSR LSR LSR TAY LDA TBLCNV,Y JSR TSTSTOR DEX BNE @1 RTS ;------------------------------------------------------------------------------- ;------------------------------------------------------------------------------- ; Calculation method TST2HEX PHP CLD CMP #$0A BCS @1 ADC #$30 PLP RTS @1 ADC #$36 PLP RTS TSTCNV2 LDX #TSTCNT @1 LDA TSTDAT,X PHA AND #$0F JSR TST2HEX JSR TSTSTOR PLA AND #$F0 LSR LSR LSR LSR JSR TST2HEX JSR TSTSTOR DEX BNE @1 RTS
*rofl*
On Saturday, 13 December 2014 12:32:45 UTC+10, Paul Gardner-Stephen wrote:Looking a savings from rephrasing strings without losing clarity of meaning:Change "APPROX. 30 BLANK DISKS" to "ABOUT 30 BLANK DISKS" to save 2 bytes.Umm... The "non technical" language is foreign to me. I prefer the way "approximately" sounds to "about". It presents a more authoritative personality on behalf of the program.
Consider removing "BLANK " above to save a further 6 bytes.You can't really because technically, the disks have to be blank (except for the sole condition they were used for DMode test data before). I guess I could change the code to do a quick format on them instead but I didn't want to do that for saving execution time (quick format is still slow).
Change "QUITE SOME TIME" to "A LONG TIME" to save 4 bytes.Sorry, to my mind, "a long time" does not say "a very, very, so very, long time". I'm in the habit of being as informative as I can with messages I present to the user. "Quite some time" is a more accurate, although still "polite" way of saying, "you'll be here all day and probably most of tomorrow, too".
Consider merging "LEVEL SELECT: " and "TYPE SELECT: " into a single "SELECT: " or "PICK: " to save 19 or 21 bytes.Again, I'm just in the habit of providing as much information as I can. The "Level select" and "Type select" tell you what options you are configuring with your selection. I don't think this should be changed in order to allow the user to understand what it is they are doing.
Programs should be as informative as possible and avoid terse or overly specific terminology in order to be well written. I do find it a bit of a strain in such confined memory. I write a message I want to produce and, oops, those four words are longer than a line. Rephrase! You can't really afford to remind the user of what they aught to know. Still, I don't think its an excuse for being difficult to work with or immediately understand.
Replace all strings like $1F," <",$9F,"B",$1F,"> ",$2D," with a single routine that prints $1F," <",$9F,{customcharacter},$1F,"> ",$2D. This will save a lot of bytes in a lot of strings. This could be done with a template string that gets modified, e.g.:Yes, this is potentially a good idea except that I print all of the strings in one call rather than setting each of them up and printing them independently. Bulk printing saves quite a bit of code. Anyway, the pros and cons can be analysed after the string compression is done. Perhaps it will still be better to store them once and modify and call to print multiple times. I'm not entirely sure off the top of my head. The BASIC print PChar routine does not preserve the registers as far as I'm aware. You'd need to preserve the pointer before you call or load it again afterwards. I think you are probably right on this one, however.
HelloWelcome home! You said you'd been on a flight back. I hope the trip was a pleasant one.No problem. Compression can only help so much, it is generally better to remove the redundancy first if you can, because the compression scheme will almost invariable be less intelligent than the programmer. Substitution of words with shorter or lower scrabble scoring synonyms is a good place to start, thus my suggestions in the previous email.I just can't do certain things. The program has to present itself in an appropriate way and inform the user, as completely as possible, of what it is they are expected to do.Regarding the speed of printing strings if using the chained NULL terminated compressed string scheme I propose, I think you will find that the CPU time for the messages is insignificant. My decompression routine takes only a few rasters on a C64 to decode ~20 bytes. Multiply that by the ~40 messages you have, and it is still of the order of 1 message per frame, and that assumes that you don't put the most commonly used messages first, and errors that terminate last.One per frame?? But I'm having to print some 10 - 12 lines (or more) per screen. The BASIC print PChar routine is also slow. I'm sure that this will result in times of more than half a second to display a screen. Possibly even three quarters of a second. That will definitely make the program seem sluggish.*sigh* It doesn't matter I suppose. I should see the validity of the recommendation.
I need a nap now, but will try to generate a decompression routine that can lookup strings in this way when I get the chance. I'll also test the performance of my existing compressor on your string table to see if it still yields ~30%.Okay, I'd love to see your results.
Finally, don't be worried about imperfection in your code, and don't worry about apologising for it. Just present what you can, and let the community work with you to improve it. Similarly, don't unnecessarily delay release under an open-source license: they are designed to allow fast collaboration on imperfect code!Hmm... Yes, I'm probably too used to working in a more commercial environment and think of the community too much as a client. I'm thinking of the final product as being undelivered until properly accepted and that the final product is then open-source. I guess I needn't have attached copyright to the code from the start but I think that really, even if you don't, in some way it is owned by the original author and if they haven't specifically released it as public domain then it is proprietary. I didn't want the coding to be left dangling with no ownership, no one know to have cared for it. I do say that it is, for all intents and purposes, LGPL... I hate having to put all of the legal-eese at the start of each file. *Meh*
Umm.. Maybe what I should be doing is working with the code in a public hosting with LGPL license right from the start. Would you like these sort of programs to be stored with your C65GS project or should I create a new one?
Paul,Further to this, you actually can only save 2 bytes because technically, since you are using ADC, you need to save the processor status, clear the decimal mode and restore the status before exit.
; Convert a hex digit ($00-$0F) to ASCII ('0'-'9' or 'A'-'F')
HEX2ASC SED ;Enter BCD mode
CLC ;Ensure the carry is clear
ADC #$90 ;Produce $90-$99 (C=0) or $00-$05 (C=1)
ADC #$40 ;Produce $30-$39 or $41-$46
CLD ;Leave BCD modeUmm... The "non technical" language is foreign to me. I prefer the way "approximately" sounds to "about". It presents a more authoritative personality on behalf of the program."About" is a synonym for "approximately", the main difference is that more people understand "about" than "approximately", and is often true in such cases, the more understandable word is also shorter.My experience as an academic has taught me that people often think that technical language should use as many long words as possible, because it sounds "more important" or some variation on that. The opposite is true, because technical matter should be as clear as possible, and as hard as possible to mis-understand.If your text needs big words to sound authoritative, then it is possible you are relying on appearances rather than substance.The reason we still see long and often vague words and phrases in academic literature is that people learn this bad habit as students by reading the text full of long and vague words produced by the previous generation of academics.
Consider removing "BLANK " above to save a further 6 bytes.You can't really because technically, the disks have to be blank (except for the sole condition they were used for DMode test data before). I guess I could change the code to do a quick format on them instead but I didn't want to do that for saving execution time (quick format is still slow).I have no real objection to this, although to me, it is implied that the disks must be empty. What is the probability that someone will put a full disk in instead of an empty one? If you feel it is substantially above zero, then by all means "BLANK" should be retained.
Change "QUITE SOME TIME" to "A LONG TIME" to save 4 bytes.Sorry, to my mind, "a long time" does not say "a very, very, so very, long time". I'm in the habit of being as informative as I can with messages I present to the user. "Quite some time" is a more accurate, although still "polite" way of saying, "you'll be here all day and probably most of tomorrow, too".The choice is yours. If you know what order of magnitude it takes, you could change it to "HOURS", which is even shorter. It really depends how much space you need to save.
Consider merging "LEVEL SELECT: " and "TYPE SELECT: " into a single "SELECT: " or "PICK: " to save 19 or 21 bytes.Again, I'm just in the habit of providing as much information as I can. The "Level select" and "Type select" tell you what options you are configuring with your selection. I don't think this should be changed in order to allow the user to understand what it is they are doing.Again, up to you, but my feeling is that the extra information is redundant, because it is clear what the options are in each case. If you feel that people could make a mistake if offered only "SELECT:", then the extra word is justified.
You could add an escape code to the printing routine that prints the option prefix part, without having to split the strings up.
Anyway, these are all just suggestions to save memory should you need it.
Again it comes down to a time/space trade-off. If you can avoid the trade-off, do so. But also, to assess the trade-off you need to know the actual cost. My calculation is likely to be pessimistic. I think that you would find the performance to be quite fine. But without testing, we won't know.
The code is on my wife's computer, which she is using to watch Dr.Who right now, so I can't get to it at present. I can easily re-implement it, however, at least to the point of providing the compression performance data.
This is what I would recommend. Get yourself a github.com account, create a repository and put your code there. Get used to using git (there are lots of tutorials), as it will pay dividends in the long term.
There is an even more efficient way to do it using decimal mode:But it boils down to:; Convert a hex digit ($00-$0F) to ASCII ('0'-'9' or 'A'-'F') HEX2ASC SED ;Enter BCD mode CLC ;Ensure the carry is clear ADC #$90 ;Produce $90-$99 (C=0) or $00-$05 (C=1) ADC #$40 ;Produce $30-$39 or $41-$46 CLD ;Leave BCD modeIf you want to PHP/PLP you can, but I would suggest that you should explicitly control the D flag in your tests so that it can be avoided. In any case, you just need the PHP and PLP once in the surrounding routine, so the 2 bytes are amortised over the two calls, giving an effective cost of just 1 extra byte.So in total we need 8 bytes for the HEX2ASC routine, plus 2 bytes to save/restore processor flags, so 10 in total, saving 6 bytes in total.
Paul,Umm... The "non technical" language is foreign to me. I prefer the way "approximately" sounds to "about". It presents a more authoritative personality on behalf of the program."About" is a synonym for "approximately", the main difference is that more people understand "about" than "approximately", and is often true in such cases, the more understandable word is also shorter.My experience as an academic has taught me that people often think that technical language should use as many long words as possible, because it sounds "more important" or some variation on that. The opposite is true, because technical matter should be as clear as possible, and as hard as possible to mis-understand.If your text needs big words to sound authoritative, then it is possible you are relying on appearances rather than substance.The reason we still see long and often vague words and phrases in academic literature is that people learn this bad habit as students by reading the text full of long and vague words produced by the previous generation of academics.I should upsub your goodthink and make use your newspeak to doubleplusgood my speakwrite.*rofl*
I think there are layers of meaning which could be appropriate in setting a mood or context.Consider removing "BLANK " above to save a further 6 bytes.You can't really because technically, the disks have to be blank (except for the sole condition they were used for DMode test data before). I guess I could change the code to do a quick format on them instead but I didn't want to do that for saving execution time (quick format is still slow).I have no real objection to this, although to me, it is implied that the disks must be empty. What is the probability that someone will put a full disk in instead of an empty one? If you feel it is substantially above zero, then by all means "BLANK" should be retained.I want to make sure the user appreciates what is happening.Change "QUITE SOME TIME" to "A LONG TIME" to save 4 bytes.Sorry, to my mind, "a long time" does not say "a very, very, so very, long time". I'm in the habit of being as informative as I can with messages I present to the user. "Quite some time" is a more accurate, although still "polite" way of saying, "you'll be here all day and probably most of tomorrow, too".The choice is yours. If you know what order of magnitude it takes, you could change it to "HOURS", which is even shorter. It really depends how much space you need to save.Actually, yes. You are correct here. I wasn't sure when I wrote it just _how_ long it would be other than it would be _much_ more than "very". I think it probably would be better to revise this for accuracy since more information is now available. "Quite some time" should be "about 10 hours" but that only saves 1 character.Consider merging "LEVEL SELECT: " and "TYPE SELECT: " into a single "SELECT: " or "PICK: " to save 19 or 21 bytes.Again, I'm just in the habit of providing as much information as I can. The "Level select" and "Type select" tell you what options you are configuring with your selection. I don't think this should be changed in order to allow the user to understand what it is they are doing.Again, up to you, but my feeling is that the extra information is redundant, because it is clear what the options are in each case. If you feel that people could make a mistake if offered only "SELECT:", then the extra word is justified.I think they are necessary here to put the options in context of some meaning which they wouldn't have otherwise.You could add an escape code to the printing routine that prints the option prefix part, without having to split the strings up.Yes, there are standard option selections are in the core so I think I will make some standard routine to print a menu, given strings for labelling the options.Anyway, these are all just suggestions to save memory should you need it.I appreciate all of the input!Daniel.
--
--