mirror of https://github.com/a2stuff/vnIIc.git
363 lines
9.0 KiB
ArmAsm
363 lines
9.0 KiB
ArmAsm
;;;-------------------------------------------------------------------
|
|
;;;
|
|
;;; vnIIc Client Application
|
|
;;;
|
|
;;;-------------------------------------------------------------------
|
|
|
|
PADDLE_SUPPORT = 1
|
|
;;; MOUSE_SUPPORT = 1
|
|
|
|
.include "apple2.inc"
|
|
|
|
.include "macros.inc"
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Hi-res graphics constants/locations
|
|
;;;---------------------------------------------------------
|
|
|
|
PAGE := $E6 ; Active hires plotting page (Applesoft)
|
|
PAGE1 := $20
|
|
PAGE2 := $40
|
|
|
|
PAGESIZE := $20 ; Size of hi-res screen in pages
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; ROM routines
|
|
;;;---------------------------------------------------------
|
|
|
|
PREAD := $FB1E ; Monitor paddle reading routine, call
|
|
; with paddle # in X, returns value in Y
|
|
|
|
HCLR := $F3F2 ; Clear current hires screen to black
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Other
|
|
;;;---------------------------------------------------------
|
|
|
|
MAX_SLOT := 7 ; Maximum slot # on an Apple II
|
|
|
|
ZP_PTR := $FA ; Write cursor location on zero page
|
|
|
|
;;;-------------------------------------------------------------------
|
|
;;; Protocol:
|
|
;;;-------------------------------------------------------------------
|
|
|
|
.proc Protocol
|
|
Keyboard := $00
|
|
|
|
Button0 := $10
|
|
Button1 := $11
|
|
|
|
Paddle0 := $20
|
|
Paddle1 := $21
|
|
|
|
MouseX := $30
|
|
MouseY := $31
|
|
MouseBtn := $32
|
|
|
|
Screen := $80
|
|
.endproc
|
|
|
|
|
|
;;;-------------------------------------------------------------------
|
|
;;;
|
|
;;; Client Code
|
|
;;;
|
|
;;;-------------------------------------------------------------------
|
|
|
|
.org $6000
|
|
jmp AppEntry
|
|
|
|
.include "ssc.inc"
|
|
|
|
.ifdef MOUSE_SUPPORT
|
|
.include "mouse.inc"
|
|
.endif
|
|
|
|
|
|
;;;-------------------------------------------------------------------
|
|
;;; Variables
|
|
;;;-------------------------------------------------------------------
|
|
|
|
;;; Application configuration
|
|
PSPEED: .byte SSC::BPS_115k ; Hardcoded for Apple IIc (TODO: Allow configuration)
|
|
PSLOT: .byte 2 ; Hardcoded for Apple IIc (TODO: Allow configuration)
|
|
PEXIT: .byte 0 ; Set when it's time to exit (Not Yet Implemented)
|
|
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Initialize the application, and enter the main loop
|
|
|
|
.proc AppEntry
|
|
lda PSLOT ; Use slot 2
|
|
jsr SSC::Init ; Initialize Super Serial Card
|
|
jsr InitHires ; Initialize Hi-Res graphics
|
|
jsr InitInput ; Initialize input devices
|
|
jsr MainLoop
|
|
;; fall through
|
|
.endproc
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Clean up and exit app
|
|
|
|
.proc AppExit
|
|
jsr SSC::Reset
|
|
sta LOWSCR
|
|
sta TXTSET
|
|
rts
|
|
.endproc
|
|
|
|
;;;-------------------------------------------------------------------
|
|
;;;
|
|
;;; Main loop functionality
|
|
;;;
|
|
;;;-------------------------------------------------------------------
|
|
|
|
|
|
;;;---------------------------------------------------------
|
|
.proc MainLoop
|
|
|
|
;;; TODO: Sort out the protocol - should be able to send
|
|
;;; input state without receiving data
|
|
;;; jsr SSC::HasData ; Anything to read?
|
|
;;; bne :+ ; Nope
|
|
|
|
: jsr ReceivePage
|
|
;; Input is sent every 256 bytes (32 times per page)
|
|
jsr FlipHires
|
|
|
|
jmp :- ; TODO: define an exit trigger
|
|
rts
|
|
.endproc
|
|
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Pull a hi-res page down over serial
|
|
;;;
|
|
;;; Protocol is:
|
|
;;; * Recieve 256 bytes (graphic data)
|
|
;;; * Send 1 byte (input state)
|
|
|
|
.proc ReceivePage
|
|
lda #Protocol::Screen
|
|
jsr SSC::Put
|
|
lda #0 ; data size
|
|
jsr SSC::Put
|
|
|
|
|
|
lda #0 ; set up write pointer
|
|
sta ZP_PTR
|
|
lda PAGE
|
|
sta ZP_PTR+1
|
|
ldx #PAGESIZE ; plan to receive this many pages
|
|
ldy #0
|
|
|
|
: jsr SSC::Get
|
|
sta (ZP_PTR),Y
|
|
iny
|
|
bne :- ; Do a full page...
|
|
|
|
;; Interleave to maintain responsiveness
|
|
jsr SendInputState
|
|
|
|
inc ZP_PTR+1
|
|
dex
|
|
bne :- ; ...as many pages as we need
|
|
rts
|
|
.endproc
|
|
|
|
|
|
;;;-------------------------------------------------------------------
|
|
;;;
|
|
;;; Input device routines
|
|
;;;
|
|
;;;-------------------------------------------------------------------
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Initialize input devices and storage for detecting
|
|
;;; state transitions
|
|
|
|
.proc InitInput
|
|
|
|
.ifdef MOUSE_SUPPORT
|
|
jsr Mouse::FindMouse
|
|
.endif
|
|
|
|
rts
|
|
.endproc
|
|
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Send a full set of input state updates.
|
|
|
|
;;; Assumes time to transmit is roughly comparable to time
|
|
;;; to measure input state, therefore only sending changes is
|
|
;;; not worthwhile in most cases.
|
|
|
|
.proc SendInputState
|
|
jsr MaybeSendKeyboard
|
|
jsr SendButtons
|
|
|
|
.ifdef PADDLE_SUPPORT
|
|
jsr SendPaddles
|
|
.endif
|
|
|
|
.ifdef MOUSE_SUPPORT
|
|
jsr SendMouse
|
|
.endif
|
|
|
|
.endproc
|
|
|
|
|
|
;;;------------------------------------------------------------
|
|
;;; Keyboard
|
|
|
|
;;; NOTE: Can't use KBDSTRB to detect key up -> key down transition
|
|
;;; since the msb can change before the key code. Instead, consider
|
|
;;; these cases:
|
|
;;;
|
|
;;; OLD STATE KBD KBDSTRB RESULT
|
|
;;; Up Up - No-op
|
|
;;; Up Down - Save and send key down
|
|
;;; Down - Up Save and send key up
|
|
;;; Down - Down Save and send key ONLY if different
|
|
;;;
|
|
|
|
last_kb: .byte 0
|
|
|
|
.proc MaybeSendKeyboard
|
|
lda last_kb
|
|
bne key_was_down
|
|
|
|
key_was_up:
|
|
;; Key was up - send only if now down.
|
|
lda KBD ; Read keyboard
|
|
bpl done ; Do nothing if it is still up.
|
|
jmp send ; Otherwise send.
|
|
|
|
key_was_down:
|
|
;; Key was down - strobe should match
|
|
;; unless the key changed or was released.
|
|
lda KBDSTRB
|
|
bmi kbdstrb_down
|
|
|
|
kbdstrb_up:
|
|
lda #0 ; Now released
|
|
jmp send
|
|
|
|
kbdstrb_down:
|
|
cmp last_kb ; Same key as last time?
|
|
beq done ; - no change, don't send.
|
|
jmp send
|
|
|
|
send: sta last_kb
|
|
lda Protocol::Keyboard
|
|
jsr SSC::Put
|
|
lda #1 ; Data size
|
|
jsr SSC::Put
|
|
lda last_kb
|
|
jsr SSC::Put
|
|
|
|
done: rts
|
|
.endproc
|
|
|
|
;;;------------------------------------------------------------
|
|
;;; Buttons
|
|
|
|
.proc SendButtons
|
|
|
|
lda Protocol::Button0
|
|
jsr SSC::Put
|
|
lda #1 ; Data size
|
|
jsr SSC::Put
|
|
lda BUTN0
|
|
jsr SSC::Put
|
|
|
|
lda Protocol::Button1
|
|
jsr SSC::Put
|
|
lda #1 ; Data size
|
|
jsr SSC::Put
|
|
lda BUTN1
|
|
jsr SSC::Put
|
|
|
|
rts
|
|
.endproc
|
|
|
|
;;;------------------------------------------------------------
|
|
;;; Paddles
|
|
|
|
.ifdef PADDLE_SUPPORT
|
|
.proc SendPaddles
|
|
|
|
lda Protocol::Paddle0
|
|
jsr SSC::Put
|
|
lda #1 ; Data size
|
|
jsr SSC::Put
|
|
|
|
ldx #0
|
|
jsr PREAD
|
|
tya
|
|
jsr SSC::Put
|
|
|
|
;; Assumes at least 11 cycles to send, so
|
|
;; timer has a chance to reset.
|
|
|
|
lda Protocol::Paddle1
|
|
jsr SSC::Put
|
|
lda #1 ; Data size
|
|
jsr SSC::Put
|
|
|
|
ldx #1
|
|
jsr PREAD
|
|
tya
|
|
jsr SSC::Put
|
|
|
|
rts
|
|
.endproc
|
|
.endif
|
|
|
|
;;;-------------------------------------------------------------------
|
|
;;;
|
|
;;; Hi-res graphics routines
|
|
;;;
|
|
;;;-------------------------------------------------------------------
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Set up the graphics display and pointers
|
|
|
|
.proc InitHires
|
|
lda #PAGE1 ; clear page 1
|
|
sta PAGE
|
|
jsr HCLR
|
|
|
|
jsr FlipHires ; then show it and flip to 2
|
|
sta HIRES
|
|
sta TXTCLR
|
|
sta MIXCLR
|
|
sta LOWSCR
|
|
|
|
rts
|
|
.endproc
|
|
|
|
|
|
;;;---------------------------------------------------------
|
|
;;; Call when done with the current plotting page
|
|
;;; (selected in PAGE) and it will be shown and the
|
|
;;; other page will be shown.
|
|
|
|
.proc FlipHires
|
|
lda PAGE ; plotting on which page?
|
|
cmp #PAGE1
|
|
beq :+
|
|
|
|
sta HISCR ; page 2 - so show it
|
|
lda #PAGE1 ; and plot on page 1
|
|
sta PAGE
|
|
rts
|
|
|
|
: sta LOWSCR ; page 1 - so show it
|
|
lda #PAGE2 ; and plot on page 2
|
|
sta PAGE
|
|
rts
|
|
.endproc
|