⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basic.asm

📁 6502 enhanced basic 的示範程式, 但是和applesoft又不一樣,給各位參考參考
💻 ASM
📖 第 1 页 / 共 5 页
字号:
ccflag		= $0200	; BASIC CTRL-C flag, 00 = enabled, 01 = dis
ccbyte		= ccflag+1	; BASIC CTRL-C byte
ccnull		= ccbyte+1	; BASIC CTRL-C byte timeout

VEC_CC		= ccnull+1	; ctrl c check vector

VEC_IN		= VEC_CC+2	; input vector
VEC_OUT		= VEC_IN+2	; output vector
VEC_LD		= VEC_OUT+2	; load vector
VEC_SV		= VEC_LD+2	; save vector

; Ibuffs can now be anywhere in RAM, ensure that the max length is < $80

Ibuffs		= VEC_SV+$16
					; start of input buffer after IRQ/NMI code
Ibuffe		= Ibuffs+$47; end of input buffer

Ram_base		= $0300	; start of user RAM (set as needed, should be page aligned)
Ram_top		= $C000	; end of user RAM+1 (set as needed, should be page aligned)

; This start can be changed to suit your system

	*=	$C000

; BASIC cold start entry point

LAB_COLD

; new page 2 initialisation, copy block to ccflag on

	LDY	#PG2_TABE-PG2_TABS-1	; byte count-1
LAB_2D13
	LDA	PG2_TABS,Y		; get byte
	STA	ccflag,Y		; store in page 2
	DEY				; decrement count
	BPL	LAB_2D13		; loop if not done

	LDX	#$FF			; set byte
	STX	Clineh		; set current line high byte (set immediate mode)
	TXS				; reset stack pointer

	LDA	#$4C			; code for JMP
	STA	Fnxjmp		; save for jump vector for functions

; copy block from LAB_2CEE to $00BC - $00D3

	LDX	#StrTab-LAB_2CEE	; set byte count
LAB_2D4E
	LDA	LAB_2CEE-1,X	; get byte from table
	STA	LAB_IGBY-1,X	; save byte in page zero
	DEX				; decrement count
	BNE	LAB_2D4E		; loop if not all done

; copy block from StrTab to $0000 - $0012

LAB_GMEM
	LDX	#EndTab-StrTab-1	; set byte count-1
TabLoop
	LDA	StrTab,X		; get byte from table
	STA	PLUS_0,X		; save byte in page zero
	DEX				; decrement count
	BPL	TabLoop		; loop if not all done

; set-up start values

	LDA	#$00			; clear A
	STA	NmiBase		; clear NMI handler enabled flag
	STA	IrqBase		; clear IRQ handler enabled flag
	STA	FAC1_o		; clear FAC1 overflow byte
	STA	last_sh		; clear descriptor stack top item pointer high byte

	LDA	#$0E			; set default tab size
	STA	TabSiz		; save it
	LDA	#$03			; set garbage collect step size for descriptor stack
	STA	g_step		; save it
	LDX	#des_sk		; descriptor stack start
	STX	next_s		; set descriptor stack pointer
	JSR	LAB_CRLF		; print CR/LF
	LDA	#<LAB_MSZM		; point to memory size message (low addr)
	LDY	#>LAB_MSZM		; point to memory size message (high addr)
	JSR	LAB_18C3		; print null terminated string from memory
	JSR	LAB_INLN		; print "? " and get BASIC input
	STX	Bpntrl		; set BASIC execute pointer low byte
	STY	Bpntrh		; set BASIC execute pointer high byte
	JSR	LAB_GBYT		; get last byte back

	BNE	LAB_2DAA		; branch if not null (user typed something)

	LDY	#$00			; else clear Y
					; character was null so get memory size the hard way
					; we get here with Y=0 and Itempl/h = Ram_base
LAB_2D93
	INC	Itempl		; increment temporary integer low byte
	BNE	LAB_2D99		; branch if no overflow

	INC	Itemph		; increment temporary integer high byte
	LDA	Itemph		; get high byte
	CMP	#>Ram_top		; compare with top of RAM+1
	BEQ	LAB_2DB6		; branch if match (end of user RAM)

