Classic Computer Magazine Archive COMPUTE! ISSUE 17 / OCTOBER 1981 / PAGE 132

Odds And Ends:

A Fat Forty Bug

Gordon Campbell,

Some machine language programs which work just fine in PETs with BASIC 4.0 and 9-inch screens will yield odd results on the new 12-inch, 40-column machines. Occasionally, it will appear as if the program has responded inaccurately to the key which was pressed.

This is due to a very subtle difference in the ROM. If the machine language program happens to be in decimal mode when an interrupt occurs, the keyboard decode is completely inaccurate. Even if a key is still pressed from a previous character, it will be decoded as a different character, so, instead of getting one character, you get three (the original correct one, one that is wrong, and probably the original one again).

The problem is well illustrated by the program listing attached. If you assemble the program as shown, then from the monitor type: G 0800 you can type on the keyboard and see what character the PET thought was pressed. By the way, to get out of the program, press the RVS key. Now change the SED (set decimal mode) to a NOP. The program gives accurate keyboard decode. Now the STOP key will get you out.

The way to get around this bug, if you must use decimal mode, is to precede the routine with an SEI (disable interrupts) instruction, and follow it with a CLI (enable interrupts).

               0010              .BA $0800
               0020              .OS
               0030 ; TEST KEYBOARD DECODE
               0040 ; WITH DECIMAL MODE SET!
               0050 GET          .DE $FFE4
               0060 PRINT        .DE $FFD2
               0070 ;
0800- F8       0080 STRT         SED
               0090 ;
0801- CA       0100 DLLOOP       DEX
0802- DO FD    0110              BNE DLLOOP
0804- 88       0120              DEY
0805- DO FA    0130              BNE DLLOOP
               0140 ;
0807- D8       0150              CLD
0808- 20 E4 FF 0160              JSR GET
080B- C9 00    0170              CMP #0
080D- F0 Fl    0180              BEQ STRT
080F- C9 03    0190              CMP #3
0811- F0 06    0200              BEQ STOP
0813- 20 D2 FF 0210              JSR PRINT
0816- 4C 00 08 0220              JMP STRT
0819- 00       0230 STOP         BRK
               0240              .EN
/GET = FFE4   /PRINT = FFD2  STRT = 0800
DLLOOP = 0801 STOP = 0819
//0000, 081A, 081A