mirror of
https://github.com/marketideas/qasm.git
synced 2026-10-24 22:02:28 +00:00
Move the assembler to src/qasm. qlink links OMF 1.0 and 2.0 from a script. makeBin flattens a load file, qomf dumps OMF, and qpro builds ProDOS volumes. APW and MPW assemble through the ORCA front end. Relocatable modules emit OMF objects. Listings stay off unless -l is set. make boot assembles the GS/OS 6.0.1 ProDOS 8 kernel and BASIC.SYSTEM into an 800K volume. BASIC.SYSTEM accepts ls and pfx, and its splash reports PRODOS BASIC 2.0, copyright 1983-2026. IIGS.601.SRC is the source and the BASIC.SYSTEM oracle that image is built from.
1 line
130 KiB
NASM
1 line
130 KiB
NASM
title 'Misc Tools GS ROM 3.0'
|
|
**********************************************************************
|
|
*
|
|
* Misc Tools
|
|
*
|
|
*
|
|
* Copyright (C) 1985-1988
|
|
* All Rights Reserved
|
|
* Apple Computer, Inc.
|
|
*
|
|
*
|
|
* Change History
|
|
*
|
|
* Revision Date Description Who
|
|
* Alpha1.0 02-17-86 Initial ALPHA release RBM
|
|
* 02-27-86 Implemented IDTAG MGR RBM
|
|
* Corrected error codes
|
|
* Math Divide/0 error reporting
|
|
* Fixed MAINSIDE dispatcher
|
|
* 03-07-86 Build NEW miscellaneous tools RBM
|
|
* Beta 1.0 03-26-86 Psuedo keyboard IRQ task. RBM
|
|
* Beta 2.0 04-23-86 More parms for get address. RBM
|
|
* 04-29-86 No calls to system death from RBM
|
|
* mouse tools. Added absolute
|
|
* device clamp support. The get
|
|
* address call has more parms.
|
|
* Rom 0.1 10-27-86 Fixed endcall in SetAbsClamps. RBM
|
|
* ID manager now reassigns tags.
|
|
* Fixed WrBram & RdBram so that
|
|
* buffer may be in any bank.
|
|
* Rom 0.1 10-29-86 Added SysBeep RBM
|
|
*
|
|
* For ROM 3.0
|
|
*
|
|
* 06 May 88 Joe Bo
|
|
*
|
|
* Implemented mouse hardware interfaces to mouse calling routines.
|
|
*
|
|
*
|
|
* 09 May 88 Joe Bo
|
|
*
|
|
* Added a new entry point for BASIC to initialize mouse.
|
|
*
|
|
*
|
|
* 26 Jul 88 Steven Glass
|
|
*
|
|
* Get and SetVector disable interrupts during access to the vectors.
|
|
*
|
|
* DelHeartbeat and ClearHeartbeat try and turn off vbl interrupts
|
|
* if it is safe to do so.
|
|
*
|
|
* 10 Sep 88 Steven Glass
|
|
*
|
|
* Entry in call table for BasicInit did not include -1.
|
|
*
|
|
* Added calls AddToQueue and DeleteFromQueue.
|
|
*
|
|
* 30 Sep 88 Joe Bo
|
|
*
|
|
* GetMouseClamp: Saved and restored dbr around internal calls.
|
|
*
|
|
* 03 Sep 88 Steven Glass
|
|
*
|
|
* GetMouseClamp: Changed equates to account for saving and restoring dbr.
|
|
*
|
|
* 17 Oct 88 Steven Glass
|
|
*
|
|
* The bParam table entry for slot one (address $21) is not offset
|
|
* to $58. This is to make appletalk work in the new configuration.
|
|
*
|
|
* 17 Nov 88 Konstantin Othmer
|
|
*
|
|
* Added slot arbiter stuff to fwentry. A call to _FWEntry (which really goes
|
|
* through MonEntry) will set the slots to the default configuration if the call
|
|
* is in the Cn00 space. Using fwentry directly (which only the text tools do)
|
|
* will not change the slot configuration.
|
|
*
|
|
* 08 Dec 88 Steven Glass
|
|
*
|
|
* Change to DeathMgr in way it checks for NIL ptr.
|
|
*
|
|
* 04 Jan 89 Mensch
|
|
*
|
|
* Added ReadMouse2 Call. and changed ReadMouse call, The new read mouse is
|
|
* identical to old read mouse read mouse, except that
|
|
* it will allow journaling to occur. ReadMouse2 is the old readmouse call
|
|
* should only be used by the event manager. Everyone else should stick with
|
|
* the old readmouse
|
|
*
|
|
* 12 Jan 89 Mensch
|
|
* Fix bug introduced on jan 4 that caused infinite loop in readmouse.
|
|
*
|
|
* 17 Jan 89 Mensch
|
|
* Added GetROMResource and ReleaseROMResource to Misc Tools
|
|
*
|
|
* 26-Sep-90 Dave Lyons
|
|
*
|
|
* Changed _SysDeath to _SysFailMgr so it builds.
|
|
*
|
|
* 4-Mar-91 Dave Lyons
|
|
*
|
|
* Adding new call $3B03 StringToText to translate 8-bit "Shaston 8" style
|
|
* text into the nearest equivalent Text-screen text (allowing for mousetext,
|
|
* etc). (Code is really in the ROM 3 patch file.)
|
|
*
|
|
**********************************************************************
|
|
|
|
|
|
include 'all.macros'
|
|
include '::sys.equs.asm'
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Global Version Number
|
|
;
|
|
Version equ $0300 ; version number
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; from e16.misctool
|
|
;
|
|
vblDisable EQU $0003 ; Interrupt Ref Number - Parameter to IntSource
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Slot Arbiter Entry point
|
|
;
|
|
Slot_arbiter equ $E10208
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Definition of Record used by Queue Routines
|
|
;
|
|
DSect 0
|
|
HeaderLink LONG
|
|
HeaderReserved WORD
|
|
HeaderSignature WORD
|
|
HeaderRoutine LONG
|
|
|
|
QueueSignature equ $A55A
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Misc tools Errors
|
|
;
|
|
BadInputErr equ $0301 ; bad input
|
|
noDevParamErr equ $0302 ; no device for input paramter
|
|
taskInstlErr equ $0303 ; specified task already in queue
|
|
noSigTaskErr equ $0304 ; no signature detected in task header
|
|
queueDmgdErr equ $0305 ; damaged heartbeat queue detected (fatal)
|
|
taskNtFdErr equ $0306 ; specified task not in queue
|
|
firmTaskErr equ $0307 ; Unsuccessful fw task
|
|
hbQueueBadErr equ $0308 ; damaged heartbeat queue detected (fatal)
|
|
unCnctdDevErr equ $0309 ; dispatch to unconnect device
|
|
idTagNtAvlErr equ $030B ; no id tag available
|
|
|
|
RecordNotFound equ $0380
|
|
BadSignature equ $0381
|
|
|
|
|
|
;-----------------------------------------------
|
|
;
|
|
; Imported addresses
|
|
;
|
|
;-----------------------------------------------
|
|
|
|
IMPORT EndCall0
|
|
IMPORT EndCall2
|
|
IMPORT EndCall4
|
|
IMPORT EndCall8
|
|
IMPORT ErrOut2
|
|
IMPORT ErrOut4
|
|
IMPORT FFEntry
|
|
IMPORT LastTag
|
|
IMPORT LongDiv
|
|
IMPORT Multiply
|
|
IMPORT SpecialNewHandle
|
|
IMPORT UDivide
|
|
IMPORT oEndCall0
|
|
IMPORT oEndCall2
|
|
IMPORT oEndCall4
|
|
IMPORT oEndCall6
|
|
IMPORT oEndCall8
|
|
IMPORT oErrOut0
|
|
IMPORT oErrOut2
|
|
IMPORT oErrOut4
|
|
IMPORT oErrOut6
|
|
IMPORT oErrOut8
|
|
|
|
|
|
|
|
|
|
;-----------------------------------------------
|
|
;
|
|
; Forward addresses and entries
|
|
;
|
|
;-----------------------------------------------
|
|
|
|
ENTRY ClearGlue
|
|
ENTRY ClrHeart
|
|
ENTRY DelHeart
|
|
ENTRY DeleteID
|
|
ENTRY GetAbsClamp
|
|
ENTRY GetAddr
|
|
ENTRY GetIRQenbl
|
|
ENTRY GetNewID
|
|
ENTRY GetTick
|
|
ENTRY GetVector
|
|
ENTRY HexToAscii
|
|
ENTRY HomeGlue
|
|
ENTRY ISIT44
|
|
ENTRY InitGlue
|
|
ENTRY IntSrc
|
|
ENTRY Irq_Heart
|
|
ENTRY LOOKAT4
|
|
ENTRY MTCallTable
|
|
ENTRY MTDeref
|
|
ENTRY MTInit
|
|
ENTRY MTRes7
|
|
ENTRY MTRes8
|
|
ENTRY MTReset
|
|
ENTRY MTShutDown
|
|
ENTRY MTStartup
|
|
ENTRY MTStatus
|
|
ENTRY MTVer
|
|
ENTRY MonEntry
|
|
ENTRY Munger
|
|
ENTRY PackBytes
|
|
ENTRY RdATime
|
|
ENTRY ReadBParam
|
|
ENTRY ReadBRam
|
|
ENTRY ReadMouseJ
|
|
ENTRY RdTimeHex
|
|
ENTRY SetAbsClamp
|
|
ENTRY SetHeart
|
|
ENTRY SetVector
|
|
ENTRY StatusID
|
|
ENTRY SysBeep
|
|
ENTRY SysDeathMgr
|
|
ENTRY TClmpMou
|
|
ENTRY TGetClamp
|
|
ENTRY TPosMou
|
|
ENTRY TRdMou
|
|
ENTRY TServMou
|
|
ENTRY TSetMou
|
|
ENTRY ToLDivide
|
|
ENTRY ToMainSide
|
|
ENTRY ToMult
|
|
ENTRY ToUDivide
|
|
ENTRY UnPackBytes
|
|
ENTRY WriteBParam
|
|
ENTRY WriteBRam
|
|
ENTRY WrTimeHex
|
|
|
|
|
|
ENTRY GetMData
|
|
ENTRY setdbtoe1
|
|
ENTRY MYBasicInit
|
|
ENTRY InitFlag
|
|
|
|
import AddToQueue
|
|
import DeleteFromQueue
|
|
Import ReleaseROMResource
|
|
Import GetROMResource
|
|
|
|
title 'Call Table'
|
|
****************************************************************
|
|
*
|
|
MTCallTable PROC EXPORT
|
|
*
|
|
* Call table for the tool
|
|
*
|
|
*
|
|
* Inputs:
|
|
* none
|
|
*
|
|
* Outputs:
|
|
* none
|
|
*
|
|
* External Refs:
|
|
import SetInterruptState
|
|
import GetInterruptState
|
|
import GetIntStateRecSize
|
|
import GetCodeResConverter
|
|
import ConvSeconds
|
|
import SysBeep2
|
|
import VersionString
|
|
import WaitUntil
|
|
import StringToText
|
|
|
|
*
|
|
* Entry Points:
|
|
* none
|
|
*
|
|
longa on ; mode
|
|
longi on
|
|
*
|
|
****************************************************************
|
|
|
|
|
|
Here
|
|
DC.L (TheEnd-Here)/4 ; num calls +1
|
|
DC.L MTInit-1 ; PowerUp Initialization
|
|
DC.L MTStartup-1 ; application startup
|
|
DC.L MTShutDown-1 ; application shutdown
|
|
DC.L MTVer-1 ; version number
|
|
DC.L MTReset-1 ; Misc. Tools Reset
|
|
DC.L MTStatus-1 ; Reserved
|
|
DC.L MTRes7-1 ; Reserved
|
|
DC.L MTRes8-1 ; Reserved
|
|
DC.L WriteBRam-1 ; Write battery ram
|
|
DC.L ReadBRam-1 ; Read battery ram
|
|
DC.L WriteBParam-1 ; Write battery ram parameter
|
|
DC.L ReadBParam-1 ; Read battery ram parameter
|
|
DC.L RdTimeHex-1 ; read clock w/ hex format
|
|
DC.L WrTimeHex-1 ; write clock w/ hex format
|
|
DC.L RdATime-1 ; read clock w/ ascii format
|
|
DC.L SetVector-1 ; set interrupt vector
|
|
DC.L GetVector-1 ; get interrupt vector
|
|
DC.L SetHeart-1 ; insert procedure in Heartbeat chain
|
|
DC.L DelHeart-1 ; delete procedure from heartbeat chai
|
|
DC.L ClrHeart-1 ; clear heartbeat chain
|
|
DC.L SysDeathMgr-1 ; system death manager
|
|
DC.L GetAddr-1 ; ???
|
|
DC.L ReadMouseJ-1 ; Read Mouse (Was TRdMou)
|
|
DC.L InitGlue-1 ; initialize mouse
|
|
DC.L TSetMou-1 ; set mouse mode
|
|
DC.L HomeGlue-1 ; home mouse position to min. clamp
|
|
DC.L ClearGlue-1 ; clear mouse position to 0
|
|
DC.L TClmpMou-1 ; set both X and Y clamps
|
|
DC.L TGetClamp-1 ; get both X and Y clamps
|
|
DC.L TPosMou-1 ; set mouse position
|
|
DC.L TServMou-1 ; service mouse interrupt
|
|
DC.L GetNewID-1 ; get ID tag
|
|
DC.L DeleteID-1 ; delete ID tag
|
|
DC.L StatusID-1 ; get ID tag status
|
|
DC.L IntSrc-1 ; enable interrupt source
|
|
DC.L MonEntry-1 ; Firmware entry points
|
|
DC.L GetTick-1 ; get tick counter contents
|
|
DC.L PackBytes-1 ; Pack bytes
|
|
DC.L UnPackBytes-1 ; UnPack dem dere bytes
|
|
DC.L Munger-1 ; This routine munges strings
|
|
DC.L GetIRQenbl-1 ; returns IRQ enble status
|
|
DC.L SetAbsClamp-1 ; set absolute device clamps
|
|
DC.L GetAbsClamp-1 ; get absolute device clamps
|
|
DC.L SysBeep-1 ; system beep
|
|
DC.L MyBasicInit-1 ; mouse init for BASIC from $c4xx
|
|
DC.L AddToQueue-1 ; added 10 sep 88
|
|
DC.L DeleteFromQueue-1 ; added 10 sep 88
|
|
|
|
dc.L SetInterruptState-1 ; added 24 Nov 88
|
|
dc.L GetInterruptState-1 ; added 24 Nov 88
|
|
dc.L GetIntStateRecSize-1 ; added 24 Nov 88
|
|
dc.L TRdMou-1 ; added 03 jan 89 {$3303}
|
|
dc.L GetCodeResConverter-1 ; added 12 Jan 89 {$3403}
|
|
dc.L GetROMResource-1 ; Added 17 Jan 89 {$3503}
|
|
dc.L ReleaseROMResource-1 ; Added 17 Jan 89 {$3603}
|
|
dc.l ConvSeconds-1 ; $3703
|
|
dc.l SysBeep2-1 ; $3803
|
|
dc.l VersionString-1 ; $3903
|
|
dc.l WaitUntil-1 ; $3A03
|
|
dc.l StringToText-1 ; $3B03
|
|
TheEnd
|
|
|
|
ENDP
|
|
|
|
title 'Init Routines'
|
|
****************************************************************
|
|
*
|
|
* BOOTINIT: Clears heartbeat queue. Sets no slot flags.
|
|
* Clears tick counter. Allocates IDtag memory.
|
|
* STARTUPINIT: Does nothing
|
|
* SHUTDOWN: Does nothing
|
|
* RESET: Clears heartbeat queue. Sets no slot flags.
|
|
*
|
|
****************************************************************
|
|
MTInit PROC ; Tool Boot Initialization
|
|
|
|
phb ; save the dbr on stack
|
|
|
|
|
|
IF RAMVersion THEN
|
|
|
|
bra SkipNewHandle
|
|
|
|
ENDIF
|
|
|
|
|
|
|
|
lda #0 ; Init HeartBeat chain
|
|
sta >HBptr
|
|
sta >HBptr+2
|
|
sta >TickCnt ; initialize tick counter
|
|
sta >TickCnt+2
|
|
sep #$20 ; 8 bit 'm'
|
|
sta >KBDIRQFLAG ; clear interrupt flag
|
|
dec a ; assume no Slot I/O
|
|
sta >SIOFlag
|
|
sta >MouseSlot ; assume no mouse either
|
|
rep #$20 ; 16 bit 'm'
|
|
|
|
|
|
|
|
lda #0 ; size
|
|
ldx #$4101
|
|
ldy #$0008 ; no special memory
|
|
jsr SpecialNewHandle
|
|
bcc MTInit0 ; if got block
|
|
pea $0000 ; no message
|
|
pea $0000
|
|
pea $0025 ; cant allocate IDTAG queue
|
|
_SysFailMgr ; SYSTEM DEATH
|
|
|
|
MTInit0 ;
|
|
txa ; save handle
|
|
sta >MThandle
|
|
tya
|
|
sta >MThandle+2
|
|
SkipNewHandle
|
|
plb ; restore data bank reg
|
|
|
|
ENTRY MTStartup
|
|
MTStartup ; ; Tool Startup Initialization
|
|
ENTRY MTShutdown
|
|
MTShutdown ; ; Tool Shut Down
|
|
ENTRY MTRes7
|
|
MTRes7 ; ; Reserved function #7
|
|
ENTRY MTRes8
|
|
MTRes8 ; ; Reserved function #8
|
|
|
|
jmp oEndCall0
|
|
|
|
ENTRY MTReset
|
|
MTReset ;
|
|
lda #0 ; clear HeartBeat queue
|
|
sta >HBptr
|
|
sta >HBptr+2
|
|
sep #$20 ; 8 bit 'm'
|
|
dec a ; assume no Slot I/O
|
|
sta >SIOFlag
|
|
sta >MouseSlot ; no mouse either
|
|
rep #$20 ; 16 bit 'm'
|
|
jmp oEndCall0
|
|
|
|
ENDP
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
* Return with miscellaneous tools version #
|
|
*
|
|
****************************************************************
|
|
MTVer PROC
|
|
|
|
RTL1 equ 1
|
|
RTL2 equ RTL1+3
|
|
Result equ RTL2+3
|
|
|
|
|
|
lda #version ; get MT version #
|
|
sta Result,s ; pass to caller
|
|
jmp oEndCall0
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
*
|
|
* Return with status that indicates the tool is active
|
|
*
|
|
****************************************************************
|
|
MTStatus PROC
|
|
|
|
rtl1 equ 1
|
|
rtl2 equ rtl1+3
|
|
ThisStatus equ rtl2+3
|
|
|
|
lda #$FFFF ; status = tool active
|
|
sta ThisStatus,s
|
|
jmp oEndCall0
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
* Dereference a Handle, and return with pointer in X and DBR.
|
|
*
|
|
* Inputs : MThandle contains handle to IDTAG block
|
|
* Output : DBR = Block addr (high), X=Block addr (low)
|
|
*
|
|
* NOTE : this trashes A, X, Y and D
|
|
*
|
|
****************************************************************
|
|
MTderef PROC
|
|
|
|
lda >MThandle ; get handle into X and A
|
|
tax
|
|
lda >MThandle+2
|
|
xba ; get bank into B
|
|
pha
|
|
plb ; remove trash
|
|
plb ; set bank to bank of pointer
|
|
lda |0,x ; get pointer (low)
|
|
ldy |2,x ; get pointer (high)
|
|
tax
|
|
tya
|
|
xba ; get bank into B
|
|
pha ; push bank + trash
|
|
plb ; remove trash
|
|
plb ; set bank = ptr (high)
|
|
rts
|
|
|
|
ENDP
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
MTHandleStuff PROC
|
|
*
|
|
*
|
|
* Sets or returns the size of the MT handle.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* none
|
|
*
|
|
* Outputs:
|
|
* a-reg Size of MTHandle
|
|
*
|
|
* External Refs:
|
|
* none
|
|
*
|
|
* Entry Points:
|
|
ENTRY GetMTHandleSize
|
|
ENTRY SetMTHandleSize
|
|
*
|
|
longa on ; mode
|
|
longi on
|
|
*
|
|
****************************************************************
|
|
|
|
GetMTHandleSize
|
|
pha
|
|
pha
|
|
lda >MThandle+2
|
|
pha
|
|
lda >MThandle
|
|
pha
|
|
_GetHandleSize
|
|
pla
|
|
plx
|
|
rts
|
|
|
|
SetMTHandleSize
|
|
pea 0000
|
|
pha
|
|
lda >MThandle+2
|
|
pha
|
|
lda >MThandle
|
|
pha
|
|
_SetHandleSize
|
|
rts
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
title 'Battery Ram Routines'
|
|
****************************************************************
|
|
*
|
|
* Write battery ram
|
|
*
|
|
* Input LongWord Address
|
|
*
|
|
* Change History
|
|
*
|
|
* 29 January 87 Ray Montagne
|
|
*
|
|
* Since firmware cannot generate error on write we don't
|
|
* look for one to return
|
|
*
|
|
****************************************************************
|
|
WriteBRam PROC
|
|
|
|
OrigDir equ 1
|
|
rtl1 equ OrigDir+2
|
|
rtl2 equ rtl1+3
|
|
buffer equ rtl2+3
|
|
|
|
phd ; turn stack into zp
|
|
tsc
|
|
tcd
|
|
sep #$30 ; 8 bit 'm' & 'x'
|
|
longi off
|
|
ldy #0
|
|
ldx #0
|
|
MovLoop ;
|
|
lda [buffer],y ; get application data
|
|
sta >BramBuffer,x ; move to our buffer
|
|
dex
|
|
dey
|
|
bne movloop
|
|
sep #$30 ; 8 bit m/x
|
|
jsl ToWriteBram
|
|
rep #$30
|
|
longa on
|
|
longi on
|
|
|
|
jmp EndCall4
|
|
|
|
BramErr ;
|
|
ldx #firmTaskErr ; BRAM call failed
|
|
jmp ErrOut4
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
ReadBRam PROC
|
|
*
|
|
* Reads the page of battery RAM into the callers buffer.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* BufferPtr : Long
|
|
*
|
|
* Outputs:
|
|
* none
|
|
*
|
|
* External Refs:
|
|
* none
|
|
*
|
|
* Entry Points:
|
|
* none
|
|
*
|
|
longa on ; mode
|
|
longi on
|
|
*
|
|
* Change History
|
|
*
|
|
* 17 Jun 88 Steven Glass
|
|
*
|
|
* This routine had always called the routine which did an actual
|
|
* read of the battery RAM. This is not necessary since the
|
|
* battery ram buffer is always correct before the read.
|
|
*
|
|
* Making this change we save the read time (1/10 second with
|
|
* interrupts off).
|
|
*
|
|
****************************************************************
|
|
|
|
|
|
OrigDir equ 1
|
|
rtl1 equ OrigDir+2
|
|
rtl2 equ rtl1+3
|
|
buffer equ rtl2+3
|
|
|
|
phd ; turn stack into zp
|
|
tsc
|
|
tcd
|
|
|
|
sep #$30 ; 8 bit 'm' and 'x'
|
|
longi off
|
|
longa off
|
|
|
|
ldx #0
|
|
ldy #0
|
|
movloop lda >BramBuffer,x ; data from bram buffer
|
|
sta [buffer],y ; to user buffer
|
|
dex
|
|
dey
|
|
bne movloop
|
|
|
|
|
|
rep #$30 ; 16 bit 'm' and 'x'
|
|
longa on
|
|
longi on
|
|
jmp EndCall4
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
WriteBParam PROC
|
|
*
|
|
* Takes the value from the stack, puts it into the BRam buffer
|
|
* and writes to the battery.
|
|
*
|
|
*
|
|
* Input word Data
|
|
* Input word Parameter #
|
|
*
|
|
* Outputs none
|
|
*
|
|
* External Refs:
|
|
import BParamIndexToTable
|
|
*
|
|
* Entry Points:
|
|
* none
|
|
*
|
|
longa on ; mode
|
|
longi on
|
|
*
|
|
* Change History
|
|
*
|
|
* 29 January 87 Ray Montagne
|
|
*
|
|
* Since firmware cannot generate error on write we don't
|
|
* look for one to return
|
|
*
|
|
* 10 Sep 88 Steven Glass
|
|
*
|
|
* Index number is directed through table, rather than being
|
|
* actual memory location in the BRAM.
|
|
*
|
|
* 14 Sep 88 Steven Glass
|
|
*
|
|
* Table index is only one byte wide so I mask result
|
|
*
|
|
****************************************************************
|
|
|
|
|
|
sep #$30
|
|
longa off
|
|
longi off
|
|
|
|
jsl ToReadBram ; read ram first
|
|
lda 7,s ; get parm index
|
|
and #$00FF
|
|
tax ; Turn index into buffer address
|
|
lda >BParamIndexToTable,x
|
|
and #$00FF
|
|
tax
|
|
lda 9,s ; get data
|
|
sta >BramBuffer,x ; move to BRAM buffer
|
|
jsl ToWriteBram ; now write ram
|
|
rep #$30
|
|
|
|
longa on
|
|
longi on
|
|
jmp oEndCall4
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
ReadBParam PROC
|
|
*
|
|
* Returns the specified byte from the battery RAM on the stack.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* Space for result : word
|
|
* ID of Parameter to read : word
|
|
*
|
|
* Outputs:
|
|
* Parameter value : word
|
|
*
|
|
* External Refs:
|
|
import BParamIndexToTable
|
|
*
|
|
* Entry Points:
|
|
* none
|
|
*
|
|
longa on ; mode
|
|
longi on
|
|
*
|
|
* Change History
|
|
*
|
|
* 17 Jun 88 Steven Glass
|
|
*
|
|
* This routine had always called the routine which did an actual
|
|
* read of the battery RAM. This is not necessary since the
|
|
* battery ram buffer is always correct before the read.
|
|
*
|
|
* Making this change we save the read time (1/10 second with
|
|
* interrupts off).
|
|
*
|
|
* 10 Sep 88 Steven Glass
|
|
*
|
|
* Index number is directed through table, rather than being
|
|
* actual memory location in the BRAM
|
|
*
|
|
*
|
|
* 14 Sep 88 Steven Glass
|
|
*
|
|
* Table index is only one byte wide so I mask result
|
|
*
|
|
*
|
|
****************************************************************
|
|
DefineStack
|
|
RTL1 block 3
|
|
RTL2 block 3
|
|
ParamID word
|
|
ResultValue word
|
|
|
|
lda ParamID,s ; get parm index
|
|
and #$00FF
|
|
tax ; Turn index into buffer address
|
|
lda >BParamIndexToTable,x
|
|
and #$00FF
|
|
tax
|
|
lda >BramBuffer,x ; move from BRAM buffer
|
|
and #$00FF
|
|
sta ResultValue,s
|
|
jmp oEndCall2
|
|
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
BParamIndexToTable PROC
|
|
*
|
|
* This is a table of addresses in the battery RAM. The
|
|
* zeroth entry gives the address of item 0 in the RAM. The
|
|
* next entry gives the address of the next item, etc.
|
|
*
|
|
****************************************************************
|
|
|
|
|
|
dc.b $00 ; $00 Port Type for Port 1
|
|
dc.b $01 ; $01 Line Length
|
|
dc.b $02 ; $02 Delete First LF after CR
|
|
dc.b $03 ; $03 Add LF after CR
|
|
dc.b $04 ; $04 Echo
|
|
dc.b $05 ; $05 Buffering
|
|
dc.b $06 ; $06 Baud
|
|
dc.b $07 ; $07 Parity
|
|
dc.b $08 ; $08 Data/Stop Bits
|
|
dc.b $09 ; $09 DCD Handshake
|
|
dc.b $0A ; $0A DSR/DTR Handshake
|
|
dc.b $0B ; $0B XON/XOFF Handshake
|
|
dc.b $0C ; $0C Port Type for Port 2
|
|
dc.b $0D ; $0D Line Length
|
|
dc.b $0E ; $0E Delete First LF after CR
|
|
dc.b $0F ; $0F Add LF after CR
|
|
|
|
dc.b $10 ; $10 Echo
|
|
dc.b $11 ; $11 Buffering
|
|
dc.b $12 ; $12 Baud
|
|
dc.b $13 ; $13 Parity
|
|
dc.b $14 ; $14 Data/Stop Bits
|
|
dc.b $15 ; $15 DCD Handshake
|
|
dc.b $16 ; $16 DSR/DTR Handshake
|
|
dc.b $17 ; $17 XON/XOFF Handshake
|
|
dc.b $18 ; $18 Display Type
|
|
dc.b $19 ; $19 Columns
|
|
dc.b $1A ; $1A Text Color
|
|
dc.b $1B ; $1B Background Color
|
|
dc.b $1C ; $1C Border Color
|
|
dc.b $1D ; $1D Display Cycle Rate (Hertz)
|
|
dc.b $1E ; $1E Volume
|
|
dc.b $1F ; $1F Pitch
|
|
|
|
dc.b $20 ; $20 Speed
|
|
dc.b $58 ; $21 Fake Slot 1
|
|
dc.b $22 ; $22 Slot 2
|
|
dc.b $23 ; $23 Slot 3
|
|
dc.b $24 ; $24 Slot 4
|
|
dc.b $25 ; $25 Slot 5
|
|
dc.b $26 ; $26 Slot 6
|
|
dc.b $27 ; $27 Slot 7
|
|
dc.b $28 ; $28 Startup Slot
|
|
dc.b $29 ; $29 Display Language
|
|
dc.b $2A ; $2A Keyboard Layout
|
|
dc.b $2B ; $2B Keyboard Buffering
|
|
dc.b $2C ; $2C Repeat Speed
|
|
dc.b $2D ; $2D Repeat Delay
|
|
dc.b $3A ; $2E Double Click
|
|
dc.b $2E ; $2F Cursor Flash
|
|
|
|
dc.b $2F ; $30 Shift Caps/Lower Case
|
|
dc.b $30 ; $31 Fast Space & Delete keys
|
|
dc.b $31 ; $32 Dual Speed Keys
|
|
dc.b $39 ; $33 Mouse Tracking
|
|
dc.b $34 ; $34 Date Format
|
|
dc.b $35 ; $35 Time Format
|
|
dc.b $36 ; $36 Min Ram Disk Size
|
|
dc.b $37 ; $37 Max Ram Disk Size
|
|
dc.b $3E ; $38 Number of Languages
|
|
dc.b $3F ; $39 First Language
|
|
dc.b $40 ; $3A Second Language
|
|
dc.b $41 ; $3B Third Language
|
|
dc.b $42 ; $3C Fourth Language
|
|
dc.b $43 ; $3D Fifth Language
|
|
dc.b $44 ; $3E Sixth Language
|
|
dc.b $45 ; $3F Seventh Language
|
|
|
|
dc.b $46 ; $40 Eightth Language
|
|
dc.b $47 ; $41 Number of Layouts
|
|
dc.b $48 ; $42 First Layout
|
|
dc.b $49 ; $43 Second Layout
|
|
dc.b $4A ; $44 Third Layout
|
|
dc.b $4B ; $45 Fourth Layout
|
|
dc.b $4C ; $46 Fifth Layout
|
|
dc.b $4D ; $47 Sixth Layout
|
|
dc.b $4E ; $48 Seventh Layout
|
|
dc.b $4F ; $49 Eightth Layout
|
|
dc.b $50 ; $4A Ninth Layout
|
|
dc.b $51 ; $4B Tenth Layout
|
|
dc.b $52 ; $4C Eleventh Layout
|
|
dc.b $53 ; $4D Twelvth Layout
|
|
dc.b $54 ; $4E Thirteenth Layout
|
|
dc.b $55 ; $4F Fourteenth Layout
|
|
|
|
dc.b $56 ; $50 Fifteenth Layout
|
|
dc.b $57 ; $51 Sixteenth Layout
|
|
dc.b $32 ; $52 Disk Eject 1
|
|
dc.b $33 ; $53 Disk Eject 2
|
|
dc.b $38 ; $54 Reset RAM at next Reset
|
|
dc.b $3B ; $55 Delay To Start
|
|
dc.b $3C ; $56 Acceleration
|
|
dc.b $3D ; $57 Maximum Speed
|
|
dc.b $58 ; $58 new Slot 1
|
|
dc.b $59 ; $59
|
|
dc.b $5A ; $5A
|
|
dc.b $5B ; $5B
|
|
dc.b $5C ; $5C
|
|
dc.b $5D ; $5D
|
|
dc.b $5E ; $5E
|
|
dc.b $5F ; $5F
|
|
|
|
dc.b $60 ; $60
|
|
dc.b $61 ; $61
|
|
dc.b $62 ; $62
|
|
dc.b $63 ; $63
|
|
dc.b $64 ; $64
|
|
dc.b $65 ; $65
|
|
dc.b $66 ; $66
|
|
dc.b $67 ; $67
|
|
dc.b $68 ; $68
|
|
dc.b $69 ; $69
|
|
dc.b $6A ; $6A
|
|
dc.b $6B ; $6B
|
|
dc.b $6C ; $6C
|
|
dc.b $6D ; $6D
|
|
dc.b $6E ; $6E
|
|
dc.b $6F ; $6F
|
|
|
|
dc.b $70 ; $70
|
|
dc.b $71 ; $71
|
|
dc.b $72 ; $72
|
|
dc.b $73 ; $73
|
|
dc.b $74 ; $74
|
|
dc.b $75 ; $75
|
|
dc.b $76 ; $76
|
|
dc.b $77 ; $77 Reserved
|
|
dc.b $78 ; $78 PassWord
|
|
dc.b $79 ; $79 PassWord
|
|
dc.b $7A ; $7A PassWord
|
|
dc.b $7B ; $7B PassWord
|
|
dc.b $7C ; $7C PassWord
|
|
dc.b $7D ; $7D PassWord
|
|
dc.b $7E ; $7E PassWord
|
|
dc.b $7F ; $7F PassWord
|
|
|
|
dc.b $80 ; $80 AppleTalk Node Number
|
|
dc.b $81 ; $81 OS Variables
|
|
dc.b $82 ; $82
|
|
dc.b $83 ; $83
|
|
dc.b $84 ; $84
|
|
dc.b $85 ; $85
|
|
dc.b $86 ; $86
|
|
dc.b $87 ; $87
|
|
dc.b $88 ; $88
|
|
dc.b $89 ; $89
|
|
dc.b $8A ; $8A
|
|
dc.b $8B ; $8B
|
|
dc.b $8C ; $8C
|
|
dc.b $8D ; $8D
|
|
dc.b $8E ; $8E
|
|
dc.b $8F ; $8F
|
|
|
|
dc.b $90 ; $90
|
|
dc.b $91 ; $91
|
|
dc.b $92 ; $92
|
|
dc.b $93 ; $93
|
|
dc.b $94 ; $94
|
|
dc.b $95 ; $95
|
|
dc.b $96 ; $96
|
|
dc.b $97 ; $97
|
|
dc.b $98 ; $98
|
|
dc.b $99 ; $99
|
|
dc.b $9A ; $9A
|
|
dc.b $9B ; $9B
|
|
dc.b $9C ; $9C
|
|
dc.b $9D ; $9D
|
|
dc.b $9E ; $9E
|
|
dc.b $9F ; $9F
|
|
|
|
dc.b $A0 ; $A0
|
|
dc.b $A1 ; $A1
|
|
dc.b $A2 ; $A2
|
|
dc.b $A3 ; $A3
|
|
dc.b $A4 ; $A4
|
|
dc.b $A5 ; $A5
|
|
dc.b $A6 ; $A6
|
|
dc.b $A7 ; $A7
|
|
dc.b $A8 ; $A8
|
|
dc.b $A9 ; $A9
|
|
dc.b $AA ; $AA
|
|
dc.b $AB ; $AB
|
|
dc.b $AC ; $AC
|
|
dc.b $AD ; $AD
|
|
dc.b $AE ; $AE
|
|
dc.b $AF ; $AF
|
|
|
|
dc.b $B0 ; $B0
|
|
dc.b $B1 ; $B1
|
|
dc.b $B2 ; $B2
|
|
dc.b $B3 ; $B3
|
|
dc.b $B4 ; $B4
|
|
dc.b $B5 ; $B5
|
|
dc.b $B6 ; $B6
|
|
dc.b $B7 ; $B7
|
|
dc.b $B8 ; $B8
|
|
dc.b $B9 ; $B9
|
|
dc.b $BA ; $BA
|
|
dc.b $BB ; $BB
|
|
dc.b $BC ; $BC
|
|
dc.b $BD ; $BD
|
|
dc.b $BE ; $BE
|
|
dc.b $BF ; $BF OS Variables
|
|
|
|
dc.b $C0 ; $C0 Reserved
|
|
dc.b $C1 ; $C1
|
|
dc.b $C2 ; $C2
|
|
dc.b $C3 ; $C3
|
|
dc.b $C4 ; $C4
|
|
dc.b $C5 ; $C5
|
|
dc.b $C6 ; $C6
|
|
dc.b $C7 ; $C7
|
|
dc.b $C8 ; $C8
|
|
dc.b $C9 ; $C9
|
|
dc.b $CA ; $CA
|
|
dc.b $CB ; $CB
|
|
dc.b $CC ; $CC
|
|
dc.b $CD ; $CD
|
|
dc.b $CE ; $CE
|
|
dc.b $CF ; $CF
|
|
|
|
dc.b $D0 ; $D0
|
|
dc.b $D1 ; $D1
|
|
dc.b $D2 ; $D2
|
|
dc.b $D3 ; $D3
|
|
dc.b $D4 ; $D4
|
|
dc.b $D5 ; $D5
|
|
dc.b $D6 ; $D6
|
|
dc.b $D7 ; $D7
|
|
dc.b $D8 ; $D8
|
|
dc.b $D9 ; $D9
|
|
dc.b $DA ; $DA
|
|
dc.b $DB ; $DB
|
|
dc.b $DC ; $DC
|
|
dc.b $DD ; $DD
|
|
dc.b $DE ; $DE
|
|
dc.b $DF ; $DF
|
|
|
|
dc.b $E0 ; $E0
|
|
dc.b $E1 ; $E1
|
|
dc.b $E2 ; $E2
|
|
dc.b $E3 ; $E3
|
|
dc.b $E4 ; $E4
|
|
dc.b $E5 ; $E5
|
|
dc.b $E6 ; $E6
|
|
dc.b $E7 ; $E7
|
|
dc.b $E8 ; $E8
|
|
dc.b $E9 ; $E9
|
|
dc.b $EA ; $EA
|
|
dc.b $EB ; $EB
|
|
dc.b $EC ; $EC
|
|
dc.b $ED ; $ED
|
|
dc.b $EE ; $EE
|
|
dc.b $EF ; $EF
|
|
|
|
dc.b $F0 ; $F0
|
|
dc.b $F1 ; $F1
|
|
dc.b $F2 ; $F2
|
|
dc.b $F3 ; $F3
|
|
dc.b $F4 ; $F4
|
|
dc.b $F5 ; $F5
|
|
dc.b $F6 ; $F6
|
|
dc.b $F7 ; $F7
|
|
dc.b $F8 ; $F8
|
|
dc.b $F9 ; $F9
|
|
dc.b $FA ; $FA
|
|
dc.b $FB ; $FB Reserved
|
|
dc.b $FC ; $FC Check Sum
|
|
dc.b $FD ; $FD Check Sum
|
|
dc.b $FE ; $FE Check Sum
|
|
dc.b $FF ; $FF Check Sum
|
|
|
|
|
|
|
|
|
|
ENDP
|
|
|
|
|
|
title 'Time Routines'
|
|
****************************************************************
|
|
*
|
|
* RdTimeHex:
|
|
* Input Word Space for result
|
|
* Input Word Space for result
|
|
* Input Word Space for result
|
|
* Input Word Space for result
|
|
* Output Byte Year
|
|
* Output Byte Month (0...11)
|
|
* Output Byte Day (0...30)
|
|
* Output Byte Hour (0...23)
|
|
* Output Byte Minute (0...59)
|
|
* Output Byte Second (0...59)
|
|
* Output Byte Null
|
|
* Output Byte Day of Week (0....6)
|
|
*
|
|
****************************************************************
|
|
RdTimeHex PROC
|
|
|
|
D0 equ $E103E9
|
|
D1 equ D0+4
|
|
D2 equ D1+4
|
|
D3 equ D2+4
|
|
D4 equ D3+4
|
|
|
|
OrigDir equ 1
|
|
OrigDBR equ OrigDir+2
|
|
OrigP equ OrigDBR+1
|
|
rtl1 equ OrigP+1
|
|
rtl2 equ rtl1+3
|
|
Second equ rtl2+3
|
|
Minute equ Second+1
|
|
Hour equ Minute+1
|
|
Year equ Hour+1
|
|
Day equ Year+1
|
|
Month equ Day+1
|
|
null equ Month+1
|
|
WkDay equ Null+1
|
|
|
|
WSsize equ 10 ; 10 words - DUMMY !!!
|
|
|
|
sep #$30 ; off to 8 bit land
|
|
jsl ToReadTime ; read clock
|
|
rep #$30 ; then back to 16 bit land
|
|
bcc GotTimeOK ; if read clock
|
|
ldx #firmTaskErr ; set error flag
|
|
jmp oErrOut0
|
|
|
|
*
|
|
* now convert Binary time to Hex time format
|
|
*
|
|
|
|
GotTimeOK ;
|
|
php ; save interrupt state
|
|
sei ; and disable interrupts
|
|
phb ; save data bank
|
|
pea $E1E1 ; and set to our data area
|
|
plb
|
|
plb
|
|
phd ; save direct page
|
|
tsc ; turn stack into zp
|
|
tcd
|
|
|
|
*
|
|
* Have number of seconds N 1984 in ClkRData.
|
|
* DN = number of days elapsed = N div 86400
|
|
* HMS = number of seconds in last day = N mod 86400
|
|
*
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
pea $0000
|
|
pea $0000
|
|
lda |ClkRData+2 ; numerator = N
|
|
pha
|
|
lda |ClkRData
|
|
pha
|
|
pea $0001 ; Denom = 86400
|
|
pea $5180
|
|
jsl ToLDivide ; want DN
|
|
pla ; DN = quotient
|
|
sta |D0
|
|
sta |D2 ; and make a copy in D2
|
|
pla
|
|
sta |D0+2
|
|
sta |D2+2
|
|
pla ; HMS = remainder
|
|
sta |D1
|
|
pla
|
|
sta |D1+2
|
|
*
|
|
* YearsGone = (DN * 4) div 1461 where 1461 is 4 * 365 + 1
|
|
* Formula depends on leap year being the first of the four.
|
|
*
|
|
asl |D2 ; DN * 4
|
|
rol |D2+2
|
|
asl |D2
|
|
rol |D2+2
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
pea $0000
|
|
pea $0000
|
|
lda |D2+2 ; YearsGone = (DN*4) div 1461
|
|
pha
|
|
lda |D2
|
|
pha
|
|
pea $0000 ; 1461 = $000005B5
|
|
pea $05B5
|
|
jsl ToLDivide
|
|
clc ; YG referenced to 1904
|
|
pla
|
|
sta |D2
|
|
adc #0004
|
|
sep #$20 ; 8 bit 'm'
|
|
sta year
|
|
rep #$20 ; 16 bit 'm'
|
|
clc
|
|
lda |D2
|
|
adc #1904
|
|
sta |D2 ; hex year
|
|
pla
|
|
sta |D2+2
|
|
*
|
|
* Need number of days in Jan+Feb just below.
|
|
* Take YEAR mod 3 before clearing year.
|
|
*
|
|
lda #59 ; assume not leap year
|
|
sta |D3
|
|
stz |D3+2
|
|
lda #3 ; Year MOD 3
|
|
and |D2
|
|
bne NotLeap
|
|
inc |D3
|
|
NotLeap ;
|
|
pla ; DOY * 4 in D2
|
|
sta |D2
|
|
pla
|
|
sta |D2+2 ; DOY = D2 div 4
|
|
lsr |D2+2
|
|
ror |D2
|
|
lsr |D2+2
|
|
ror |D2 ; DOY in D2
|
|
*
|
|
* Computing Month/Day from DOY is an exercise in interpolation.
|
|
* As a function of DOY, Month is a step function. Because of
|
|
* the leap year glitch, convenient to restart function at March
|
|
*
|
|
* DOY MONTH
|
|
*--------------------------------------------------------------
|
|
* 0-31 1 January
|
|
* 31-58 2 February for non leap year
|
|
* 31-59 2 February for leap year
|
|
* 0-30 3 March
|
|
* 31-60 4 April
|
|
* 61-91 5 May
|
|
* 92-121 6 June
|
|
* 122-152 7 July
|
|
* 153-183 8 August
|
|
* 184-213 9 September
|
|
* 214-244 10 October
|
|
* 245-274 11 November
|
|
* 275-305 12 December
|
|
*
|
|
* The linear interpolator is ((DOY * 128) + 71) div 3919
|
|
*
|
|
lda #1 ; month offset, 1 or 3
|
|
sta |D4
|
|
lda |D2 ; 59/60 versus DOY
|
|
cmp |D3
|
|
blt JanFeb ; less than means Jan or Feb
|
|
inc |D4 ; else adjust month offset
|
|
inc |D4
|
|
sec ; start DOY at march
|
|
lda |D2
|
|
sbc |D3
|
|
sta |D2
|
|
lda |D2+2
|
|
sbc |D3+2
|
|
sta |D2+2
|
|
JanFeb ;
|
|
ldy #7 ; DOY * 128
|
|
MultDOY ;
|
|
asl |D2
|
|
rol |D2+2
|
|
dey
|
|
bne MultDOY
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
clc ; (DOY * 128) + 71
|
|
lda #71
|
|
adc |D2
|
|
sta |D2
|
|
pha ; NUM = (DOY * 128) + 71
|
|
lda #0
|
|
adc |D2+2
|
|
sta |D2+2
|
|
pea $0F4F ; DEN = 3919
|
|
jsl ToUDivide
|
|
clc
|
|
pla ; month = Quot + MOffset
|
|
adc |D4
|
|
sta |D2+2 ; D2 (MSB) = Month (1..12)
|
|
sep #$20 ; 8 bit 'm'
|
|
dec a ; make month (0.....11)
|
|
sta Month
|
|
rep #$20 ; 16 bit 'm'
|
|
pla ; divide by 128 to get DOM
|
|
ldy #7
|
|
DivDOM ;
|
|
lsr a
|
|
dey
|
|
bne DivDOM
|
|
sep #$20 ; 8 bit 'm'
|
|
sta Day ; day (0....30)
|
|
rep #$20
|
|
*
|
|
* Hours = HMS div 3600
|
|
* MS = HMS mod 3600
|
|
* Minutes = MS div 60
|
|
* Seconds = MS mod 60
|
|
*
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
pea $0000
|
|
pea $0000
|
|
lda |D1+2 ; Numerator = HMS
|
|
pha
|
|
lda |D1
|
|
pha
|
|
pea $0000 ; Denominator = 3600
|
|
pea $0E10
|
|
jsl ToLDivide
|
|
pla
|
|
plx ; Hours = Quot
|
|
sep #$20 ; 8 bit 'm'
|
|
sta Hour
|
|
rep #$20
|
|
pla ; MS = remainder
|
|
plx
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
pha ; Numerator = MS
|
|
pea $003C ; Denominator = 60
|
|
jsl ToUDivide
|
|
pla ; Minutes = Quot
|
|
sep #$20 ; 8 bit 'm'
|
|
sta Minute
|
|
pla
|
|
sta Second
|
|
pla ; clean up
|
|
rep #$30 ; 16 bit 'm'
|
|
*
|
|
* Finally get the day of week = ((DN + 5) mod 7) + 1
|
|
* The 5 is added since 1 Jan 1904 was a Friday.
|
|
*
|
|
pea $0000 ; space for divide
|
|
pea $0000
|
|
pea $0000
|
|
pea $0000
|
|
clc
|
|
lda #5 ; DN+5
|
|
adc D0
|
|
tax
|
|
lda #0
|
|
adc D0+2
|
|
pha
|
|
phx
|
|
pea $0000
|
|
pea $0007
|
|
jsl ToLDivide ; ((DN + 5) mod 7)
|
|
pla
|
|
pla
|
|
pla ; Get DOW-1
|
|
inc a ; ((DN + 5) mod 7) + 1
|
|
plx
|
|
sep #$20 ; 8 bit 'm'
|
|
sta WkDay ; store day of week
|
|
rep #$20 ; 16 bit 'm'
|
|
pld ; restore direct page
|
|
plb ; restore data area
|
|
plp ; restore interrupt state
|
|
jmp oEndCall0 ; all done
|
|
|
|
ENTRY ToLDivide
|
|
ToLDivide ;
|
|
jsl LongDiv
|
|
rtl
|
|
|
|
ENTRY ToUDivide
|
|
ToUDivide ;
|
|
jsl UDivide
|
|
rtl
|
|
|
|
ENDP
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
* WrTimeHex:
|
|
*
|
|
* Input Byte second (0.....59)
|
|
* Input Byte Minute (0.....59)
|
|
* Input Byte Hour (0.....23)
|
|
* Input Byte Day (0.....30)
|
|
* Input Byte Month (0.....11)
|
|
* Input Byte Year
|
|
*
|
|
* Change History
|
|
*
|
|
* February 18, 1987 Ray Montagne
|
|
*
|
|
* Wrong error code was being returned.
|
|
*
|
|
****************************************************************
|
|
|
|
WrTimeHex PROC
|
|
|
|
D0 equ $E103E9
|
|
D1 equ D0+4
|
|
D2 equ D1+4
|
|
D3 equ D2+4
|
|
D4 equ D3+4
|
|
|
|
OrigDir equ 1
|
|
OrigDBR equ OrigDir+2
|
|
OrigP equ OrigDBR+1
|
|
rtl1 equ OrigP+1
|
|
rtl2 equ rtl1+3
|
|
Second equ rtl2+3
|
|
Minute equ Second+1
|
|
Hour equ Minute+1
|
|
Year equ Hour+1
|
|
Day equ Year+1
|
|
Month equ Day+1
|
|
|
|
WSsize equ 10 ; is 20 bytes workspace area
|
|
|
|
php ; save interrupt state
|
|
sei ; and disable IRQ
|
|
phb ; save data area
|
|
pea $E1E1 ; set our own
|
|
plb
|
|
plb
|
|
phd ; save direct page
|
|
tsc ; set stack = zp
|
|
tcd
|
|
sep #$30 ; 8 bit 'm' and 'x'
|
|
longa off
|
|
longi off
|
|
phb ; save DBR for bounds chk
|
|
phk ; set DBR to code segment
|
|
plb
|
|
ldy Month ; get month
|
|
lda Year ; get year
|
|
and #3 ; leap year?
|
|
bne DayCheck ; no
|
|
cpy #1 ; if yes, is it February?
|
|
bne DayCheck ; no
|
|
ldy #12 ; if February & leap year
|
|
DayCheck ;
|
|
lda Day ; and day
|
|
cmp MonthLen,y ; check valid day ?
|
|
rep #$30 ; 16 bit 'm' and 'x'
|
|
longa on
|
|
longi on
|
|
bcc DayOK ; if valid
|
|
plb
|
|
pld ; restore direct page
|
|
plb ; and data bank
|
|
plp ; restore interrupt state
|
|
ldx #badInputErr ; bad input parm error changed 18 Feb
|
|
; ; 87 by RBM
|
|
jmp oErrOut6
|
|
DayOK ;
|
|
plb ; restore DBR
|
|
|
|
*
|
|
* Have Year/Month/Day/Hour/Minute/Second in a sequence of words
|
|
* in direct page.
|
|
*
|
|
* DAYSGONE * 86400 + HOURS * 3600 + MINUTES * 60 + SECONDS
|
|
*
|
|
* Do the easy part with HOURS, MINUTES, and SECONDS.
|
|
*
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
pea $0000
|
|
pea $0000
|
|
lda Hour ; Convert hour to minutes
|
|
and #$00FF
|
|
pha
|
|
pea $003C ; Hour * 60
|
|
jsl ToMult
|
|
clc
|
|
lda Minute ; (Hour * 60) + Minute
|
|
and #$00FF
|
|
adc 1,s
|
|
sta 1,s
|
|
lda #0
|
|
adc 3,s
|
|
sta 3,s
|
|
pla
|
|
plx
|
|
pha
|
|
pea $003C ; ((Hour * 60) + Minute) * 60
|
|
jsl ToMult
|
|
clc
|
|
lda Second ; now add in seconds
|
|
and #$00FF
|
|
adc 1,s
|
|
sta 1,s
|
|
lda #0
|
|
adc 3,s
|
|
sta 3,s
|
|
pla ; and store in D0
|
|
sta |D0
|
|
pla
|
|
sta |D0+2
|
|
*
|
|
* Compute DAYSGONE in D1
|
|
*
|
|
lda Day ; Days
|
|
and #$00FF ; have day (0.......30)
|
|
sta |D1
|
|
stz |D1+2
|
|
lda Month ; get Month
|
|
and #$00FF ; have Month (0.....11)
|
|
inc a ; make Month (1.....12)
|
|
sta |D2
|
|
stz |D2+2
|
|
lda Year ; and Year
|
|
and #$00FF
|
|
clc
|
|
adc #1900
|
|
sta |D3
|
|
sta |D4 ; copy year for LEAP test
|
|
stz |D3+2
|
|
stz |D4+2
|
|
*
|
|
* To find number of days in elapsed years use:
|
|
* ((YEARSGONE * 1461) + 3) div 4
|
|
* Formula depends on leap year being the first of 4.
|
|
*
|
|
sec ; years gone
|
|
lda |D3
|
|
sbc #1904
|
|
sta |D3
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
pha ; YearsGone * 1461
|
|
pea $05B5
|
|
jsl ToMult
|
|
clc
|
|
lda #3 ; (YearsGone * 1461) + 3
|
|
adc 1,s
|
|
sta 1,s
|
|
lda #0
|
|
adc 3,s
|
|
lsr a ; ((YG * 1461) + 3) div 4
|
|
sta 3,s
|
|
lda 1,s
|
|
ror a
|
|
sta 1,s
|
|
lda 3,s
|
|
lsr a
|
|
sta 3,s
|
|
sta |D3+2
|
|
lda 1,s
|
|
ror a
|
|
sta 1,s
|
|
sta |D3
|
|
pla ; accumulate days gone
|
|
clc
|
|
adc |D1
|
|
sta |D1
|
|
pla
|
|
adc |D1+2
|
|
sta |D1+2 ; D1 = DAYSGONE
|
|
*
|
|
* As above, the tough part is finding the number of days in
|
|
* elapsed months.
|
|
*
|
|
dec |D2 ; month-1 (ranges 0..11)
|
|
lda |D2 ; 2 or more is March
|
|
cmp #2
|
|
blt DSJanFeb
|
|
|
|
dec |D2 ; Month-3 (Restart at March)
|
|
dec |D2
|
|
lda #59 ; Days in Jan + Feb
|
|
sta |D3
|
|
lda |D4 ; Check for leap year, MOD 3
|
|
and #3
|
|
bne DSNotLeap ; if not leap year
|
|
inc |D3 ; Leap Days in Jan + Feb
|
|
|
|
DSNotLeap ;
|
|
clc
|
|
lda |D3 ; some more elapsed days
|
|
adc |D1
|
|
sta |D1
|
|
|
|
DSJanFeb ;
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
lda |D2 ; Month * 3917
|
|
pha
|
|
lda #3917
|
|
pha
|
|
jsl ToMult
|
|
clc
|
|
lda #52 ; (Month * 3917) + 52
|
|
adc 1,s
|
|
sta 1,s
|
|
lda #0
|
|
adc 3,s
|
|
sta 3,s
|
|
pla
|
|
sta |D2
|
|
pla
|
|
sta |D2+2
|
|
ldy #7 ; ((Month * 3917) + 52 div 128
|
|
Div128 ;
|
|
lsr |D2+2
|
|
ror |D2
|
|
dey
|
|
bne Div128
|
|
clc
|
|
lda |D1 ; more elapsed days
|
|
adc |D2
|
|
sta |D1
|
|
lda |D1+2
|
|
adc |D2+2
|
|
sta |D1+2
|
|
*
|
|
* Finally multiply the number of days elapsed by
|
|
* 24 * 60 * 60 = 86400 = 43200 * 2
|
|
*
|
|
pea $0000 ; space for result
|
|
pea $0000
|
|
pea $A8C0 ; (43200)
|
|
lda |D1
|
|
pha
|
|
jsl ToMult
|
|
lda 1,s ; (43200 * 2)
|
|
asl a
|
|
sta 1,s
|
|
lda 3,s
|
|
rol a
|
|
sta 3,s
|
|
clc
|
|
pla
|
|
adc |D0
|
|
sta |ClkWData ; store to set time
|
|
pla
|
|
adc |D0+2
|
|
sta |ClkWData+2
|
|
sep #$30 ; off to 8 bit land
|
|
jsl ToWriteTime ; set the clock
|
|
rep #$30 ; back to 16 bit land
|
|
pld ; restore direct page
|
|
plb ; restore data area
|
|
rol a ; save carry
|
|
plp ; restore interrupt state
|
|
ror a ; and restore carry
|
|
bcs WrHexErr ; if can't write time
|
|
jmp oEndCall6 ; else cleanup & return
|
|
|
|
WrHexErr ;
|
|
ldx #firmTaskErr ; set error flag
|
|
jmp oErrOut6 ; and return with error
|
|
|
|
ENTRY ToMult
|
|
ToMult ;
|
|
jsl Multiply
|
|
rtl
|
|
|
|
MonthLen ;
|
|
DC.B 31 ; days in January
|
|
DC.B 28 ; days in Febuary (non-leap)
|
|
DC.B 31 ; days in March
|
|
DC.B 30 ; days in April
|
|
DC.B 31 ; days in May
|
|
DC.B 30 ; days in June
|
|
DC.B 31 ; days in July
|
|
DC.B 31 ; days in August
|
|
DC.B 30 ; days in September
|
|
DC.B 31 ; days in October
|
|
DC.B 30 ; days in November
|
|
DC.B 31 ; days in December
|
|
DC.B 29 ; days in February (leap)
|
|
|
|
ENDP
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
* RdATime:
|
|
*
|
|
* Input LongWord Buffer address
|
|
*
|
|
* Format of data in buffer is dependent on the values set
|
|
* in the battery ram for time and date format.
|
|
*
|
|
* Date Format Time Format ASCII Format
|
|
* ----------- ----------- -----------------------
|
|
* 0 0 mm/dd/yy HH:MM:SS AM-PM
|
|
* 1 0 dd/mm/yy HH:MM:SS AM-PM
|
|
* 2 0 yy/mm/dd HH:MM:SS AM-PM
|
|
* 0 1 mm/dd/yy HH:MM:SS
|
|
* 1 1 dd/mm/yy HH:MM:SS
|
|
* 2 1 yy/mm/dd HH:MM:SS
|
|
*
|
|
* where : HH = Hour
|
|
* MM = Minute
|
|
* SS = Second
|
|
* mm = Month
|
|
* dd = Day
|
|
* yy = Year
|
|
*
|
|
****************************************************************
|
|
|
|
RdATime PROC
|
|
|
|
OrigDir equ 1
|
|
OrigDBR equ OrigDir+2
|
|
rtl1 equ OrigDBR+1
|
|
rtl2 equ rtl1+3
|
|
pointer equ rtl2+3
|
|
|
|
NewDir equ 1
|
|
Second equ NewDir+2
|
|
Minute equ Second+1
|
|
Hour equ Minute+1
|
|
Year equ Hour+1
|
|
Day equ Year+1
|
|
Month equ Day+1
|
|
Null equ Month+1
|
|
WkDay equ Null+1
|
|
|
|
phb ; save data area
|
|
phd ; save direct page
|
|
tsc ; turn stack into zp
|
|
tcd
|
|
pea $0000 ; setup for RdHexTime
|
|
pea $0000
|
|
pea $0000
|
|
pea $0000
|
|
jsl ToRdHexT ; now go get it
|
|
bcc NoAtimeErr ; if no error
|
|
jmp ATimeErr ; if can't get it
|
|
|
|
*
|
|
* Now convert HEX time to ascii time and send to buffer
|
|
*
|
|
|
|
NoAtimeErr ;
|
|
ldx Pointer ; get pointer to App. Buffer
|
|
sep #$20 ; 8 bit 'm'
|
|
longa off
|
|
lda Pointer+2
|
|
pha ; set App. Buffer bank
|
|
plb
|
|
phd ; save new dir
|
|
tsc ; and make stack into zp
|
|
tcd
|
|
lda #$A0 ; time/date delimiter
|
|
sta |8,x
|
|
sta |17,x
|
|
lda >UserAMPM ; get time format
|
|
rep #$20 ; 16 bit 'm'
|
|
longa on
|
|
php ; time format in Z flag
|
|
ldy #$A0A0 ; assume 24 hour format
|
|
lda Hour ; get hour
|
|
plp ; Z=1 says 12 hour format
|
|
bne Fmt24 ; else 24 hour format
|
|
ldy #$CDC1 ; assume AM
|
|
and #$00FF ; truncate hour
|
|
cmp #12 ; hour less than 12?
|
|
blt StillAM ; if yes, then still AM
|
|
ldy #$CDD0 ; else set PM
|
|
StillAM ;
|
|
cmp #13 ; if > 13:00 then subtract 12
|
|
blt H0TO12 ; yes
|
|
sec ; else hour=hour-12
|
|
sbc #12
|
|
bra Fmt24
|
|
H0TO12 ;
|
|
cmp #0 ; if zero, make it 12
|
|
bne Fmt24 ; but if its not, dont
|
|
lda #12 ;
|
|
Fmt24 ;
|
|
jsr HexToAscii ; convert hour to ascii
|
|
sta |9,x ; stuff into App. Buffer
|
|
tya ; now set time format
|
|
sta |18,x
|
|
lda Minute ; convert minute
|
|
jsr HexToAscii
|
|
sta |12,x ; stuff into App. buffer
|
|
lda Second ; convert seconds
|
|
jsr HexToAscii
|
|
sta |15,x ; stuff into app. buffer
|
|
lda Month ; convert month
|
|
inc a ; 0=Jan
|
|
jsr HexToAscii
|
|
sta |0,x ; stuff into app. buffer
|
|
lda Day ; convert day
|
|
inc a ; 0=first day of month
|
|
jsr HexToAscii
|
|
sta |3,x ; stuff into app. buffer
|
|
lda Year ; convert Year
|
|
jsr HexToAscii
|
|
sta |6,x ; stuff into app. buffer
|
|
sep #$20 ; 8 bit 'm'
|
|
longa off
|
|
lda #$BA ; time delimiter
|
|
sta |11,x
|
|
sta |14,x
|
|
lda #$AF ; date delimiter
|
|
sta |2,x
|
|
sta |5,x
|
|
*
|
|
* Now blank all leading zeros
|
|
*
|
|
ldy #$A0 ; Yreg = ' '
|
|
lda |9,x ; first check hours
|
|
cmp #$B0 ; is it a zero ?
|
|
bne NoHrsZ ; no
|
|
tya
|
|
sta |9,x ; blank leading zero
|
|
NoHrsZ ;
|
|
lda |0,x ; now check month
|
|
cmp #$B0 ; is it a zero ?
|
|
bne NoMoZ ; no
|
|
tya
|
|
sta |0,x ; else blank leading zero
|
|
NoMoZ ;
|
|
lda |3,x ; now check day
|
|
cmp #$B0 ; is it a zero ?
|
|
bne NoDayZ ; no
|
|
tya ; else blank leading zero
|
|
sta |3,x
|
|
NoDayZ ;
|
|
lda >UserDATE ; get DATE format
|
|
rep #$20 ; 16 bit 'm'
|
|
longa on
|
|
beq DateFmt0 ; mm/dd/yy HH:MM:SS
|
|
and #$00FF ; limit options
|
|
pha
|
|
lda |3,x ; swap month and year
|
|
tay ; Yreg = dd
|
|
lda |0,x
|
|
sta |3,x
|
|
tya
|
|
sta |0,x ; dd/mm/yy
|
|
pla
|
|
dec a ; format 2?
|
|
beq DateFmt0 ; no
|
|
lda |6,x ; now swap year and day
|
|
sta |0,x
|
|
tya
|
|
sta |6,x
|
|
DateFmt0 ;
|
|
pld ; clean up stack
|
|
pla
|
|
pla
|
|
pla
|
|
pla
|
|
pld ; restore direct page
|
|
plb ; and data area
|
|
jmp oEndCall4 ; clean up and return
|
|
|
|
ATimeErr ;
|
|
pla ; clean up stack
|
|
pla
|
|
pla
|
|
pla
|
|
pld ; restore direct page
|
|
plb ; restore DBR
|
|
ldx #firmTaskErr ; set error flag
|
|
jmp oErrOut4 ; and return with error
|
|
|
|
ToRdHexT ;
|
|
jsl RdTimeHex ; go read HEX time
|
|
rtl
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
*
|
|
* Convert Hex to Ascii
|
|
*
|
|
* Input passed in low byte of 16 bit A register
|
|
* Output returned in 16 bit A register (Most significant in
|
|
* digit is in low byte of register. Both the X and Y registers
|
|
* are preserved.
|
|
*
|
|
****************************************************************
|
|
|
|
HexToAscii PROC
|
|
|
|
OrigDir equ 1
|
|
OrigY equ OrigDir+2
|
|
OrigX equ OrigY+2
|
|
Decimal equ OrigX+2
|
|
|
|
pha ; input data to convert
|
|
phx ; save App. buffer pointer
|
|
phy ; and this too!!!
|
|
phd ; save direct page
|
|
tsc ; turn stack into zp
|
|
tcd
|
|
sep #$30 ; 8 bit 'm' and 'x'
|
|
longa off
|
|
longi off
|
|
ldy #$02 ; number of times through loop
|
|
DecAsc1 ;
|
|
ldx #9 ; 8 bit and 1st time do nothing
|
|
lda #0
|
|
clc ; C=0 so 1st ROL leaves A=0
|
|
DecAsc2 ;
|
|
rol a
|
|
cmp #10 ; A >= 10 ?
|
|
blt DecAsc4 ; if <
|
|
sbc #10 ; C=1 from CMP and is left set
|
|
DecAsc4 ;
|
|
rol Decimal
|
|
dex
|
|
bne DecAsc2
|
|
ora #$B0 ; make an ASCII character
|
|
pha ; preserve on stack
|
|
dey
|
|
bne DecAsc1
|
|
rep #$30 ; 16 bit 'm' and 'x'
|
|
longa on
|
|
longi on
|
|
pla ; returned data
|
|
sta Decimal
|
|
pld ; clean up and r
|
|
ply ; restore pointer
|
|
plx ; restore App. buffer pointer
|
|
pla ; returned data in A reg
|
|
rts
|
|
|
|
ENDP
|
|
|
|
title 'Vector Routines'
|
|
****************************************************************
|
|
*
|
|
* SetVector (RefNum : integer; NewAdr : Long);
|
|
*
|
|
* Change History
|
|
*
|
|
* 26 Jul 88 Steven Glass
|
|
*
|
|
* Interrupts disabled during access.
|
|
*
|
|
* 23 Feb 89 Mensch
|
|
*
|
|
* Removed error checking.
|
|
****************************************************************
|
|
SetVector PROC
|
|
|
|
RTL1 equ 1
|
|
RTL2 equ RTL1+3
|
|
NewAdr equ RTL2+3
|
|
RefNum equ NewAdr+4
|
|
|
|
VTblLen equ $002D
|
|
|
|
lda RefNum,s ;get reference
|
|
and #$00FF ;mask excess
|
|
|
|
; Error checking removed 2/23/89
|
|
; cmp #VTblLen
|
|
; bge AnError ;if out of bounds
|
|
|
|
asl a ;and make index
|
|
asl a
|
|
tax
|
|
|
|
php
|
|
sei
|
|
|
|
lda NewAdr-1+1,s ;get vector addr 0-7
|
|
and #$FF00 ;patch 'JML' opcode in low byte
|
|
ora #$005C
|
|
sta >Dispatch1,x ;set A0-7 & op
|
|
lda NewAdr+1+1,s ;get addr 8-23
|
|
sta >Dispatch1+2,x ;set addr 8-23
|
|
|
|
|
|
plp
|
|
jmp oEndCall6
|
|
|
|
|
|
AnError ldx #badInputErr
|
|
jmp oErrOut6
|
|
|
|
ENDP
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
* GetVector (RefNum : integer; NewAdr : Long);
|
|
*
|
|
* Change History
|
|
*
|
|
* 26 Jul 88 Steven Glass
|
|
*
|
|
* Interrupts disabled during access.
|
|
*
|
|
* 23 Feb 89 Mensch
|
|
*
|
|
* Removed error checking.
|
|
****************************************************************
|
|
GetVector PROC
|
|
|
|
RTL1 equ 1
|
|
RTL2 equ RTL1+3
|
|
RefNum equ RTL2+3
|
|
Result equ RefNum+2
|
|
|
|
VTblLen equ $002D
|
|
|
|
lda RefNum,s ;get reference
|
|
and #$00FF ;mask excess
|
|
|
|
; Error checking removed 2/23/89
|
|
; cmp #VTblLen
|
|
; bge AnError ;if out of bounds
|
|
|
|
asl a ;and make index
|
|
asl a
|
|
tax
|
|
|
|
php
|
|
sei
|
|
|
|
lda >Dispatch1+1,x
|
|
sta Result+1,s
|
|
lda >Dispatch1+3,x
|
|
and #$00FF
|
|
sta Result+2+1,s
|
|
|
|
plp
|
|
|
|
jmp oEndCall2
|
|
|
|
|
|
AnError ldx #badInputErr
|
|
jmp oErrOut2
|
|
|
|
ENDP
|
|
|
|
title 'Heartbeat Routines'
|
|
****************************************************************
|
|
*
|
|
* Set System Heartbeat Vector
|
|
* Input LongWord Address
|
|
*
|
|
* Possible errors are :
|
|
* 3 = Task error (task already in queue)
|
|
* 4 = Header error (no signature in new task)
|
|
* 5 = Queue error (queue got trashed - system fatal)
|
|
* 6 = Task Not Found
|
|
*
|
|
****************************************************************
|
|
SetHeart PROC
|
|
|
|
OrigD equ 1
|
|
RTL1 equ OrigD+2
|
|
RTL2 equ RTL1+3
|
|
VPtr equ RTL2+3
|
|
|
|
phd
|
|
tsc ; make stack into zp
|
|
tcd
|
|
php ; save IRQ enbl status
|
|
sei ; 'cuz no interrupts for now !
|
|
lda #Irq_Heart ; install heartbeat handler
|
|
pha
|
|
xba
|
|
and #$FF00
|
|
ora #$005C ; opcode = jmp al
|
|
sta >Irq_VBL ; install JMP opcode and addrl
|
|
pla
|
|
and #$FF00
|
|
ora #^Irq_Heart
|
|
xba
|
|
sta >Irq_VBL+2 ; install addrm & addrh
|
|
phb
|
|
Sep #$20 ; 8 bit 'm'
|
|
lda Vptr+2 ; make pointer to task header
|
|
pha
|
|
plb
|
|
rep #$30 ; 16 bit 'm'
|
|
lda Vptr
|
|
tax
|
|
lda |6,x ; check task header signature
|
|
cmp #$A55A
|
|
beq QueOK ; no problem with new task
|
|
BadQue ;
|
|
ldx #$0304 ; flag bad queue signature
|
|
brl HdrErr
|
|
QueOK ;
|
|
lda >HBptr ; check if task in queue
|
|
cmp Vptr
|
|
bne DoFirst ; if not, install it
|
|
lda >HBptr+2
|
|
cmp Vptr+2
|
|
bne DoFirst
|
|
ldx #taskInstlErr ; else flag task error
|
|
bra HdrErr
|
|
DoFirst ;
|
|
lda >HBptr ; get heartbeat vector
|
|
ora >HBptr+2 ; is it the first one
|
|
bne GrowChain ; nope
|
|
lda VPtr ; get addrl
|
|
sta >HBptr ; set the first one
|
|
lda VPtr+2
|
|
sta >HBptr+2
|
|
sep #$20 ; 8 bit m
|
|
lda >HBptr+2 ; point at next entry
|
|
pha
|
|
plb
|
|
rep #$20 ; 16 bit m
|
|
lda >HBptr
|
|
tax
|
|
|
|
SetLast ;
|
|
lda #0
|
|
sta |0,x ; set last link flag
|
|
sta |2,x
|
|
|
|
ExitHB ;
|
|
plb
|
|
plp ;
|
|
jmp EndCall4
|
|
|
|
GrowChain ;
|
|
sep #$20 ; 8 bit m
|
|
lda >HBptr+2 ; point at first entry
|
|
pha
|
|
plb
|
|
rep #$20 ; 16 bit m
|
|
lda >HBptr
|
|
tax
|
|
|
|
ChkChain ;
|
|
lda |6,x ; check queue signature
|
|
cmp #$A55A
|
|
beq QueueOK ; no problem
|
|
ldx #5 ; else flag queue trashed
|
|
bra HdrErr
|
|
QueueOK ;
|
|
lda |0,x ; check if task already exists
|
|
cmp vptr
|
|
bne taskok ; it's not the same task
|
|
lda |2,x
|
|
cmp vptr+2
|
|
bne taskok ; it's not the same task
|
|
|
|
ldx #taskInstlErr ; task error
|
|
HdrErr ;
|
|
plb ; clean up stack
|
|
plp
|
|
jmp ErrOut4
|
|
|
|
TaskOK ;
|
|
lda |0,x ; is this the end of the queue
|
|
ora |2,x
|
|
beq GrowHere ; yes, now insert next task
|
|
sep #$20 ; 8 bit 'm' to move down queue
|
|
lda |2,x ; point at next one
|
|
pha
|
|
rep #$20 ; 16 bit m
|
|
lda |0,x
|
|
tax
|
|
plb
|
|
bra ChkChain ; search for last one
|
|
|
|
GrowHere ;
|
|
lda vptr+2 ; insert link address
|
|
sta |2,x
|
|
lda vptr
|
|
sta |0,x
|
|
tax ; point at next link
|
|
sep #$20 ; 8 bit m
|
|
longa off
|
|
lda Vptr+2
|
|
pha
|
|
plb
|
|
rep #$20 ; 16 bit m
|
|
longa on
|
|
bra SetLast ; set last link flag
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
* Delete System Heartbeat Vector
|
|
* Input LongWord Address
|
|
*
|
|
* Change History
|
|
*
|
|
* 26 Jul 88 Steven Glass
|
|
*
|
|
* Try and turn off vbl interrupts.
|
|
*
|
|
****************************************************************
|
|
DelHeart PROC
|
|
import KillIntsIfCan
|
|
|
|
OrigDir equ 1
|
|
RTL1 equ OrigDir+2
|
|
RTL2 equ RTL1+3
|
|
Vptr equ RTL2+3
|
|
|
|
phd
|
|
tsc ; turn stack into zp
|
|
tcd
|
|
php ; save interrupt enable status
|
|
sei ; no interrupts for now
|
|
phb
|
|
sep #$20 ; 8 bit m
|
|
longa off
|
|
lda #^HBptr ; point at link addr
|
|
pha
|
|
plb
|
|
rep #$20 ; 16 bit m
|
|
longa on
|
|
ldx #HBptr**$FFFF
|
|
lda |0,x ; is queue empty ?
|
|
ora |2,x
|
|
beq DelErr0
|
|
rep #$20 ; 16 bit 'm'
|
|
lda |0,x ; is the first one it ?
|
|
cmp vptr
|
|
bne notfirst
|
|
sep #$20 ; 8 bit 'm'
|
|
lda |2,x
|
|
cmp vptr+2
|
|
bne notfirst
|
|
phb ; save current queue pointer
|
|
phx
|
|
pha
|
|
rep #$20 ; 16 bit 'm'
|
|
lda |0,x ; point at task
|
|
tax
|
|
plb
|
|
lda |2,x ; get task's link pointer
|
|
tay
|
|
lda |0,x
|
|
plx ; restore queue pointer
|
|
plb
|
|
sta |0,x ; make new first link
|
|
tya
|
|
sta |2,x
|
|
bra DelDone ; all done
|
|
|
|
DelErr0 ;
|
|
bra DelErr
|
|
|
|
notfirst ;
|
|
sep #$20 ; 8 bit 'm'
|
|
lda |2,x
|
|
pha ; point at first link
|
|
rep #$20
|
|
lda |0,x
|
|
tax
|
|
plb
|
|
DelSrch ;
|
|
lda |6,x ; check task signature
|
|
cmp #$A55A
|
|
beq QueueOK ; no problem
|
|
ldx #queueDmgdErr ; else queue error
|
|
plb
|
|
plp
|
|
jmp ErrOut4
|
|
QueueOK ;
|
|
lda |0,x ; is this the last link ?
|
|
ora |2,x
|
|
beq DelErr ; yes, didnt find kaka
|
|
|
|
lda |0,x ; is the next link the target
|
|
cmp Vptr
|
|
bne DelSrch0 ; no
|
|
lda |2,x
|
|
cmp Vptr+2
|
|
bne DelSrch0 ; no
|
|
phb ; save current link ptr
|
|
phx
|
|
sep #$20 ; 8 bit m
|
|
longa off
|
|
lda |2,x ; get next link addr
|
|
pha
|
|
rep #$20 ; 16 bit m
|
|
longa on
|
|
lda |0,x
|
|
tax
|
|
plb
|
|
lda |0,x ; now get 2nd like addr
|
|
sta Vptr ; stuff on stack
|
|
lda |2,x
|
|
sta Vptr+2
|
|
plx ; restore link ptr
|
|
plb
|
|
lda Vptr ; now patch over previous link
|
|
sta |0,x
|
|
lda Vptr+2
|
|
sta |2,x
|
|
DelDone ;
|
|
|
|
jsr KillIntsIfCan
|
|
|
|
plb
|
|
plp ; restore interrupt enble
|
|
jmp EndCall4
|
|
|
|
|
|
DelSrch0 ;
|
|
sep #$20 ; 8 bit m
|
|
longa off
|
|
lda |2,x ; get next link addr
|
|
pha
|
|
rep #$20 ; 16 bit m
|
|
longa on
|
|
lda |0,x
|
|
tax
|
|
plb
|
|
bra DelSrch ; continue search
|
|
|
|
|
|
DelErr ;
|
|
plb
|
|
plp
|
|
ldx #taskNtFdErr ; task not found error
|
|
jmp ErrOut4
|
|
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
*
|
|
* Clear Heartbeat Interrupt chain
|
|
*
|
|
* Change History
|
|
*
|
|
* 26 Jul 88 Steven Glass
|
|
*
|
|
* Try and turn off vbl interrupts.
|
|
*
|
|
****************************************************************
|
|
ClrHeart PROC
|
|
import KillIntsIfCan
|
|
|
|
|
|
lda #0
|
|
sta >HBptr ; clear out the links
|
|
sta >HBptr+2
|
|
|
|
jsr KillIntsIfCan
|
|
|
|
|
|
jmp oEndCall0
|
|
ENDP
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
KillIntsIfCan PROC
|
|
*
|
|
* This routine turns off VBL interrupts if it is safe to do so.
|
|
* It is safe to turn them off under the following conditions:
|
|
*
|
|
* 1) No heartbeat tasks are installed.
|
|
* 2) The heartbeat interrupt vector points to our interrupt
|
|
* handler.
|
|
* 3) the mouse is not running in vbl interrupt mode.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* none
|
|
*
|
|
* Outputs:
|
|
* none
|
|
*
|
|
* External Refs:
|
|
import IRQ_Heart
|
|
*
|
|
* Entry Points:
|
|
* none
|
|
*
|
|
longa on ; mode
|
|
longi on
|
|
*
|
|
****************************************************************
|
|
lda >HBPtr
|
|
ora >HBPtr+2
|
|
bne CannotTurnOff
|
|
|
|
lda >IRQ_VBL+1
|
|
cmp #IRQ_Heart
|
|
bne CannotTurnOff
|
|
|
|
lda >IRQ_VBL+2
|
|
cmp #>IRQ_Heart
|
|
bne CannotTurnOff
|
|
|
|
pha
|
|
pha
|
|
pha
|
|
_ReadMouse
|
|
pla
|
|
plx
|
|
plx
|
|
bcs CanTurnOff
|
|
and #%0000000000001000
|
|
bne CannotTurnOff
|
|
|
|
CanTurnOff
|
|
PushWord #vblDisable
|
|
_IntSource
|
|
|
|
CannotTurnOff rts
|
|
|
|
ENDP
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
* HeartBeat Interrupt Handler
|
|
*
|
|
* Dispatches to this handler are made in response to VBL
|
|
* interrupts. This handler will increment the Tick Counter,
|
|
* and then each task in the heartbeat interrupt queue will
|
|
* have its counter decremented. If a zero value results, the
|
|
* associated handler will be called. It is the task's
|
|
* responsibility to reset the count each time it is called.
|
|
*
|
|
* Chain looks like.....
|
|
*
|
|
* HBptr --> link address --> link address --> $0000
|
|
* Counter Counter counter
|
|
* Signature Signature Signature
|
|
* (code) (code) (code)
|
|
*
|
|
*
|
|
* Change History
|
|
*
|
|
* 31 March 88 Steven Glass
|
|
*
|
|
* Moved the clearing of the interrupt source from the last
|
|
* thing done to the first thing done. This is to prevent
|
|
* this interrupt from clearing other interrupts that are
|
|
* cleared at the same address.
|
|
*
|
|
****************************************************************
|
|
IRQ_Heart PROC EXPORT
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Start by turning off the interrupt source. Then we can
|
|
; go on and run all the installed tasks.
|
|
;
|
|
;
|
|
sta >ClrVBLint ; turn off interrupt source
|
|
|
|
|
|
|
|
rep #$30 ; off to 16 bit land
|
|
lda >TickCnt ; increment tick counter
|
|
inc a
|
|
sta >TickCnt
|
|
bne TickDone
|
|
lda >TickCnt+2
|
|
inc a
|
|
sta >TickCnt+2
|
|
|
|
TickDone ;
|
|
|
|
rep #$30 ; off to 16 bit land
|
|
lda >HBptr ; is heart beat chain empty
|
|
tax
|
|
ora >HBptr+2
|
|
beq NoChain1 ; yes
|
|
|
|
phb
|
|
sep #$20 ; 8 bit m
|
|
lda >HBptr+2 ; point at link
|
|
pha
|
|
plb
|
|
rep #$20 ; 16 bit m
|
|
|
|
NextHB ;
|
|
phx ;
|
|
_MidiInputPoll ; Poll Midi before each task.
|
|
plx
|
|
|
|
lda |6,x ; check task signature
|
|
cmp #$A55A
|
|
beq QueueOK ; looks ok to me
|
|
pea hbQueueBadErr ; heartbeat queue error
|
|
pea $0000 ; Heartbeat queue death message
|
|
pea $0000
|
|
_SysFailMgr ; off to the system death handler
|
|
|
|
QueueOK ;
|
|
lda |4,x ; if cnt = 0, ignore this task
|
|
beq NextQueue
|
|
dec |4,x ; else decrement task counter
|
|
bne NextQueue ; if task cnt not zero, don't execute
|
|
phb ; save environment prior to dispatch
|
|
phx
|
|
phk ; here's where we come back to
|
|
pea HBentry-1
|
|
phb ; and here's where were going to
|
|
clc
|
|
txa
|
|
adc #7
|
|
pha
|
|
sep #$30 ; dispatch is native, 8 bit m/x
|
|
rtl ; and this does the dispatch
|
|
|
|
HBentry ;
|
|
|
|
clc ; native mode, 16 bit m/x
|
|
xce
|
|
rep #$30
|
|
plx ; restore queue pointer
|
|
plb
|
|
|
|
NextQueue ;
|
|
|
|
lda |0,x ; is this the last link ?
|
|
ora |2,x
|
|
beq NoChain ; yes
|
|
sep #$20 ; 8 bit m
|
|
lda |2,x ; get next link addr
|
|
pha
|
|
rep #$20
|
|
lda |0,x
|
|
tax
|
|
plb
|
|
bra NextHB ; traverse the chain
|
|
|
|
|
|
NoChain ;
|
|
|
|
_MIDIInputPoll ; Poll one last time just to be safe.
|
|
plb
|
|
|
|
NoChain1 ;
|
|
|
|
sep #$30 ; off to 8 bit land
|
|
clc ; flag that interrupt was handled !
|
|
rtl
|
|
|
|
|
|
ENDP
|
|
|
|
title 'System Death Manager'
|
|
****************************************************************
|
|
*
|
|
* System Death Manager (ErrCode : integer; MsgPtr : long)
|
|
* Input Word Error Code
|
|
* Input LongWord Pointer to ascii
|
|
*
|
|
* Change History
|
|
*
|
|
* 08 Dec 88 Steven Glass
|
|
*
|
|
* Check for NIL pointer to string was wrong, ored low word with
|
|
* low word to see if nil. If string was at beginning of bank,
|
|
* it would not have worked.
|
|
*
|
|
****************************************************************
|
|
SysDeathMgr PROC
|
|
|
|
|
|
RTL1 equ 1
|
|
RTL2 equ RTL1+3
|
|
Ptr equ RTL2+3
|
|
ErrCode equ Ptr+4
|
|
|
|
clc
|
|
lda Ptr,s
|
|
ora Ptr+2,s ; Default
|
|
bne DSysD ; yes
|
|
sec ; else user msg
|
|
|
|
DSysD ;
|
|
phb ; clean 3 bytes of stack
|
|
pla
|
|
pla
|
|
|
|
jmp >SysDMgrV ; off through SysDeath vector
|
|
|
|
; and never come back.
|
|
|
|
ENDP
|
|
|
|
|
|
title 'GetAddress'
|
|
****************************************************************
|
|
*
|
|
* Return Interrupt Status Address
|
|
*
|
|
* Input word refnum
|
|
* Input LongWord Don't care
|
|
*
|
|
* Output LongWord Pointer
|
|
*
|
|
* Modification History
|
|
*
|
|
* May 6, 1986 See 5 lines changed below.
|
|
*
|
|
****************************************************************
|
|
GetAddr PROC
|
|
|
|
RTL1 equ 1
|
|
RTL2 equ RTL1+3
|
|
RefNum equ RTL2+3
|
|
Ptr equ RefNum+2
|
|
|
|
lda RefNum,s ; get ref #
|
|
asl a ; and make an index
|
|
asl a
|
|
cmp #MaxRef ; index out of range ?
|
|
bcc GetAddr0 ; nope
|
|
ldx #badInputErr ; error is bad input parm.
|
|
jmp oErrOut2 ; uses oErrOut SEG 6 May 86
|
|
|
|
GetAddr0 ;
|
|
tax ; get param. addr
|
|
lda >Ptbl,x ; abs long,x addressing SEG 6 May 86
|
|
sta Ptr,s
|
|
lda >Ptbl+2,x ; abs long,x addressing SEG 6 May 86
|
|
sta Ptr+2,s ; missing +2 SEG 6 May 86
|
|
jmp oEndCall2 ; uses oEndCall SEG 6 May 86
|
|
|
|
Ptbl ;
|
|
DC.L irq_intflag ; status of INTFLAG at IRQ
|
|
DC.L irq_datareg ; status of DATREG at IRQ
|
|
DC.L irq_ser1 ; user interrupt info
|
|
DC.L irq_ser2 ; user interrupt info
|
|
DC.L irq_aptlkhi ; user interrupt info
|
|
DC.L TickCnt ; longword tick count value
|
|
DC.L irq_volume ; volume used during IRQ time
|
|
DC.L irq_active ; <> 0 if called during IRQ
|
|
DC.L irq_soundd ; sound data at irq
|
|
DC.L irq_a ; registers at break
|
|
DC.L evmgrdata ; event manager data
|
|
DC.L mouseslot ; the little squeeker is here
|
|
DC.L LowXClamp ; 8 bytes of mouse clamp data
|
|
DC.L AbsClamps ; 8 bytes of absolute device clamp
|
|
DC.L SerFlag ; something for mike/fern
|
|
; ; added 6 Mar 87 by Ray, Mike, Steve
|
|
; ; fern and witnessed by Dan O.
|
|
PtblEnd ;
|
|
|
|
MaxRef equ PtblEnd-Ptbl
|
|
|
|
|
|
ENDP
|
|
|
|
|
|
title 'Mouse Tools'
|
|
****************************************************************
|
|
*
|
|
* Mouse Tool Sets for Mars
|
|
*
|
|
****************************************************************
|
|
*
|
|
* Copyright (C) 1985-1987
|
|
* Apple Computer, Inc.
|
|
* All Rights Reserved
|
|
*
|
|
****************************************************************
|
|
|
|
|
|
****************************************************************
|
|
;
|
|
setdbtoe1 PROC
|
|
;
|
|
pea $e1e1 ;change data bank to $e1
|
|
plb ;dummy pull
|
|
plb ;set data bank to $e1
|
|
rts
|
|
|
|
ENDP
|
|
|
|
EJECT
|
|
*******************************************************************************
|
|
*
|
|
ReadMouseJ PROC
|
|
*
|
|
* Description: This call will function identically to read mouse except that
|
|
* it will allow journaling to take place.
|
|
*
|
|
* Screen holes, buttons and movement status
|
|
* bits updated; interrupt status bits are cleared
|
|
* If data not contaminated, then first read $c024
|
|
* return X position data (ADB low byte), second
|
|
* reads return Y position data (ADB high byte)
|
|
*
|
|
* |MseStat ($077c): bit7, previously but1 was up/down (0/1)
|
|
* bit6, movement interrupt
|
|
* bit5, button 0/1 interrupt
|
|
* bit4, vbl interrupt
|
|
* bit3, currently but1 is up/down (0/1)
|
|
* bit2, x/y moved since last READMOUSE
|
|
* bit1, previously but0 was up/down (0/1)
|
|
* bit0, currently but0 is up/down (0/1)
|
|
*
|
|
* Input word: don't care
|
|
* Input word: don't care
|
|
* Input word: don't care
|
|
* Output word: X position
|
|
* Output word: Y position
|
|
* Output word: Status & Mode
|
|
*
|
|
* External Refs:
|
|
Import AltTRdMouse
|
|
*
|
|
*******************************************************************************
|
|
*
|
|
longa on
|
|
longi on
|
|
|
|
;
|
|
; stack structure
|
|
;
|
|
DBreg equ 1
|
|
Preg equ DBreg+1
|
|
RTL1 equ Preg+1
|
|
RTL2 equ RTL1+3
|
|
StatMode equ RTL2+3
|
|
YPos equ StatMode+2
|
|
XPos equ YPos+2
|
|
;
|
|
php ;save interrupt status
|
|
sei ;disable interrupt
|
|
phb ;save data bank
|
|
jsr setdbtoe1 ;change data bank to $00
|
|
;
|
|
; First, check the journaling flag, if its zero, then simply call ReadMouse direct
|
|
; and go no further.
|
|
lda >JournalFlag
|
|
bne rm2010
|
|
brl AltTRdMouse ; if its zero, then let read mouse handle this
|
|
;
|
|
; Next, check to see if the event manager is active, if it is, then we can continue,
|
|
; if it isn't well, just exit...
|
|
rm2010
|
|
pha ; room for result
|
|
_EMStatus
|
|
pla
|
|
bne rm2OK ; if its true, then its ok to go on
|
|
brl AltTRdMouse ; if the event manager is off then let ReadMouse handle this
|
|
;
|
|
rm2OK
|
|
; If we get this far, we know that the event manager is active and that journaling is turned on.
|
|
|
|
pha ; call the real read mouse to get the current mouse data
|
|
pha
|
|
pha
|
|
_ReadMouse2
|
|
|
|
pla ; get the current mouse data from the call
|
|
ply
|
|
plx
|
|
sta StatMode,s ; and save them into our record
|
|
tya
|
|
sta yPos,s ; on the stack for journaling to use.
|
|
txa
|
|
sta xPos,s
|
|
;
|
|
; Now that our result is set properly, we must call the journaling routine so that it will save
|
|
; these new bytes for us. Or load in whatever it should be for playback
|
|
; First create the address of our data on the stack so we can pass it
|
|
tsc ; get the current stack pointer
|
|
clc
|
|
adc #StatMode ; add in the proper offset
|
|
tax ; and save it in <X> for later
|
|
|
|
lda >JournalFlag ; first push the flag on the stack
|
|
pha
|
|
pea $0006 ; journal code for ReadMouse (Also the data size...hmmm...)
|
|
pea $0000 ; now push the address of our data, (its on the stack...)
|
|
phx ; push low word of data buffer
|
|
jsl JournalPtr ; and call the journaling routine
|
|
;
|
|
; Journaling is all finished, and so should we be... so simply exit
|
|
|
|
plb ;restore data bank
|
|
plp ;restore interrupt state during entry
|
|
jmp oEndCall0 ;exit tool with good MouseRead
|
|
|
|
EndP
|
|
|
|
****************************************************************
|
|
*
|
|
* ReadMouse - Read Mouse Position
|
|
* Screen holes, buttons and movement status
|
|
* bits updated; interrupt status bits are cleared
|
|
* If data not contaminated, then first read $c024
|
|
* return X position data (ADB low byte), second
|
|
* reads return Y position data (ADB high byte)
|
|
*
|
|
* |MseStat ($077c): bit7, previously but1 was up/down (0/1)
|
|
* bit6, movement interrupt
|
|
* bit5, button 0/1 interrupt
|
|
* bit4, vbl interrupt
|
|
* bit3, currently but1 is up/down (0/1)
|
|
* bit2, x/y moved since last READMOUSE
|
|
* bit1, previously but0 was up/down (0/1)
|
|
* bit0, currently but0 is up/down (0/1)
|
|
*
|
|
* Input word: don't care
|
|
* Input word: don't care
|
|
* Input word: don't care
|
|
* Output word: X position
|
|
* Output word: Y position
|
|
* Output word: Status & Mode
|
|
*
|
|
****************************************************************
|
|
*
|
|
TRdMou PROC
|
|
Export AltTRdMouse
|
|
longa on
|
|
longi on
|
|
;
|
|
; stack structure
|
|
;
|
|
DBreg equ 1
|
|
Preg equ DBreg+1
|
|
RTL1 equ Preg+1
|
|
RTL2 equ RTL1+3
|
|
StatMode equ RTL2+3
|
|
YPos equ StatMode+2
|
|
XPos equ YPos+2
|
|
;
|
|
php ;save interrupt status
|
|
sei ;disable interrupt
|
|
phb ;save data bank
|
|
jsr setdbtoe1 ;change data bank to $00
|
|
;
|
|
AltTRdMouse
|
|
longa off
|
|
longi off
|
|
sep #$30 ;off to 8-bit land
|
|
jsr GetMdata ;read in mouse data from keygloo
|
|
bcc RealData ;'c' = 0 if real live data
|
|
lda |MseStat ;Fake data if here to get state history
|
|
eor #$90 ;was 0=up -- after eor then 0=down
|
|
tax ;save in 'x'
|
|
and #$80 ;mask for current button0 state
|
|
tay
|
|
txa
|
|
and #$10 ;
|
|
asl a ;move to msb
|
|
asl a
|
|
asl a
|
|
tax
|
|
RealData ;
|
|
lda #$20 ;anticipate no movement
|
|
trb |MseStat ;reset to no movement first
|
|
tya ;get back y data from GetMdata
|
|
and #$3f ;mask off but0 and direction bit
|
|
pha ;save in stack
|
|
txa ;get back x data from GetMdata
|
|
and #$3f ;mask off but1 and direction bit
|
|
ora 1,s ;ora together x/y data byte
|
|
beq NoMove ;both x/y =0, no movement
|
|
lda #$20 ;else set movement bit
|
|
tsb |MseStat ;set movement status bit
|
|
;
|
|
Nomove ;movement status bit already reset
|
|
pla ;clean up stack
|
|
lda |MseStat ;get current buttons status
|
|
pha ;save temporarily
|
|
and #$2e ;reset bits 7,6,4,1, buttons bits
|
|
sta |MseStat ; i.e. button 1/0 all up first
|
|
pla ;recall current buttons status
|
|
and #$90 ;mask for last current buto/but1
|
|
asl a ;shift last current but0 to 'c'
|
|
bcc LstBut0Off ;bra if last current but0 is off
|
|
beq But0on1off ;bra here for last current but0 on
|
|
; ; and but1 off
|
|
lda #$41 ;get here if both last current buttons
|
|
; ; state were1, i.e. buttons pressed
|
|
SetHole ;
|
|
tsb |MseStat ;set it for screen hole
|
|
bra NewData ;bra to update for new states being
|
|
; ; read in by GetMdata
|
|
;
|
|
LstBut0Off ;
|
|
beq NewData ;bra for both off
|
|
lda #$01 ;else but1 on, down
|
|
bra SetHole ;update screen hole but1 stat
|
|
;
|
|
But0on1off ;
|
|
lda #$40 ;set but0 on
|
|
bra SetHole ;update screen hole but0 stat
|
|
;
|
|
NewData ;
|
|
tya ;get new but0 back
|
|
rol a ;save but0 status in 'c'
|
|
txa ;get new but1 back, bit7
|
|
;
|
|
; enter here with new buttons status, but0 = c, but1 = N (bit7)
|
|
; on=down=0, off=up=1, same to ADB spev but opposite to |MseStat !!!
|
|
;
|
|
bcs But0off ;bra if new but0 stat = 1, off
|
|
bmi But1off ;bra here for but0 = on, but1 = off
|
|
lda #$90 ;get here for both on, update it
|
|
UpdateHole ;
|
|
tsb |MseStat ;update screen holes with newly stat
|
|
bra AnyMove ;continue to handler any new movement
|
|
;
|
|
But0off ;
|
|
bmi AnyMove ;bra if both buttons off
|
|
lda #$10 ;get here for but1 on only
|
|
bra UpdateHole ;update it
|
|
;
|
|
But1off ;
|
|
lda #$80 ;get here for but0 on only
|
|
bra UpdateHole ;update it
|
|
;
|
|
AnyMove ;Handling mouse movements
|
|
txa ;get back x-pos new detla
|
|
and #$7f ;mask off button1 status, already done
|
|
tax ;temp store direction and movement
|
|
asl a ;direction bit to msb
|
|
bpl PosXmov ;bra for positive x direction move
|
|
txa ;else neg x move, make 2's
|
|
ora #$80 ;set 2's data
|
|
ldx #$ff ;set high byte to 2's also
|
|
bra NegXMov ;bra to handle this neg move
|
|
;
|
|
PosXmov ;
|
|
txa ;pos x move, make high byte also +
|
|
ldx #$00
|
|
;
|
|
NegXMov ;
|
|
PosNeg ;
|
|
phx ;push hi byte of delta x (word) on stk
|
|
pha ;push lo byte of delta x on stack
|
|
tya ;process delta y stuff
|
|
and #$7f ;ignore button0 status, already handled
|
|
tay ;store delta y without but0 status
|
|
asl a ;shift direction bit to msb
|
|
bpl PosYMov ;bra for pos y movement
|
|
tya ;get back delta y
|
|
ora #$80 ;negative y movement, make 2's
|
|
ldy #$ff ;set high byte also
|
|
bra NegYMOv ;
|
|
PosYMov ;
|
|
tya ;pos y movement, then make hi byte '+'
|
|
ldy #$00
|
|
;
|
|
NegYMov ;
|
|
phy ;push hi byte of delta y on stack
|
|
pha ;push lo byte of delta y on stack
|
|
;
|
|
lda |HighAbsy ;read back previous value and
|
|
; ; update with the current value
|
|
sta |MseSpare ;save the previous value temporarily
|
|
; ; for 'YclampTest'
|
|
pla ;get back lo byte of delta y from stack
|
|
clc ;clear carry for the following adding
|
|
adc |LowAbsy ;add in new value for low byte abs y
|
|
sta |LowAbsy ;update the screen hole also
|
|
;
|
|
pla ;get back high byte of delta y
|
|
adc |HighAbsy ;add in new value for high byte abs y
|
|
sta |HighAbsy ;update screen hole also
|
|
jsr YclampTest ;test y against clamp
|
|
;
|
|
lda |HighAbsx ;process delta x stuff
|
|
sta |MseSpare
|
|
;
|
|
pla ;get back lo byte of delta x from stack
|
|
clc ;make sure 'c'=0
|
|
adc |LowAbsx ;add in new value for low byte of x
|
|
sta |LowAbsx ;update screen hole also
|
|
;
|
|
pla ;get back high byte of delat x
|
|
adc |HighAbsx ;add in new value for high byte of x
|
|
sta |HighAbsx ;update screen hole also
|
|
jsr XclampTest ;test x against clamp
|
|
;
|
|
lda |HighAbsx ;after proper clamps testing, read
|
|
; ; it and set properly for the toos call
|
|
sta Xpos+1,s
|
|
lda |LowAbsx
|
|
sta Xpos,s
|
|
lda |HighAbsy
|
|
sta Ypos+1,s
|
|
lda |LowAbsy
|
|
sta Ypos,s
|
|
lda |MseStat ;get status
|
|
sta StatMode+1,s ;move status to stack for tools call
|
|
lda |MseMode ;get mouse mode
|
|
sta StatMode,s ;move mode to stack
|
|
;
|
|
rep #$30 ;must exit with 16-bit m/x
|
|
plb ;restore data bank
|
|
plp ;restore interrupt state during entry
|
|
jmp oEndCall0 ;exit tool with good MouseRead
|
|
;
|
|
; How about error reading ?????????? ErrorCode ???????
|
|
;
|
|
ENTRY GetMData
|
|
GetMdata ;
|
|
lda kmstatus ;test if data available
|
|
bpl NotAvail ;bra if not available, set 'c'
|
|
ror a ;set 'c'=0, if data ok bit1=0
|
|
ror a ; i.e. data not contaminated
|
|
lda MouseData ;read in mouse data register, $c024
|
|
tax
|
|
bcs NotAvail ;c=1 if data is contaminated
|
|
lda kmstatus ;verify Y ardware has X data ready
|
|
and #$02 ;bit1=1, Y pos data available
|
|
beq NotAVail
|
|
lda MouseData ;read in Y position data
|
|
tay ;store for calling routine
|
|
clc ;good reading of mouse data
|
|
rts ;return to caller
|
|
NotAvail ;
|
|
sec ;not a good reading
|
|
rts
|
|
;
|
|
**************************************************************************
|
|
*
|
|
* Clamping is done after the delta has been added to the absolute value.
|
|
* The new absolute values are tested against the current clamp values.
|
|
*
|
|
**************************************************************************
|
|
*
|
|
XclampTest ;
|
|
ldy #$00 ;y=0 for Xdata, y=$01 for Ydata
|
|
tyx ;x=0 for Xdata, x=$02 for Ydata
|
|
xba ;high byte of data to hi byte of 'A'
|
|
lda |LowAbsx,y ;read lo byte of data to lo byte of 'A'
|
|
xba ;swap hi and low byte of 'A'
|
|
tay ;y=high byte of data
|
|
bvc NoOverflow ;no overflow then all's fine
|
|
bit |MseMode ;chk which test flag in use
|
|
bra YclampTst0 ;continue this way
|
|
NoOverflow ;
|
|
bit |MseMode ;set up N and V for later
|
|
bra ClampTest ;continue this way
|
|
;
|
|
YclampTest ;
|
|
ldy #$01 ;y=0 for Xdata, y=$01 for Ydata
|
|
ldx #$02 ;x=0 for Xdata, y=$02 for Ydata
|
|
xba ;high byte of y data to hi byte of 'A'
|
|
lda |LowAbsx,y ;read lo byte of y data to lo byte 'A'
|
|
xba ;swap hi and low byte of 'A'
|
|
tay ;y=high byte of y data
|
|
bvc YclampTst2 ;No overflow then all's fine
|
|
bit |MseInfo ;chk which test flag in use, Info set
|
|
; ; in InitTool
|
|
YclampTst0 ;
|
|
bmi Chk2or3 ;either 2 or 3 if -
|
|
bvc MaxClamp ;Test 0 if v=0
|
|
tya ;test 1 if v=1
|
|
bmi MaxClamp ;if - was + before
|
|
bpl MinClamp ;if + was - before
|
|
Chk2or3 ;
|
|
bvc MinClamp ;test 2 if v=0
|
|
YclampTst2 ;
|
|
bit |MseInfo ;setup N and V for later
|
|
;
|
|
ClampTest ;
|
|
php ;save status
|
|
tya ;is it + or -
|
|
bmi NegNum ;bra if -
|
|
plp ;value is +
|
|
bmi Must2or3 ;must be 2 or 3
|
|
bvc MinMax ;must be test 0]
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16-bit land
|
|
xba ;put high data back to hi byte of 'A'
|
|
cmp |HiXclamp,x ;test against high clamp
|
|
longa off
|
|
longi off
|
|
sep #$30 ;back of 8-bit land
|
|
beq OkValue ;bra if equal to max clamp, ok
|
|
bcs MaxClamp ;> maxclamp is not ok
|
|
OkValue ;
|
|
rts ;back to caller
|
|
Must2or3 ;
|
|
bvs MinMax ;do regular min/max test
|
|
;
|
|
MaxClamp ;
|
|
txy ;test whether x or y data change
|
|
beq XChange ;bra for Xdata, x=y=0
|
|
ldy #$01 ;else set for Ydata, y=$01
|
|
Xchange ;
|
|
lda |HiXclamp,x
|
|
sta |LowAbsx,y ;Modify user data to max clamp value
|
|
lda |HiXclamp+1,x
|
|
MaxClamp2 ;
|
|
sta |HighAbsx,y ;save as new abs hi value
|
|
rts ;back to caller
|
|
;
|
|
NegNum ;
|
|
plp ;bit7 to N / bit6 to V
|
|
bmi MinMax ;must be 2 or 3
|
|
bvs Testm1 ;must be test 1
|
|
;
|
|
MinClamp ;must be test 0
|
|
txy ;test whether x or y data change
|
|
beq XChange1 ;x=y=0 for Xdata
|
|
ldy #$01 ;else set for Ydata
|
|
Xchange1 ;
|
|
lda |LowXclamp,x
|
|
sta |LowAbsx,y ;Modify user data to min clamp value
|
|
lda |LowXclamp+1,x
|
|
bra Maxclamp2 ;exit this way
|
|
;
|
|
Testm1 ;
|
|
xba ;put high byte in hi byte of 'A'
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16 bit land
|
|
cmp |LowXclamp,x ;test against min clamp
|
|
longa off
|
|
longi off
|
|
sep #$30 ;back to 8 bit land
|
|
bcc MinClamp ;< min clamp then use min clamp
|
|
rts ;ok value, back to caller
|
|
;
|
|
MinMax ;do regular min/max testing
|
|
tya ;pick up value to test
|
|
bmi MinMax0 ;current valur is -
|
|
lda |MseSpare ;what was previous abs sign
|
|
bpl MinMax1 ;previous was +
|
|
SpecTest ;
|
|
sec ;set carry to subtract
|
|
txy ;make proper y index
|
|
beq Xxdata
|
|
ldy #$01 ;set for ydata
|
|
Xxdata ;
|
|
sbc |HighAbsx,y ;subtract current abs hi byte
|
|
bvs MinMax1 ;v=1 then all's fine
|
|
bit |MseSpare ;test sign
|
|
bpl MinClamp ;+ then use min clamp
|
|
bmi MaxClamp ;- then use max clamp
|
|
MinMax0 ;
|
|
lda |MseSpare ;test previous bi byte for sign
|
|
bpl SpecTest ;previous was +
|
|
;
|
|
MinMax1 ;
|
|
txy ;make proper y index
|
|
beq Xxxdata
|
|
ldy #$01
|
|
Xxxdata ;
|
|
lda |HighAbsx,y ;get current abs hi byte
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16 bit land
|
|
xba ;put high byte into hi byte of 'A'
|
|
cmp |HiXclamp,x
|
|
longa off
|
|
longi off
|
|
sep #$30 ;back to 8 bit land
|
|
beq OkValue2 ;= is ok
|
|
bcs MaxClamp ;> than max then use max clamp value
|
|
OkValue2 ;
|
|
rep #$30 ;off to 16 bit land
|
|
cmp |LowXclamp,x ;test against min clamp
|
|
sep #$30 ;back to 8 bit land
|
|
bcc MinClamp ;< min clamp then use min clamp value
|
|
rts ;back to caller
|
|
|
|
ENDP
|
|
|
|
|
|
*************************************************************
|
|
*
|
|
* InitMouse - init mouse clamp values to $0000 and $03ff,
|
|
* set mouse position to 0,0 and also clear
|
|
* mouse mode and status
|
|
*
|
|
* Input : word, mouseslot (miscellaneous tool)
|
|
* If mouse is going to be always active, then there
|
|
* is not necessary to have such input, the following
|
|
* routine doesn't take care of this input word but
|
|
* maintain compatibility with miscellaneous tool and
|
|
* therefore exits with oEndCall02
|
|
*
|
|
*************************************************************
|
|
*
|
|
InitGlue PROC
|
|
|
|
longa on
|
|
longi on
|
|
;
|
|
; The stack is not affected by this call
|
|
;
|
|
php ;save interrupt state
|
|
sei ;disable interrupt
|
|
phb ;save data bank
|
|
jsr setdbtoe1 ;change data bank to $00
|
|
;
|
|
lda #$0000 ;16 bit land
|
|
sta |LowXclamp ;reset low clamps to 00
|
|
sta |LowYclamp ;
|
|
lda #$03ff ;reset high clamps to$3ff
|
|
sta |HiXclamp
|
|
sta |HiYclamp
|
|
longa off
|
|
longi off
|
|
sep #$30 ;off to 8 bit land
|
|
stz |LowAbsx ;set screen holes to 00
|
|
stz |LowAbsy
|
|
stz |HighAbsx
|
|
stz |HighAbsy
|
|
|
|
lda #$04 ;??? assume mouse at slot4
|
|
sta mouseslot
|
|
|
|
jsl InitFlag ;must set up clamp flags
|
|
longa on ;exit with 16 bit land a must
|
|
longi on
|
|
rep #$30
|
|
plb ;restore data bank
|
|
plp ;restore interrupt state
|
|
jmp oEndcall2
|
|
|
|
ENDP
|
|
|
|
***********************************************************
|
|
*
|
|
* SetMouse - set mouse mode, |MseMode
|
|
*
|
|
* Input word: |MseMode
|
|
*
|
|
* bit7/6, for X clmaping flags
|
|
* bit5/4, reserved
|
|
* bit3, Interrupt on VBL
|
|
* bit2, Interrupt on next VBL if button pressed
|
|
* bit1, Interrupt on next CBL if mouse is moved
|
|
* bit0, Mouse button off/on (0/1)
|
|
*
|
|
***********************************************************
|
|
*
|
|
TSetMou PROC
|
|
|
|
longa on
|
|
longi on
|
|
|
|
;
|
|
; stack structure
|
|
;
|
|
DBreg equ 1
|
|
Preg equ DBreg+1
|
|
RTL1 equ Preg+3 ;rtl for tool dispatcher
|
|
RTL2 equ RTL1+3 ;rtl for application caller
|
|
ModeUser equ RTL2+1 ;mode set by application
|
|
;
|
|
ErrMode equ $1d01 ;Illegal mode error code
|
|
;
|
|
php ;save interrupt status
|
|
sei ;disable interrupt
|
|
phb ;save data bank
|
|
jsr setdbtoe1 ;change data bank to $00
|
|
lda ModeUser,s ;get input mode
|
|
;
|
|
longa off
|
|
longi off
|
|
sep #$30 ;8-bit m/x
|
|
tay ;temp store the mode
|
|
and #$f0 ;chk for legal mode
|
|
bne BadMode ;bra if illegal mode
|
|
|
|
tya ;get back mode
|
|
ror a ;test mouse on/off bit
|
|
php ;c=1=enable mouse and z=0=turn ints on
|
|
lda #$0f ;reset bits 0,1,2,3
|
|
trb |MseMode
|
|
tya ;recall user mode nibble
|
|
tsb |MseMode ;put new mode in lo nibble
|
|
and #$08 ;make irq.mousvbl=0 if no VBL to user
|
|
sta |irq_MousVbl ;make irq.mousvbl <>0 if VBL to user
|
|
plp ;what should be done?
|
|
bcc DisMouse ;bra to disable mouse
|
|
tya ;recall mode byte
|
|
and #$06 ;bit2=button int, bit1=movement bit
|
|
beq DisMouse ;if =0 then no mouse ints except VBL
|
|
|
|
lda #$40 ;else only bit3<>0, alter it in gloo
|
|
tsb |kmstatus ;alter the interrupt bit in keygloo
|
|
bra EndSet
|
|
;
|
|
DisMouse ;
|
|
lda #$40 ;alter the bit in Kmstatus
|
|
trb |kmstatus
|
|
;
|
|
EndSet ;
|
|
tya ;see if we should turn on VBL ints too
|
|
and #$08 ;bit3, interrupt on VBL
|
|
beq EndSet1 ;exit if not enabled
|
|
tsb |inten ;enable VBL interrupt
|
|
;
|
|
EndSet1 ;
|
|
jsr GetMdata ;reset keygloo mouse information
|
|
longa on
|
|
longi on
|
|
rep #$30 ;16-bit m/x exits a must
|
|
plb ;restore data bank register
|
|
plp ;restore interrupt state
|
|
jmp oEndcall2 ;exit tool by adjusting stack ptr
|
|
;
|
|
BadMode ;
|
|
longa on
|
|
longi on
|
|
rep #$30 ;16 bit m/x exits a must
|
|
lda #ErrMode
|
|
plb
|
|
plp
|
|
sec ;c=1 error mode
|
|
jmp oErrout2
|
|
;
|
|
ENDP
|
|
|
|
********************************************************************
|
|
*
|
|
* HomeMouse - set mouse to upper-left corner of clamping window
|
|
* or saying position mouse at minimum clamp position
|
|
*
|
|
********************************************************************
|
|
*
|
|
HomeGlue PROC
|
|
|
|
longa on
|
|
longi on
|
|
;
|
|
; The stack is not affected by this call, from toolcall point of view
|
|
;
|
|
php ;save interrupt state on entry
|
|
sei ;disable interrupt
|
|
phb ;save data bank register
|
|
jsr setdbtoe1 ;change data bank register to $00
|
|
longa off
|
|
longi off
|
|
sep #$30 ;off to 8 bit land
|
|
lda |LowXclamp
|
|
sta |HighAbsx
|
|
lda |LowXclamp+1
|
|
sta |LowAbsx
|
|
lda |LowYclamp
|
|
sta |HighAbsy
|
|
lda |LowYclamp+1
|
|
sta |LowAbsy
|
|
;
|
|
HomeExit ;
|
|
jsr GetMdata ;exit via reset keygloo mouse info
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16 bit land
|
|
plb ;restore data bank
|
|
plp ;restore interrupt state
|
|
jmp oEndCall0 ;exit the tool
|
|
|
|
ENDP
|
|
|
|
*******************************************************************
|
|
*
|
|
* ClearMouse - Reset buttons, movement and interrupt status to 0.
|
|
* Set screen holes to $0000.
|
|
*
|
|
********************************************************************
|
|
*
|
|
ClearGlue PROC
|
|
|
|
longa on
|
|
longi on
|
|
;
|
|
; stacks from the tool call are not affected
|
|
; no input or output parameters are required
|
|
;
|
|
php ;save interrupt state
|
|
sei ;disable interrupt
|
|
phb ;save data bank
|
|
jsr setdbtoe1 ;change data bank to $00
|
|
;
|
|
longa off
|
|
longi off
|
|
sep #$30 ;off to 8 bit land
|
|
stz |LowAbsx ;clear screen holes
|
|
stz |LowAbsy
|
|
stz |HighAbsx
|
|
stz |HighAbsy
|
|
stz |MseStat ;clear mouse status also
|
|
jsr GetMdata ;reset keygloo mouse information also
|
|
;
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16 bit land
|
|
plb ;restore data bank
|
|
plp ;restore interrupt state
|
|
jmp oEndCall0 ;exit with c=0, A=0
|
|
|
|
ENDP
|
|
|
|
***************************************************************
|
|
*
|
|
* ClampMouse - set mouse bounds in a window and then set
|
|
* mouse positions to the minimum clamp values
|
|
*
|
|
* Input word: X axis minimum clamp
|
|
* Input word: X axis maximum clamp
|
|
* Input word: Y axis minimum clamp
|
|
* Input word: Y axis maximum clamp
|
|
*
|
|
***************************************************************
|
|
*
|
|
TClmpMou PROC
|
|
|
|
|
|
longa on
|
|
longi on
|
|
;
|
|
; stack structure
|
|
;
|
|
DBreg equ 1
|
|
Preg equ DBreg+1
|
|
RTL1 equ Preg+1
|
|
RTL2 equ RTL1+3
|
|
YMaxLo equ RTL2+3
|
|
YMaxHi equ YMaxLo+1
|
|
YMinLo equ YMaxHi+1
|
|
YMinHi equ YMinLo+1
|
|
XMaxLo equ YMinHi+1
|
|
XMaxHi equ XMaxLo+1
|
|
XMinLo equ XMaxHi+1
|
|
XMinHi equ XMinLo+1
|
|
;
|
|
php ;save interrupt state
|
|
sei
|
|
phb ;save data bank register
|
|
jsr setdbtoe1 ;change data bank reg to $00
|
|
;
|
|
lda YMaxLo,s ;move clamp values from stack to clamp
|
|
; ; locations in RAM $e1 bank for event
|
|
; ; manager
|
|
sta |HiYclamp ; 16 bit land
|
|
lda YMinLo,s
|
|
sta |LowYclamp
|
|
lda XMaxLo,s
|
|
sta |HiXclamp
|
|
lda XMinLo,s
|
|
sta |LowXclamp
|
|
jsl InitFlag ;update clamp flags
|
|
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16 bit land
|
|
pea $0000
|
|
pea $0000
|
|
pea $0000
|
|
phk ;dummy 3 bytes
|
|
per clmpxit-1 ;part of 3 dummy bytes
|
|
jsl >TRdMou ;execute ReadMouse to reflect new clmps
|
|
rtl ;remove 3 dummy bytes and go to next
|
|
|
|
clmpxit ;
|
|
pla ;remove 3 more words from ReadMouse
|
|
pla
|
|
pla
|
|
|
|
plb ;restore data bank
|
|
plp ;restore interrupt state during entry
|
|
jmp oEndCall8 ;exit the tool
|
|
|
|
ENDP
|
|
|
|
******************************************************************
|
|
*
|
|
* GetClamp - Read the current clamp values
|
|
*
|
|
* Input word: don't care
|
|
* Input word: don't care
|
|
* Input word: don't care
|
|
* Input word: don't care
|
|
* Output word: Y maximum clamp
|
|
* Output word: Y mimimum clamp
|
|
* Output word: X Maximum clamp
|
|
* Output word: X minimum clamp
|
|
*
|
|
******************************************************************
|
|
*
|
|
TGetClamp PROC
|
|
|
|
longa on
|
|
longi on
|
|
;
|
|
; stack structure
|
|
; no change for data bank register
|
|
;
|
|
DefineStack
|
|
Preg byte
|
|
Breg byte
|
|
RTL1 block 3
|
|
RTL2 block 3
|
|
MaxY word
|
|
MinY word
|
|
MaxX word
|
|
MinX word
|
|
;
|
|
php ;save interrupt state
|
|
sei ;disable interrupt
|
|
phb ;save data bank register
|
|
jsr setdbtoe1
|
|
lda |HiYclamp ;move clamp values to stack
|
|
sta MaxY,s
|
|
lda |LowYclamp
|
|
sta MinY,s
|
|
lda |HiXclamp
|
|
sta MaxX,s
|
|
lda |LowXclamp
|
|
sta MinX,s
|
|
plb ;restore data bank register
|
|
plp ;restore interrupt
|
|
|
|
jmp oEndCall0 ;exit tool
|
|
|
|
ENDP
|
|
|
|
************************************************************
|
|
*
|
|
* PosMouse - set mouse position to user-defined position
|
|
*
|
|
* Input word: X position
|
|
* Input word: Y position
|
|
*
|
|
************************************************************
|
|
*
|
|
TPosMou PROC
|
|
|
|
longa on
|
|
longi on
|
|
;
|
|
; stack structure
|
|
;
|
|
DBreg equ 1
|
|
Preg equ DBreg+1
|
|
RTL1 equ Preg+1
|
|
RTL2 equ RTL1+3
|
|
Ypos equ RTL2+3
|
|
Xpos equ Ypos+2
|
|
;
|
|
php ;save interrupt state
|
|
sei ;disable interrupt
|
|
phb ;save data bank register
|
|
jsr setdbtoe1
|
|
longa off
|
|
longi off
|
|
sep #$30 ;off to 8 bit land
|
|
lda Xpos+1,s ;move position to screen holes
|
|
sta |HighAbsx
|
|
lda Xpos,s
|
|
sta |LowAbsx
|
|
lda Ypos+1,s
|
|
sta |HighAbsy
|
|
lda Ypos,s
|
|
sta |LowAbsy
|
|
jsr GetMdata ;also reset keygloo mouse information
|
|
longa on
|
|
longi on
|
|
rep #$30 ;back to 16 bit land for exit
|
|
plb ;restore data bank
|
|
plp ;restore interrupt state
|
|
jmp oEndCall4
|
|
|
|
ENDP
|
|
|
|
**************************************************************
|
|
*
|
|
* ServeMouse - Service mouse interrupt
|
|
* Update interrupt status bit at screen hole ($077c)
|
|
* to show current status
|
|
*
|
|
* Input word: Space, don't care
|
|
* Output word: Interrupt status
|
|
**************************************************************
|
|
*
|
|
TServMou PROC
|
|
|
|
longa on
|
|
longi on
|
|
;
|
|
; stack structure
|
|
;
|
|
DBreg equ 1
|
|
Preg equ DBreg+1
|
|
RTL1 equ Preg+1
|
|
RTL2 equ RTL1+3
|
|
IntStat equ RTL2+3
|
|
|
|
|
|
php ;save interrupt status on entry
|
|
sei ;disable interrupt
|
|
phb ;save data bank
|
|
jsr setdbtoe1 ;change data bank to $00
|
|
longa off
|
|
longi off
|
|
sep #$30 ;off to 8-bit land
|
|
lda #$0e ;reset bit3, VBL interrupt
|
|
; ; bit2, Button 0/1 interrupt
|
|
; ; bit1, Movement interrupt
|
|
trb |MseStat ;cause to reset
|
|
lda |irq_Intflag ;test VBL enabled/active status flag
|
|
tay ;temp store
|
|
and #$08 ;bit3 = 1, if vbl interrupted
|
|
beq NotVbl ;bra if not vbl interrupt, don't reset
|
|
sta |ClrVblint ;else disable vbl interrupt, $c047
|
|
tya ;get back intflag
|
|
and #$f7 ; to clr the vbl interrupt stat
|
|
sta |irq_Intflag ; clear it
|
|
lda #$08 ;prepare bit to update |MseStat
|
|
|
|
NotVbl ;
|
|
tay ;save status
|
|
tsb |MseStat ;update mouse state screen hole
|
|
bit |kmstatus ;chk for mouse info in gloo
|
|
bvc MseIntdis ;bra if mouse interrupts noe enabled
|
|
bpl MseIntdis ;bra if ints enabled but mse didn't int
|
|
lda #$0e ;chk what's ints status
|
|
tay ; set 'y' non-zero for exit from here
|
|
tsb |MseStat ;Update |MseStat, $077c
|
|
|
|
MseIntdis ;
|
|
tya ;test if mousey interrupt or not
|
|
lda |MseStat ;finally read back the new status
|
|
sta IntStat,s ;store to proper location in stack
|
|
; for application to read it
|
|
plb ;restore data bank register
|
|
plp ;restore interrupt status
|
|
tya ;test if mousey interrupt or not
|
|
beq NotMseInt ;bra for not mousey type interrupt
|
|
clc ;maintain compatibility for firmware call
|
|
bra ExitSerMse
|
|
|
|
NotMseInt ;
|
|
sec ;maintain compatibility for firmware call
|
|
ExitSerMse ;
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16-bit land a must
|
|
jmp oEndcall0 ;exit the tool
|
|
|
|
ENDP
|
|
|
|
****************************************************************
|
|
*
|
|
* GetAbsclamp - get absolute clamp values
|
|
*
|
|
* Input word: Space for result
|
|
* Input word: Space for result
|
|
* Input word: Space for result
|
|
* Input word: Space for result
|
|
* <----- sp
|
|
* Output word: X minimum clamp
|
|
* Output word: X maximum clamp
|
|
* Output word: Y minimum clamp
|
|
* Output word: Y maximum clamp
|
|
* <----- sp
|
|
*
|
|
***************************************************************
|
|
;
|
|
GetAbsClamp PROC
|
|
|
|
longa on
|
|
longi on
|
|
|
|
;
|
|
; stack structure
|
|
;
|
|
RTL1 equ 1
|
|
RTL2 equ RTL1+3
|
|
MaxY equ RTL2+3
|
|
MinY equ MaxY+2
|
|
MaxX equ MinY+2
|
|
MinX equ MaxX+2
|
|
|
|
lda >AbsClamps ;move clamps to stack
|
|
sta MinX,s
|
|
lda >AbsClamps+2
|
|
sta MinY,s
|
|
lda >AbsClamps+4
|
|
sta MaxX,s
|
|
lda >AbsClamps+6
|
|
sta MaxY,s
|
|
|
|
jmp oEndCall0
|
|
|
|
ENDP
|
|
|
|
********************************************************************
|
|
*
|
|
* SetAbsclamp - set absolute device clamp values
|
|
*
|
|
* Input word: X axis minimum clamp
|
|
* Input word: X axis maximum clamp
|
|
* Input word: Y axis minimum clamp
|
|
* Input word: Y axis maximum clamp
|
|
* <----- sp
|
|
*
|
|
********************************************************************
|
|
*
|
|
SetAbsClamp PROC
|
|
|
|
longa on
|
|
longi on
|
|
|
|
;
|
|
; stack structure
|
|
;
|
|
RTL1 equ 1
|
|
RTL2 equ RTL1+3
|
|
Ymax equ RTL2+3
|
|
Ymin equ Ymax+2
|
|
Xmax equ Ymin+2
|
|
Xmin equ Xmax+2
|
|
|
|
lda Xmin,s ;move clamps from stack to its area
|
|
sta >AbsClamps
|
|
lda Ymin,s
|
|
sta >AbsClamps+2
|
|
lda Xmax,s
|
|
sta >AbsClamps+4
|
|
lda Ymax,s
|
|
sta >AbsClamps+6
|
|
|
|
jmp oEndCall8 ;exit tool by adjusting stack ptr
|
|
|
|
ENDP
|
|
|
|
*********************************************************************
|
|
*
|
|
* BasicInit - An unofficial tool to set up the clamp flags when
|
|
* calling from BASICMOUSE.
|
|
* InitFlag - The flags are returned in bits 6, 7 of 'A'.
|
|
* Called during power up, InitMouse, ClampMouse and
|
|
* BASICMOUSE (firmware).
|
|
*
|
|
* The following is a break down of what the clamping flags mean. The
|
|
* X flag is in bits 6, 7 of |MseMode byte and the Y flag is in bits 6, 7
|
|
* of the Info byte.
|
|
*
|
|
* Hi nibble Lo nibble Comments
|
|
*--------------------------------------------------------------------
|
|
* for X
|
|
* A: 00xx xxxx both x clamps are +
|
|
* 01xx xxxx min is - / max is +
|
|
* 10xx xxxx both x clamps are -
|
|
* 11xx xxxx min is + / max is -
|
|
* absolute clamping
|
|
*
|
|
* for Y
|
|
* A: 00xx xxxx both y clamps are +
|
|
* 01xx xxxx min is - / max is +
|
|
* 10xx xxxx both y clamps are -
|
|
* 11xx xxxx min is + / max is -
|
|
* absolute clamping
|
|
*
|
|
***********************************************************************
|
|
*
|
|
MyBasicInit PROC ;support entry for BASICMOUSE
|
|
|
|
longa on
|
|
longi on
|
|
;
|
|
; The stack is not affected by this call. Only BASICMOUSE is an external
|
|
; call to this tool, all others are internal call in the tool.
|
|
;
|
|
phb ;save data bank register
|
|
jsr setdbtoe1 ;change data bank to $00
|
|
longa off
|
|
longi off
|
|
sep #$30 ;off to 8 bit land
|
|
jsl >InitFlag
|
|
;
|
|
longa on
|
|
longi on
|
|
plb
|
|
rep #$30 ;exit with 16 bit land
|
|
jmp oEndCall0 ;exit from BASICMOUSE call
|
|
|
|
|
|
InitFlag PROC
|
|
;
|
|
longa off
|
|
longi off ;enter w/ 8 bit mode
|
|
sep #$30
|
|
;
|
|
ldx #$00 ;$00 for x-axis clamping
|
|
lda #$c0 ;ready to clear bits 6, 7
|
|
trb |MseMode ;reset it
|
|
trb |MseInfo ;reset it
|
|
jsr TstSwap4 ;go set a flag, return in 'A'
|
|
tsb |MseMode ;set appropriate bits
|
|
jsr TstClampVal8 ;do hi byte test
|
|
bcs XOK ;x ok now test y
|
|
bit |MseMode ;pick up flags in N and V
|
|
jsl >TstSwap ;go test it
|
|
;
|
|
XOK ;
|
|
ldx #$02 ;$02 for y-axis clamping
|
|
jsr TstSwap4 ;go set a flag
|
|
tsb |MseInfo ;set appropriate bits
|
|
jsr TstClampVal8 ;do hi byte test
|
|
bcs Tstclrts ;exit with 'c'=1
|
|
bit |MseInfo ;else pick up flags and test
|
|
;
|
|
TstSwap ;swap clamp values
|
|
bvs Tstclrts ;no swap if flag = 0 or 1
|
|
bpl PosNegnum ;'+' only if 2 pos # entered
|
|
sep #$40 ;'v'=1 if 2 neg # entered
|
|
PosNegnum ;
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16 bit land
|
|
lda |LowXclamp,x
|
|
bvs JustSwap ;'v'=0 then just swap
|
|
bit #$ff00 ;else test if illegal '-' number
|
|
bne JustSwap ;do regular swap
|
|
bit #$0080 ;test for illegal '-' number
|
|
beq JustSwap ;do regular swap
|
|
ora #$ff00 ;else extend sign to hi byte
|
|
sta |LowXclamp,x ;resave modified clamp
|
|
;
|
|
longa off
|
|
longi off
|
|
sep #$30 ;back to 8 bit land
|
|
lda #$40 ;change bit 6,7 (00) to (01)
|
|
cpx #$02 ;2 if change info else change |MseMode
|
|
bne ChMseMode ;
|
|
tsb |MseInfo ;set bit 6
|
|
rtl
|
|
;
|
|
ChMseMode ;
|
|
tsb |MseMode ;set bit 6
|
|
rtl
|
|
;
|
|
JustSwap ;
|
|
longa on
|
|
longi on ;enter with 16 bit m/x
|
|
tay ;save in y
|
|
lda |HiXclamp,x ;high clamp swap with low clamp
|
|
sta |LowXclamp,x
|
|
tya ;for indirect, bridge...
|
|
sta |HiXclamp,x
|
|
longa off
|
|
longi off
|
|
sep #$30 ;back to 8 bit land
|
|
;
|
|
Tstclrts ;
|
|
rtl ;back to caller
|
|
;
|
|
TstSwap4 ;
|
|
lda |HiXclamp+1,x ;get hi clamp hi byte
|
|
php ;save for later
|
|
lda |LowXclamp+1,x ;get low clamp hi byte
|
|
bmi LowclampNeg ;bra if low clamp -
|
|
plp ;what about hi clamp hi byte
|
|
bmi Flag3 ;if - set flag 3
|
|
lda #$00 ;must set flag to 0
|
|
rts ;return to internal call
|
|
;
|
|
Flag3 ;
|
|
lda #$c0 ;flag = 3
|
|
rts
|
|
;
|
|
LowclampNeg ;
|
|
plp ;what was sign of hi byte
|
|
bmi Flag2 ;if - then use flag 2
|
|
lda #$40 ;flag = 1
|
|
rts
|
|
;
|
|
Flag2 ;
|
|
lda #$80 ;flag = 2
|
|
rts
|
|
;
|
|
TstClampval8 ;
|
|
longa on
|
|
longi on
|
|
rep #$30 ;off to 16 bit land
|
|
lda |HiXclamp,x ;test hi clamp
|
|
cmp |LowXclamp,x ; against low clamp
|
|
longa off
|
|
longi off
|
|
sep #$30 ;back to 8 bit land
|
|
rts
|
|
;
|
|
ENDP
|
|
|
|
|
|
|
|
title 'FWEntry'
|
|
****************************************************************
|
|
*
|
|
* Full Native Dispatch to Firmware
|
|
*
|
|
* Input Word Entry point - 1
|
|
*
|
|
* This routine dispatches from full native mode to an emulation
|
|
* mode entry point. The 8 bit A,X and Y registers will be
|
|
* passed through to the target routine. A,X and Y will also
|
|
* be returned to the application from the target routine.
|
|
* If the dispatch is in the address range of $C0xx-$C7xx, then
|
|
* the dispatcher must determine if the slot to be accessed is
|
|
* internal or external. If external, then the system speed is
|
|
* kicked down to slow mode.
|
|
*
|
|
****************************************************************
|
|
|
|
|
|
FwEntry PROC EXPORT
|
|
|
|
DirReg equ 1
|
|
OrigState equ DirReg+2
|
|
OrigCya equ OrigState+1
|
|
OrigDbr equ OrigCya+1
|
|
OrigAReg equ OrigDbr+1
|
|
EntryWord equ OrigAReg+1
|
|
RetAddr1 equ EntryWord+2
|
|
|
|
sep #$30 ; 8 bit m/x
|
|
longa off
|
|
longi off
|
|
pha ; save processor environment
|
|
phb
|
|
lda #0
|
|
pha
|
|
plb
|
|
lda |CyaReg ; save current system speed
|
|
pha
|
|
lda |StateReg
|
|
pha
|
|
lda #%00001000
|
|
sta |StateReg
|
|
phd
|
|
tsc
|
|
tcd
|
|
phx ; save $Cn
|
|
rep #$20 ; 16 bit 'm'
|
|
lda EntryWord ; get dispatch page
|
|
inc a ; adjust to absolute entry point
|
|
xba ; get high byte entry point
|
|
sep #$20 ; 8 bit 'm'
|
|
cmp #$C8 ; $C000 < EntryPoint < $C800 ?
|
|
bge NotIO ; no
|
|
and #$F0
|
|
cmp #$C0
|
|
bne NotIO ; if not in $Cxxx space
|
|
rep #$20 ; 16 bit 'm'
|
|
lda EntryWord ; get dispatch page
|
|
inc a ; adjust to absolute entry point
|
|
xba ; want $Cn
|
|
sep #$20 ; 8 bit 'm'
|
|
and #$07 ; determine the slot were going to
|
|
cmp #$03 ; is it slot 3?
|
|
bne NotSlot3 ; no
|
|
lda >RDC3ROM ; is slot 3 internal or external ?
|
|
and #%10000000 ; mask excess bits
|
|
bra SetSpeed ; if external, set slow!
|
|
NotSlot3 ;
|
|
tax
|
|
lda |SltRomSel ; now get slot rom selection
|
|
SlowChk ;
|
|
ror a ; get internal/external to 'c'
|
|
dex
|
|
bpl SlowChk
|
|
lda #0 ; get ready to set system speed
|
|
ror a ; bit 7 = not speed
|
|
SetSpeed ;
|
|
trb |CyaReg ; set the system speed
|
|
NotIO ;
|
|
plx ; restore $Cn
|
|
rep #$30 ; 16 bit m/x
|
|
longa on
|
|
longi on
|
|
|
|
****************************************************************
|
|
*
|
|
* This saves the states of the 8 bit X and Y while
|
|
* we play around with switching the stack from native
|
|
* mode to emulation mode. If the native stack is not in
|
|
* page $01, then the 16 bit stack pointer must be saved while
|
|
* the stack pointer is reset to Main memory stack page $01XX.
|
|
* Then the 16 bit native mode stack pointer is saved on the
|
|
* emulation mode stack. It's strange, but neccessary.
|
|
*
|
|
****************************************************************
|
|
|
|
txa ; get 8 bit X
|
|
xba ; save it
|
|
sep #$20 ; 8 bit 'm'
|
|
tya ; now get 8 bit Y
|
|
rep #$20 ; 16 bit 'm'
|
|
tax ; now X really has both X and Y
|
|
tsc ; get current stack pointer
|
|
tay ; and save in Y register
|
|
sep #$20 ; 8 bit 'm'
|
|
longa off
|
|
xba ; check if stack is in page $01
|
|
dec a
|
|
beq AlreadyPG1 ; if page 1, then don't get it
|
|
lda #1 ; stack will be in page 1
|
|
xba
|
|
lda >MNEMSTKPTR ; get low byte of stack pointer
|
|
rep #$20 ; 16 bit 'm'
|
|
longa on
|
|
tcs ; set the page 1 stack pointer
|
|
AlreadyPG1 ;
|
|
phy ; and save the 16 bit stack pointer
|
|
rep #$20 ; 16 bit 'm'
|
|
txa ; get back both X and Y
|
|
sep #$30 ; 8 bit 'm' & 'x'
|
|
tay ; now restore Y
|
|
xba ; and then restore X
|
|
tax
|
|
phd ; save current direct register
|
|
pea FWRET-1 ; save return address
|
|
lda |RDCXROM ; save FE bank evironment
|
|
pha
|
|
rep #$20 ; 16 bit 'm'
|
|
lda EntryWord ; save dispatch address
|
|
pha
|
|
sep #$30 ; 8 bit m/x
|
|
longa off
|
|
longi off
|
|
lda OrigAReg ; get entry 'A' reg
|
|
pea $0000 ; set direct register to $0000
|
|
pld
|
|
brl ToMainSide ; here we go
|
|
|
|
FWRET ;
|
|
pld ; restore direct page
|
|
sta EntryWord ; save 'A' on return from firmware
|
|
php ; save 'P' on return from firmware
|
|
pla
|
|
sta EntryWord+1
|
|
rep #$30 ; 16 bit 'x' and 'm'
|
|
pla ; get native mode stack pointer
|
|
tcs ; and reset the stack pointer
|
|
sep #$30 ; 8 bit 'm' and 'x'
|
|
pld ; restore direct register
|
|
pla ; restore state
|
|
sta |StateReg
|
|
pla ; restore system speed
|
|
sta |CyaReg
|
|
plb ; restore Data Bank Register
|
|
sep #$30 ; 8 bit 'm' and 'x'
|
|
longa on
|
|
longi on
|
|
pla ; clean entry acc. off stack
|
|
pla ; A reg = value from firmware call
|
|
plp ; P reg = value from firmware call
|
|
rep #$30 ; back to 16 bit land
|
|
rts
|
|
|
|
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
* This routine used to dispatch to mainside
|
|
*
|
|
* ENTRY : Rom Enabled
|
|
* Native Mode
|
|
* 8 Bit m/x
|
|
* Stack = RDSLOTCXROM
|
|
* Dispatch Address-1 (MSB)
|
|
* Dispatch Address-1 (LSB)
|
|
*
|
|
* EXIT : Fast Mode
|
|
*
|
|
*
|
|
****************************************************************
|
|
ToMainSide PROC
|
|
|
|
longa off ; start off in 8 bit mode
|
|
longi off
|
|
xba ;Preserve 'A' in 'B'
|
|
txa ;preserve 'X' in 'A'
|
|
rep #$30 ;off to 16 bit land
|
|
longa on
|
|
longi on
|
|
|
|
plx ;save routine address in 'X'
|
|
phk ;Return bank
|
|
pea FEBankRts-1 ;Return address in bank FE
|
|
pea MainExit-1 ;Exit point in main monitor ROM
|
|
phx ;Routine to execute back to stack
|
|
sep #$30 ;back to 8 bit land
|
|
longa off
|
|
longi off
|
|
tax ;Restore 'X' from 'A'
|
|
xba ;Restore 'A' from 'B'
|
|
|
|
ToMainSid2 ;
|
|
xba ;Save 'A' value
|
|
lda >CyaReg ;save speed
|
|
and #$7F ;slow down system
|
|
ora >SystemSpd ;System speed mask
|
|
sta >CyaReg ;
|
|
xba ;Restore user 'A' value
|
|
phb ;Data bank register is new program bank
|
|
pea MainSide-1 ;Main ROM area entry point
|
|
sta >SetSlotCXRom ;disable internal CxROM
|
|
rtl ;go to mainside
|
|
|
|
FEBankRts ;
|
|
sep #$30
|
|
xba ;save user's 'A' value
|
|
phb
|
|
pea 0
|
|
plb
|
|
plb
|
|
lda #$80 ;go fast in here
|
|
tsb |CyaReg ;
|
|
lda 2,s ; get rom select
|
|
bpl SetExtRom ; if external
|
|
sta |SetIntCxROM ;Restore bank FE operating environment
|
|
OKforExit ;
|
|
plb
|
|
pla
|
|
xba
|
|
rts ;Back to bank $FF caller
|
|
SetExtRom ;
|
|
sta |SetSlotCXROM
|
|
bra OKforExit
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
title 'ID Tag Manager'
|
|
*********************************************************************
|
|
*
|
|
* This tool is used to insert, delete and inquire status
|
|
* regarding an ID tag. The ID tag is used to mark segments
|
|
* as belonging to a specific application.
|
|
*
|
|
* GetNewID
|
|
* Input Word Space for result
|
|
* Input Word ID tag (Type and Aux)
|
|
* Output Word ID tag (Full tag returned)
|
|
*
|
|
* DeleteID
|
|
* Input Word ID tag (Type and Main)
|
|
*
|
|
* StatusID
|
|
* Input Word ID tag (Type and Main)
|
|
*
|
|
* ID tag structure is shown below.....
|
|
* ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
|
|
* | | | | | | | | | | | | | | | | |
|
|
* | F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
|
|
* |___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|
|
|
* |___|___|___| |___|___|___| |___|___|___|___|___|___|___|
|
|
* | | |
|
|
* Type Field Aux ID Field Main ID Field
|
|
*
|
|
* Type = 0 Memory Manager
|
|
* 1 Application
|
|
* 2 Controlling Program (Finder, Shell, etc.)
|
|
* 3 ProDOS
|
|
* 4 Tool Kits..................Not managed here.
|
|
* 5 Desk Accessories
|
|
* 6 Run Time Libraries
|
|
* 7 System loader..............Not managed here
|
|
* 8 Firmware / System Function
|
|
* 9 Tool Locator...............Not managed here.
|
|
* A Setup File
|
|
* B Undefined
|
|
* C Undefined
|
|
* D Undefined
|
|
* E Undefined
|
|
* F Undefined
|
|
*
|
|
* Change History
|
|
*
|
|
* 13 Nov 88 Steven Glass
|
|
*
|
|
* No longer manage ID 4000, 7000 or 9000. (These are used
|
|
* throughout the system without anyone reserving them. so we
|
|
* return error when someone trys to reserve them).
|
|
*
|
|
* Also removed unnecessary Hlock and hUnlock calls.
|
|
*
|
|
*
|
|
*********************************************************************
|
|
GetNewID PROC
|
|
longa on
|
|
longi on
|
|
|
|
taglist equ 1
|
|
size equ taglist+4
|
|
SrchTag equ size+2
|
|
SrchCnt equ SrchTag+2
|
|
OrigDBR equ SrchCnt+2
|
|
OrigDir equ OrigDBR+1
|
|
rtl1 equ OrigDir+2
|
|
rtl2 equ rtl1+3
|
|
UserTag equ rtl2+3
|
|
IDTag equ UserTag+2
|
|
Bounds equ LastTag
|
|
|
|
DefineStack
|
|
s_Rtl1 block 3
|
|
s_Rtl2 block 3
|
|
s_UserTag word
|
|
s_result word
|
|
|
|
lda s_UserTag,s
|
|
and #$F000
|
|
cmp #$4000
|
|
beq NoCanDo
|
|
|
|
cmp #$7000
|
|
beq NoCanDo
|
|
|
|
cmp #$9000
|
|
bne CanDo
|
|
|
|
NoCanDo ldx #BadInputErr
|
|
jmp oErrOut2
|
|
|
|
|
|
CanDo
|
|
|
|
|
|
phd ; environment
|
|
phb
|
|
lda #0 ; init space to 0
|
|
pha ; space for search counter
|
|
pha ; space for search tag
|
|
pha ; space for list size
|
|
pha ; space for list address
|
|
pha
|
|
tsc ; and turn stack into zp
|
|
tcd
|
|
|
|
jsr GetMTHandleSize
|
|
sta size ; save current size
|
|
sta srchcnt ; initialize search counter
|
|
ina ; grow for a word entry in list
|
|
ina
|
|
jsr SetMTHandleSize
|
|
jsr MTderef ; dereference the handle
|
|
stx taglist ; set tag list address
|
|
sty taglist+2 ; ready for direct-indirect-indexed
|
|
*
|
|
* Search for a hole in the tag list with the requested type.
|
|
* The search routine ignores the AUX field. Post processing
|
|
* of the IDTAG returned from the search must check for a
|
|
* nonzero MAIN field before returning the tag to the requestor.
|
|
* Only the TYPE and MAIN fields in the IDTAG are maintained in
|
|
* the IDTAG list. IDTAGS with a MAIN field set to zero are
|
|
* invalid and not maintained in the list. IDTAGS with a TYPE
|
|
* field of zero are not maintained in the list. This means that
|
|
* the maximum number of tags maintained in the list is 3825 IDTAGS
|
|
* or 15*255. Since tags are word wide, the maximum length of the
|
|
* list is 7650 bytes ($1DE2).
|
|
*
|
|
ldy size ; decrement remaining list size
|
|
beq emptylist
|
|
dey ; to point at last entry
|
|
dey
|
|
sty size ; point at top of list
|
|
emptylist ;
|
|
lda UserTag ; get callers ID
|
|
and #$F000 ; keep only relevant parms
|
|
inc a ; make initial tag = $NX01
|
|
sta SrchTag ; set search tag
|
|
and #$F000 ; and check requested type
|
|
bne TypeOK
|
|
ldx #badInputErr ; bad input parm
|
|
bra NoParmErr
|
|
TypeOK ;
|
|
lda UserTag ; get callers ID
|
|
and #$0F00 ; preserve AUX
|
|
sta UserTag
|
|
cpy #0 ; any tags in list?
|
|
beq NewTag ; no
|
|
FindLast ;
|
|
lda [taglist],y ; else get tag from list
|
|
and #$F0FF ; is it same as search tag
|
|
cmp SrchTag
|
|
beq SameTag ; yes
|
|
cpy #0 ; was this the last list entry?
|
|
beq NewTag ; yes
|
|
dey ; point at next list entry
|
|
dey
|
|
bra findlast ; and loop to check
|
|
SameTag ;
|
|
inc SrchTag ; set next possibility
|
|
ldy size ; point at last list entry
|
|
dec SrchCnt ; how many more searches
|
|
dec SrchCnt
|
|
bne FindLast ; at least this one
|
|
NewTag ;
|
|
lda SrchTag ; Get unassigned tag
|
|
ora UserTag ; add in the AUX
|
|
sta IDtag ; save for caller
|
|
ldy size ; point at top of tag list
|
|
iny
|
|
iny
|
|
sta [taglist],y ; store into list
|
|
ldx #0 ; assume no error
|
|
and #$00FF ; check tag in bounds
|
|
bne NoParmErr ; assumed right !
|
|
ldx #idTagNtAvlErr ; else tag not available
|
|
NoParmErr ;
|
|
pla ; clean off tag list address
|
|
pla
|
|
pla ; clean off size
|
|
pla ; clean off search tag
|
|
pla ; clean off search count
|
|
plb ; restore data bank
|
|
pld ; restore direct page
|
|
cpx #$0000
|
|
bne TagError ; if out of bounds
|
|
jmp oEndCall2
|
|
|
|
TagError ;
|
|
phx ; save error code
|
|
jsr GetMTHandleSize
|
|
dec a ; reduce size by a word
|
|
dec a
|
|
jsr SetMTHandleSize
|
|
plx ; restore error code
|
|
|
|
jmp oErrOut2
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
DeleteID PROC
|
|
*
|
|
* Removes the specified ID from the IDTagList
|
|
*
|
|
*
|
|
* Inputs:
|
|
* word : id to remove
|
|
*
|
|
* Outputs:
|
|
* none
|
|
*
|
|
* External Refs:
|
|
* none
|
|
*
|
|
* Entry Points:
|
|
* none
|
|
*
|
|
longa on ; mode
|
|
longi on
|
|
*
|
|
****************************************************************
|
|
|
|
longa on
|
|
longi on
|
|
|
|
TagList equ 1 ; tag list address
|
|
size equ taglist+4 ; ID list size
|
|
DeleteCnt equ size+2 ; list size
|
|
OrigDBR equ DeleteCnt+2 ; saved data bank reg
|
|
OrigDir equ OrigDBR+1 ; saved direct reg
|
|
rtl1 equ OrigDir+2
|
|
rtl2 equ rtl1+3
|
|
IDtag equ rtl2+3 ; ID tag (type and aux)
|
|
|
|
phd ; save direct page
|
|
phb ; save data bank
|
|
lda #0 ; init space with zero
|
|
pha ; space for tag list address
|
|
pha
|
|
pha ; space for size
|
|
pha ; delete counter
|
|
tsc ; turn stack into zp
|
|
tcd
|
|
lda IDtag ; get ID tag
|
|
and #$F0FF ; Type and Main parms only
|
|
sta IDtag
|
|
|
|
jsr GetMTHandleSize
|
|
sta size
|
|
jsr MTderef ; dereference the handle
|
|
stx taglist ; set tag list address
|
|
sty taglist+2
|
|
*
|
|
* search for and delete the requested tag
|
|
*
|
|
lda size ; any list entries?
|
|
beq deletedone ; no
|
|
ldy #0 ; point at base of list
|
|
FindID ;
|
|
lda [taglist],y ; get id from list
|
|
and #$F0FF ; Type and Main parms only
|
|
cmp IDtag ; check against target
|
|
beq FoundIt
|
|
iny ; point at next list entry
|
|
iny
|
|
cpy size ; done all entries?
|
|
bne FindID ; no, keep looking
|
|
beq deletedone ; yes, no id found
|
|
FoundIt ;
|
|
inc DeleteCnt ; bump deleted counter
|
|
DeleteIt ;
|
|
cpy size ; done ?
|
|
beq DeleteDone ; yes
|
|
iny
|
|
iny
|
|
lda [taglist],y ; move remaining list down
|
|
dey
|
|
dey
|
|
sta [taglist],y
|
|
iny ; point at next list entry
|
|
iny
|
|
bra DeleteIt ; move entire list
|
|
DeleteDone ;
|
|
asl DeleteCnt ; count bytes not words
|
|
|
|
jsr GetMTHandleSize
|
|
sec
|
|
sbc DeleteCnt ; word wide entries that were
|
|
jsr SetMTHandleSize
|
|
|
|
pla ; clean off tag list address
|
|
pla
|
|
pla ; clean up size
|
|
pla ; clean up delete count
|
|
plb
|
|
jmp EndCall2
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
|
|
****************************************************************
|
|
*
|
|
StatusID PROC
|
|
*
|
|
* Indicates whether or not the specified user id is active.
|
|
* If the ID is in the list of reserved ID's, no error is
|
|
* returned. If the ID is not in the list, the idTagNtAvlErr is
|
|
* returned.
|
|
*
|
|
* This seems kind of silly I know, but what can I say. I
|
|
* have to maintain this code, not justify it.
|
|
*
|
|
*
|
|
* Inputs:
|
|
* word : UserID to check.
|
|
*
|
|
* Outputs:
|
|
* none
|
|
*
|
|
* External Refs:
|
|
* none
|
|
*
|
|
* Entry Points:
|
|
* none
|
|
*
|
|
longa on ; mode
|
|
longi on
|
|
*
|
|
****************************************************************
|
|
|
|
longa on
|
|
longi on
|
|
|
|
taglist equ 1
|
|
size equ taglist+4
|
|
OrigDBR equ size+2
|
|
OrigDir equ OrigDBR+1
|
|
rtl1 equ OrigDir+2
|
|
rtl2 equ rtl1+3
|
|
IDtag equ rtl2+3
|
|
|
|
phd ; save direct page
|
|
phb ; save DBR
|
|
lda #0 ; start by getting local space on stack and zeroing it
|
|
pha ; space for tag list ptr
|
|
pha
|
|
pha ; space for size
|
|
tsc ; turn stack into zp
|
|
tcd
|
|
|
|
jsr GetMTHandleSize
|
|
sta size
|
|
jsr MTderef ; dereference the handle
|
|
stx taglist ; set tag list address
|
|
sty taglist+2
|
|
*
|
|
* now search for ID tag
|
|
*
|
|
lda IDtag ; get search tag
|
|
and #$F0FF ; Main & Type only
|
|
sta IDtag
|
|
ldy #0 ; point at base of list
|
|
FindID ;
|
|
cpy size ; done ?
|
|
beq SrchDone ; no ID tag found
|
|
lda [taglist],y ; check for tag
|
|
and #$F0FF ; type and main only
|
|
cmp IDtag
|
|
beq FoundIt ; ID is active
|
|
iny ; point at next list entry
|
|
iny
|
|
bra FindID ; and keep looking
|
|
SrchDone ;
|
|
stz size ; set not found flag
|
|
FoundIt ;
|
|
pla ; clean up tag list address
|
|
pla
|
|
pla ; clean off size
|
|
plb
|
|
cmp #0 ; was ID found?
|
|
beq IDinact ; if did not find tag
|
|
jmp EndCall2
|
|
|
|
IDinact ;
|
|
ldx #idTagNtAvlErr ; no id for input parm
|
|
jmp ErrOut2
|
|
|
|
ENDP
|
|
|
|
|
|
title 'IRQ Stuff'
|
|
****************************************************************
|
|
*
|
|
* This tool call is used to enable interrupt sources or other
|
|
* special functions such as keyboard buffering
|
|
*
|
|
* Change History
|
|
*
|
|
* 13 Feb 87 Ray Montagne
|
|
*
|
|
* Keyboard interrupts did not enable the VBL interrupt
|
|
* source. Now it does!
|
|
*
|
|
****************************************************************
|
|
IntSrc PROC
|
|
|
|
KeyTaskHdr equ $E1014C
|
|
KeyTaskCnt equ KeyTaskHdr+4
|
|
KeyTaskSig equ KeyTaskCnt+2
|
|
KeyTaskJmp equ KeyTaskSig+2
|
|
|
|
longa on
|
|
longi on
|
|
|
|
lda 7,s ; get reference #
|
|
asl a ; make index
|
|
tax
|
|
cpx #$0020 ; check tool reference
|
|
bge DsptchErr ; oops!!!
|
|
pea DsptchRet-1 ; push return address
|
|
lda >Disptch,x ; and then dispatch address
|
|
pha
|
|
sep #$30 ; off to 8 bit land for dispatch
|
|
longa off
|
|
longi off
|
|
rts ; do dispatch
|
|
|
|
DsptchRet ;
|
|
rep #$30 ;back to 16 bit land
|
|
longa on
|
|
longi on
|
|
bcs DsptchErr ; if error, then go here
|
|
jmp oEndCall2 ; all done
|
|
DsptchErr ;
|
|
ldx #badInputErr ; Parameter error occured
|
|
jmp oErrOut2 ; error exit
|
|
|
|
Disptch ;
|
|
DC.W EnblKbd-1 ; enable keyboard interrupts
|
|
DC.W DsblKbd-1 ; disable keyboart int
|
|
DC.W EnblVbl-1 ; enable vertical blanking interrupts
|
|
DC.W DsblVbl-1 ; disable VBL int
|
|
DC.W EnblQtr-1 ; enable quarter second interrupt
|
|
DC.W DsblQtr-1 ; disable quarter second int
|
|
DC.W EnblSec-1 ; enable 1 second int
|
|
DC.W DsblSec-1 ; disable 1 second int
|
|
DC.W EnblBuf-1 ; enable keyboard buffering
|
|
DC.W DsblBuf-1 ; disable keyboard buffering
|
|
DC.W EnblDat-1 ; enable keymicro data int
|
|
DC.W DsblDat-1 ; disable keymicro data int
|
|
DC.W EnblScan-1 ; enable scan line int
|
|
DC.W DsblScan-1 ; disable scan line int
|
|
DC.W EnblExt-1 ; enable external VGC int
|
|
DC.W DsblExt-1 ; disable external VGC int
|
|
|
|
EnblKbd ;
|
|
longa off
|
|
lda #%10000000 ; set KBD IRQ flag
|
|
sta >KBDIRQFLAG
|
|
rep #$30 ; to 16 bit land
|
|
longa on
|
|
longi on
|
|
lda #1 ; initialize task count
|
|
sta >KeyTaskCnt
|
|
lda #$A55A ; and set task signature
|
|
sta >KeyTaskSig
|
|
lda #KeyTask ; now set up jump to task
|
|
pha
|
|
xba
|
|
and #$FF00
|
|
ora #$005C
|
|
sta >KeyTaskJmp
|
|
pla
|
|
and #$FF00
|
|
ora #^KeyTask
|
|
xba
|
|
sta >KeyTaskJmp+2
|
|
pea $00E1 ; pointer to KBD task
|
|
pea $014C
|
|
_SetHeartBeat ; install keyboard task
|
|
sep #$30
|
|
clc
|
|
bra ENBLVbl ; changed 13 Feb 87 RBM
|
|
|
|
KeyTask ;
|
|
longa off
|
|
longi off
|
|
lda #$01 ; reset task count
|
|
sta >KeyTaskCnt
|
|
lda >KBD ; read keyboard data
|
|
bpl NoKBDirq ; if no key, no dispatch
|
|
jmp >IRQ_KBD
|
|
NoKBDirq ;
|
|
rtl
|
|
|
|
|
|
DsblKbd ;
|
|
longa off
|
|
lda #%00000000 ; clear KBD IRQ flag
|
|
sta >KBDIRQFLAG
|
|
rep #$30 ; to 16 bit land
|
|
longa on
|
|
longi on
|
|
pea $00E1 ; pointer to KBD task
|
|
pea $014C
|
|
_DelHeartBeat
|
|
rts
|
|
|
|
EnblVbl ;
|
|
longa off
|
|
longi off
|
|
lda >INTEN ; get mega interrupt reg
|
|
ora #%00001000 ; enable VBL interrupts
|
|
sta >INTEN
|
|
rts
|
|
|
|
DsblVbl ;
|
|
lda >INTEN ; get mega interrupt reg
|
|
and #%11110111 ; disable VBL interrupts
|
|
sta >INTEN
|
|
rts
|
|
|
|
EnblQtr ;
|
|
lda >INTEN ; get mega interrupt reg
|
|
ora #%00010000 ; enable 1/4 sec interrupt
|
|
sta >INTEN
|
|
rts
|
|
|
|
DsblQtr ;
|
|
lda >INTEN ; get mega interrupt reg
|
|
and #%11101111 ; disable 1/4 sec interrupt
|
|
sta >INTEN
|
|
rts
|
|
|
|
EnblSec ;
|
|
lda >VGCINT ; get VGC interrupt reg
|
|
ora #%00000100 ; enable 1 sec interrupt
|
|
sta >VGCINT
|
|
rts
|
|
|
|
DsblSec ;
|
|
lda >VGCINT ; get VGC interrupt reg
|
|
and #%11111011 ; disable 1 sec interrupt
|
|
sta >VGCINT
|
|
rts
|
|
|
|
EnblScan ;
|
|
lda >VGCINT ; get VGC interrupt reg
|
|
ora #%00000010 ; enable scan line interrupt
|
|
sta >VGCINT
|
|
rts
|
|
|
|
DsblScan ;
|
|
lda >VGCINT ; get VGC interrupt reg
|
|
and #%11111101 ; disable scan line interrupt
|
|
sta >VGCINT
|
|
rts
|
|
|
|
EnblExt ;
|
|
lda >VGCINT ; get VGC interrupt reg
|
|
ora #%00000001 ; enable external VGC interrupt
|
|
sta >VGCINT
|
|
rts
|
|
|
|
DsblExt ;
|
|
lda >VGCINT ; get VGC interrupt reg
|
|
and #%11111110 ; disable external VGC interrupt
|
|
sta >VGCINT
|
|
rts
|
|
|
|
EnblBuf ;
|
|
rts
|
|
|
|
DsblBuf ;
|
|
rts
|
|
|
|
|
|
EnblDat ;
|
|
lda >KMStatus ; get Keyboard u cmd/status
|
|
ora #%00010000 ; enable data interrupts
|
|
sta >KMStatus
|
|
rts
|
|
|
|
DsblDat ;
|
|
lda >KMStatus ; get Keyboard u cmd/status
|
|
and #%11101111 ; disable data interrupts
|
|
sta >KMStatus
|
|
rts
|
|
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
title 'GetTick'
|
|
**************************************************************
|
|
*
|
|
* Returns current tick count value
|
|
*
|
|
****************************************************************
|
|
GetTick PROC
|
|
longa on
|
|
longi on
|
|
|
|
IRQstate equ 1
|
|
rtl1 equ IRQstate+1
|
|
rtl2 equ rtl1+3
|
|
LowTick equ rtl2+3
|
|
HiTick equ LowTick+2
|
|
|
|
php ; save interrupt status
|
|
sei ; and disable for now
|
|
lda >TickCnt ; move tick count to stack
|
|
sta LowTick,s
|
|
lda >TickCnt+2
|
|
sta HiTick,s
|
|
plp ; restore interrupt status
|
|
jmp oEndCall0
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
title 'FWEntry'
|
|
****************************************************************
|
|
*
|
|
* Firmware Entry Points
|
|
*
|
|
* This function requires two words of input as follows
|
|
*
|
|
* Input Word Room for result
|
|
* Input Word Room for result
|
|
* Input Word Room for result
|
|
* Input Word Room for result
|
|
* Input Word Accumulator value (low byte)
|
|
* Input Word X register value (low byte)
|
|
* Input Word Y register value (low byte)
|
|
* Input Word Address of Apple// entry point
|
|
* Output Word Y register (low byte)
|
|
* Output Word X register (low byte)
|
|
* Output Word A register (low byte)
|
|
* Output Word 6502 status (low byte)
|
|
*
|
|
* Modification History
|
|
*
|
|
* 9 Mar 87 Ray Montagne
|
|
*
|
|
* Processor status was comming off stack in wrong byte of word.
|
|
*
|
|
* 12 Mar 87 Ray Montagne
|
|
*
|
|
* Steve buggered my code by puting an and #$00CF in the wrong
|
|
* spot. So I fixed it!!!
|
|
*
|
|
* 17 Nov 88 Konstantin Othmer
|
|
*
|
|
* Added calls to slot arbiter so that the default slot configuration
|
|
* is selected anytime a call is made to the Cn00 space.
|
|
* NOTE: This does not effect the text tools since they call fwentry directly.
|
|
*
|
|
****************************************************************
|
|
MonEntry PROC
|
|
|
|
dir equ 1
|
|
ret1 equ dir+2
|
|
ret2 equ ret1+3
|
|
fwep equ ret2+3
|
|
yin equ fwep+2
|
|
xin equ yin+2
|
|
ain equ xin+2
|
|
yout equ ain+2
|
|
xout equ yout+2
|
|
aout equ xout+2
|
|
pout equ aout+2
|
|
|
|
longa on
|
|
longi on
|
|
|
|
phd ; turn stack into zp
|
|
tsc
|
|
tcd
|
|
;
|
|
; Are we in Cn00 Space?
|
|
;
|
|
|
|
lda fwep
|
|
cmp #$C000
|
|
bcc NotInC000
|
|
cmp #$C7FF
|
|
bcs NotInC000
|
|
|
|
;
|
|
; Set slots to default configuration and put old config. on stack
|
|
;
|
|
InC000
|
|
lda #$0200 ;request default configuration
|
|
jsl slot_arbiter ;
|
|
phx ;save original configuration
|
|
bra SlotDone
|
|
|
|
;
|
|
; Don't change configuration. Get current and put on stack to be symmetrical with
|
|
; above case.
|
|
;
|
|
NotInC000
|
|
lda #$8000 ;Get current configuration but don't change
|
|
jsl slot_arbiter ;anything.
|
|
phx ;save original configuration
|
|
|
|
SlotDone
|
|
lda fwep ; get fw entry point address
|
|
dec a ; adjust for dispatch to FW
|
|
pea fwdsptch-1 ; push return address
|
|
pha ; push dispatch address
|
|
ldy yin ; set up register inputs
|
|
ldx xin
|
|
lda ain
|
|
brl fwentry ; do dispatch
|
|
|
|
fwdsptch ;
|
|
php ; save returned parameters
|
|
and #$00FF ; truncate to byte
|
|
sta aout ; store output parmeters
|
|
stx xout
|
|
sty yout
|
|
lda 1,s ; get FW 6502 status
|
|
and #$00C7 ; truncate to byte
|
|
xba ; put processor status in high byte
|
|
sta pout ; and store as output parm
|
|
rep #$20 ; 16 bit 'm'
|
|
plp ; clean up stack
|
|
plx ;get old configuration
|
|
php ;
|
|
;
|
|
; Restore old slot configuration which is stored on stack
|
|
;
|
|
lda #$0300 ;restore to configuration in x reg
|
|
jsl slot_arbiter
|
|
plp
|
|
jmp EndCall8 ; pulls d and cleans up stack
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
|
|
title 'Pack and Unpack bytes'
|
|
************************************************************************
|
|
* *
|
|
* FUNCION PackBytes(VAR PicPtr : POINTER; *
|
|
* VAR PicSize: INTEGER; *
|
|
* BufPtr : POINTER; *
|
|
* BufSize: INTEGER) : INTEGER; *
|
|
* *
|
|
* Params: PicPtr - Pointer to start of picture area to be packed *
|
|
* PicSize- Total size to be packed *
|
|
* BufPtr - Start of output buffer to pack into *
|
|
* BufSize- Maximum space available for packed picture *
|
|
* *
|
|
* Returns: PackBytes return value: Number of packed bytes generated *
|
|
* PicPtr: updated to end of last byte used from picture *
|
|
* PicSize: reduced by number of bytes of picture processed *
|
|
* *
|
|
* FUNCTION UnPackBytes( BufPtr : POINTER; *
|
|
* BufSize: INTEGER; *
|
|
* VAR PicPtr : POINTER; *
|
|
* VAR PicSize: INTEGER) : INTEGER; *
|
|
* *
|
|
* Params: BufPtr - pointer to area containing packed data *
|
|
* BufSize- max size of area containing packed data *
|
|
* PicPtr - Pointer to start of area to unpack into *
|
|
* PicSize- Maximum space available for unpacked picture *
|
|
* *
|
|
* Returns: UnPackBytes return Value: Actual number of bytes unpacked *
|
|
* PicPtr: Updated to one past end of last byte unpacked *
|
|
* PicSize: reduced by number of bytes of picture generated *
|
|
* *
|
|
* ------------------------------------------------------ *
|
|
* *
|
|
* Sample Calls: *
|
|
* *
|
|
* picsize:=$7d00; *
|
|
* bufsize:=$400; *
|
|
* REPEAT *
|
|
* HowMuch:=PackBytes(PicPtr,PicSize,BufPtr,BufSize); *
|
|
* Write(f,bufptr,howmuch); *
|
|
* UNTIL picsize=0; *
|
|
* *
|
|
* *
|
|
* {***} *
|
|
* *
|
|
* *
|
|
* OpenFile; *
|
|
* Mark:=StartofFile; *
|
|
* PicSize:=$7d00; *
|
|
* BufSize:=$400; *
|
|
* REPEAT *
|
|
* SetFileMark(Mark); *
|
|
* Read(f,BufPtr,Bufsize); *
|
|
* HowMuch:=UnPackBytes(BufPtr,BufSize,PicPtr,PicSize); *
|
|
* Mark:=Mark+HowMuch; *
|
|
* UNTIL ( (PicSize=0) OR EOF(f) ); *
|
|
* *
|
|
* ----------------------------------------------------------- *
|
|
* *
|
|
* Packed data incription format: *
|
|
* *
|
|
* %00xxxxxx : (xxxxxx : 0->63) = 1 to 64 bytes follow - *
|
|
* All Different *
|
|
* *
|
|
* %01xxxxxx : (xxxxxx : 1,2,3,5,6,7) = 1,2,3,5,6,7 repeats - *
|
|
* of next byte *
|
|
* *
|
|
* %10xxxxxx : (xxxxxx : 0->63) = 1 to 64 repeats - *
|
|
* of next 4 bytes *
|
|
* *
|
|
* %11xxxxxx : (xxxxxx : 0->63) = 1 to 64 times 4 repeats - *
|
|
* of next byte *
|
|
* *
|
|
* ----------------------------------------------------------- *
|
|
* *
|
|
* Written By: Eagle I. Berns *
|
|
* *
|
|
* Modification History: *
|
|
* *
|
|
* 10-DEC-85 EIB First coding begun *
|
|
* 5-Mar-87 SEG Error code returned is now 0 *
|
|
* in both Pack and Unpack *
|
|
* *
|
|
************************************************************************
|
|
|
|
|
|
************************************************************************
|
|
* Main Packbits entry *
|
|
************************************************************************
|
|
|
|
PACKBYTES PROC
|
|
|
|
from EQU 1
|
|
to EQU from+4
|
|
endbuf EQU TO+4
|
|
prev EQU endbuf+4
|
|
count EQU prev+4
|
|
lf EQU count+2
|
|
|
|
Origdrct EQU lf+2
|
|
|
|
rtl1 EQU origdrct+2
|
|
rtl2 EQU rtl1+3
|
|
|
|
Bufsize EQU rtl2+3
|
|
BufPtr EQU Bufsize+2
|
|
PicsizeP EQU BufPtr+4
|
|
PicPtrP EQU PicSizeP+4
|
|
Result EQU PicPtrP+4
|
|
; -> +2
|
|
|
|
PHD ; SET UP STACK AS ZERO PAGE +PARMS
|
|
TSC
|
|
SEC
|
|
SBC #ORIGDRCT-1
|
|
TCS
|
|
TCD
|
|
|
|
LDA [PICPTRP] ; GET THE ARGS.
|
|
TAX ; (PICPTRP NEEDS DE-REFERANCE)
|
|
LDY #2
|
|
LDA [PICPTRP],Y
|
|
STA FROM+2
|
|
STX FROM
|
|
|
|
LDA [PICSIZEP]
|
|
STA COUNT
|
|
|
|
|
|
LDA BUFSIZE
|
|
SEC
|
|
SBC #5 ;END LESS FIVE FOR ENDING TEST
|
|
CLC
|
|
ADC BUFPTR
|
|
STA ENDBUF
|
|
LDA BUFPTR+2
|
|
STA TO+2
|
|
ADC #0
|
|
STA ENDBUF+2
|
|
LDA BUFPTR
|
|
STA TO
|
|
|
|
LDA #0
|
|
TAY
|
|
STA [TO],Y
|
|
STA LF
|
|
INC LF ; MAKE LAST<>FIRST TO BEGIN
|
|
LDA #$FFFF ; SET PREV TO INVALID
|
|
STA PREV
|
|
STA PREV+2
|
|
|
|
MAINLOOP JSR ISIT44 ; CHECK IF MULTI-4 MATCH
|
|
BCC CNT4S ; YES, OUNT THEM
|
|
JMP MORECL ; NO, MOVE ALONG FOR MORE CHECKS
|
|
|
|
*****************************************
|
|
* *
|
|
* Now, count 4's grouping on the *
|
|
* input and store the results in the *
|
|
* output and adjusts all necessary *
|
|
* pointers. NOTE: this routine will *
|
|
* assume at least one match got you *
|
|
* in here, thus one match assumed. *
|
|
* *
|
|
*****************************************
|
|
|
|
CNT4S LDX #1 ; X COUNTS HOW MANY PAIRS
|
|
CLOOP JSR ISIT44 ; DO IT DO THE 4 4 MATCH
|
|
BCS CDONE ; NO IT DON'T - GO FINISH UP
|
|
CPX #64 ; REMEMBER, $3F MAX
|
|
BEQ CDONE
|
|
LDA COUNT ; DON'T GO PAST END
|
|
BEQ CDONE
|
|
SEC
|
|
SBC #4
|
|
BLT CDONE
|
|
LDA FROM
|
|
CLC
|
|
ADC #4
|
|
STA FROM
|
|
LDA FROM+2
|
|
ADC #0
|
|
STA FROM+2
|
|
INX ; BUMP THE COUNT
|
|
LDA COUNT
|
|
SEC
|
|
SBC #4
|
|
STA COUNT
|
|
BRA CLOOP
|
|
CDONE DEX ; LESS ONE FOR CMD.
|
|
PHX ; SAVE COUNT AWHILE
|
|
JSR LOOKAT4
|
|
BEQ CMAT4 ; GOT 4'S AND THEY'RE ALL THE SAME
|
|
PLA ; GET COUNT BACK FOR THIS CASE
|
|
ORA #$80 ; SET APPROPRIATE FLAGS
|
|
LDY #0
|
|
STA [TO],Y ; STORE COMPRESSIION TYPE WORD+COUNT
|
|
LDA [FROM],Y ; GET 1ST TWO BYTES TO STORE
|
|
INY
|
|
STA [TO],Y ; STORE 1ST TWO AFTER COMMAND
|
|
INY
|
|
LDA [FROM],Y ; GET NEXT 2 INPUTS (Y IS NEATLY OK!)
|
|
STA LF
|
|
INY
|
|
STA [TO],Y ; NOW DATA IS STORED CORRECTLY
|
|
|
|
LDA TO ; 'TO' LOC BUMPS BY 5
|
|
STA PREV
|
|
CLC
|
|
ADC #5
|
|
STA TO
|
|
LDA TO+2
|
|
STA PREV+2
|
|
ADC #0
|
|
STA TO+2
|
|
BRA CJOIN ;GO FINISH UP
|
|
CMAT4 PLA ;GET THE COUNT
|
|
ORA #$C0
|
|
STA [TO] ;STORE CONTROL INFO+COUNT
|
|
LDY #3
|
|
LDA [FROM],Y ;GET THE BYTE THAT MATCHES
|
|
STA LF
|
|
LDY #1
|
|
STA [TO],Y ; STORE 2 BUT COUNT ONLY 1
|
|
LDA TO ; 'TO' LOC BUMPS BY 2
|
|
STA PREV
|
|
CLC
|
|
ADC #2
|
|
STA TO
|
|
LDA TO+2
|
|
STA PREV+2
|
|
ADC #0
|
|
STA TO+2
|
|
CJOIN LDX #4 ;'FROM' AND 'COUNT' NEED 4 BUMP STILL
|
|
JMP BMPF
|
|
|
|
MORECL JSR ISIT44 ; DO WE HAVE 4-4 MATCH FROM HERE
|
|
BCC DOSTR2 ; YES, GO HANDLE IT
|
|
INY
|
|
CPY #4 ; HAVE WE MOVED THROUGH 4
|
|
BCC MORECL
|
|
DOSTR2 PHY
|
|
LDY #0
|
|
JSR LOOKAT4 ; CHECK FOR SOME MATCHES
|
|
TXA ; NUMBER OF THEM TO A
|
|
PLX ; NO. TO DEAL WITH TO X
|
|
|
|
*****************************************
|
|
* *
|
|
* Now, add into the output stream *
|
|
* a spec for consecutive bytes of *
|
|
* from 1 to 4 (all matching) and will *
|
|
* modify previous spec if necessary *
|
|
* A reg. contains max no. of the *
|
|
* chars we may consider. *
|
|
* X reg. has 1,2,3 or 4 for the num. *
|
|
* of matched chars. *
|
|
*****************************************
|
|
|
|
LDY #0
|
|
PHA
|
|
TXA
|
|
SEC
|
|
SBC 1,S ; A NOW HAS REG. X - REG Y
|
|
BLT STU1
|
|
LDA 1,S
|
|
TAX ; NOW, X HAS MAX REALLY TO CONSIDER
|
|
STU1 PLA ; FROM EXTRA PUSH FOR ARITH.
|
|
TXA ; STORE IT FOR CHECK ON END
|
|
CMP COUNT
|
|
BLT STU2
|
|
LDX COUNT ; IF PAST END, USE LOWER COUNT
|
|
STU2 LDA LF ; CHECK IF LAST=FIRST
|
|
XBA
|
|
CMP LF
|
|
BNE DIFF ; NO, SO GO STORE DIFF. DATA
|
|
LDA PREV+2 ; IS THERE A PREV
|
|
CMP #$FFFF
|
|
BEQ DIFF ; NOPE, SO NO MATCH
|
|
LDA [PREV],Y ; GET LAST COMMAND TO SE WHAT TO DO
|
|
AND #$FF ; CHECK FOR COMMAND 'C0',BYTE
|
|
CMP #$C0
|
|
BNE DIFF ; NOPE, SO JUST DO THESE ALONE
|
|
TXA ; GOOD ONE, SO X+4 WILL STORE TO PREV
|
|
CLC
|
|
ADC #3 ; 4 - 1 FOR CMD. OFFSET
|
|
ORA #$40 ; SET FLAGS INTO CMD
|
|
PHA ; TEMP.
|
|
LDA [PREV],Y ; GET PREVIOUS
|
|
AND #$FF00 ; DATA ONLY
|
|
STA [PREV],Y
|
|
PLA
|
|
ORA [PREV],Y ; WITH NEW COUNT & DATA
|
|
STA [PREV],Y ; SAVE IT
|
|
BMPF TXA ; GET COUNT
|
|
CLC
|
|
ADC FROM
|
|
STA FROM ;BUMP FROM BY X (AMT.)
|
|
LDA FROM+2
|
|
ADC #0
|
|
STA FROM+2
|
|
PHX
|
|
LDA COUNT
|
|
SEC
|
|
SBC 1,S
|
|
PLX
|
|
STA COUNT
|
|
CMP #0
|
|
BNE MORCHK
|
|
JMP ALLDONE
|
|
MORCHK LDA TO+2 ; CHECK IF PAST END OF BUFFER
|
|
CMP ENDBUF+2
|
|
BNE NOTDON
|
|
LDA TO
|
|
CMP ENDBUF
|
|
BLT NOTDON
|
|
JMP ALLDONE
|
|
NOTDON LDY #0 ; BE SURE Y=0 WHEN WE GO BACK
|
|
JMP MAINLOOP ; ALL DONE, BACK TO MAIN LOOP
|
|
|
|
|
|
DIFF CPX #3 ;IF 1 OR 2, JUST ADD
|
|
BLT DO12
|
|
BEQ DO3 ; IF 3, GO SET UP IT'S COMMAND
|
|
LDA #$C0 ; FOR 4, SET IT'S COMMAND
|
|
BRA JDO
|
|
DO3 LDA #$42
|
|
JDO PHA ; SAVE IT
|
|
LDA [FROM],Y ; GET THE CHAR.
|
|
AND #$FF ; -JUST THE CHAR
|
|
XBA
|
|
STA [TO],Y
|
|
PLA
|
|
ORA [TO],Y ; NOW HAVE CMD & COUNT
|
|
STA [TO],Y
|
|
TXY ;FOLLOWING IS TO GET LF RIGHT
|
|
DEY
|
|
LDA [FROM],Y
|
|
STA LF
|
|
LDY #0 ;RESET Y
|
|
BMPT2 LDA TO ; TO:=TO+2;
|
|
STA PREV
|
|
CLC
|
|
ADC #2
|
|
STA TO
|
|
LDA TO+2
|
|
STA PREV+2
|
|
ADC #0
|
|
STA TO+2
|
|
BRA BMPF
|
|
DO12 LDA PREV+2 ; CHECK FOR A PREV
|
|
CMP #$FFFF
|
|
BEQ NEW1
|
|
LDA [PREV],Y ; CHECK PREV CMD.
|
|
AND #$C0 ; IF WAS ADD 1 CHAR, JUST ADD 1 OR 2 IN
|
|
CMP #00
|
|
BNE NEW1 ; NO, GO DO NEW 1 OR 2
|
|
LDA [PREV],Y ; CHECK IF>MAX- MAKE NEW 1 OR 2 IF SO
|
|
AND #$FF
|
|
CMP #$3F
|
|
BEQ NEW1
|
|
CPX #2 ; IF 2, & AT $3E JUST ADD 1
|
|
BNE OKADDIN
|
|
CMP #$3E
|
|
BNE OKADDIN
|
|
LDX #1 ; JUST 1, GET NEXT ONE NEXT TIME AROUND
|
|
OKADDIN TXA ; YES, ADD IN 1 OR 2
|
|
CLC
|
|
ADC [PREV],Y ; YES, ADD 1 OR 2 IN
|
|
STA [PREV],Y
|
|
LDA [FROM],Y
|
|
STA LF
|
|
STA [TO],Y
|
|
TXA
|
|
CLC
|
|
ADC TO
|
|
STA TO
|
|
LDA TO+2
|
|
ADC #0
|
|
STA TO+2
|
|
JMP BMPF ; GO BUMP FROM
|
|
NEW1 LDA [FROM],Y ; GET THE DATA
|
|
STA LF
|
|
AND #$FF ; JUST 1 CHAR
|
|
XBA
|
|
STA [TO],Y
|
|
LDX #1 ; DO ONLY ONE, IF 2 GET IT NEXT TIME
|
|
BRA BMPT2 ; GO ADJUST POINTERS
|
|
|
|
ALLDONE LDA TO
|
|
SEC
|
|
SBC BUFPTR
|
|
STA RESULT ; SET RESULT LENGTH
|
|
|
|
LDA FROM
|
|
SEC
|
|
SBC [PICPTRP]
|
|
PHA ; HOLD IT, NEED SIZE - IT
|
|
LDA [PICSIZEP]
|
|
SEC
|
|
SBC 1,S
|
|
STA [PICSIZEP]
|
|
PLA
|
|
|
|
LDA FROM
|
|
STA [PICPTRP]
|
|
LDA FROM+2
|
|
LDY #2
|
|
STA [PICPTRP],Y
|
|
|
|
LDA ORIGDRCT
|
|
TCD
|
|
LDA RTL1,S ;FIX STACK UP CORRECTLY
|
|
STA RESULT-6,S
|
|
LDA RTL1+2,S
|
|
STA RESULT-4,S
|
|
LDA RTL1+4,S
|
|
STA RESULT-2,S
|
|
TSC
|
|
CLC
|
|
ADC #RESULT-7
|
|
TCS
|
|
LDA #0 ; fix by SEG on 5 March 87
|
|
CLC ; fix by SEG on 5 March 87
|
|
RTL
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
************************************************************************
|
|
* Support routines called by packbits *
|
|
************************************************************************
|
|
|
|
*****************************************
|
|
* *
|
|
* Lookat4: looks at 4 bytes at [FROM],Y *
|
|
* and returns in X : *
|
|
* *
|
|
* X=4 => XXXX (i.e 4 same bytes) *
|
|
* X=3 => XXX- *
|
|
* X=2 => XX-- *
|
|
* x=1 => x--- *
|
|
* *
|
|
* RETURN ALSO: CONDITION = IF X=4 *
|
|
* CONDITION <> IF NOT *
|
|
* *
|
|
*****************************************
|
|
|
|
Lookat4 PROC
|
|
|
|
from EQU 1
|
|
to EQU from+4
|
|
endbuf EQU to+4
|
|
prev EQU endbuf+4
|
|
count EQU prev+4
|
|
lf EQU count+2
|
|
|
|
LDX #1 ; INIT X TO DEFAULT NO MATCHES
|
|
LDA [FROM],Y ; GET TWO BYTES TO COMPARE
|
|
XBA ; SWITCH FOR COMPARE
|
|
CMP [FROM],Y
|
|
BNE LDONE ; NOT =, RETURN (X=1)
|
|
INX
|
|
INY ; CHECK FOR 2ND AND 3RD MATCHING
|
|
CMP [FROM],Y
|
|
BNE LDONE ; NOT =, RETURN (X=2)
|
|
INX
|
|
INY
|
|
CMP [FROM],Y
|
|
BNE LDONE ; NOT =, RETURN (X=3)
|
|
INX ; ELSE, X=4 ALL 4 MATCH
|
|
CPX #4 ; (JUST TO SET COND. TO =)
|
|
LDONE RTS
|
|
ENDP
|
|
|
|
*****************************************
|
|
* *
|
|
* ISIT44 - Checks for two consecutive *
|
|
* sets of 4 matching bytes. *
|
|
* Returns Carry Set for no match and *
|
|
* Carry Clear for match. *
|
|
* NOTE: X register is not changed. *
|
|
* *
|
|
*****************************************
|
|
|
|
ISIT44 PROC
|
|
|
|
from EQU 1
|
|
to EQU from+4
|
|
endbuf EQU to+4
|
|
prev EQU endbuf+4
|
|
count EQU prev+4
|
|
lf EQU count+2
|
|
|
|
PHY ;MUST PRESERVE
|
|
LDA [FROM],Y ;1ST 2 BYTES OF FIRST 4
|
|
INY ;BUMP BY 4
|
|
INY
|
|
INY ;NOTE: CHECK IF PAST END ONLY IF WE
|
|
INY ; GET THE MATCH, ELSE, WHO CARES
|
|
CMP [FROM],Y ; 1ST 2 BYES OF NEXT 4
|
|
BNE NOT44
|
|
DEY
|
|
DEY ;BACK UP TO 2ND 2 OF 1ST 4
|
|
LDA [FROM],Y
|
|
INY
|
|
INY
|
|
INY
|
|
INY
|
|
CMP [FROM],Y ;COMPARE TO 2ND 2 OF 2ND 4
|
|
BNE NOT44 ;NOPE, GET OUT
|
|
*
|
|
* HERE, WE GOT THE MATCH, BUT BE SURE 8 BYTES REMAIN SO WE CAN DO IT
|
|
*
|
|
LDA COUNT
|
|
SEC
|
|
SBC #8
|
|
BMI NOT44 ; LESS THAN 8 , WE CANT COUNT IT
|
|
PLY ; RESTORE Y
|
|
CLC ; ALLS WELL, RETURN CLEAR CARRY
|
|
RTS
|
|
NOT44 PLY
|
|
SEC ; NO MATCH
|
|
RTS
|
|
ENDP
|
|
|
|
|
|
|
|
************************************************************************
|
|
* Main UnPackbits entry *
|
|
************************************************************************
|
|
|
|
UNPACKBYTES PROC
|
|
|
|
from EQU 1
|
|
to EQU from+4
|
|
endbuf EQU to+4
|
|
temp EQU endbuf+4
|
|
count EQU temp+4
|
|
lf EQU count+2
|
|
|
|
Origdrct EQU lf+2
|
|
|
|
rtl1 EQU origdrct+2
|
|
rtl2 EQU rtl1+3
|
|
|
|
PicSizeP EQU rtl2+3
|
|
PicPtrP EQU PicSizeP+4
|
|
Bufsize EQU PicPtrP+4
|
|
BufPtr EQU BufSize+2
|
|
Result EQU BufPtr+4
|
|
; -> +2
|
|
|
|
PHD ; SET UP STACK AS ZERO PAGE +PARMS
|
|
TSC
|
|
SEC
|
|
SBC #ORIGDRCT-1
|
|
TCS
|
|
TCD
|
|
|
|
LDA [PICPTRP] ; GET THE ARGS.
|
|
TAX ; (PICPTRP NEEDS DE-REFERANCE)
|
|
LDY #2
|
|
LDA [PICPTRP],Y
|
|
STA TO+2
|
|
STX TO
|
|
|
|
LDA [PICSIZEP]
|
|
STA COUNT
|
|
|
|
LDA BUFPTR
|
|
STA FROM
|
|
CLC
|
|
ADC BUFSIZE
|
|
STA ENDBUF
|
|
LDA BUFPTR+2
|
|
STA FROM+2
|
|
ADC #0
|
|
STA ENDBUF+2
|
|
|
|
DOUNPACK LDY #0
|
|
|
|
LDA [FROM],Y ; GET THE COMMAND
|
|
STA TEMP
|
|
AND #$3F
|
|
TAX ; GET COUNT ONLY INTO X
|
|
INC FROM ; BUMP TO FIRST BYTE TO TRANSFER
|
|
BNE M1
|
|
INC FROM+2
|
|
M1 BIT TEMP-1 ; V & C BITS GIVE COMMAND
|
|
BMI REP4
|
|
BVS REP1 ; 01xxxxxx -> REPEAT NEXT 1 BYTE
|
|
BRA DIFF ; 00xxxxxx -> ALL DIFFERENT
|
|
REP4 BVS REP41 ; 11xxxxxx -> REPEAT 4 OF NEXT 1 BYTE
|
|
BRA REP44 ; 10xxxxxx -> REPEAT OF NEXT 4 BYTES
|
|
|
|
OUTP PLA
|
|
JMP UDONE ; GO FINISH UP
|
|
|
|
*****************************************
|
|
* *
|
|
* DIFF : 0 ->63 IN A MEANS 1->64 *
|
|
* DIFFERENT BYTES FOLLOW TO BE MOVED *
|
|
* *
|
|
*****************************************
|
|
DIFF PHA ; WHEN WE GO TO COMMON CODE, WE NEED
|
|
; SOMETHING STACKED (OTHER CALLS USE IT)
|
|
BRA JOIN
|
|
|
|
*****************************************
|
|
* *
|
|
* REP1 : 1,2,3,5,6,7 REPEATS OF FOLLOW- *
|
|
* ING BYTE. *
|
|
* *
|
|
*****************************************
|
|
|
|
|
|
REP1 LDA TEMP ; PUT BYTE IF LOW & HIGH & ON STACK
|
|
AND #$FF00
|
|
PHA
|
|
XBA
|
|
ORA 1,S
|
|
STA 1,S
|
|
BRA JOIN ; JOIN UP, X=LEN IS CORRECT STILL
|
|
|
|
*****************************************
|
|
* *
|
|
* REP41 : IS SAME AS REP1 ABOVE, EXCEPT *
|
|
* COUNT IN X MUST BE 4 TIMES > *
|
|
* *
|
|
*****************************************
|
|
REP41 INX
|
|
TXA
|
|
ASL A
|
|
ASL A
|
|
TAX
|
|
DEX
|
|
BRA REP1
|
|
|
|
*****************************************
|
|
* *
|
|
* REP44 : MUST SET UP FOR 2 STORES I.E. *
|
|
* 4 BYTES WORTH, AND COUNT IS *
|
|
* DOUBLED (2 STORES EACH TIME) *
|
|
* *
|
|
*****************************************
|
|
REP44 INX
|
|
TXA
|
|
ASL A
|
|
TAX ; FIRST DOUBLE X
|
|
DEX
|
|
PHA ; MUST PUT SOMETHING ON STACK FOR
|
|
; OTHER CASES
|
|
|
|
* BRA JOIN ; WE FIND 4 BYTES AT [FROM],
|
|
* (FALL THROUGH TO JOIN) ; SO MUST REMEMBER TO FIND IT THERE
|
|
|
|
*****************************************
|
|
* *
|
|
* JOIN : HERE, THE LOAD STORE SEQUENCE *
|
|
* OF DATA TRANSFER TAKES PLACE *
|
|
* *
|
|
*****************************************
|
|
JOIN CPX COUNT ; BE SURE THERE'S ROOM
|
|
BGE OUTP ; NO - DONE (BUT PULL OFF EXTRA PUSH)
|
|
|
|
LDA #1 ; CHECK IF LENGTH WOULD GO OVER
|
|
BIT TEMP-1 ; DEPENDS ON TYPE OF CMD.
|
|
BVS L1 ; LEN=1 FOR %01 & %11
|
|
BMI L4 ; LEN=4 FOR %10
|
|
TXA
|
|
INC A ; LEN=N+1 FOR %00..N...
|
|
BRA L1
|
|
L4 LDA #4
|
|
L1 CLC ; FROM+LEN .LT. ENDBUF MEANS NOT DONE
|
|
ADC FROM
|
|
PHA ; SAVE FOR COMPARE
|
|
LDA FROM+2
|
|
ADC #0
|
|
CMP ENDBUF+2
|
|
BCC NOTDONP
|
|
PLA
|
|
CMP ENDBUF
|
|
BLT NOTDON
|
|
BEQ NOTDON
|
|
BRA OUTP
|
|
NOTDONP PLA
|
|
|
|
NOTDON CPX #0 ; (NEEDED FOR 1ST ENTRY IN LOOP)
|
|
LOOP BMI DOUPD ; YES
|
|
|
|
|
|
*****************************************
|
|
* *
|
|
* MOVEIT : USED LOCALLY TO FETCH PROPER *
|
|
* INPUT, DEPENDING ON TYPE OF *
|
|
* CMD. BEING PROCESSED *
|
|
* NOTE: X<0 MEANS STORE 1 BYTE ONLY *
|
|
*****************************************
|
|
BIT TEMP-1 ; THIS HAS THE FLAGS
|
|
BMI MREP4
|
|
BVS MREP1
|
|
CPX #0 ; IF NEG. IT'S ONE BYTE ONLY
|
|
BEQ MSPEC
|
|
LDA [FROM],Y
|
|
STA [TO],Y
|
|
INY
|
|
INY
|
|
JMP NDMOV
|
|
MSPEC SEP #%00100000
|
|
LDA [FROM],Y
|
|
STA [TO],Y
|
|
REP #%00100000
|
|
INY
|
|
JMP NDMOV
|
|
MREP1 CPX #0
|
|
BEQ M2SPEC
|
|
LDA 1,S
|
|
STA [TO],Y
|
|
INY
|
|
INY
|
|
JMP NDMOV
|
|
M2SPEC SEP #%00100000
|
|
LDA 1,S
|
|
STA [TO],Y
|
|
REP #%00100000
|
|
INY
|
|
JMP NDMOV
|
|
MREP4 BVS MREP1 ;REP41 SAME AS REP1 BUT LARGER COUNT
|
|
LDA [FROM]
|
|
STA [TO],Y
|
|
PHY ; HOLD Y A SEC
|
|
LDY #2
|
|
LDA [FROM],Y
|
|
PLY
|
|
INY
|
|
INY
|
|
STA [TO],Y
|
|
INY
|
|
INY
|
|
******
|
|
NDMOV DEX
|
|
DEX
|
|
BRA LOOP ; GO DO NEXT ONES
|
|
DOUPD PLA ; GET RID OF EXTRA PUSH
|
|
LDA TEMP ; UPDATE APPROPRIATE POINTERS
|
|
AND #$3F
|
|
INC A
|
|
BIT TEMP-1
|
|
BMI XREP4 ; FROM DEPENDS ON TYPE
|
|
BVC XDIFF ; FOR 00xxxxxx ADD LENGTH
|
|
FP1 LDA #1 ; FOR 01xxxxxx ADD 1
|
|
XDIFF CLC
|
|
ADC FROM
|
|
STA FROM
|
|
LDA FROM+2
|
|
ADC #0
|
|
STA FROM+2
|
|
BRA DOTO
|
|
XREP4 BVS FP1 ; FOR 11xxxxxx ALSO ADD 1
|
|
LDA #4 ; FOR 10xxxxxx ADD 4
|
|
BRA XDIFF
|
|
|
|
DOTO TYA ; Y IS OUTPUT COUNT
|
|
CLC
|
|
ADC TO
|
|
STA TO
|
|
LDA TO+2
|
|
ADC #0
|
|
STA TO+2
|
|
TYA
|
|
STA TEMP
|
|
LDA COUNT
|
|
SEC
|
|
SBC TEMP
|
|
STA COUNT
|
|
JMP DOUNPACK
|
|
|
|
UDONE LDA FROM
|
|
SEC
|
|
SBC BUFPTR
|
|
DEC A
|
|
STA RESULT ; SET RESULT LENGTH
|
|
|
|
LDA TO
|
|
SEC
|
|
SBC [PICPTRP]
|
|
PHA ; HOLD IT, NEED SIZE - IT
|
|
LDA [PICSIZEP]
|
|
SEC
|
|
SBC 1,S
|
|
STA [PICSIZEP]
|
|
PLA
|
|
|
|
LDA TO
|
|
STA [PICPTRP]
|
|
LDA TO+2
|
|
LDY #2
|
|
STA [PICPTRP],Y
|
|
|
|
LDA ORIGDRCT
|
|
TCD
|
|
LDA RTL1,S ;FIX STACK UP CORRECTLY
|
|
STA RESULT-6,S
|
|
LDA RTL1+2,S
|
|
STA RESULT-4,S
|
|
LDA RTL1+4,S
|
|
STA RESULT-2,S
|
|
TSC
|
|
CLC
|
|
ADC #RESULT-7
|
|
TCS
|
|
LDA #0 ; fix by SEG 5 March 87
|
|
CLC ; fix by SEG 5 March 87
|
|
RTL
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
title 'Munger'
|
|
************************************************************************
|
|
* *
|
|
* FUNCION Munger (VAR DestPtr : POINTER; *
|
|
* VAR DestLen : INTEGER; *
|
|
* TargPtr : POINTER; *
|
|
* TargLen : INTEGER; *
|
|
* ReplPtr : POINTER; *
|
|
* ReplLen : INTEGER; *
|
|
* VAR Pad : INTEGER) : INTEGER; *
|
|
* *
|
|
* Params: DestPtr - Pointer to text to be manipulated *
|
|
* DestLen - Number of bytes to be included in manipulation *
|
|
* TargPtr - String to be searched for in above text *
|
|
* TargLen - its length *
|
|
* ReplPtr - string to replace with when target string found *
|
|
* ReplLen - its length *
|
|
* Pad - <on entry> : character to pad with stored as int.*
|
|
* Pad - <returned value> : pad amount *
|
|
* *
|
|
* Returns: Munger returns a negative value if target not found *
|
|
* *
|
|
* Pad returns the net effect of the replacement. If data is *
|
|
* truncated, a negative value, and if blanks are padded in *
|
|
* at the end, a positive value count *
|
|
* *
|
|
* DestPtr is updated to one past the replacement *
|
|
* DestLen is reduced by amount of data passed over *
|
|
* *
|
|
* *
|
|
* Special considerations: *
|
|
* *
|
|
* - If TargPtr is 0, the substring of length TargLen is *
|
|
* replaced by ReplPtr's string *
|
|
* *
|
|
* - If TargLen is 0, ReplPtr's string is inserted at DestPtr *
|
|
* *
|
|
* - If ReplPtr is 0, DestPtr is updated to past the end of the *
|
|
* TargPtr's string *
|
|
* *
|
|
* - If ReplLen is 0, (and ReplPtr is NOT 0) TargPtr's string is *
|
|
* deleted rather than replaced (since the replacement string *
|
|
* is empty) *
|
|
* *
|
|
* There is one case in which munger performs a replacement even *
|
|
* if it doesn't find all of the target string. If DestPtr's *
|
|
* entire string is at the begining of TargPtr's string, then *
|
|
* the entire DestPtr string is replaced with ReplPtr's string *
|
|
* *
|
|
* ------------------------------------------------------ *
|
|
* *
|
|
* Sample Calls: *
|
|
* *
|
|
* {***} *
|
|
* *
|
|
* *
|
|
* ----------------------------------------------------------- *
|
|
* *
|
|
* *
|
|
* Written By: Eagle I. Berns *
|
|
* *
|
|
* Modification History: *
|
|
* *
|
|
* 01-JAN-86 EIB First coding begun *
|
|
* 01-AUG-86 EIB fixed targptr=0 bug *
|
|
* 02-AUG-86 EIB fixed delete (repllen=0) *
|
|
* 05-Mar-87 EIB fixed one byte compare problem for targe string of *
|
|
* length one. *
|
|
* SEG Routine now clears carry and puts zero in A-reg *
|
|
* on exit *
|
|
* *
|
|
************************************************************************
|
|
|
|
|
|
************************************************************************
|
|
* Main munger entry *
|
|
************************************************************************
|
|
MUNGER PROC
|
|
|
|
search EQU 1
|
|
find EQU search+4
|
|
destptr EQU find+4
|
|
destlen EQU destptr+4
|
|
temp EQU destlen+2
|
|
padchar EQU temp+4
|
|
Origdrct EQU padchar+2
|
|
|
|
rtl1 EQU origdrct+2
|
|
rtl2 EQU rtl1+3
|
|
|
|
padP EQU rtl2+3
|
|
repllen EQU padP+4
|
|
replptr EQU repllen+2
|
|
targlen EQU replptr+4
|
|
targptr EQU targlen+2
|
|
destlenP EQU targptr+4
|
|
destptrP EQU destlenP+4
|
|
result EQU destptrP+4
|
|
; -> +2
|
|
|
|
PHD ; SET UP STACK AS ZERO PAGE +PARMS
|
|
TSC
|
|
SEC
|
|
SBC #ORIGDRCT-1
|
|
TCS
|
|
TCD
|
|
|
|
LDA [DESTPTRP] ; GET THE ARGS.
|
|
STA DESTPTR
|
|
STA SEARCH
|
|
LDY #2
|
|
LDA [DESTPTRP],Y
|
|
STA DESTPTR+2
|
|
STA SEARCH+2
|
|
|
|
LDA [DESTLENP]
|
|
STA DESTLEN
|
|
CMP REPLLEN ; IF REPLLEN >, SHORTEN IT
|
|
BGE MLBZ
|
|
STA REPLLEN
|
|
MLBZ CMP TARGLEN ; TARGLEN ALSO
|
|
BGE MLB0
|
|
STA TARGLEN
|
|
|
|
MLB0 LDA [PADP]
|
|
STA PADCHAR
|
|
|
|
LDA TARGPTR ; SAVE LOCAL TARGET PTR.,CHECK FOR ZERO
|
|
STA FIND
|
|
TAX
|
|
LDA TARGPTR+2
|
|
STA FIND+2 ; IF ZERO - SPECIAL CASE - INSERT
|
|
BNE MLB1
|
|
CPX #0
|
|
BNE MLB1
|
|
|
|
*===> bug fix: next line deleted EIB 1-AUG-86
|
|
* STA DESTLEN ; SET TO 0 , DO REPLACE - (INSERT)
|
|
|
|
BRA MUNGREP ; (ARGS ARE 'SEARCH' AND 'DESTLEN')
|
|
MLB1 LDA DESTLEN ; DESTLEN<=TARGLEN SPECIAL - CHECK @ CHAR 1
|
|
SEC
|
|
SBC TARGLEN
|
|
BEQ MLB2
|
|
BLT MLB2
|
|
JMP MUNGGNRL
|
|
MLB2 LDA DESTLEN ; CALL COMPARE (DESTLEN,SEARCH,FIND)
|
|
STA TARGLEN ; FORCE SAME LEN. FOR PTR. ADJ. LATER
|
|
JSR MUNGCMPR
|
|
BEQ MUNGREP ; MATCH, GO REPL. FULL DEST. STRING
|
|
MUNGOUT LDA #0 ; DONE, RETURN 0 PAD
|
|
STA [PADP]
|
|
STA RESULT
|
|
DEC RESULT ; NEGATIVE RESULT
|
|
JMP MUNGXIT
|
|
|
|
MUNGGNRL TAX ; X HOLDS HOW FAR DOWN 'SEARCH' WE GO
|
|
MLB4 LDA TARGLEN ; CALL COMPARE (TARGLEN,SEARCH,FIND)
|
|
JSR MUNGCMPR
|
|
BEQ MUNGREP ; GOT IT, GO DO REPLACE
|
|
INC SEARCH ; NO, MOVE ALONG SEARCH
|
|
BNE MLB5
|
|
INC SEARCH+2
|
|
MLB5 DEX
|
|
BPL MLB4 ; BACK IF WE CAN SEARC MORE
|
|
BRA MUNGOUT ; NO MATCH, GO QUIT
|
|
|
|
*****
|
|
*
|
|
* HERE, MOVE destlen CHARS FROM replptr TO search
|
|
* AFTER VERIFYING replptr & repllen & SPECIAL CASES
|
|
*
|
|
****
|
|
|
|
MUNGREP LDA REPLPTR ; SIMPLE CASE - UPDATE destptr
|
|
BNE MLB6 ; IF replptr 0
|
|
LDA REPLPTR+2
|
|
BNE MLB6
|
|
|
|
*===> bug fix: next 2 lines not needed any longer EIB 1-AUG-86
|
|
* LDA [DESTLENP] ; IN CASE WE CHANGED IT BEFORE
|
|
* STA DESTLEN
|
|
|
|
LDA TARGLEN ; IF TARGLEN ALSO 0, MAKE DESTLEN 0
|
|
BNE MUNGRP2
|
|
STA DESTLEN
|
|
MUNGRP2 JSR MUNGPMOV ; UPDATE destptr & destlen
|
|
|
|
LDA #0 ; ALL DONE - RETURN 0
|
|
STA RESULT
|
|
STA [PADP] ; PAD ALSO 0 - NO CHANGE
|
|
JMP MGD2OUT
|
|
MLB6 JSR MUNGPMOV ; HAVE REPLPTR - SO ADJUST PTRS FIRST
|
|
|
|
***
|
|
*
|
|
* MOVE FROM DESTPTR TO SEARCH+REPLLEN FOR LENGTH DESTLEN
|
|
* AND ADJUST PAD BY TARGLEN-REPLLEN
|
|
*
|
|
***
|
|
|
|
LDY #2
|
|
LDA [DESTPTRP] ; COMPUTE TRUE END OF INPUT
|
|
CLC
|
|
ADC [DESTLENP]
|
|
STA FIND ; (USE 'FIND' TO HOLD IT IN)
|
|
LDA [DESTPTRP],Y
|
|
ADC #0
|
|
STA FIND+2
|
|
|
|
|
|
LDA DESTLEN ; CHECK IF PAST END AND ADJUST
|
|
PHA ; SAVE FOR LATER
|
|
|
|
LDA TARGLEN
|
|
SEC
|
|
SBC REPLLEN
|
|
STA [PADP] ; THATS PAD AMOUNT, WILL NEED LATER
|
|
|
|
LDA SEARCH
|
|
CLC
|
|
ADC REPLLEN
|
|
STA TEMP
|
|
LDA SEARCH+2
|
|
ADC #0
|
|
STA TEMP+2 ; TEMP:=SEARCH+REPLLEN
|
|
CMP FIND+2 ; CHECK IF TEMP>FIND (I.E. END OF INPUT)
|
|
BGE CHKMOR
|
|
DSTGRTR LDA [PADP]
|
|
BPL MGD1 ; POS. SO CAN DO FULL MOVE
|
|
CLC
|
|
ADC DESTLEN ; ADD NEG. (SUBT.) FOR CORRECT LEN
|
|
DSTGT2 STA DESTLEN
|
|
STA 1,S
|
|
BRA MGD1
|
|
|
|
CHKMOR BNE DSTSMLR
|
|
LDA FIND
|
|
CMP TEMP
|
|
BGE DSTGRTR
|
|
DSTSMLR LDA FIND ; TOO BIG, ADJ. REPLLEN & REPLACE ONLY
|
|
SEC
|
|
SBC SEARCH
|
|
STA REPLLEN
|
|
PLA ; DON'T FORGET TO GET RID OF THIS
|
|
JMP MGDOUT
|
|
|
|
|
|
************************************************************************
|
|
* *
|
|
* MEMORY MANAGER BLOCKMOVE PROCEEDURE WITH SRC = <DESTPTR> , *
|
|
* DEST = <TEMP> , AND LENGTH ON THE STACK (DO THE PULL) *
|
|
* *
|
|
************************************************************************
|
|
|
|
MGD1 PLX
|
|
PUSHLONG DESTPTR
|
|
PUSHLONG TEMP
|
|
PEA 0
|
|
PHX
|
|
_BLOCKMOVE
|
|
|
|
|
|
MGDS LDA TARGLEN ; TARGLEN>REPLLEN - MUST PAD
|
|
SEC
|
|
SBC REPLLEN ; TARGLEN BLANKS FROM DESTPTR+DESTLEN
|
|
BEQ MGDOUT
|
|
BLT MGDOUT
|
|
PHA ; SAVE FOR COMPUTATION
|
|
LDA DESTPTR
|
|
CLC
|
|
ADC DESTLEN
|
|
STA TEMP
|
|
TAX ; SRC - FOR RIPPLE MOVE
|
|
LDA DESTPTR+2
|
|
ADC #0
|
|
STA TEMP+2
|
|
TXA
|
|
SEC ; TEMP:=TEMP-<DIFF. IN COUNT>
|
|
SBC 1,S
|
|
STA TEMP
|
|
LDA TEMP+2
|
|
SBC #0
|
|
STA TEMP+2
|
|
LDA [TEMP]
|
|
AND #$FF00 ; STORE 1 BLANK BYTE
|
|
ORA PADCHAR ; OR IN PAD CHARACTER
|
|
STA [TEMP]
|
|
LDA PADCHAR ; GET TWO BYE PAD
|
|
XBA
|
|
ORA PADCHAR
|
|
TAX ; HOLD IN X AWHILE
|
|
LDA 1,S ; WAS COUNT ODD OR EVEN
|
|
AND #$01
|
|
BEQ MGD2 ; EVEN, GO DO IT
|
|
PLA
|
|
DEC A ; MAKE EVEN IF WASN'T
|
|
BEQ MGDOUT ; BUT DONE IF WAS 1
|
|
PHA
|
|
INC TEMP ; BUMP ADDRESS 1 ALSO
|
|
BNE MGD2
|
|
INC TEMP+1
|
|
MGD2 PLY ; Y NOW HAS COUNT OF STORES
|
|
TXA ; A NOW HAS PAD TO FILL WITH
|
|
MGD3 DEY ; DO THE TIGHT STORE LOOP
|
|
DEY
|
|
STA [TEMP],Y
|
|
BNE MGD3
|
|
|
|
|
|
****
|
|
*
|
|
* NOW MOVE REPLLEN CHARS. FROM REPLPTR TO SEARCH
|
|
*
|
|
***
|
|
|
|
* ===> bug fix: PUSHLONGS must be AFTER test below - EIB 2-AUG-86
|
|
MGDOUT LDA REPLLEN ;LEN
|
|
BEQ MGD2OUT
|
|
PUSHLONG REPLPTR ;SRC
|
|
PUSHLONG SEARCH ;DEST
|
|
PEA 0
|
|
LDA REPLLEN
|
|
PHA
|
|
_BLOCKMOVE
|
|
|
|
MGD2OUT LDY #2
|
|
LDA SEARCH
|
|
CLC
|
|
ADC REPLLEN
|
|
STA [DESTPTRP]
|
|
LDA SEARCH+2
|
|
ADC #0
|
|
STA [DESTPTRP],Y
|
|
|
|
LDA DESTLEN
|
|
STA [DESTLENP]
|
|
|
|
MUNGXIT LDA ORIGDRCT
|
|
TCD
|
|
LDA RTL1,S ;FIX STACK UP CORRECTLY
|
|
STA RESULT-6,S
|
|
LDA RTL1+2,S
|
|
STA RESULT-4,S
|
|
LDA RTL1+4,S
|
|
STA RESULT-2,S
|
|
TSC
|
|
CLC
|
|
ADC #RESULT-7
|
|
TCS
|
|
lda #0 ; fixed 5 March 87 SEG
|
|
clc ; fixed 5 March 87 SEG
|
|
RTL
|
|
|
|
*****************************************
|
|
* *
|
|
* MUNGPMOV - UPDATE DESTPTR & DESTLEN *
|
|
* BY TARGLEN AMOUNT *
|
|
* *
|
|
*****************************************
|
|
|
|
MUNGPMOV LDA SEARCH ; TEMP:=SEARCH+TARGLEN (WHERE TO WIND UP)
|
|
CLC
|
|
ADC TARGLEN
|
|
STA TEMP
|
|
LDA SEARCH+2
|
|
ADC #0
|
|
STA TEMP+2
|
|
LDA TEMP ; FIND := TEMP-DESTPTR (DIST. MOVED)
|
|
SEC
|
|
SBC DESTPTR
|
|
STA FIND
|
|
LDA DESTLEN ; DESTLEN:=DESTLEN-FIND (LEFT TO SCAN)
|
|
SEC
|
|
SBC FIND
|
|
STA DESTLEN
|
|
LDA TEMP ; DESTPTR:=TEMP (WHERE TO GO NEXT)
|
|
STA DESTPTR
|
|
LDA TEMP+2
|
|
STA DESTPTR+2
|
|
RTS
|
|
|
|
*****************************************
|
|
* *
|
|
* MUNGCMPR - COMPARE REG. A BYTES *
|
|
* @ SEARCH *
|
|
* & FIND *
|
|
* *
|
|
*****************************************
|
|
|
|
MUNGCMPR LDY #0 ; (USUALLY)
|
|
PHX ;MUST PRESERVE X REG.
|
|
CMP #0 ; 0 LENGTH ALWAYS =
|
|
BNE MGC1
|
|
LDA #0 ; SET FOR RETURN = CONDITION
|
|
BRA MGCOND
|
|
MGC1 PHA
|
|
AND #01 ; ODD OR EVEN COMPARE LENGTH
|
|
BEQ MGCLP ; IF EVEN, JUST DO COMPARES
|
|
LDA [SEARCH]
|
|
AND #$FF ; ODD, DO FIRST BYTE - THEN EVEN AMT.
|
|
PHA
|
|
LDA [FIND]
|
|
AND #$FF
|
|
CMP 1,S
|
|
BEQ MGONE
|
|
PLA
|
|
PLA ; GET RID OF PUSH
|
|
MGCNO LDA #1
|
|
MGCOND PLX ; RESTORE X
|
|
CMP #0 ; SET COND. CODE
|
|
MGCOUT RTS
|
|
|
|
MGONE PLA ; EXTRA
|
|
PLA ; GET LENGTH
|
|
DEC A ; LESS 1 TO MAKE EVEN
|
|
BEQ MGCEQU ; patch on 5 March 87 by EIB
|
|
PHA ; BACK ON
|
|
LDY #1 ; MOVE FORWARD 1
|
|
MGCLP PLX ; GUARENTEED EVEN
|
|
MGCLP1 LDA [SEARCH],Y
|
|
CMP [FIND],Y
|
|
BNE MGCNO
|
|
INY
|
|
INY
|
|
DEX
|
|
DEX
|
|
BNE MGCLP1
|
|
MGCEQU LDA #0 ; SET EQUAL RETURN
|
|
BRA MGCOND ; GO QUIT
|
|
ENDP
|
|
|
|
|
|
|
|
|
|
title 'IRQ Stuff'
|
|
****************************************************************
|
|
*
|
|
* This tool returns the state of hardware interrupt enables
|
|
* under the control of the miscellaneous tool set.
|
|
*
|
|
* D8-15 Undefined
|
|
* D7 1 = Keyboard interrupts enabled
|
|
* D6 1 = Vertical blanking interrupts enabled
|
|
* D5 1 = Quarter second interrupts enabled
|
|
* D4 1 = One second interrupts enabled
|
|
* D3 RESERVED
|
|
* D2 1 = Front desk bus data interrupts enabled
|
|
* D1 1 = Scan line interrupts enabled
|
|
* D0 1 = External VGC interrupts enabled
|
|
*
|
|
****************************************************************
|
|
GetIRQenbl PROC
|
|
longa on
|
|
longi on
|
|
|
|
OrigDir equ 1
|
|
rtl1 equ OrigDir+2
|
|
rtl2 equ rtl1+3
|
|
irqstate equ rtl2+3
|
|
|
|
phd ; turn stack into zp
|
|
tsc
|
|
tcd
|
|
stz irqstate ; assume no sources enbl
|
|
sep #$20 ; 8 bit 'm'
|
|
longa off
|
|
lda >KBDIRQFLAG ; if KBD interrupts, set flag
|
|
tsb irqstate
|
|
nokbden ;
|
|
lda >inten ; get mega irq reg
|
|
pha
|
|
and #%00001000 ; vbl on?
|
|
beq novblen ; set flag bit if on
|
|
lda #%01000000
|
|
tsb irqstate
|
|
novblen ;
|
|
pla ; get mega irq reg
|
|
and #%00010000 ; 1/4 sec on?
|
|
asl a ; set flag bit if enabled
|
|
tsb irqstate
|
|
lda >vgcint ; get VGC irq reg
|
|
pha
|
|
and #%00000100 ; 1 sec on?
|
|
asl a
|
|
asl a ; set flag bit if enabled
|
|
tsb irqstate
|
|
lda >kmstatus ; get KBDu status
|
|
and #%00010000 ; fdb data irq on?
|
|
lsr a ; set flag bit if enabled
|
|
lsr a
|
|
tsb irqstate
|
|
pla ; get VGC irq reg
|
|
and #%00000011 ; scan lines or ext on?
|
|
tsb irqstate ; set flag bit if on
|
|
rep #$30 ; 16 bit 'm' & 'x'
|
|
longa on
|
|
longi on
|
|
jmp EndCall0
|
|
|
|
ENDP
|
|
|
|
|
|
|
|
title 'SysBeep'
|
|
SysBeep PROC
|
|
****************************************************************
|
|
*
|
|
* There are no input parameters to this tool call.
|
|
* No output parameters will be returned on this tool call.
|
|
* This call will dispatch to the Apple// entry point 'BELL1'.
|
|
* The bell routine may be patched out by using the setvector
|
|
* call with a parameter reference number of $001B. Any routine
|
|
* installed into the bellvector will be called in native mode
|
|
* with 8 bit 'm' and 'x'.
|
|
*
|
|
****************************************************************
|
|
ldx #8 ; 8 words to push
|
|
lda #$FBDD ; BELL1 entry in rom
|
|
here ;
|
|
pha
|
|
dex
|
|
bne here
|
|
_FWEntry
|
|
pla ; clean off stack
|
|
pla
|
|
pla
|
|
pla
|
|
jmp oEndcall0 ; return to application
|
|
|
|
ENDP
|
|
|
|
END
|