mirror of
https://github.com/Klaus2m5/6502_EhBASIC_V2.22.git
synced 2024-06-02 09:41:28 +00:00
131 lines
5.4 KiB
Plaintext
131 lines
5.4 KiB
Plaintext
EhBASIC 2.22 has a few 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
|