LAB_2D99
	LDA	#$55			; set test byte
	STA	(Itempl),Y		; save via temporary integer
	CMP	(Itempl),Y		; compare via temporary integer
	BNE	LAB_2DB6		; branch if fail

	ASL				; shift test byte left (now $AA)
	STA	(Itempl),Y		; save via temporary integer
	CMP	(Itempl),Y		; compare via temporary integer
	BEQ	LAB_2D93		; if ok go do next byte

	BNE	LAB_2DB6		; branch if fail

LAB_2DAA
	JSR	LAB_2887		; get FAC1 from string
	LDA	FAC1_e		; get FAC1 exponent
	CMP	#$98			; compare with exponent = 2^24
	BCS	LAB_GMEM		; if too large go try again

	JSR	LAB_F2FU		; save integer part of FAC1 in temporary integer
					; (no range check)

LAB_2DB6
	LDA	Itempl		; get temporary integer low byte
	LDY	Itemph		; get temporary integer high byte
	CPY	#<Ram_base+1	; compare with start of RAM+$100 high byte
	BCC	LAB_GMEM		; if too small go try again


; uncomment these lines if you want to check on the high limit of memory. Note if
; Ram_top is set too low then this will fail. default is ignore it and assume the
; users know what they're doing!

;	CPY	#>Ram_top		; compare with top of RAM high byte
;	BCC	MEM_OK		; branch if < RAM top

;	BNE	LAB_GMEM		; if too large go try again
					; else was = so compare low bytes
;	CMP	#<Ram_top		; compare with top of RAM low byte
;	BEQ	MEM_OK		; branch if = RAM top

;	BCS	LAB_GMEM		; if too large go try again

;MEM_OK
	STA	Ememl			; set end of mem low byte
	STY	Ememh			; set end of mem high byte
	STA	Sstorl		; set bottom of string space low byte
	STY	Sstorh		; set bottom of string space high byte

	LDY	#<Ram_base		; set start addr low byte
	LDX	#>Ram_base		; set start addr high byte
	STY	Smeml			; save start of mem low byte
	STX	Smemh			; save start of mem high byte

; this line is only needed if Ram_base is not $xx00

;	LDY	#$00			; clear Y
	TYA				; clear A
	STA	(Smeml),Y		; clear first byte
	INC	Smeml			; increment start of mem low byte

; these two lines are only needed if Ram_base is $xxFF

;	BNE	LAB_2E05		; branch if no rollover

;	INC	Smemh			; increment start of mem high byte
LAB_2E05
	JSR	LAB_CRLF		; print CR/LF
	JSR	LAB_1463		; do "NEW" and "CLEAR"
	LDA	Ememl			; get end of mem low byte
	SEC				; set carry for subtract
	SBC	Smeml			; subtract start of mem low byte
	TAX				; copy to X
	LDA	Ememh			; get end of mem high byte
	SBC	Smemh			; subtract start of mem high byte
	JSR	LAB_295E		; print XA as unsigned integer (bytes free)
	LDA	#<LAB_SMSG		; point to sign-on message (low addr)
	LDY	#>LAB_SMSG		; point to sign-on message (high addr)
	JSR	LAB_18C3		; print null terminated string from memory
	LDA	#<LAB_1274		; warm start vector low byte
	LDY	#>LAB_1274		; warm start vector high byte
	STA	Wrmjpl		; save warm start vector low byte
	STY	Wrmjph		; save warm start vector high byte
	JMP	(Wrmjpl)		; go do warm start

; open up space in memory
; move (Ostrtl)-(Obendl) to new block ending at (Nbendl)

; Nbendl,Nbendh - new block end address (A/Y)
; Obendl,Obendh - old block end address
; Ostrtl,Ostrth - old block start address

; returns with ...

; Nbendl,Nbendh - new block start address (high byte - $100)
; Obendl,Obendh - old block start address (high byte - $100)
; Ostrtl,Ostrth - old block start address (unchanged)

