VM02/src/vm02.s

374 lines
6.6 KiB
ArmAsm
Executable File

;*
;* JAVA VIRTUAL MACHINE FOR APPLE II PRODOS
;*
.INCLUDE "global.inc"
.INCLUDE "class.inc"
.IMPORT UTIL_INIT,HOME,GETLN,PRSTR,PRSTRLN,PRHSTRLN,COUT,CROUT,PUTS,PRBYTE,KBWAIT,MEMSRC,MEMDST,MEMCPY
.IMPORT HMEM_INIT,HMEM_ALLOC,HMEM_FREE
.IMPORT HMEM_PTR,HMEM_REF_INC,HMEM_REF_DEC,HMEM_LOCK,HMEM_GC
.IMPORT HSTR_INIT,STR_HASH,HSTR_HASH,HSTRPL_ADD,HSTRPL_DEL
.IMPORT LOADCLASS_INIT,IO_INIT,IODEV_INIT,VBL_INIT
.IMPORT HCLASS_INIT,HCLASS_NAME,HCLASS_HNDL,CLASS_MATCH_NAME,CLASS_MATCH_DESC
.IMPORT RESOLVE_CLASS,RESOLVE_METHOD,CLASS_METHODPTR
.IMPORT SYSCLASS_INIT,EXCEPT_INIT,SYS_CALL
.IMPORT HMAINNAMESTR,HMAINDESCSTR
.IMPORT THREAD_INIT,THREAD_NEW,THREAD_SETRUN,THREAD_YIELD
.IMPORT ITHREAD_PUSH_SP,ITHREAD_PUSH_TLS,LOADEXECSTATE,BEST_THREAD
.IMPORT INTERP_INIT,INTERP_END,DVM_INIT
.IMPORT CLASSPREFIX,PREFIX_SET,FILE_GETINFO,FILE_OPEN,FILE_CLOSE,FILE_SETBUFFER,FILE_BLOAD
.IFDEF SWAPPING
.IMPORT HMEM_SWAP_CLEANUP
.ENDIF
.EXPORT INIT_START,VM_RESTART,WARM_INIT
.IFDEF DEBUG
.IMPORT HMEM_DUMP,HSTRPL_DUMP
.ENDIF
PARSELEN EQU $A0
.SEGMENT "INIT"
INIT_START:
VM_WARMINIT: DEC WARM_INIT
LDX #$9E ; DEVICE CTRL CALL FUNC INDEX
: STX DEVSLOT
TXA ; CONVERT TO SLOT #
LSR
AND #$07
ORA #IOCTL_DEACTIVATE
TAY
SEI ; DISABLE INTERRUPTS
JSR DEVCALL ; DEACTIVATE DEVICES
CLI
LDX DEVSLOT
DEX
DEX
CPX #$90
BNE :-
PSTRLN "" ; I HAVE NO IDEA WHY THIS IS NEEDED
LDX #$FF ; RESET STACK
TXS
LDA CHAIN_CMD ; NO PASSED IN PARAMS
PHA
.IF 0
BNE :+
PSTR "PRESS ESC TO REBOOT, RETURN TO CONTINUE."
JSR KBWAIT
CMP #$9B
BNE :+
JSR PRODOS
.BYTE $41 ; DE-ALLOC INTERRUPT
.ADDR DEALLOCINTPARMS
BIT ROMIN ; SWAP ROM IN
LDA #$00
STA $3F4 ; INVALIDATE POWER-UP BYTE
JMP ($FFFC) ; RESET
: JSR CROUT
.ENDIF
JMP SKIPBANNER
;
; INITIALIZE SYSTEM
;
VM_INIT: LDA #$00
STA $3F4 ; INVALIDATE POWER-UP BYTE
LDX #$F0 ; CLEAR LINK TABLE
LDA #$00
: DEX
STA LINK_TABLE,X
BNE :-
JSR IO_INIT
JSR HOME
.IFDEF BIGMEM
PSTR "VM02 128K"
.ELSE
PSTR "VM02 64K"
.ENDIF
.IFDEF FLOATING_POINT
PSTR " Floating Point"
.ENDIF
PSTRLN " Version 1.0"
PSTRLN "Copyright 2010, David Schmenk"
; PSTRLN "'EXIT' to reboot"
SKIPBANNER:
.IFDEF DEBUG
PSTRLN "DEBUG ENABLED"
LDA #$69 ; PLACE FENCE AT BOTTOM OF STACK
STA $0100
STA $0101
.ENDIF
.IFDEF DEBUG_DUMP
LDA #$00 ; TURN ON DEBUG SLOT
STA CSWL
LDA #$C0|DEBUG_DUMP
STA CSWH
.ENDIF
LDA #$4C ; JMP INSTRUCTION
STA OPJMP
LDA #<VM_RESTART
STA LINK_EXIT
LDA #>VM_RESTART
STA LINK_EXIT+1
LDA #<VM_REBOOT
STA LINK_REBOOT
LDA #>VM_REBOOT
STA LINK_REBOOT+1
JSR UTIL_INIT
JSR HMEM_INIT
JSR IODEV_INIT
JSR HSTR_INIT
JSR HCLASS_INIT
JSR THREAD_INIT
JSR EXCEPT_INIT
JSR INTERP_INIT
JSR DVM_INIT
JSR LOADCLASS_INIT
SEI ; DISABLE INTERRUPTS
BIT LCBNK2 ; MAKE SURE LCBANK2 SET UP
BIT LCBNK2
CLI
JSR SYSCLASS_INIT
;
; LOOK FOR STARTUP FILE IN INPUT BUFFER ($01FF = LEN OF STARTUP STRING)
;
PLA
BEQ :+
TAX
BNE PARSECMD
: LDA #<STARTUP ; CHECK FOR EXISTANCE OF STARTUP FILE
LDX #>STARTUP
JSR FILE_GETINFO
BCS CMDLINE ; NOPE, INPUT COMMAND LINE
LDA #$00
PHA
STA PARSELEN
LDA #<STARTUP
LDX #>STARTUP
JMP SETRUNCLASS
;
; PROMPT FOR MAIN CLASS
;
CMDLINE: PSTR "Main class"
LDA #':'|$80
STA PROMPTCHAR
JSR GETLN
CPX #$00
BEQ CMDLINE
PARSECMD: STX PARSELEN
: LDA $0200,X ; STRIP OFF HIGH BITS
AND #$7F
STA $0200,X
DEX
BPL :-
LDX #$00
JSR PARSELINE
TXA
BEQ CMDLINE
PHA ; CLEVERLY PUT STRING LENGTH
LDA #$FF ; IN FRONT OF INPUT BUFFER AT $200
LDX #$01
SETRUNCLASS: JSR HSTRPL_ADD
STA RUNCLASS
STX RUNCLASS+1
.IFDEF DEBUG_PARAMS
JSR PRHSTRLN
JSR KBWAIT
.ENDIF
PARSEARGS: PLA
BEQ :+
TAX
JSR PARSELINE
TXA
BEQ :+
PHA
LDA #$FF
LDX #$01
JSR HSTRPL_ADD
STY TMP
LDY NARGS
STA HARGSL,Y
TXA
STA HARGSH,Y
LDA TMP
STA ARGSHASH,Y
INC NARGS
BNE PARSEARGS
: LDA NARGS ; ALLOCATE ARGS ARRAY
ASL
ASL
CLC
ADC #$02
LDX #$00
LDY #$00
JSR HMEM_ALLOC
STA HARGS
STX HARGS+1
JSR HMEM_PTR
STA $A0
STX $A1
LDY #$00
LDA NARGS
STA ($A0),Y
TYA
TAX
INY
STA ($A0),Y
LDA NARGS
BEQ RUNMAIN
INY
FILLARGS: LDA HARGSL,X
STA ($A0),Y
INY
LDA HARGSH,X
STA ($A0),Y
INY
LDA #CL_STR
STA ($A0),Y
INY
LDA ARGSHASH,X
STA ($A0),Y
INY
INX
DEC NARGS
BNE FILLARGS
RUNMAIN: JSR VBL_INIT ; TURN VBL IRQS ON IF PRESSENT
LDA #$00
BIT CLRKBD ; CLEAR KEYBOARD
STA TYPEBUFFLEN ; FLUSH INPUT BUFFER
STA CHAIN_CMD ; CLEAR CHAIN COMMAND
TAX
JSR THREAD_NEW ; NEED TO CREATE THREAD INSTANCE OBJECT
LDA #T_REF
LDX #CL_ARRAY
JSR ITHREAD_PUSH_SP ; PUSH MAIN PARAM ON STACK
LDA HARGS+1
LDX HARGS
JSR ITHREAD_PUSH_SP
LDA HMAINNAMESTR ; RUN MAIN METHOD
LDX HMAINNAMESTR+1
JSR ITHREAD_PUSH_SP
LDA HMAINDESCSTR
LDX HMAINDESCSTR+1
JSR ITHREAD_PUSH_SP
LDA RUNCLASS ; RETRIEVE CLASS NAME
LDX RUNCLASS+1
JSR ITHREAD_PUSH_SP
JSR THREAD_SETRUN
STY BEST_THREAD
JSR LOADEXECSTATE ; JUMP TO SCHEDULER
PERR "OOPS, RETURN FROM YIELD"
BRK
LDA INTERP_END ; DUMMY READ TO MAKE EXTERN SHOW UP IN MAP FILE
PARSELINE: LDY #$00 ; SKIP PREVIOUS STRING
LDA INQUOTE
BEQ :+
DEC INQUOTE
INX
: LDA PARSELEN
STX PARSELEN
SEC
SBC PARSELEN
STA PARSELEN
BNE SKIPPREV
PARSEDONE: LDX #$00
RTS
SKIPPREV: LDA $0200,X
STA $0200,Y
INY
INX
BPL SKIPPREV
LDX #$00
SKIPSPACE: LDA $0200
CMP #'"'
BEQ PARSEQUOTE
CMP #' '+1 ; CHECK FOR WHITESPACE
BCS PARSESTR
DEC PARSELEN
BEQ PARSEEXIT
: LDA $0201,X ; SHIFT BUFFER DOWN
STA $0200,X
INX
BPL :-
LDX #$00
BEQ SKIPSPACE
PARSESTR: INX
CPX PARSELEN
BEQ PARSEEXIT
LDA $0200,X
CMP #' '+1
BCS PARSESTR
PARSEEXIT: RTS
PARSEQUOTE: DEC PARSELEN
: LDA $0201,X ; SKIP QUOTE CHAR
STA $0200,X
INX
BPL :-
LDX #$FF
FINDQUOTE: INX
CPX PARSELEN
BEQ PARSEEXIT
LDA $0200,X
CMP #'"'
BNE FINDQUOTE
INC INQUOTE
RTS
DEVCALL: .BYTE $6C
DEVSLOT: .BYTE $92,$03
STARTUP: .BYTE 7,"STARTUP"
RUNCLASS: .WORD $0000
NARGS: .BYTE $00
INQUOTE: .BYTE $00
HARGSL: .RES 10
HARGSH: .RES 10
ARGSHASH: .RES 10
HARGS: .WORD $0000
WARM_INIT: .BYTE $00
DEALLOCINTPARMS: .BYTE $01
.BYTE $00 ; INT NUM
.CODE
;*
;* MAIN ENTRYPOINT
;*
; ORG $1000
VM_STARTUP: JMP VM_INIT
;*
;* ALL THREADS ARE DONE, OR AN UNRECOVERABLE ERROR OCCURED
;* EXIT TO PRODOS
;*
VM_RESTART: STA EXIT_STATUS ; SAVE EXIT STATUS
STX EXIT_STATUS+1
LDX #$05 ; CLOSE ALL OPEN FILES
: LDA LINK_OPENFILES,X
BEQ :+
STX ACNT
TAY
JSR FILE_CLOSE
LDX ACNT
: DEX
BPL :--
LDA #<CLASSPREFIX ; RELOAD VM02 FROM ORIGINAL LOCATION
LDX #>CLASSPREFIX
JSR PREFIX_SET
LDA #$00
LDX #$10
JSR FILE_SETBUFFER
LDA #<VM02FILE
LDX #>VM02FILE
JSR FILE_BLOAD
.IFDEF SWAPPING
JSR HMEM_SWAP_CLEANUP ; CALL CLEANUP IN INIT SECTION - TOO COOL
.ENDIF
JMP VM_WARMINIT ; WARM INIT
VM_REBOOT: SEI
DEC $3F4 ; INVALIDATE POWER-UP BYTE
BIT ROMIN ; SWAP ROM IN
JMP ($FFFC) ; RESET
.DATA
.IFDEF BIGMEM
VM02FILE: .BYTE 5,"VM02E"
.ELSE
VM02FILE: .BYTE 4,"VM02"
.ENDIF