6502_EhBASIC_V2.22/bugsnquirks.txt
2017-01-05 11:11:26 +01:00

131 lines
5.4 KiB
Plaintext

EhBASIC 2.22 has a view bugs and quirks that you should know about.
1. The interrupt system is severely broken.
When an IRQ occurs and IRQ_vec is called in min_mon.asm the interrupt is only
registered with IRQbase but the interrupt source is not serviced nor is the
interrupt disable bit set at RTI. As a consequence the interrupt is immediately
called again and again and IRQbase is trashed until the interrupt is serviced
by the ON IRQ handler in basic.
The problem is discussed in http://forum.6502.org/viewtopic.php?f=5&t=2411
How I solved the problem for my emulator:
https://github.com/Klaus2m5/AVR_emulated_6502_4SBC/tree/master/EhBASIC
However, you should keep in mind that the interrupt service capacity in EhBASIC
is very limited. In a 2MHz system more than 100 interrupts per second or
interrupts requiring less than 10ms service time should be handled in machine
language. The numbers are worse if the interrupt handler gets more complex.
2. String handling when the string is in the input buffer.
When a string is entered via the input buffer (Ibuffs - Ibuffe) in Ehbasic it
is transient because it gets overwritten by the next input. In this case it
needs to be copied to the string area. In all other cases the string remains in
place and only a pointer needs to be set to the string location.
There is a bug in EhBASIC to determine where the string is.
LAB_20DC
STX Sendh ; save string end high byte
LDA ssptr_h ; get string start high byte
CMP #>Ram_base ; compare with start of program memory
BCS LAB_RTST ; branch if not in utility area
This does not work, if RAM_base is below the input buffer or EhBASIC itself is
below RAM_base. The fix requires the input buffer not to cross a page boundary:
LAB_20DC
STX Sendh ; save string end high byte
LDA ssptr_h ; get string start high byte
; *** begin RAM above code / Ibuff above EhBASIC patch ***
; *** replace
; CMP #>Ram_base ; compare with start of program memory
; BCS LAB_RTST ; branch if not in utility area
; *** with
CMP #>Ibuffs ; compare with location of input buffer page
BNE LAB_RTST ; branch if not in utility area
; *** end RAM above code / Ibuff above EhBASIC patch ***
3. Output of some functions limited to integers is negative.
This is not a bug but documented behavior.
Affected functions FRE(), SADD(), VARPTR(), DEEK()
If you want to use FRE() with large RAM you must write:
? FRE(0)-(FRE(0)<0)*$10000
If you really want to deviate from the beaten path, you can add a routine to
convert unsigned integers and jump to it from the functions that you want to
respond with an unsigned number. It replaces LAB_AYFC for these functions.
; save and convert unsigned integer AY to FAC1
LAB_UAYFC
LSR Dtypef ; clear data type flag, $FF=string, $00=numeric
STA FAC1_1 ; save FAC1 mantissa1
STY FAC1_2 ; save FAC1 mantissa2
LDX #$90 ; set exponent=2^16 (integer)
SEC ; always positive
JMP LAB_STFA ; set exp=X, clear FAC1_3, normalise and return
You cannot apply this routine to operators which also use LAB_AYFC (=, OR, AND
EOR <<, >>) as they require signed integers. The value -1 is asigned to a
comparison evaluating as TRUE. Therefore logical operators must be able to
evaluate -1 correctly.
4. Use of decimal mode and invalid BCD
There is only one place in EhBASIC where decimal mode is used. HEX$() uses
invalid BCD to convert a number to a hexadecimal string. Some processors do not
support decimal mode and emulators most of the time will not support invalid
BCD (nibbles in the range of $A - $F).
LAB_AL2X
CMP #$0A ; set carry for +1 if >9
ADC #'0' ; add ASCII "0"
STA (str_pl),Y ; save to temp string
DEY ; decrement counter
RTS
A patch is available to disable use of decimal mode in EhBASIC.
LAB_AL2X
CMP #$0A ; set carry for +1 if >9
; *** begin disable decimal mode patch ***
; *** insert
BCC LAB_AL20 ; skip adjust if <= 9
ADC #$06 ; adjust for A to F
LAB_AL20
; *** end disable decimal mode patch ***
ADC #'0' ; add ASCII "0"
STA (str_pl),Y ; save to temp string
DEY ; decrement counter
RTS
At the same time you must disable SED & CLD at the HEX$() function.
LAB_HEXS
CPX #$07 ; max + 1
BCS BinFErr ; exit if too big ( > or = )
STX TempB ; save # of characters
LDA #$06 ; need 6 bytes for string
JSR LAB_MSSP ; make string space A bytes long
LDY #$05 ; set string index
; *** disable decimal mode patch - comment next line ***
; SED ; need decimal mode for nibble convert
LDA nums_3 ; get lowest byte
JSR LAB_A2HX ; convert A to ASCII hex byte and output
LDA nums_2 ; get middle byte
JSR LAB_A2HX ; convert A to ASCII hex byte and output
LDA nums_1 ; get highest byte
JSR LAB_A2HX ; convert A to ASCII hex byte and output
; *** disable decimal mode patch - comment next line ***
; CLD ; back to binary