LAB_11CF
	JSR	LAB_121F		; check available memory, "Out of memory" error if no room
					; addr to check is in AY (low/high)
	STA	Earryl		; save new array mem end low byte
	STY	Earryh		; save new array mem end high byte

; open up space in memory
; move (Ostrtl)-(Obendl) to new block ending at (Nbendl)
; don't set array end

LAB_11D6
	SEC				; set carry for subtract
	LDA	Obendl		; get block end low byte
	SBC	Ostrtl		; subtract block start low byte
	TAY				; copy MOD(block length/$100) byte to Y
	LDA	Obendh		; get block end high byte
	SBC	Ostrth		; subtract block start high byte
	TAX				; copy block length high byte to X
	INX				; +1 to allow for count=0 exit
	TYA				; copy block length low byte to A
	BEQ	LAB_120A		; branch if length low byte=0

					; block is (X-1)*256+Y bytes, do the Y bytes first

	SEC				; set carry for add + 1, two's complement
	EOR	#$FF			; invert low byte for subtract
	ADC	Obendl		; add block end low byte

	STA	Obendl		; save corrected old block end low byte
	BCS	LAB_11F3		; branch if no underflow

	DEC	Obendh		; else decrement block end high byte
	SEC				; set carry for add + 1, two's complement
LAB_11F3
	TYA				; get MOD(block length/$100) byte
	EOR	#$FF			; invert low byte for subtract
	ADC	Nbendl		; add destination end low byte
	STA	Nbendl		; save modified new block end low byte
	BCS	LAB_1203		; branch if no underflow

	DEC	Nbendh		; else decrement block end high byte
	BCC	LAB_1203		; branch always

LAB_11FF
	LDA	(Obendl),Y		; get byte from source
	STA	(Nbendl),Y		; copy byte to destination
LAB_1203
	DEY				; decrement index
	BNE	LAB_11FF		; loop until Y=0

					; now do Y=0 indexed byte
	LDA	(Obendl),Y		; get byte from source
	STA	(Nbendl),Y		; save byte to destination
LAB_120A
	DEC	Obendh		; decrement source pointer high byte
	DEC	Nbendh		; decrement destination pointer high byte
	DEX				; decrement block count
	BNE	LAB_1203		; loop until count = $0

	RTS				;

; check room on stack for A bytes
; stack too deep? do OM error

LAB_1212
	STA	TempB			; save result in temp byte
	TSX				; copy stack
	CPX	TempB			; compare new "limit" with stack
	BCC	LAB_OMER		; if stack < limit do "Out of memory" error then warm start

	RTS				;

; check available memory, "Out of memory" error if no room
; addr to check is in AY (low/high)

LAB_121F
	CPY	Sstorh		; compare bottom of string mem high byte
	BCC	LAB_124B		; if less then exit (is ok)

	BNE	LAB_1229		; skip next test if greater (tested <)

					; high byte was =, now do low byte
	CMP	Sstorl		; compare with bottom of string mem low byte
	BCC	LAB_124B		; if less then exit (is ok)

					; addr is > string storage ptr (oops!)
LAB_1229
	PHA				; push addr low byte
	LDX	#$08			; set index to save Adatal to expneg inclusive
	TYA				; copy addr high byte (to push on stack)

					; save misc numeric work area
LAB_122D
	PHA				; push byte
	LDA	Adatal-1,X		; get byte from Adatal to expneg ( ,$00 not pushed)
	DEX				; decrement index
	BPL	LAB_122D		; loop until all done

	JSR	LAB_GARB		; garbage collection routine

					; restore misc numeric work area
	LDX	#$F8			; set index to restore bytes
