Hola, > > Can anyone tell me why the REM <SHIFT+L> trick works. I'm sure you know Yup! > > The only investigation I've done is to look at the REM routine at 43323, > > but I saw nothing in the following opcodes that represents a shifted L. As others have said, it is LIST -- specifically QPLOP, which prints tokens -- which causes the problem, albeit indirectly. Ethan wrote: > Back in the PET days, we used to poke odd tokens into REM statements to keep > our BASIC programs unlistable. I think what you will find if you dump hex > for your line 20, is that the token following the REM token is out of bounds > and the lookup routine in LIST errors out when asked to translate that token > back into a printable word. IIRC, we used to poke a 204 into a REM to screw > things up on a PET with BASIC 2.0 ROMs. The table is larger for BASIC 4.0, > so it was a different value there. Shift-L is character code $CC -- 204 decimal, as Ethan says above. In BASIC, tokens are indicated by having the high bit set. The highest token is "go" (so that "go to" works), which has token value $CB. Although you might be thinking "ah, larger than the largest token", note that shift-M shift-N etc. list just fine; the problem only occurs with shift-L, and the reason is quite interesting. Keywords are printed by searching forwards through the keyword table: :LOOP1 DEX ;Traverse the keyword table BEQ :PLOOP :LOOP2 INY ;read a keyword LDA RESLST,Y BPL :LOOP2 BMI :LOOP1 :PLOOP INY ;Print out the keyword LDA RESLST,Y BMI LISTENT1 ;Exit if on last char JSR HAB47 ;Print char, AND #$FF BNE :PLOOP The last char of each keyword has the high bit set; the above code just counts .X characters that have the high bit set. Note that absolute addressing is used, though, so that the size of the text in RESLST can't be larger than 256 bytes total. It turns out that there are 255 text bytes in the table -- token $CC begins at RESLST+255, the last byte of the table, which has a value of zero. So what happens is that $AB47, which prints the character in .A, is called with .A=0. AB47 is part of the PRINT command used with the CMD command. And what _it_ does is call $E10C, which calls $FFD2 and branches to an error if the carry is set. But send a zero to $FFD2 and he sets the carry flag on exit, causing $E10C to branch to the error routine. So it's all because the first character of "token" $CB is CHR$(0), which causes an error in the print routine. Why doesn't a line like 10 PRINT shift-L work? Because the tokenizer discards all bytes larger than 127, except for REM. You can also see why shift-M, shift-N etc. work -- in the QPLOP code, .Y just wraps back around to zero, and those higher "tokens" just correspond to tokens $81, $82, etc. ($80 gets skipped -- it would be token $CB if it weren't for the zero). The one thing I'm not sure of is why the check for carry set is made in $E10C -- I'll try to look it up when I get home. -Steve - This message was sent through the cbm-hackers mailing list. To unsubscribe: echo unsubscribe | mail cbm-hackers-request@dot.tcm.hut.fi.
Archive generated by hypermail 2.1.1.