📄 basic.asm
字号:
BCS LAB_12D0 ; branch if overflow
INX ; increment block count (correct for =0 loop exit)
DEC ut2_ph ; decrement destination high byte
LAB_12D0
CLC ; clear carry for add
ADC ut1_pl ; add source pointer low byte
BCC LAB_12D8 ; branch if no overflow
DEC ut1_ph ; else decrement source pointer high byte
CLC ; clear carry
; close up memory to delete old line
LAB_12D8
LDA (ut1_pl),Y ; get byte from source
STA (ut2_pl),Y ; copy to destination
INY ; increment index
BNE LAB_12D8 ; while <> 0 do this block
INC ut1_ph ; increment source pointer high byte
INC ut2_ph ; increment destination pointer high byte
DEX ; decrement block count
BNE LAB_12D8 ; loop until all done
; got new line in buffer and no existing same #
LAB_12E6
LDA Ibuffs ; get byte from start if input buffer
BEQ LAB_1319 ; if null line just go flush stack/vars & exit
; got new line and it isn't empty line
LDA Ememl ; get end of mem low byte
LDY Ememh ; get end of mem high byte
STA Sstorl ; set bottom of string space low byte
STY Sstorh ; set bottom of string space high byte
LDA Svarl ; get start of vars low byte (end of BASIC)
STA Obendl ; save old block end low byte
LDY Svarh ; get start of vars high byte (end of BASIC)
STY Obendh ; save old block end high byte
ADC Ibptr ; add input buffer pointer (also buffer length)
BCC LAB_1301 ; branch if no overflow from add
INY ; else increment high byte
LAB_1301
STA Nbendl ; save new block end low byte (move to, low byte)
STY Nbendh ; save new block end high byte
JSR LAB_11CF ; open up space in memory
; old start pointer Ostrtl,Ostrth set by the find line call
LDA Earryl ; get array mem end low byte
LDY Earryh ; get array mem end high byte
STA Svarl ; save start of vars low byte
STY Svarh ; save start of vars high byte
LDY Ibptr ; get input buffer pointer (also buffer length)
DEY ; adjust for loop type
LAB_1311
LDA Ibuffs-4,Y ; get byte from crunched line
STA (Baslnl),Y ; save it to program memory
DEY ; decrement count
CPY #$03 ; compare with first byte-1
BNE LAB_1311 ; continue while count <> 3
LDA Itemph ; get line # high byte
STA (Baslnl),Y ; save it to program memory
DEY ; decrement count
LDA Itempl ; get line # low byte
STA (Baslnl),Y ; save it to program memory
DEY ; decrement count
LDA #$FF ; set byte to allow chain rebuild. if you didn't set this
; byte then a zero already here would stop the chain rebuild
; as it would think it was the [EOT] marker.
STA (Baslnl),Y ; save it to program memory
LAB_1319
JSR LAB_1477 ; reset execution to start, clear vars & flush stack
LDX Smeml ; get start of mem low byte
LDA Smemh ; get start of mem high byte
LDY #$01 ; index to high byte of next line pointer
LAB_1325
STX ut1_pl ; set line start pointer low byte
STA ut1_ph ; set line start pointer high byte
LDA (ut1_pl),Y ; get it
BEQ LAB_133E ; exit if end of program
; rebuild chaining of Basic lines
LDY #$04 ; point to first code byte of line
; there is always 1 byte + [EOL] as null entries are deleted
LAB_1330
INY ; next code byte
LDA (ut1_pl),Y ; get byte
BNE LAB_1330 ; loop if not [EOL]
SEC ; set carry for add + 1
TYA ; copy end index
ADC ut1_pl ; add to line start pointer low byte
TAX ; copy to X
LDY #$00 ; clear index, point to this line's next line pointer
STA (ut1_pl),Y ; set next line pointer low byte
TYA ; clear A
ADC ut1_ph ; add line start pointer high byte + carry
INY ; increment index to high byte
STA (ut1_pl),Y ; save next line pointer low byte
BCC LAB_1325 ; go do next line, branch always, carry clear
LAB_133E
JMP LAB_127D ; else we just wait for Basic command, no "Ready"
; print "? " and get BASIC input
LAB_INLN
JSR LAB_18E3 ; print "?" character
JSR LAB_18E0 ; print " "
BNE LAB_1357 ; call for BASIC input & return
; receive line from keyboard
; $08 as delete key (BACKSPACE on standard keyboard)
LAB_134B
JSR LAB_PRNA ; go print the character
DEX ; decrement the buffer counter (delete)
.byte $2C ; make LDX into BIT abs
; call for BASIC input (main entry point)
LAB_1357
LDX #$00 ; clear BASIC line buffer pointer
LAB_1359
JSR V_INPT ; call scan input device
BCC LAB_1359 ; loop if no byte
BEQ LAB_1359 ; loop until valid input (ignore NULLs)
CMP #$07 ; compare with [BELL]
BEQ LAB_1378 ; branch if [BELL]
CMP #$0D ; compare with [CR]
BEQ LAB_1384 ; do CR/LF exit if [CR]
CPX #$00 ; compare pointer with $00
BNE LAB_1374 ; branch if not empty
; next two lines ignore any non print character & [SPACE] if input buffer empty
CMP #$21 ; compare with [SP]+1
BCC LAB_1359 ; if < ignore character
LAB_1374
CMP #$08 ; compare with [BACKSPACE] (delete last character)
BEQ LAB_134B ; go delete last character
LAB_1378
CPX #Ibuffe-Ibuffs ; compare character count with max
BCS LAB_138E ; skip store & do [BELL] if buffer full
STA Ibuffs,X ; else store in buffer
INX ; increment pointer
LAB_137F
JSR LAB_PRNA ; go print the character
BNE LAB_1359 ; always loop for next character
LAB_1384
JMP LAB_1866 ; do CR/LF exit to BASIC
; announce buffer full
LAB_138E
LDA #$07 ; [BELL] character into A
BNE LAB_137F ; go print the [BELL] but ignore input character
; branch always
; crunch keywords into Basic tokens
; position independent buffer version ....
; faster, dictionary search version ....
LAB_13A6
LDY #$FF ; set save index (makes for easy math later)
SEC ; set carry for subtract
LDA Bpntrl ; get basic execute pointer low byte
SBC #<Ibuffs ; subtract input buffer start pointer
TAX ; copy result to X (index past line # if any)
STX Oquote ; clear open quote/DATA flag
LAB_13AC
LDA Ibuffs,X ; get byte from input buffer
BEQ LAB_13EC ; if null save byte then exit
CMP #'_' ; compare with "_"
BCS LAB_13EC ; if >= go save byte then continue crunching
CMP #'<' ; compare with "<"
BCS LAB_13CC ; if >= go crunch now
CMP #'0' ; compare with "0"
BCS LAB_13EC ; if >= go save byte then continue crunching
STA Scnquo ; save buffer byte as search character
CMP #$22 ; is it quote character?
BEQ LAB_1410 ; branch if so (copy quoted string)
CMP #'*' ; compare with "*"
BCC LAB_13EC ; if < go save byte then continue crunching
; else crunch now
LAB_13CC
BIT Oquote ; get open quote/DATA token flag
BVS LAB_13EC ; branch if b6 of Oquote set (was DATA)
; go save byte then continue crunching
STX TempB ; save buffer read index
STY csidx ; copy buffer save index
LDY #<TAB_1STC ; get keyword first character table low address
STY ut2_pl ; save pointer low byte
LDY #>TAB_1STC ; get keyword first character table high address
STY ut2_ph ; save pointer high byte
LDY #$00 ; clear table pointer
LAB_13D0
CMP (ut2_pl),Y ; compare with keyword first character table byte
BEQ LAB_13D1 ; go do word_table_chr if match
BCC LAB_13EA ; if < keyword first character table byte go restore
; Y and save to crunched
INY ; else increment pointer
BNE LAB_13D0 ; and loop (branch always)
; have matched first character of some keyword
LAB_13D1
TYA ; copy matching index
ASL ; *2 (bytes per pointer)
TAX ; copy to new index
LDA TAB_CHRT,X ; get keyword table pointer low byte
STA ut2_pl ; save pointer low byte
LDA TAB_CHRT+1,X ; get keyword table pointer high byte
STA ut2_ph ; save pointer high byte
LDY #$FF ; clear table pointer (make -1 for start)
LDX TempB ; restore buffer read index
LAB_13D6
INY ; next table byte
LDA (ut2_pl),Y ; get byte from table
LAB_13D8
BMI LAB_13EA ; all bytes matched so go save token
INX ; next buffer byte
CMP Ibuffs,X ; compare with byte from input buffer
BEQ LAB_13D6 ; go compare next if match
BNE LAB_1417 ; branch if >< (not found keyword)
LAB_13EA
LDY csidx ; restore save index
; save crunched to output
LAB_13EC
INX ; increment buffer index (to next input byte)
INY ; increment save index (to next output byte)
STA Ibuffs,Y ; save byte to output
CMP #$00 ; set the flags, set carry
BEQ LAB_142A ; do exit if was null [EOL]
; A holds token or byte here
SBC #$3A ; subtract ":" (carry set by CMP #00)
BEQ LAB_13FF ; branch if it was ":" (is now $00)
; A now holds token-$3A
CMP #TK_DATA-$3A ; compare with DATA token - $3A
BNE LAB_1401 ; branch if not DATA
; token was : or DATA
LAB_13FF
STA Oquote ; save token-$3A (clear for ":", TK_DATA-$3A for DATA)
LAB_1401
EOR #TK_REM-$3A ; effectively subtract REM token offset
BNE LAB_13AC ; If wasn't REM then go crunch rest of line
STA Asrch ; else was REM so set search for [EOL]
; loop for REM, "..." etc.
LAB_1408
LDA Ibuffs,X ; get byte from input buffer
BEQ LAB_13EC ; branch if null [EOL]
CMP Asrch ; compare with stored character
BEQ LAB_13EC ; branch if match (end quote)
; entry for copy string in quotes, don't crunch
LAB_1410
INY ; increment buffer save index
STA Ibuffs,Y ; save byte to output
INX ; increment buffer read index
BNE LAB_1408 ; loop while <> 0 (should never be 0!)
; not found keyword this go
LAB_1417
LDX TempB ; compare has failed, restore buffer index (start byte!)
; now find the end of this word in the table
LAB_141B
LDA (ut2_pl),Y ; get table byte
PHP ; save status
INY ; increment table index
PLP ; restore byte status
BPL LAB_141B ; if not end of keyword go do next
LDA (ut2_pl),Y ; get byte from keyword table
BNE LAB_13D8 ; go test next word if not zero byte (end of table)
; reached end of table with no match
LDA Ibuffs,X ; restore byte from input buffer
BPL LAB_13EA ; branch always (all bytes in buffer are $00-$7F)
; go save byte in output and continue crunching
; reached [EOL]
LAB_142A
INY ; increment pointer
INY ; increment pointer (makes it next line pointer high byte)
STA Ibuffs,Y ; save [EOL] (marks [EOT] in immediate mode)
INY ; adjust for line copy
INY ; adjust for line copy
INY ; adjust for line copy
DEC Bpntrl ; allow for increment (change if buffer starts at $xxFF)
RTS ;
; search Basic for temp integer line number from start of mem
LAB_SSLN
LDA Smeml ; get start of mem low byte
LDX Smemh ; get start of mem high byte
; search Basic for temp integer line number from AX
; returns carry set if found
; returns Baslnl/Baslnh pointer to found or next higher (not found) line
; old 541 new 507
LAB_SHLN
LDY #$01 ; set index
STA Baslnl ; save low byte as current
STX Baslnh ; save high byte as current
LDA (Baslnl),Y ; get pointer high byte from addr
BEQ LAB_145F ; pointer was zero so we're done, do 'not found' exit
LDY #$03 ; set index to line # high byte
LDA (Baslnl),Y ; get line # high byte
DEY ; decrement index (point to low byte)
CMP Itemph ; compare with temporary integer high byte
BNE LAB_1455 ; if <> skip low byte check
LDA (Baslnl),Y ; get line # low byte
CMP Itempl ; compare with temporary integer low byte
LAB_1455
BCS LAB_145E ; else if temp < this line, exit (passed line#)
LAB_1456
DEY ; decrement index to next line ptr high byte
LDA (Baslnl),Y ; get next line pointer high byte
TAX ; copy to X
DEY ; decrement index to next line ptr low byte
LDA (Baslnl),Y ; get next line pointer low byte
BCC LAB_SHLN ; go search for line # in temp (Itempl/Itemph) from AX
; (carry always clear)
LAB_145E
BEQ LAB_1460 ; exit if temp = found line #, carry is set
LAB_145F
CLC ; clear found flag
LAB_1460
RTS ;
; perform NEW
LAB_NEW
BNE LAB_1460 ; exit if not end of statement (to do syntax error)
LAB_1463
LDA #$00 ; clear A
TAY ; clear Y
STA (Smeml),Y ; clear first line, next line pointer, low byte
INY ; increment index
STA (Smeml),Y ; clear first line, next line pointer, high byte
CLC ; clear carry
LDA Smeml ; get start of mem low byte
ADC #$02 ; calculate end of BASIC low byte
STA Svarl ; save start of vars low byte
LDA Smemh ; get start of mem high byte
ADC #$00 ; add any carry
STA Svarh ; save start of vars high byte
; reset execution to start, clear vars & flush stack
LAB_1477
CLC ; clear carry
LDA Smeml ; get start of mem low byte
ADC #$FF ; -1
STA Bpntrl ; save BASIC execute pointer low byte
LDA Smemh ; get start of mem high byte
ADC #$FF ; -1+carry
STA Bpntrh ; save BASIC execute pointer high byte
; "CLEAR" command gets here
LAB_147A
LDA Ememl ; get end of mem low byte
LDY Ememh ; get end of mem high byte
STA Sstorl ; set bottom of string space low byte
STY Sstorh ; set bottom of string space high byte
LDA Svarl ; get start of vars low byte
LDY Svarh ; get start of vars high byte
STA Sarryl ; save var mem end low byte
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -