mirror of
https://github.com/flowenol/applesoft-lite.git
synced 2024-12-21 21:29:20 +00:00
initial
This commit is contained in:
commit
6a1e34ba6f
23
Makefile
Normal file
23
Makefile
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
AFLAGS =
|
||||||
|
LFLAGS = -C replica1.cfg
|
||||||
|
BINFILE = applesoft-lite.bin
|
||||||
|
OBJS = applesoft-lite.o io.o cffa1.o wozmon.o
|
||||||
|
|
||||||
|
$(BINFILE): $(OBJS)
|
||||||
|
ld65 $(LFLAGS) $(OBJS) -o $(BINFILE)
|
||||||
|
|
||||||
|
applesoft-lite.o: applesoft-lite.s
|
||||||
|
ca65 $(AFLAGS) $<
|
||||||
|
|
||||||
|
wozmon.o: wozmon.s
|
||||||
|
ca65 $(AFLAGS) $<
|
||||||
|
|
||||||
|
cffa1.o: cffa1.s
|
||||||
|
ca65 $(AFLAGS) $<
|
||||||
|
|
||||||
|
io.o: io.s
|
||||||
|
ca65 $(AFLAGS) $<
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm $(OBJS) $(BINFILE)
|
||||||
|
|
5
README.md
Normal file
5
README.md
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# applesoft-lite
|
||||||
|
|
||||||
|
This is a stripped-down version of Applesoft BASIC (Microsoft 6502 BASIC) for the Apple-1.
|
||||||
|
|
||||||
|
See https://cowgod.org/replica1/applesoft/
|
5501
applesoft-lite.s
Normal file
5501
applesoft-lite.s
Normal file
File diff suppressed because it is too large
Load Diff
185
cffa1.s
Normal file
185
cffa1.s
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
; CFFA1 I/O routines for Applesoft Lite
|
||||||
|
; by Tom Greene
|
||||||
|
; 8-May-2008
|
||||||
|
|
||||||
|
.setcpu "6502"
|
||||||
|
.segment "BASIC"
|
||||||
|
|
||||||
|
.include "zeropage.s"
|
||||||
|
|
||||||
|
.importzp ERR_SYNTAX, ERR_NOCFFA
|
||||||
|
.import ERROR, FIX_LINKS
|
||||||
|
.export CFFALoad, CFFASave, CFFAMenu
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; CFFA1 firmware addresses
|
||||||
|
|
||||||
|
;CFFA_ID1 := $AFFC ; CFFA1 API documentation says AFFC and AFFD...
|
||||||
|
;CFFA_ID2 := $AFFD
|
||||||
|
CFFA_ID1 := $AFDC ; But the CFFA1 firmware says AFDC and AFDD...
|
||||||
|
CFFA_ID2 := $AFDD
|
||||||
|
CFFA_MENU := $9006 ; Entry point for the CFFA1 menu
|
||||||
|
CFFA_API := $900C ; Entry point for the CFFA1 API
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; CFFA1 API functions
|
||||||
|
|
||||||
|
CFFA1_DisplayError = $04 ; Displays error message for error value in A
|
||||||
|
CFFA1_WriteFile = $20
|
||||||
|
CFFA1_ReadFile = $22
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; CFFA1 API parameters in the ZP
|
||||||
|
|
||||||
|
Destination := $00 ; File load/save address
|
||||||
|
Filename := $02 ; Pointer to file name
|
||||||
|
Filetype := $06 ; ProDOS file type
|
||||||
|
AuxType := $07 ; ProDOS file auxtype
|
||||||
|
FileSize := $09 ; File size
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Scratch memory used during API calls
|
||||||
|
|
||||||
|
ZPTemp := $0380 ; ZP locations get backed up here
|
||||||
|
CFFAFileName := $03C0 ; File name string
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; ProDOS file type value for write operations
|
||||||
|
; The CFFA1 doesn't really care, so this is just for show.
|
||||||
|
|
||||||
|
SaveType = $F8 ; F8 = "PRG"?
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; See if CFFA1 card is present and display error if not
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
CheckCFFA:
|
||||||
|
ldy CFFA_ID1
|
||||||
|
cpy #$CF
|
||||||
|
bne CFFAErr
|
||||||
|
ldy CFFA_ID2
|
||||||
|
cpy #$FA
|
||||||
|
bne CFFAErr
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Bring up the CFFA1 menu
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
CFFAMenu:
|
||||||
|
jsr CheckCFFA
|
||||||
|
jmp CFFA_MENU
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; This sets up the zero page locations file name for the read/write calls
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
APISetup:
|
||||||
|
jsr CheckCFFA ; Make sure CFFA card is present first
|
||||||
|
ldy #0
|
||||||
|
@1: lda GOWARM,y ; Back up first 12 bytes of the ZP
|
||||||
|
sta ZPTemp,y ; so they can used during CFFA API call
|
||||||
|
iny
|
||||||
|
cpy #12
|
||||||
|
bne @1
|
||||||
|
GetFileName: ; Get file name from input line
|
||||||
|
dec TXTPTR
|
||||||
|
ldy #0
|
||||||
|
@1: jsr CHRGET ; Get next character from the input line
|
||||||
|
beq @2 ; Is it null (EOL)?
|
||||||
|
sta CFFAFileName+1,y ; Not EOL, store it in filename string
|
||||||
|
iny
|
||||||
|
cpy #15 ; 15 chars yet?
|
||||||
|
bne @1 ; no, go back for more
|
||||||
|
@2: cpy #0 ; Read 15 chars or EOL, did we get anything?
|
||||||
|
beq SynErr ; No, syntax error
|
||||||
|
sty CFFAFileName ; Store file name length
|
||||||
|
lda #<CFFAFileName ; Load address of file name string
|
||||||
|
ldy #>CFFAFileName
|
||||||
|
sta Filename ; and store it for API call
|
||||||
|
sty Filename+1
|
||||||
|
lda PRGEND ; Set up file size
|
||||||
|
sbc TXTTAB ; (PRGEND - TXTTAB)
|
||||||
|
sta FileSize
|
||||||
|
lda PRGEND+1
|
||||||
|
sbc TXTTAB+1
|
||||||
|
sta FileSize+1
|
||||||
|
lda TXTTAB ; Set up start address and auxtype
|
||||||
|
ldy TXTTAB+1 ; (these will be the same)
|
||||||
|
sta Destination
|
||||||
|
sta AuxType
|
||||||
|
sty Destination+1
|
||||||
|
sty AuxType+1
|
||||||
|
lda #SaveType ; Set up ProDOS file type
|
||||||
|
sta Filetype
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Display an error message if something went wrong during APISetup
|
||||||
|
; Uses the Applesoft ERROR routine
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
CFFAErr:
|
||||||
|
ldx #ERR_NOCFFA
|
||||||
|
.byte $2C ; Bogus BIT instruction
|
||||||
|
SynErr:
|
||||||
|
ldx #ERR_SYNTAX
|
||||||
|
jmp ERROR ; Jump to Applesoft ERROR routine
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Restores the first 12 bytes of the ZP which were saved during APISetup
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
RestoreZP:
|
||||||
|
ldy #0
|
||||||
|
@1: lda ZPTemp,y ; Load byte from temporary storage
|
||||||
|
sta GOWARM,y ; put it back in its original location
|
||||||
|
iny
|
||||||
|
cpy #12 ; Repeat for next 11 bytes
|
||||||
|
bne @1
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Write a file to the CFFA card (SAVE command)
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
CFFASave:
|
||||||
|
jsr APISetup ; Set up zero page locations for API call
|
||||||
|
ldx #CFFA1_WriteFile; Select WriteFile API function
|
||||||
|
jsr DoCFFACall ; Do it
|
||||||
|
@1: jsr RestoreZP ; put ZP back together
|
||||||
|
@2: rts
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Read file from CFFA, then fix up Applesoft zero page to point to the
|
||||||
|
; loaded program (LOAD command)
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
CFFALoad:
|
||||||
|
jsr APISetup
|
||||||
|
ldx #CFFA1_ReadFile ; Select ReadFile API function
|
||||||
|
jsr DoCFFACall ; Do it
|
||||||
|
lda TXTTAB ; Compute program end address
|
||||||
|
adc FileSize ; (Add file size to program start)
|
||||||
|
sta VARTAB ; Store end address
|
||||||
|
lda TXTTAB+1
|
||||||
|
adc FileSize+1
|
||||||
|
sta VARTAB+1
|
||||||
|
jsr RestoreZP ; Put the zero page back
|
||||||
|
jmp FIX_LINKS ; Done loading, fix pointers and restart
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Call the CFFA1 API and display error message if one occurred
|
||||||
|
; CFFA function number is passed in X
|
||||||
|
; CFFA API returns error status in C, error number in A
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
DoCFFACall:
|
||||||
|
jsr CFFA_API ; Call CFFA API
|
||||||
|
ldx #CFFA1_DisplayError ; Set next command to show error message
|
||||||
|
bcs DoCFFACall ; Call API again if error occurred
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
92
io.s
Normal file
92
io.s
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
; Apple-1 I/O routines for Applesoft Lite
|
||||||
|
; Last modified 10-May-2008
|
||||||
|
|
||||||
|
.setcpu "6502"
|
||||||
|
.segment "BASIC"
|
||||||
|
|
||||||
|
.export KEYBOARD, GETLN, RDKEY, CLS, OUTDO, CRDO, OUTQUES, OUTSP
|
||||||
|
.import INPUTBUFFER
|
||||||
|
|
||||||
|
.include "zeropage.s"
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; I/O Locations
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
KEYBOARD := $D010
|
||||||
|
KEYBOARDCR := $D011
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Monitor Subroutines
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
MONECHO := $FFEF
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Get keystroke from keyboard (RDKEY)
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
RDKEY:
|
||||||
|
lda KEYBOARDCR ; Key ready?
|
||||||
|
bpl RDKEY ; Loop until ready
|
||||||
|
lda KEYBOARD ; Load character
|
||||||
|
and #$7F ; Clear hi bit
|
||||||
|
rts
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Get line of input (GETLN)
|
||||||
|
; adapted from Apple II monitor
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
NOTCR:
|
||||||
|
cmp #$18 ; CTRL-X?
|
||||||
|
beq CANCEL ; Cancel line if so
|
||||||
|
jsr MONECHO ; Output using monitor ECHO routine
|
||||||
|
cmp #'_' ; backspace?
|
||||||
|
beq BCKSPC ; Yes, do backspace...
|
||||||
|
NOTCR1: inx
|
||||||
|
bne NXTCHAR ; Wasn't backspace or CTRL+X, get next key
|
||||||
|
CANCEL: jsr OUTSLASH ; Output a "\" to indicate cancelled line
|
||||||
|
GETLNZ: jsr CRDO ; new line
|
||||||
|
GETLN: jsr OUTPROMPT ; Display the prompt
|
||||||
|
ldx #$01 ; Set cursor at 1, it gets decremented later
|
||||||
|
BCKSPC: txa
|
||||||
|
beq GETLNZ ; Backspace with nothing on the line? start new line
|
||||||
|
dex ; Move "cursor" back one space
|
||||||
|
NXTCHAR:
|
||||||
|
jsr RDKEY ; Read key from keyboard
|
||||||
|
ADDINP: sta INPUTBUFFER,x ; Put it in the input buffer
|
||||||
|
cmp #$0D ; CR?
|
||||||
|
bne NOTCR ; No, keep looping
|
||||||
|
jsr CRDO ; Output CR
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; These moved here from the main Applesoft code to save a few bytes
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
OUTSLASH:
|
||||||
|
lda #'\'
|
||||||
|
.byte $2C ; Fake BIT instruction to skip next 2 bytes
|
||||||
|
OUTPROMPT:
|
||||||
|
lda PROMPT
|
||||||
|
.byte $2C
|
||||||
|
OUTSP: lda #' '
|
||||||
|
.byte $2C
|
||||||
|
OUTQUES:
|
||||||
|
lda #'?'
|
||||||
|
.byte $2C
|
||||||
|
CRDO: lda #$0D
|
||||||
|
OUTDO: ora #$80 ; Set hi bit
|
||||||
|
jsr MONECHO ; Send character to monitor ECHO
|
||||||
|
and #$7F ; clear hi bit
|
||||||
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Corny method of clearing the screen by sending a bunch of CR's.
|
||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
CLS:
|
||||||
|
ldy #24 ; loop 24 times
|
||||||
|
@1: jsr CRDO ; ouput CR
|
||||||
|
dey
|
||||||
|
bpl @1 ; ... do it again
|
||||||
|
rts
|
10
macros.s
Normal file
10
macros.s
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
; ----------------------------------------------------------------------------
|
||||||
|
; Macros
|
||||||
|
|
||||||
|
; htasc - set the hi bit on the last byte of a string for termination
|
||||||
|
.macro htasc str
|
||||||
|
.repeat .strlen(str)-1,I
|
||||||
|
.byte .strat(str,I)
|
||||||
|
.endrep
|
||||||
|
.byte .strat(str,.strlen(str)-1) | $80
|
||||||
|
.endmacro
|
10
replica1.cfg
Normal file
10
replica1.cfg
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
MEMORY {
|
||||||
|
BASROM: start = $E000, size = $1F00, fill = yes, file = %O;
|
||||||
|
MONROM: start = $FF00, size = $100, fill = yes, file = %O;
|
||||||
|
}
|
||||||
|
|
||||||
|
SEGMENTS {
|
||||||
|
BASIC: load = BASROM, type = ro;
|
||||||
|
MONITOR: load = MONROM, type = ro;
|
||||||
|
}
|
||||||
|
|
183
wozmon.s
Normal file
183
wozmon.s
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
; Apple I Monitor ROM
|
||||||
|
; Steve Wozniak
|
||||||
|
; 1976
|
||||||
|
; --------------------------------------------------------
|
||||||
|
|
||||||
|
.setcpu "6502"
|
||||||
|
.segment "MONITOR"
|
||||||
|
|
||||||
|
.export ECHO
|
||||||
|
|
||||||
|
; --------------------------------------------------------
|
||||||
|
; Zero page variables
|
||||||
|
XAML := $24
|
||||||
|
XAMH := $25
|
||||||
|
STL := $26
|
||||||
|
STH := $27
|
||||||
|
L := $28
|
||||||
|
H := $29
|
||||||
|
YSAV := $2A
|
||||||
|
MODE := $2B
|
||||||
|
|
||||||
|
; I/O locations
|
||||||
|
IN := $0200 ; Input buffer is $0200 to $027F
|
||||||
|
KBD := $D010 ; Keyboard data
|
||||||
|
DSP := $D012 ; Display data
|
||||||
|
KBDCR := $D011 ; Keyboard control register
|
||||||
|
DSPCR := $D013 ; Display control register
|
||||||
|
|
||||||
|
; ASCII codes
|
||||||
|
CR = $0D | $80 ; Carriage return
|
||||||
|
ESC = $1B | $80 ; Escape
|
||||||
|
SLASH = '\' | $80 ; \
|
||||||
|
UNDERSC = '_' | $80 ; Underscore (acts as backspace)
|
||||||
|
DOT = '.' | $80 ; .
|
||||||
|
COLON = ':' | $80 ; :
|
||||||
|
R = 'R' | $80 ; "R"
|
||||||
|
SPACE = ' ' | $80 ; blank
|
||||||
|
ZERO = '0' | $80 ; "0"
|
||||||
|
|
||||||
|
; --------------------------------------------------------
|
||||||
|
RESET: cld ; Clear decimal arithmetic mode
|
||||||
|
cli
|
||||||
|
ldy #$7F ; Mask for DSP data direction register
|
||||||
|
sty DSP ; Set it up
|
||||||
|
lda #$A7 ; KBD and DSP control register mask
|
||||||
|
sta KBDCR ; Enable interrupts, set CA1, CB1 for
|
||||||
|
sta DSPCR ; positive edge sense/output mode
|
||||||
|
NOTCR: cmp #UNDERSC ; Backspace?
|
||||||
|
beq BACKSPACE ; Yes
|
||||||
|
cmp #ESC ; ESC?
|
||||||
|
beq ESCAPE ; Yes
|
||||||
|
iny ; Advance text index
|
||||||
|
bpl NEXTCHAR ; Auto ESC if > 127
|
||||||
|
ESCAPE: lda #SLASH ; "\"
|
||||||
|
jsr ECHO ; Output it
|
||||||
|
GETLINE:
|
||||||
|
lda #CR ; CR
|
||||||
|
jsr ECHO ; Output it
|
||||||
|
ldy #$01 ; Initialize text index
|
||||||
|
BACKSPACE:
|
||||||
|
dey ; Back up text index
|
||||||
|
bmi GETLINE ; Beyond start of line, reinitialize
|
||||||
|
NEXTCHAR:
|
||||||
|
lda KBDCR ; Key ready?
|
||||||
|
bpl NEXTCHAR ; Loop until ready
|
||||||
|
lda KBD ; Load character. B7 should be '1'
|
||||||
|
sta IN,y ; Add to text buffer
|
||||||
|
jsr ECHO ; Display character
|
||||||
|
cmp #CR ; CR?
|
||||||
|
bne NOTCR ; No
|
||||||
|
ldy #$FF ; Reset text index
|
||||||
|
lda #$00 ; For XAM mode
|
||||||
|
tax ; 0 -> x
|
||||||
|
SETSTOR:
|
||||||
|
asl ; Leaves $7B if setting STOR mode
|
||||||
|
SETMODE:
|
||||||
|
sta MODE ; $00 = XAM, $7B = STOR, $AE = BLOCK XAM
|
||||||
|
BLSKIP: iny ; Advance text index
|
||||||
|
NEXTITEM:
|
||||||
|
lda IN,y ; Get character
|
||||||
|
cmp #CR ; CR?
|
||||||
|
beq GETLINE ; Yes, done this line
|
||||||
|
cmp #DOT ; "."?
|
||||||
|
bcc BLSKIP ; Skip delimiter
|
||||||
|
beq SETMODE ; Set BLOCK XAM mode
|
||||||
|
cmp #COLON ; ":"?
|
||||||
|
beq SETSTOR ; Yes, set STOR mode
|
||||||
|
cmp #R ; "R"?
|
||||||
|
beq RUN ; Yes, run user program
|
||||||
|
stx L ; $00 -> L
|
||||||
|
stx H ; and H
|
||||||
|
sty YSAV ; Save Y for comparison
|
||||||
|
NEXTHEX:
|
||||||
|
lda IN,y ; Get character for hex test
|
||||||
|
eor #$B0 ; Map digits to $0-9
|
||||||
|
cmp #$0A ; Digit?
|
||||||
|
bcc DIG ; Yes
|
||||||
|
adc #$88 ; Map letter "A"-"F" to $FA-FF
|
||||||
|
cmp #$FA ; Hex letter?
|
||||||
|
bcc NOTHEX ; No, character not hext
|
||||||
|
DIG: asl
|
||||||
|
asl ; Hex digit to MSD of A
|
||||||
|
asl
|
||||||
|
asl
|
||||||
|
ldx #$04 ; Shift count
|
||||||
|
HEXSHIFT:
|
||||||
|
asl ; Hex digit left, MSB to carry
|
||||||
|
rol L ; Rotate into LSD
|
||||||
|
rol H ; Rotate into MSD's
|
||||||
|
dex ; Done 4 shifts?
|
||||||
|
bne HEXSHIFT ; No, loop
|
||||||
|
iny ; Advance text index
|
||||||
|
bne NEXTHEX ; Always taken. Check next character for hex
|
||||||
|
NOTHEX:
|
||||||
|
cpy YSAV ; Check if L, H empty (no hex digits)
|
||||||
|
beq ESCAPE ; Yes, generate ESC sequence
|
||||||
|
bit MODE ; Test MODE byte
|
||||||
|
bvc NOTSTOR ; B6 = 0 for STOR, 1 for XAM and BLOCK XAM
|
||||||
|
lda L ; LSD's of hex data
|
||||||
|
sta (STL,x) ; Store at current 'store index'
|
||||||
|
inc STL ; Increment store index
|
||||||
|
bne NEXTITEM ; Get next item (no carry)
|
||||||
|
inc STH ; Add carry to 'store index' high order
|
||||||
|
TONEXTITEM:
|
||||||
|
jmp NEXTITEM ; Get next command item
|
||||||
|
RUN: jmp (XAML) ; Run at current XAM index
|
||||||
|
NOTSTOR:
|
||||||
|
bmi XAMNEXT ; B7=0 for XAM, 1 for BLOCK XAM
|
||||||
|
ldx #$02 ; Byte count
|
||||||
|
SETADR: lda L-1,x ; Copy hex data to
|
||||||
|
sta STL-1,x ; 'store index'
|
||||||
|
sta XAML-1,x ; And to 'XAM index'
|
||||||
|
dex ; Next of 2 bytes
|
||||||
|
bne SETADR ; Loop unless X=0
|
||||||
|
NXTPRNT:
|
||||||
|
bne PRDATA ; NE means no address to print
|
||||||
|
lda #CR ; CR
|
||||||
|
jsr ECHO ; Output it
|
||||||
|
lda XAMH ; 'Examine index' high-order byte
|
||||||
|
jsr PRBYTE ; Output it in hex format
|
||||||
|
lda XAML ; Low-order 'examine index' byte
|
||||||
|
jsr PRBYTE ; Output it in hex format
|
||||||
|
lda #COLON ; ":"
|
||||||
|
jsr ECHO ; Output it
|
||||||
|
PRDATA: lda #SPACE ; Blank
|
||||||
|
jsr ECHO ; Output it
|
||||||
|
lda (XAML,x) ; Get data byte at 'examine index'
|
||||||
|
jsr PRBYTE ; Output it in hex format
|
||||||
|
XAMNEXT:
|
||||||
|
stx MODE ; 0 -> MODE (XAM mode)
|
||||||
|
lda XAML
|
||||||
|
cmp L ; Compare 'examine index' to hex data
|
||||||
|
lda XAMH
|
||||||
|
sbc H
|
||||||
|
bcs TONEXTITEM ; Not less, so no more data to output
|
||||||
|
inc XAML
|
||||||
|
bne MOD8CHK ; Increment 'examine index'
|
||||||
|
inc XAMH
|
||||||
|
MOD8CHK:
|
||||||
|
lda XAML ; Check low-order 'examine index' byte
|
||||||
|
and #$07 ; For MOD 8 = 0
|
||||||
|
bpl NXTPRNT ; Always taken
|
||||||
|
PRBYTE: pha ; Save A for LSD
|
||||||
|
lsr
|
||||||
|
lsr
|
||||||
|
lsr ; MSD to LSD position
|
||||||
|
lsr
|
||||||
|
jsr PRHEX ; Output hex digit
|
||||||
|
pla ; Restore A
|
||||||
|
PRHEX: and #$0F ; Mask LSD for hex print
|
||||||
|
ora #ZERO ; Add "0"
|
||||||
|
cmp #$BA ; Digit?
|
||||||
|
bcc ECHO ; Yes, output it
|
||||||
|
adc #$06 ; Add offset for letter
|
||||||
|
ECHO: bit DSP ; DA bit (B7) cleared yet?
|
||||||
|
bmi ECHO ; No, wait for display
|
||||||
|
sta DSP ; Output character. Sets DA.
|
||||||
|
rts ; Return
|
||||||
|
; --------------------------------------------------------
|
||||||
|
.word $0000 ; (unused)
|
||||||
|
.addr $0F00 ; (NMI vector)
|
||||||
|
.addr RESET ; (RESET vector)
|
||||||
|
.addr $0000 ; (IRQ vector)
|
88
zeropage.s
Normal file
88
zeropage.s
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
; Zero Page locatinos used by Applesoft Lite
|
||||||
|
|
||||||
|
GOWARM := $0000 ; Gets "jmp RESTART"
|
||||||
|
GOSTROUTZ := $0003 ; Gets "jmp STROUT"
|
||||||
|
CHARAC := $000D ; Alternate string terminator
|
||||||
|
ENDCHR := $000E ; String terminator
|
||||||
|
TKNCNTR := $000F ; Used in PARSE
|
||||||
|
EOLPNTR := $000F ; Used in NXLIN
|
||||||
|
NUMDIM := $000F ; Used in array routines
|
||||||
|
DIMFLG := $0010
|
||||||
|
VALTYP := $0011 ; $: VALTYP=$FF; %: VALTYP+1=$80
|
||||||
|
DATAFLG := $0013 ; Used in PARSE
|
||||||
|
GARFLG := $0013 ; Used in GARBAG
|
||||||
|
SUBFLG := $0014
|
||||||
|
INPUTFLG := $0015 ; = $40 for GET, $98 for READ
|
||||||
|
CPRMASK := $0016 ; Receives CPRTYP in FRMEVL
|
||||||
|
PROMPT := $0033
|
||||||
|
LINNUM := $0050 ; Converted line #
|
||||||
|
TEMPPT := $0052 ; Last used temp string desc
|
||||||
|
LASTPT := $0053 ; Last used temp string pntr
|
||||||
|
TEMPST := $0055 ; Holds up to 3 descriptors
|
||||||
|
INDEX := $005E
|
||||||
|
DEST := $0060
|
||||||
|
RESULT := $0062 ; Result of last * or /
|
||||||
|
TXTTAB := $0067 ; Start of program text
|
||||||
|
VARTAB := $0069 ; Start of variable storage
|
||||||
|
ARYTAB := $006B ; Start of array storage
|
||||||
|
STREND := $006D ; End of array storage
|
||||||
|
FRETOP := $006F ; Start of string storage
|
||||||
|
FRESPC := $0071 ; Temp pntr, string routines
|
||||||
|
MEMSIZ := $0073 ; End of string space (HIMEM)
|
||||||
|
CURLIN := $0075 ; Current line number
|
||||||
|
OLDLIN := $0077 ; Addr. of last line executed
|
||||||
|
OLDTEXT := $0079
|
||||||
|
DATLIN := $007B ; Line # of current data stt.
|
||||||
|
DATPTR := $007D ; Addr of current data stt.
|
||||||
|
INPTR := $007F
|
||||||
|
VARNAM := $0081 ; Name of variable
|
||||||
|
VARPNT := $0083 ; Addr of variable
|
||||||
|
FORPNT := $0085
|
||||||
|
TXPSV := $0087 ; Used in INPUT
|
||||||
|
LASTOP := $0087 ; Scratch flag used in FRMEVL
|
||||||
|
CPRTYP := $0089 ; >,=,< flag in FRMEVL
|
||||||
|
TEMP3 := $008A
|
||||||
|
FNCNAM := $008A
|
||||||
|
DSCPTR := $008C
|
||||||
|
DSCLEN := $008F ; used in GARBAG
|
||||||
|
JMPADRS := $0090 ; gets "jmp ...."
|
||||||
|
LENGTH := $0091 ; used in GARBAG
|
||||||
|
ARGEXTENSION := $0092 ; FP extra precision
|
||||||
|
TEMP1 := $0093 ; save areas for FAC
|
||||||
|
ARYPNT := $0094 ; used in GARBAG
|
||||||
|
HIGHDS := $0094 ; pntr for BLTU
|
||||||
|
HIGHTR := $0096 ; pntr for BLTU
|
||||||
|
TEMP2 := $0098
|
||||||
|
TMPEXP := $0099 ; used in FIN (EVAL)
|
||||||
|
INDX := $0099 ; used by array rtns
|
||||||
|
EXPON := $009A ; "
|
||||||
|
DPFLG := $009B ; flags dec pnt in FIN
|
||||||
|
LOWTR := $009B
|
||||||
|
EXPSGN := $009C
|
||||||
|
FAC := $009D ; main floating point accumulator
|
||||||
|
VPNT := $00A0 ; temp var ptr
|
||||||
|
FACSIGN := $00A2 ; holds unpacked sign
|
||||||
|
SERLEN := $00A3 ; holds length of series - 1
|
||||||
|
SHIFTSIGNEXT := $00A4 ; sign extension, right shifts
|
||||||
|
ARG := $00A5 ; secondary FP accumulator
|
||||||
|
ARGSIGN := $00AA
|
||||||
|
SGNCPR := $00AB ; flags opp sign in FP routines
|
||||||
|
FACEXTENSION := $00AC ; FAC extension byte
|
||||||
|
SERPNT := $00AD ; pntr to series data in FP
|
||||||
|
STRNG1 := $00AB
|
||||||
|
STRNG2 := $00AD
|
||||||
|
PRGEND := $00AF
|
||||||
|
CHRGET := $00B1
|
||||||
|
CHRGOT := $00B7
|
||||||
|
TXTPTR := $00B8
|
||||||
|
RNDSEED := $00C9
|
||||||
|
LOCK := $00D6 ; no user access if > 127
|
||||||
|
ERRFLG := $00D8 ; $80 if ON ERR active
|
||||||
|
ERRLIN := $00DA ; line # where error occurred
|
||||||
|
ERRPOS := $00DC ; TXTPTR save for HANDLERR
|
||||||
|
ERRNUM := $00DE ; which error occurrred
|
||||||
|
ERRSTK := $00DF ; stack pntr before error
|
||||||
|
TRCFLG := $00F2
|
||||||
|
TXTPSV := $00F4
|
||||||
|
CURLSV := $00F6
|
||||||
|
REMSTK := $00F8 ; stack pntr before each stt.
|
Loading…
Reference in New Issue
Block a user