LAB_1238
	PLA				; pop byte
	STA	expneg+1,X		; save byte to Adatal to expneg ( ,$00 not pulled)
	INX				; increment index
	BMI	LAB_1238		; loop while -ve

	PLA				; pop addr high byte
	TAY				; copy back to Y
	PLA				; pop addr low byte
	CPY	Sstorh		; compare bottom of string mem high byte
	BCC	LAB_124B		; if less then exit (is ok)

	BNE	LAB_OMER		; if greater do "Out of memory" error then warm start

					; high byte was =, now do low byte
	CMP	Sstorl		; compare with bottom of string mem low byte
	BCS	LAB_OMER		; if >= do "Out of memory" error then warm start

					; ok exit, carry clear
LAB_124B
	RTS				;

; do "Out of memory" error then warm start

LAB_OMER
	LDX	#$0C			; error code $0C ("Out of memory" error)

; do error #X, then warm start

LAB_XERR
	JSR	LAB_CRLF		; print CR/LF

	LDA	LAB_BAER,X		; get error message pointer low byte
	LDY	LAB_BAER+1,X	; get error message pointer high byte
	JSR	LAB_18C3		; print null terminated string from memory

	JSR	LAB_1491		; flush stack & clear continue flag
	LDA	#<LAB_EMSG		; point to " Error" low addr
	LDY	#>LAB_EMSG		; point to " Error" high addr
LAB_1269
	JSR	LAB_18C3		; print null terminated string from memory
	LDY	Clineh		; get current line high byte
	INY				; increment it
	BEQ	LAB_1274		; go do warm start (was immediate mode)

					; else print line number
	JSR	LAB_2953		; print " in line [LINE #]"

; BASIC warm start entry point
; wait for Basic command

LAB_1274
					; clear ON IRQ/NMI bytes
	LDA	#$00			; clear A
	STA	IrqBase		; clear enabled byte
	STA	NmiBase		; clear enabled byte
	LDA	#<LAB_RMSG		; point to "Ready" message low byte
	LDY	#>LAB_RMSG		; point to "Ready" message high byte

	JSR	LAB_18C3		; go do print string

; wait for Basic command (no "Ready")

LAB_127D
	JSR	LAB_1357		; call for BASIC input
LAB_1280
	STX	Bpntrl		; set BASIC execute pointer low byte
	STY	Bpntrh		; set BASIC execute pointer high byte
	JSR	LAB_GBYT		; scan memory
	BEQ	LAB_127D		; loop while null

; got to interpret input line now ....

	LDX	#$FF			; current line to null value
	STX	Clineh		; set current line high byte
	BCC	LAB_1295		; branch if numeric character (handle new BASIC line)

					; no line number .. immediate mode
	JSR	LAB_13A6		; crunch keywords into Basic tokens
	JMP	LAB_15F6		; go scan & interpret code

; handle new BASIC line

LAB_1295
	JSR	LAB_GFPN		; get fixed-point number into temp integer
	JSR	LAB_13A6		; crunch keywords into Basic tokens
	STY	Ibptr			; save index pointer to end of crunched line
	JSR	LAB_SSLN		; search BASIC for temp integer line number
	BCC	LAB_12E6		; branch if not found

					; aroooogah! line # already exists! delete it
	LDY	#$01			; set index to next line pointer high byte
	LDA	(Baslnl),Y		; get next line pointer high byte
	STA	ut1_ph		; save it
	LDA	Svarl			; get start of vars low byte
	STA	ut1_pl		; save it
	LDA	Baslnh		; get found line pointer high byte
	STA	ut2_ph		; save it
	LDA	Baslnl		; get found line pointer low byte
	DEY				; decrement index
	SBC	(Baslnl),Y		; subtract next line pointer low byte
	CLC				; clear carry for add
	ADC	Svarl			; add start of vars low byte
	STA	Svarl			; save new start of vars low byte
	STA	ut2_pl		; save destination pointer low byte
	LDA	Svarh			; get start of vars high byte
	ADC	#$FF			; -1 + carry
	STA	Svarh			; save start of vars high byte
	SBC	Baslnh		; subtract found line pointer high byte
	TAX				; copy to block count
	SEC				; set carry for subtract
	LDA	Baslnl		; get found line pointer low byte
	SBC	Svarl			; subtract start of vars low byte
	TAY				; copy to bytes in first block count

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -