Disk 2 COMMON library 0.3.0 updates

- added some error control
- added initial jump table
- fixed a few minor bugs
- separated common library into separate subroutine files
This commit is contained in:
nathanriggs 2019-01-14 10:57:05 -05:00
parent f5c097e70f
commit 12a0b19398
30 changed files with 4464 additions and 5167 deletions

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,7 @@
*
CYC AVE
EXP ONLY
TR ON
DSK COMMON.DEMO
OBJ $BFE0
ORG $6000
@ -26,6 +27,7 @@
* TOP INCLUDES (HOOKS,MACROS) *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
PUT REQUIRED.VARS
USE REQUIRED.MAC.MIN
PUT REQUIRED.HOOKS.MIN
USE COMMON.MAC.MIN
@ -39,6 +41,7 @@
** IMPLIES: IT FILLS A BLOCK OF MEMORY
** WITH A PARTICULAR CHARACTER.
*
_PRNT " ",8D8D
MFILL #$300;#10;#0
_PRNT "MFILL FILLS A PORTION OF MEMORY WITH",8D
_PRNT "A SPECIFIED VALUE. ",8D8D
@ -143,15 +146,6 @@
_DUMP $300;#10
_DUMP $320;#10
_WAIT
*
** THE FOLLOWING ILLUSTRATES THE _RDUMP MACRO IN
** THE REQUIRED LIBRARY.
*
LDA #$11
LDX #$12
LDY #$13
CLC
_RDUMP
*
JMP REENTRY
*
@ -161,6 +155,15 @@
*
** BOTTOM INCLUDES
*
PUT COMMON.LIB.MIN
PUT REQUIRED.LIB.MIN
*
** INDIVIDUAL SUBROUTINE INCLUDES
*
* COMMON LIBRARY SUBROUTINES
*
PUT MEMFILL.SUB.MIN
PUT MEMMOVE.SUB.MIN
PUT DELAYMS.SUB.MIN
PUT ZMSAVE.SUB.MIN
PUT ZMLOAD.SUB.MIN
PUT MEMSWAP.SUB.MIN

View File

@ -1,827 +0,0 @@
*
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
* *
* COMMON.LIB *
* *
* AUTHOR: NATHAN RIGGS *
* CONTACT: NATHAN.RIGGS@ *
* OUTLOOK.COM *
* *
* VERSION: 0.3.0 *
* DATE: 10-JAN-2019 *
* ASSEMBLER: MERLIN 8 PRO *
* LICENSE: APACHE 2.0 *
* OS: DOS 3.3 *
* *
* COMMON ASM ROUTINES *
* LIBRARY FOR FUNCTIONS SUCH *
* AS MEMORY SWAPPING. *
* *
*------------------------------*
* *
* LIST OF ROUTINES *
* *
* MEMFILL : FILL LOCATION WITH *
* A SINGLE VALUE. *
* MEMMOVE : MOVE A BLOCK OF *
* MEMORY FROM ONE *
* LOC TO ANOTHER. *
* DELAYMS : DELAY FOR A NUMBER *
* OF MILLISECONDS. *
* THIS DEPENDS ON *
* THE ACTUAL SYSTEM *
* BEING USED, SO *
* ISN'T AS EASILY *
* PORTED TO OTHER *
* 6502 SIBLINGS. *
* ZMSAVE : SAVE STATE OF FREE *
* ZERO PAGE LOCATIONS *
* AT MEM LOC SPECIFIED *
* ZMLOAD : LOAD PREVIOUS SAVED *
* ZERO PAGE VALUES *
* BACK INTO PROPER *
* LOCATION. *
* MEMSWAP: SWAP RANGE OF MEM *
* WITH ANOTHER RANGE. *
* *
*-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*
*
*``````````````````````````````*
* MEMFILL :: FILL MEMORY LOC *
*- -*
* FILLS A BLOCK OF MEMORY WITH *
* THE SPECIFIED VALUE; USED *
* OFTEN TO CLEAR LARGE BLOCKS. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>$6A00 *
* PHA *
* LDA #<$6A00 *
* PHA *
* LDA #>1024 *
* PHA *
* LDA #<1024 *
* PHA *
* LDA #0 *
* PHA *
* JSR MEMFILL *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* FILL VALUE FOR MEMORY *
* ARRAY SIZE *
* LOW BYTE OF STARTING POINT *
* HIGH BYTE OF STARTING POINT *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* Y = COUNTER; TRASH *
* X = COUNTER; TRASH *
* A = LOW BYTE OF RET ADDR *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
MEMFILL
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA :VALUE
PLA
STA :ARYSZ
PLA
STA :ARYSZ+1
PLA
STA ADDR1 ; ZERO PAGE POINTER
PLA ; DEFINED IN
STA ADDR1+1 ; DECS
*
** FILL WHOLE PAGES FIRST
*
LDA :VALUE ; GET VAL FOR FILL
LDX :ARYSZ+1 ; X=# OF PAGES TO DO
BEQ :PARTPG ; BRANCH IF HIGHBYTE OF SZ = 0
LDY #0
:FULLPG
STA (ADDR1),Y
INY ; INC TO NEXT BYTE
BNE :FULLPG ; BRANCH IF NOT DONE W/ PAGE
INC ADDR1+1 ; ADVANCE TO NEXT PAGE
DEX
BNE :FULLPG ; BRANCH IF NOT DONE W/ PAGES
*
** DO THE REMAINING PARTIAL PAGE
** REGISTER A STILL CONTAINS VALUE
*
:PARTPG
LDX :ARYSZ ;GET # OF BYTES IN FINAL PAGE
BEQ :EXIT ; BRANCH IF LOW BYTE = 0
LDY #0
:PARTLP
STA (ADDR1),Y ; STORE VAL
INY ; INCREMENT INDEX
DEX ; DECREMENT COUNTER
BNE :PARTLP ; BRANCH IF NOT DONE
:EXIT
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
*
** DATA
*
:VALUE DS 1 ; FILL VALUE
:ARYSZ DS 2 ; ARRAY SIZE
*
*``````````````````````````````*
* MEMMOVE :: MOVE MEM BLOCK *
*- -*
* MOVES A SPECIFIED BLOCK OF *
* MEMORY FROM A SOURCE ADDRESS *
* TO A DESTINATION ADDRESS *
* RANGE. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>$6A00 *
* PHA *
* LDA #<$6A00 *
* PHA *
* LDA #>$7000 ; DEST *
* PHA *
* LDA #<$7000 *
* PHA *
* LDA #>1024 *
* PHA *
* LDA #<1024 *
* PHA *
* JSR MEMMOVE *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* NUMBER OF BYTES TO MOVE *
* LOW BYTE OF DESTINATION *
* HIGH BYTE OF DESTINATION *
* LOW BYTE OF SOURCE ADDRESS *
* HIGH BYTE OF SOURCE ADDRESS *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* Y = COUNTER; TRASH *
* X = COUNTER; TRASH *
* A = LOW BYTE OF RET ADDR *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
MEMMOVE
*
** SAVE RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET PARAMETERS
*
PLA
STA :MVELEN
PLA
STA :MVELEN+1
PLA
STA ADDR2 ; ZERO PAGE POINTER
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
*
** DETERMINE IF DEST AREA IS
** ABOVE SRC AREA BUT OVERLAPS
** IT. REMEMBER, OVERLAP CAN BE
** MOD 64K. OVERLAP OCCURS IF
** STARTING DEST ADDRESS MINUS
** STARTING SRC ADDRESS (MOD
** 64K) IS LESS THAN NUMBER
** OF BYTES TO MOVE.
*
LDA ADDR2 ;CALC DEST-SRC
SEC
SBC ADDR1
TAX
LDA ADDR2+1
SBC ADDR1+1 ; MOD 64K AUTOMATIC
; -- DISCARD CARRY
TAY
TXA ; CMP WITH # OF BYTES TO MOVE
CMP :MVELEN
TYA
SBC :MVELEN+1
BCS :DOLEFT ; BRANCH IF NO OVERLAP
*
** DEST AREA IS ABOVE SRC AREA
** BUT OVERLAPS IT.
** MOVE FROM HIGHEST ADDR TO
** AVOID DESTROYING DATA
*
JSR :MVERHT
JMP :EXIT
*
** NO PROB DOING ORDINARY MOVE
** STARTING AT LOWEST ADDR
*
:DOLEFT
JSR :MVELEFT
:EXIT
JMP :MREXIT
*
********************************
* SUBROUTINE: MVELEFT *
********************************
*
:MVELEFT
LDY #0 ; ZERO INDEX
LDX :MVELEN+1 ; X=# OF FULL PP TO MOVE
BEQ :MLPART ; IF X=0, DO PARTIAL PAGE
:MLPAGE
LDA (ADDR1),Y
STA (ADDR2),Y ;MOVE ONE BYTE
INY ; NEXT BYTE
BNE :MLPAGE ; CONT UNTIL 256B MOVED
INC ADDR1+1 ; ADV TO NEXT SRC PAGE
INC ADDR2+1 ; ADV NEXT DEST PAGE
DEX ; DEC PAGE COUNT
BNE :MLPAGE ; CONT UNTIL ALL FULL
; PAGES ARE MOVED
:MLPART
LDX :MVELEN ; GET LENGTH OF LAST PAGE
BEQ :MLEXIT ; BR IF LENGTH OF LAST
; PAGE = 0
; REG Y IS 0
:MLLAST
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
INY ; NEXT BYTE
DEX ; DEC COUNTER
BNE :MLLAST ; CONT UNTIL LAST P DONE
:MLEXIT
JMP :MREXIT
*
********************************
* SUBROUTINE: MVERHT *
********************************
*
:MVERHT
*
** MOVE THE PARTIAL PAGE FIRST
*
LDA :MVELEN+1
CLC
ADC ADDR1+1
STA ADDR1+1 ;POINT TO LAST P OF SRC
LDA :MVELEN+1
CLC
ADC ADDR2+1
STA ADDR2+1 ; POINT TO LAST P OF DEST
*
** MOVE THE LAST PARTIAL PAGE FIRST
*
LDY :MVELEN ;GET LENGTH OF LAST PAGE
BEQ :MRPAGE ; IF Y=0 DO THE FULL PAGES
:MR0
DEY ; BACK UP Y TO NEXT BYTE
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
CPY #0
BNE :MR0 ; BR IF NOT DONE W LAST P
:MRPAGE
LDX :MVELEN+1 ; GET BYTE OF COUNT AS P CT
BEQ :MREXIT ; BR IF HYBYTE = 0 (NO FULL P)
:MR1
DEC ADDR1+1 ; BACK UP TO PREV SRC PAGE
DEC ADDR2+1 ; AND DEST
:MR2
DEY ; BACK UP Y TO NEXT BYTE
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
CPY #0
BNE :MR2 ; BR IF NOT DONE W THIS PAGE
DEX
BNE :MR1 BR IF NOT ALL PAGES MOVED
:MREXIT
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
*
** DATA
*
:MVELEN DS 2
*
*``````````````````````````````*
* DELAYMS :: DELAY X MILLISECS *
*- -*
* DELAYS FOR X NUMBER OF *
* MILLISECONDS BY LOOPING *
* THROUGH PRECISELY CALCULATED *
* NUMBER OF CYCLES. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: -XY- *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDY #250 ;1/4 SEC *
* JSR DELAYMS *
*- -*
* ENTRY *
* *
* Y = NUMBER OF MILLISECONDS *
*- -*
* EXIT *
* *
* Y = COUNTER; TRASH *
* X = COUNTER; TRASH *
* A = UNCHANGED *
*- -*
* ADAPTED FROM LEVANTHAL AND *
* WINTHROP'S /6502 ASSEMBLY *
* LANGUAGE ROUTINES/. *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
DELAYMS
*
MSCNT EQU $0CA ; 202 TIMES THROUGH DELAY1
; SPECIFIC TO 1.23 MHZ
; SPEED OF APPLE II
:DELAY
CPY #0 ; 2 CYCLES
BEQ :EXIT ; 2C (EXIT IF DEL=0)
NOP ; 2 CYCLES (MAKE OVERHEAD=25C)
*
** IF DELAY IS 1MS THEN GOTO LAST1
** THIS LOGIC IS DESIGNED TO BE
** 5 CYCLES THROUGH EITHER ATH
*
CPY #1 ; 2 CYCLES
BNE :DELAYA ; 3C IF TAKEN, ELSE 2C
JMP :LAST1 ; 3C
*
** DELAY 1 MILLISENCOND TIMES (Y-1)
*
:DELAYA
DEY ; 2C (PREDEC Y)
:DELAY0
LDX #MSCNT ; 2C
:DELAY1
DEX ; 2C
BNE :DELAY1 ; 3C
NOP ; 2C
NOP ; 2C
DEY ; 2C
BNE :DELAY0 ; 3C
:LAST1
*
** DELAY THE LAST TIME 25 CYCLES
** LESS TO TAKE THE CALL, RETURN,
** AND ROUTINE OVERHEAD INTO
** ACCOUNT.
*
LDX #MSCNT-3 ; 2C
:DELAY2
DEX ; 2C
BNE :DELAY2 ; 3C
:EXIT
RTS ; 6C
*
*
*``````````````````````````````*
* ZMSAVE :: SAVE 0-PAGE FREE *
*- -*
* STORES THE VALUES IN THE *
* LITTLE FREE SPACE ON THE *
* ZERO PAGE AT AN ALTERNATE *
* MEMORY LOCATION TO BE *
* RETRIEVED AND RESTORED AT A *
* LATER POINT. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>$6A00 *
* PHA *
* LDA #<$6A00 *
* PHA *
* JSR ZMSAVE *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* LOW BYTE OF DESTINATION *
* HIGH BYTE OF DESTINATION *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
* Y = TRASH *
* X = TRASH *
* A = LOW BYTE OF RET ADDR *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
ZMSAVE
*
** LOAD ADDR1 ZERO PAGE AREA FIRST,
** SINCE WE'LL BE USING THAT
*
** NOTE THAT THIS SHOULD ALWAYS BE
** $06 AND $07, OR ELSE CODE WILL
** HAVE TO CHANGE.
*
LDX ADDR1
LDY ADDR1+1
*
** SAVE RETURN ADDRESS
*
PLA
STA :RETADR ; LOCAL BECAUSE RETADDR
PLA ; IS STORED ON ZERO PAGE
STA :RETADR+1
*
** GET PARAMETERS
*
PLA
STA ADDR1
PLA
STA ADDR1+1
*
** COPY ZERO PAGE TO SPECIFIED
** NON-ZERO LOCATION (ONLY THE
** FREE ONES..)
*
TYA ; STORE ADDR1 VALS
LDY #1 ; FIRST
STA (ADDR1),Y
LDY #0
TXA
STA (ADDR1),Y
LDY #2
LDA $08
STA (ADDR1),Y
INY
LDA $09
STA (ADDR1),Y
INY
LDA $19
STA (ADDR1),Y
INY
LDA $1E
STA (ADDR1),Y
INY
LDA $E3
STA (ADDR1),Y
INY
LDA $EB
STA (ADDR1),Y
INY
LDA $EC
STA (ADDR1),Y
INY
LDA $ED
STA (ADDR1),Y
INY
LDA $EE
STA (ADDR1),Y
INY
LDA $EF
STA (ADDR1),Y
INY
LDA $FA
STA (ADDR1),Y
INY
LDA $FB
STA (ADDR1),Y
INY
LDA $FC
STA (ADDR1),Y
INY
LDA $FD
STA (ADDR1),Y
INY
LDA $FE
STA (ADDR1),Y
INY
LDA $FF
STA (ADDR1),Y
*
** RESTORE RETURN ADDRESS
*
LDA :RETADR+1
PHA
LDA :RETADR
PHA
*
RTS
*
** DATA
*
:RETADR DS 2
*
*``````````````````````````````*
* ZMLOAD :: RESTORE 0-PAGE MEM *
*- -*
* RESTORES PREVIOUSLY SAVED *
* ZERO PAGE VALUES FROM *
* HIGHER MEMORY LOCATION. *
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>$6A00 *
* PHA *
* LDA #<$6A00 *
* PHA *
* JSR ZMLOAD *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* LOW BYTE OF SOURCE *
* HIGH BYTE OF SOURCE *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
ZMLOAD
*
** SAVE RETURN ADDRESS
*
PLA
STA :RETADR
PLA
STA :RETADR+1
*
** GET PARAMETERS
*
PLA
STA ADDR1
PLA
STA ADDR1+1
*
** COPY ZERO PAGE TO SPECIFIED
** NON-ZERO LOCATION (ONLY THE
** FREE ONES..)
*
LDY #2 ; START 2 AHEAD
LDA (ADDR1),Y ; AND PUT ADDR1
STA $08 ; AREA LAST
INY
LDA (ADDR1),Y
STA $09
INY
LDA (ADDR1),Y
STA $19
INY
LDA (ADDR1),Y
STA $1E
INY
LDA (ADDR1),Y
STA $E3
INY
LDA (ADDR1),Y
STA $EB
INY
LDA (ADDR1),Y
STA $EC
INY
LDA (ADDR1),Y
STA $ED
INY
LDA (ADDR1),Y
STA $EE
INY
LDA (ADDR1),Y
STA $EF
INY
LDA (ADDR1),Y
STA $FA
INY
LDA (ADDR1),Y
STA $FB
INY
LDA (ADDR1),Y
STA $FC
INY
LDA (ADDR1),Y
STA $FD
INY
LDA (ADDR1),Y
STA $FE
INY
LDA (ADDR1),Y
STA $FF
*
** NOW GET ZERO PAGE VALUES
** FOR SPACE OCCUPIED BY ADDR; RETURN IN X,Y
*
LDY #0
LDA (ADDR1),Y
TAX
LDA (ADDR1+1),Y
TAY
STX ADDR1
STY ADDR1+1
*
** RESTORE RETURN ADDRESS
*
LDA :RETADR+1
PHA
LDA :RETADR
PHA
*
RTS
*
** DATA
*
:RETADR DS 2
*
*``````````````````````````````*
* MEMSWAP :: MEMORY SWAP *
*- -*
* SWAPS THE VALUES STORED IN *
* TWO BLOCKS OF SEQUENTIAL *
* MEMORY. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>$6A00 *
* PHA *
* LDA #<$6A00 *
* PHA *
* LDA #>$300 *
* PHA *
* LDA #<$300 *
* PHA *
* LDA #$100 *
* PHA *
* JSR MEMSWAP *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* LOW BYTE OF FIRST ADDRESS *
* HIGH BYTE OF FIRST ADDRESS *
* LOBYTE OF SECOND ADDRESS *
* HIBYTE OF SECOND ADDRESS *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
MEMSWAP
*
** GET RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET VARIABLES
*
PLA
STA :LENGTH
PLA
STA ADDR1
PLA
STA ADDR1+1
PLA
STA ADDR2
PLA
STA ADDR2+1
*
LDY #255 ; COUNTER
:LP
INY
LDA (ADDR1),Y
TAX ; X CONTAINS ADDR1 VAL
LDA (ADDR2),Y ; A CONTAINS ADDR2 VAL
STA (ADDR1),Y
TXA
STA (ADDR2),Y
CPY :LENGTH
BNE :LP
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
RTS
*
** VARIABLES
*
:LENGTH DS 1
*

View File

@ -1,346 +0,0 @@
MEMFILL
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :VALUE
PLA
STA :ARYSZ
PLA
STA :ARYSZ+1
PLA
STA ADDR1 ; ZERO PAGE POINTER
PLA ; DEFINED IN
STA ADDR1+1 ; DECS
LDA :VALUE ; GET VAL FOR FILL
LDX :ARYSZ+1 ; X=# OF PAGES TO DO
BEQ :PARTPG ; BRANCH IF HIGHBYTE OF SZ = 0
LDY #0
:FULLPG
STA (ADDR1),Y
INY ; INC TO NEXT BYTE
BNE :FULLPG ; BRANCH IF NOT DONE W/ PAGE
INC ADDR1+1 ; ADVANCE TO NEXT PAGE
DEX
BNE :FULLPG ; BRANCH IF NOT DONE W/ PAGES
:PARTPG
LDX :ARYSZ ;GET # OF BYTES IN FINAL PAGE
BEQ :EXIT ; BRANCH IF LOW BYTE = 0
LDY #0
:PARTLP
STA (ADDR1),Y ; STORE VAL
INY ; INCREMENT INDEX
DEX ; DECREMENT COUNTER
BNE :PARTLP ; BRANCH IF NOT DONE
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:VALUE DS 1 ; FILL VALUE
:ARYSZ DS 2 ; ARRAY SIZE
MEMMOVE
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :MVELEN
PLA
STA :MVELEN+1
PLA
STA ADDR2 ; ZERO PAGE POINTER
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA ADDR2 ;CALC DEST-SRC
SEC
SBC ADDR1
TAX
LDA ADDR2+1
SBC ADDR1+1 ; MOD 64K AUTOMATIC
; -- DISCARD CARRY
TAY
TXA ; CMP WITH # OF BYTES TO MOVE
CMP :MVELEN
TYA
SBC :MVELEN+1
BCS :DOLEFT ; BRANCH IF NO OVERLAP
JSR :MVERHT
JMP :EXIT
:DOLEFT
JSR :MVELEFT
:EXIT
JMP :MREXIT
:MVELEFT
LDY #0 ; ZERO INDEX
LDX :MVELEN+1 ; X=# OF FULL PP TO MOVE
BEQ :MLPART ; IF X=0, DO PARTIAL PAGE
:MLPAGE
LDA (ADDR1),Y
STA (ADDR2),Y ;MOVE ONE BYTE
INY ; NEXT BYTE
BNE :MLPAGE ; CONT UNTIL 256B MOVED
INC ADDR1+1 ; ADV TO NEXT SRC PAGE
INC ADDR2+1 ; ADV NEXT DEST PAGE
DEX ; DEC PAGE COUNT
BNE :MLPAGE ; CONT UNTIL ALL FULL
; PAGES ARE MOVED
:MLPART
LDX :MVELEN ; GET LENGTH OF LAST PAGE
BEQ :MLEXIT ; BR IF LENGTH OF LAST
; PAGE = 0
; REG Y IS 0
:MLLAST
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
INY ; NEXT BYTE
DEX ; DEC COUNTER
BNE :MLLAST ; CONT UNTIL LAST P DONE
:MLEXIT
JMP :MREXIT
:MVERHT
LDA :MVELEN+1
CLC
ADC ADDR1+1
STA ADDR1+1 ;POINT TO LAST P OF SRC
LDA :MVELEN+1
CLC
ADC ADDR2+1
STA ADDR2+1 ; POINT TO LAST P OF DEST
LDY :MVELEN ;GET LENGTH OF LAST PAGE
BEQ :MRPAGE ; IF Y=0 DO THE FULL PAGES
:MR0
DEY ; BACK UP Y TO NEXT BYTE
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
CPY #0
BNE :MR0 ; BR IF NOT DONE W LAST P
:MRPAGE
LDX :MVELEN+1 ; GET BYTE OF COUNT AS P CT
BEQ :MREXIT ; BR IF HYBYTE = 0 (NO FULL P)
:MR1
DEC ADDR1+1 ; BACK UP TO PREV SRC PAGE
DEC ADDR2+1 ; AND DEST
:MR2
DEY ; BACK UP Y TO NEXT BYTE
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
CPY #0
BNE :MR2 ; BR IF NOT DONE W THIS PAGE
DEX
BNE :MR1 BR IF NOT ALL PAGES MOVED
:MREXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:MVELEN DS 2
DELAYMS
MSCNT EQU $0CA ; 202 TIMES THROUGH DELAY1
; SPECIFIC TO 1.23 MHZ
; SPEED OF APPLE II
:DELAY
CPY #0 ; 2 CYCLES
BEQ :EXIT ; 2C (EXIT IF DEL=0)
NOP ; 2 CYCLES (MAKE OVERHEAD=25C)
CPY #1 ; 2 CYCLES
BNE :DELAYA ; 3C IF TAKEN, ELSE 2C
JMP :LAST1 ; 3C
:DELAYA
DEY ; 2C (PREDEC Y)
:DELAY0
LDX #MSCNT ; 2C
:DELAY1
DEX ; 2C
BNE :DELAY1 ; 3C
NOP ; 2C
NOP ; 2C
DEY ; 2C
BNE :DELAY0 ; 3C
:LAST1
LDX #MSCNT-3 ; 2C
:DELAY2
DEX ; 2C
BNE :DELAY2 ; 3C
:EXIT
RTS ; 6C
ZMSAVE
LDX ADDR1
LDY ADDR1+1
PLA
STA :RETADR ; LOCAL BECAUSE RETADDR
PLA ; IS STORED ON ZERO PAGE
STA :RETADR+1
PLA
STA ADDR1
PLA
STA ADDR1+1
TYA ; STORE ADDR1 VALS
LDY #1 ; FIRST
STA (ADDR1),Y
LDY #0
TXA
STA (ADDR1),Y
LDY #2
LDA $08
STA (ADDR1),Y
INY
LDA $09
STA (ADDR1),Y
INY
LDA $19
STA (ADDR1),Y
INY
LDA $1E
STA (ADDR1),Y
INY
LDA $E3
STA (ADDR1),Y
INY
LDA $EB
STA (ADDR1),Y
INY
LDA $EC
STA (ADDR1),Y
INY
LDA $ED
STA (ADDR1),Y
INY
LDA $EE
STA (ADDR1),Y
INY
LDA $EF
STA (ADDR1),Y
INY
LDA $FA
STA (ADDR1),Y
INY
LDA $FB
STA (ADDR1),Y
INY
LDA $FC
STA (ADDR1),Y
INY
LDA $FD
STA (ADDR1),Y
INY
LDA $FE
STA (ADDR1),Y
INY
LDA $FF
STA (ADDR1),Y
LDA :RETADR+1
PHA
LDA :RETADR
PHA
RTS
:RETADR DS 2
ZMLOAD
PLA
STA :RETADR
PLA
STA :RETADR+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #2 ; START 2 AHEAD
LDA (ADDR1),Y ; AND PUT ADDR1
STA $08 ; AREA LAST
INY
LDA (ADDR1),Y
STA $09
INY
LDA (ADDR1),Y
STA $19
INY
LDA (ADDR1),Y
STA $1E
INY
LDA (ADDR1),Y
STA $E3
INY
LDA (ADDR1),Y
STA $EB
INY
LDA (ADDR1),Y
STA $EC
INY
LDA (ADDR1),Y
STA $ED
INY
LDA (ADDR1),Y
STA $EE
INY
LDA (ADDR1),Y
STA $EF
INY
LDA (ADDR1),Y
STA $FA
INY
LDA (ADDR1),Y
STA $FB
INY
LDA (ADDR1),Y
STA $FC
INY
LDA (ADDR1),Y
STA $FD
INY
LDA (ADDR1),Y
STA $FE
INY
LDA (ADDR1),Y
STA $FF
LDY #0
LDA (ADDR1),Y
TAX
LDA (ADDR1+1),Y
TAY
STX ADDR1
STY ADDR1+1
LDA :RETADR+1
PHA
LDA :RETADR
PHA
RTS
:RETADR DS 2
MEMSWAP
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :LENGTH
PLA
STA ADDR1
PLA
STA ADDR1+1
PLA
STA ADDR2
PLA
STA ADDR2+1
LDY #255 ; COUNTER
:LP
INY
LDA (ADDR1),Y
TAX ; X CONTAINS ADDR1 VAL
LDA (ADDR2),Y ; A CONTAINS ADDR2 VAL
STA (ADDR1),Y
TXA
STA (ADDR2),Y
CPY :LENGTH
BNE :LP
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:LENGTH DS 1

View File

@ -1,320 +0,0 @@
JMP COMMONX
*
MEMFILL
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :VALUE
PLA
STA :ARYSZ
PLA
STA :ARYSZ+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA :VALUE
LDX :ARYSZ+1
BEQ :PARTPG
LDY #0
:FULLPG
STA (ADDR1),Y
INY
BNE :FULLPG
INC ADDR1+1
DEX
BNE :FULLPG
:PARTPG
LDX :ARYSZ
BEQ :EXIT
LDY #0
:PARTLP
STA (ADDR1),Y
INY
DEX
BNE :PARTLP
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:VALUE DS 1
:ARYSZ DS 2
*
MEMMOVE
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :MVELEN
PLA
STA :MVELEN+1
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA ADDR2
SEC
SBC ADDR1
TAX
LDA ADDR2+1
SBC ADDR1+1
TAY
TXA
CMP :MVELEN
TYA
SBC :MVELEN+1
BCS :DOLEFT
JSR :MVERHT
JMP :EXIT
:DOLEFT
JSR :MVELEFT
:EXIT
JMP :MREXIT
:MVELEFT
LDY #0
LDX :MVELEN+1
BEQ :MLPART
:MLPAGE
LDA (ADDR1),Y
STA (ADDR2),Y
INY
BNE :MLPAGE
INC ADDR1+1
INC ADDR2+1
DEX
BNE :MLPAGE
:MLPART
LDX :MVELEN
BEQ :MLEXIT
:MLLAST
LDA (ADDR1),Y
STA (ADDR2),Y
INY
DEX
BNE :MLLAST
:MLEXIT
JMP :MREXIT
:MVERHT
LDA :MVELEN+1
CLC
ADC ADDR1+1
STA ADDR1+1
LDA :MVELEN+1
CLC
ADC ADDR2+1
STA ADDR2+1
LDY :MVELEN
BEQ :MRPAGE
:MR0
DEY
LDA (ADDR1),Y
STA (ADDR2),Y
CPY #0
BNE :MR0
:MRPAGE
LDX :MVELEN+1
BEQ :MREXIT
:MR1
DEC ADDR1+1
DEC ADDR2+1
:MR2
DEY
LDA (ADDR1),Y
STA (ADDR2),Y
CPY #0
BNE :MR2
DEX
BNE :MR
:MREXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:MVELEN DS 2
*
DELAYMS
*
MSCNT EQU $0CA
:DELAY
CPY #0
BEQ :EXIT
NOP
CPY #1
BNE :DELAYA
JMP :LAST1
:DELAYA
DEY
:DELAY0
LDX #MSCNT
:DELAY1
DEX
BNE :DELAY1
NOP
NOP
DEY
BNE :DELAY0
:LAST1
LDX #MSCNT-3
:DELAY2
DEX
BNE :DELAY2
:EXIT
RTS
*
ZMSAVE
*
LDX ADDR1
LDY ADDR1+1
PLA
STA :RETADR
PLA
STA :RETADR+1
PLA
STA ADDR1
PLA
STA ADDR1+1
TYA
LDY #1
STA (ADDR1),Y
LDY #0
TXA
STA (ADDR1),Y
LDY #2
LDA $08
STA (ADDR1),Y
INY
LDA $09
STA (ADDR1),Y
INY
LDA $19
STA (ADDR1),Y
INY
LDA $1E
STA (ADDR1),Y
INY
LDA $E3
STA (ADDR1),Y
INY
LDA $EB
STA (ADDR1),Y
INY
LDA $EC
STA (ADDR1),Y
INY
LDA $ED
STA (ADDR1),Y
INY
LDA $EE
STA (ADDR1),Y
INY
LDA $EF
STA (ADDR1),Y
INY
LDA $FA
STA (ADDR1),Y
INY
LDA $FB
STA (ADDR1),Y
INY
LDA $FC
STA (ADDR1),Y
INY
LDA $FD
STA (ADDR1),Y
INY
LDA $FE
STA (ADDR1),Y
INY
LDA $FF
STA (ADDR1),Y
LDA :RETADR+1
PHA
LDA :RETADR
PHA
RTS
:RETADR DS 2
*
ZMLOAD
*
PLA
STA :RETADR
PLA
STA :RETADR+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDY #2
LDA (ADDR1),Y
STA $08
INY
LDA (ADDR1),Y
STA $09
INY
LDA (ADDR1),Y
STA $19
INY
LDA (ADDR1),Y
STA $1E
INY
LDA (ADDR1),Y
STA $E3
INY
LDA (ADDR1),Y
STA $EB
INY
LDA (ADDR1),Y
STA $EC
INY
LDA (ADDR1),Y
STA $ED
INY
LDA (ADDR1),Y
STA $EE
INY
LDA (ADDR1),Y
STA $EF
INY
LDA (ADDR1),Y
STA $FA
INY
LDA (ADDR1),Y
STA $FB
INY
LDA (ADDR1),Y
STA $FC
INY
LDA (ADDR1),Y
STA $FD
INY
LDA (ADDR1),Y
STA $FE
INY
LDA (ADDR1),Y
STA $FF
LDY #0
LDA (ADDR1),Y
TAX
LDA (ADDR1+1),Y
TAY
STX ADDR1
STY ADDR1+1
LDA :RETADR+1
PHA
LDA :RETADR
PHA
RTS
:RETADR DS 2
COMMONX RTS

View File

@ -1,29 +0,0 @@
*
DELAYMS
*
MSCNT EQU $0CA
:DELAY
CPY #0
BEQ :EXIT
NOP
CPY #1
BNE :DELAYA
JMP :LAST1
:DELAYA
DEY
:DELAY0
LDX #MSCNT
:DELAY1
DEX
BNE :DELAY1
NOP
NOP
DEY
BNE :DELAY0
:LAST1
LDX #MSCNT-3
:DELAY2
DEX
BNE :DELAY2
:EXIT
RTS

View File

@ -0,0 +1,29 @@
DELAYMS
MSCNT EQU $0CA ; 202 TIMES THROUGH DELAY1
; SPECIFIC TO 1.23 MHZ
; SPEED OF APPLE II
:DELAY
CPY #0 ; 2 CYCLES
BEQ :EXIT ; 2C (EXIT IF DEL=0)
NOP ; 2 CYCLES (MAKE OVERHEAD=25C)
CPY #1 ; 2 CYCLES
BNE :DELAYA ; 3C IF TAKEN, ELSE 2C
JMP :LAST1 ; 3C
:DELAYA
DEY ; 2C (PREDEC Y)
:DELAY0
LDX #MSCNT ; 2C
:DELAY1
DEX ; 2C
BNE :DELAY1 ; 3C
NOP ; 2C
NOP ; 2C
DEY ; 2C
BNE :DELAY0 ; 3C
:LAST1
LDX #MSCNT-3 ; 2C
:DELAY2
DEX ; 2C
BNE :DELAY2 ; 3C
:EXIT
RTS ; 6C

View File

@ -1,45 +0,0 @@
*
MEMFILL
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :VALUE
PLA
STA :ARYSZ
PLA
STA :ARYSZ+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA :VALUE
LDX :ARYSZ+1
BEQ :PARTPG
LDY #0
:FULLPG
STA (ADDR1),Y
INY
BNE :FULLPG
INC ADDR1+1
DEX
BNE :FULLPG
:PARTPG
LDX :ARYSZ
BEQ :EXIT
LDY #0
:PARTLP
STA (ADDR1),Y
INY
DEX
BNE :PARTLP
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:VALUE DS 1
:ARYSZ DS 2

View File

@ -0,0 +1,43 @@
MEMFILL
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :VALUE
PLA
STA :ARYSZ
PLA
STA :ARYSZ+1
PLA
STA ADDR1 ; ZERO PAGE POINTER
PLA ; DEFINED IN
STA ADDR1+1 ; DECS
LDA :VALUE ; GET VAL FOR FILL
LDX :ARYSZ+1 ; X=# OF PAGES TO DO
BEQ :PARTPG ; BRANCH IF HIGHBYTE OF SZ = 0
LDY #0
:FULLPG
STA (ADDR1),Y
INY ; INC TO NEXT BYTE
BNE :FULLPG ; BRANCH IF NOT DONE W/ PAGE
INC ADDR1+1 ; ADVANCE TO NEXT PAGE
DEX
BNE :FULLPG ; BRANCH IF NOT DONE W/ PAGES
:PARTPG
LDX :ARYSZ ;GET # OF BYTES IN FINAL PAGE
BEQ :EXIT ; BRANCH IF LOW BYTE = 0
LDY #0
:PARTLP
STA (ADDR1),Y ; STORE VAL
INY ; INCREMENT INDEX
DEX ; DECREMENT COUNTER
BNE :PARTLP ; BRANCH IF NOT DONE
:EXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:VALUE DS 1 ; FILL VALUE
:ARYSZ DS 2 ; ARRAY SIZE

View File

@ -1,99 +0,0 @@
*
MEMMOVE
*
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :MVELEN
PLA
STA :MVELEN+1
PLA
STA ADDR2
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA ADDR2
SEC
SBC ADDR1
TAX
LDA ADDR2+1
SBC ADDR1+1
TAY
TXA
CMP :MVELEN
TYA
SBC :MVELEN+1
BCS :DOLEFT
JSR :MVERHT
JMP :EXIT
:DOLEFT
JSR :MVELEFT
:EXIT
JMP :MREXIT
:MVELEFT
LDY #0
LDX :MVELEN+1
BEQ :MLPART
:MLPAGE
LDA (ADDR1),Y
STA (ADDR2),Y
INY
BNE :MLPAGE
INC ADDR1+1
INC ADDR2+1
DEX
BNE :MLPAGE
:MLPART
LDX :MVELEN
BEQ :MLEXIT
:MLLAST
LDA (ADDR1),Y
STA (ADDR2),Y
INY
DEX
BNE :MLLAST
:MLEXIT
JMP :MREXIT
:MVERHT
LDA :MVELEN+1
CLC
ADC ADDR1+1
STA ADDR1+1
LDA :MVELEN+1
CLC
ADC ADDR2+1
STA ADDR2+1
LDY :MVELEN
BEQ :MRPAGE
:MR0
DEY
LDA (ADDR1),Y
STA (ADDR2),Y
CPY #0
BNE :MR0
:MRPAGE
LDX :MVELEN+1
BEQ :MREXIT
:MR1
DEC ADDR1+1
DEC ADDR2+1
:MR2
DEY
LDA (ADDR1),Y
STA (ADDR2),Y
CPY #0
BNE :MR2
DEX
BNE :MR
:MREXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:MVELEN DS 2

View File

@ -193,7 +193,7 @@ MEMMOVE
CPY #0
BNE :MR2 ; BR IF NOT DONE W THIS PAGE
DEX
BNE :MR1 BR IF NOT ALL PAGES MOVED
BNE :MR1 ; BR IF NOT ALL PAGES MOVED
:MREXIT
*
** RESTORE RETURN ADDRESS

View File

@ -0,0 +1,101 @@
MEMMOVE
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :MVELEN
PLA
STA :MVELEN+1
PLA
STA ADDR2 ; ZERO PAGE POINTER
PLA
STA ADDR2+1
PLA
STA ADDR1
PLA
STA ADDR1+1
LDA ADDR2 ;CALC DEST-SRC
SEC
SBC ADDR1
TAX
LDA ADDR2+1
SBC ADDR1+1 ; MOD 64K AUTOMATIC
; -- DISCARD CARRY
TAY
TXA ; CMP WITH # OF BYTES TO MOVE
CMP :MVELEN
TYA
SBC :MVELEN+1
BCS :DOLEFT ; BRANCH IF NO OVERLAP
JSR :MVERHT
JMP :EXIT
:DOLEFT
JSR :MVELEFT
:EXIT
JMP :MREXIT
:MVELEFT
LDY #0 ; ZERO INDEX
LDX :MVELEN+1 ; X=# OF FULL PP TO MOVE
BEQ :MLPART ; IF X=0, DO PARTIAL PAGE
:MLPAGE
LDA (ADDR1),Y
STA (ADDR2),Y ;MOVE ONE BYTE
INY ; NEXT BYTE
BNE :MLPAGE ; CONT UNTIL 256B MOVED
INC ADDR1+1 ; ADV TO NEXT SRC PAGE
INC ADDR2+1 ; ADV NEXT DEST PAGE
DEX ; DEC PAGE COUNT
BNE :MLPAGE ; CONT UNTIL ALL FULL
; PAGES ARE MOVED
:MLPART
LDX :MVELEN ; GET LENGTH OF LAST PAGE
BEQ :MLEXIT ; BR IF LENGTH OF LAST
; PAGE = 0
; REG Y IS 0
:MLLAST
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
INY ; NEXT BYTE
DEX ; DEC COUNTER
BNE :MLLAST ; CONT UNTIL LAST P DONE
:MLEXIT
JMP :MREXIT
:MVERHT
LDA :MVELEN+1
CLC
ADC ADDR1+1
STA ADDR1+1 ;POINT TO LAST P OF SRC
LDA :MVELEN+1
CLC
ADC ADDR2+1
STA ADDR2+1 ; POINT TO LAST P OF DEST
LDY :MVELEN ;GET LENGTH OF LAST PAGE
BEQ :MRPAGE ; IF Y=0 DO THE FULL PAGES
:MR0
DEY ; BACK UP Y TO NEXT BYTE
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
CPY #0
BNE :MR0 ; BR IF NOT DONE W LAST P
:MRPAGE
LDX :MVELEN+1 ; GET BYTE OF COUNT AS P CT
BEQ :MREXIT ; BR IF HYBYTE = 0 (NO FULL P)
:MR1
DEC ADDR1+1 ; BACK UP TO PREV SRC PAGE
DEC ADDR2+1 ; AND DEST
:MR2
DEY ; BACK UP Y TO NEXT BYTE
LDA (ADDR1),Y
STA (ADDR2),Y ; MOVE BYTE
CPY #0
BNE :MR2 ; BR IF NOT DONE W THIS PAGE
DEX
BNE :MR1 ; BR IF NOT ALL PAGES MOVED
:MREXIT
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:MVELEN DS 2

View File

@ -0,0 +1,163 @@
*
*``````````````````````````````*
* MEMSWAP :: MEMORY SWAP *
*- -*
* SWAPS THE VALUES STORED IN *
* TWO BLOCKS OF SEQUENTIAL *
* MEMORY. *
*- -*
* CLOBBERS: *
* *
* FLAGS: ????---- REG: AXYM *
*- -*
* CYCLES: ??? *
* SIZE: *
*- -*
* USAGE: *
* *
* LDA #>$6A00 *
* PHA *
* LDA #<$6A00 *
* PHA *
* LDA #>$300 *
* PHA *
* LDA #<$300 *
* PHA *
* LDA #$100 *
* PHA *
* JSR MEMSWAP *
*- -*
* ENTRY *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* LOW BYTE OF FIRST ADDRESS *
* HIGH BYTE OF FIRST ADDRESS *
* LOBYTE OF SECOND ADDRESS *
* HIBYTE OF SECOND ADDRESS *
*- -*
* EXIT *
* *
* TOP OF STACK *
* *
* LOW BYTE OF RETURN ADDRESS *
* HI BYTE OF RETURN ADDRESS *
* *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
MEMSWAP
*
** GET RETURN ADDRESS
*
PLA
STA RETADR
PLA
STA RETADR+1
*
** GET VARIABLES
*
PLA
STA :LENGTH
PLA
STA ADDR1
STA :A1
PLA
STA ADDR1+1
STA :A1+1
PLA
STA ADDR2
STA :A2
PLA
STA ADDR2+1
STA :A2+1
*
********************************
*
* ERROR CONTROL
*
********************************
*
LDA ERRCTRL
CMP #1
BEQ :CHKERR
JMP :ERREND
:CHKERR
LDA ADDR2+1 ; IF #>A2 => #>A1
CMP ADDR1+1
BCS :CHKLO ; CHECK LOW BYTES
JMP :A1GTA2 ; ELSE, A1 > A2
:CHKLO
LDA ADDR2
CMP ADDR1
BCS :A2GTA1
JMP :A1GTA2
:A2GTA1
LDA ADDR2 ;CALC DEST-SRC
SEC
SBC ADDR1
TAX
LDA ADDR2+1
SBC ADDR1+1 ; MOD 64K AUTOMATIC
; -- DISCARD CARRY
TAY
TXA ; CMP WITH # OF BYTES TO MOVE
CMP :LENGTH
TYA
SBC :LENGTH+1
BCS :ERREND ; BRANCH IF NO OVERLAP
JMP :OVF
:A1GTA2
LDA ADDR1
SEC
SBC ADDR2
TAX
LDA ADDR1+1
SBC ADDR2+1
TAY
TXA
CMP :LENGTH
TYA
SBC :LENGTH+1
BCS :ERREND
:OVF
_ERR :E_SID;:E_OVF;:E_DUMP;:LENGTH;#6
*
********************************
*
:ERREND
*
********************************
*
LDY #255 ; COUNTER
:LP
INY
LDA (ADDR1),Y
TAX ; X CONTAINS ADDR1 VAL
LDA (ADDR2),Y ; A CONTAINS ADDR2 VAL
STA (ADDR1),Y
TXA
STA (ADDR2),Y
CPY :LENGTH
BNE :LP
*
** RESTORE RETURN ADDRESS
*
LDA RETADR+1
PHA
LDA RETADR
PHA
*
RTS
*
** VARIABLES
*
:LENGTH DS 2
:A1 DS 2
:A2 DS 2
*
:E_SID ASC "MEMSWAP (MSWAP MACRO)",00
:E_DUMP ASC "DUMPING LENGTH (2) A1(2) A2(2)",00
:E_OVF ASC "OVERFLOW! ADDRESSES OVERLAP.",00
*

View File

@ -0,0 +1,86 @@
MEMSWAP
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :LENGTH
PLA
STA ADDR1
STA :A1
PLA
STA ADDR1+1
STA :A1+1
PLA
STA ADDR2
STA :A2
PLA
STA ADDR2+1
STA :A2+1
LDA ERRCTRL
CMP #1
BEQ :CHKERR
JMP :ERREND
:CHKERR
LDA ADDR2+1 ; IF #>A2 => #>A1
CMP ADDR1+1
BCS :CHKLO ; CHECK LOW BYTES
JMP :A1GTA2 ; ELSE, A1 > A2
:CHKLO
LDA ADDR2
CMP ADDR1
BCS :A2GTA1
JMP :A1GTA2
:A2GTA1
LDA ADDR2 ;CALC DEST-SRC
SEC
SBC ADDR1
TAX
LDA ADDR2+1
SBC ADDR1+1 ; MOD 64K AUTOMATIC
; -- DISCARD CARRY
TAY
TXA ; CMP WITH # OF BYTES TO MOVE
CMP :LENGTH
TYA
SBC :LENGTH+1
BCS :ERREND ; BRANCH IF NO OVERLAP
JMP :OVF
:A1GTA2
LDA ADDR1
SEC
SBC ADDR2
TAX
LDA ADDR1+1
SBC ADDR2+1
TAY
TXA
CMP :LENGTH
TYA
SBC :LENGTH+1
BCS :ERREND
:OVF
_ERR :E_SID;:E_OVF;:E_DUMP;:LENGTH;#6
:ERREND
LDY #255 ; COUNTER
:LP
INY
LDA (ADDR1),Y
TAX ; X CONTAINS ADDR1 VAL
LDA (ADDR2),Y ; A CONTAINS ADDR2 VAL
STA (ADDR1),Y
TXA
STA (ADDR2),Y
CPY :LENGTH
BNE :LP
LDA RETADR+1
PHA
LDA RETADR
PHA
RTS
:LENGTH DS 2
:A1 DS 2
:A2 DS 2
:E_SID ASC "MEMSWAP (MSWAP MACRO)",00
:E_DUMP ASC "DUMPING LENGTH (2) A1(2) A2(2)",00
:E_OVF ASC "OVERFLOW! ADDRESSES OVERLAP.",00

View File

@ -36,36 +36,3 @@ RESULT2 EQU $FC
*
REENTRY EQU $3D0
*
*
*
*
** ERROR HANDLING
*
** SET ERRSTOP TO 1 IF YOU WANT THE PROGRAM TO
** HALT WHEN A RUNTIME ERROR OCCURS (BRK)
*
LDA #1
STA ERRSTOP
*
** SET ERRMESG TO 1 IF YOU WANT THE LIBRARY TO
** OUTPUT AN ERROR MESSAGE WHEN AN ERROR OCCURS,
** RATHER THAN JUST PASSING THE ERROR BACK TO
** THE CALLING ROUTINE.
*
LDA #1
STA ERRMESG
*
** SET ERRCTRL TO 1 IF YOU WANT ERROR CATCHING ON
** IN THE FIRST PLACE. HAVING THIS TURNED OFF WILL
** SAVE A FEW CYCLES, BUT POSSIBLY AT THE EXPENSE
** OF YOUR FRUSTRATION. CAN BE TURNED ON LATER THOUGH.
*
LDA #1
STA ERRCTRL
*
JMP VARSKIP
ERRSTOP DS 1
ERRMESG DS 1
ERRCTRL DS 1
VARSKIP
*

View File

@ -8,16 +8,3 @@ RETADR EQU $FE
RESULT EQU $FA
RESULT2 EQU $FC
REENTRY EQU $3D0
LDA #1
STA ERRSTOP
LDA #1
STA ERRMESG
LDA #1
STA ERRCTRL
JMP VARSKIP
ERRSTOP DS 1
ERRMESG DS 1
ERRCTRL DS 1
VARSKIP
RSKIP
*

View File

@ -206,13 +206,13 @@ __W
RTS
*
*``````````````````````````````*
* __RDMP: REGISTRY DUMP *
* __RSAV: REGISTRY SAVE *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
__RDMP
STA :A
STX :X
STY :Y
__RSAV
STA ERRA
STX ERRX
STY ERRY
:C BCC :C0
BCS :C1
:Z BEQ :Z1
@ -221,44 +221,50 @@ __RDMP
BPL :N0
:O BVC :O0
BVS :O1
JMP :RDUMP
JMP :EXIT
:C0 LDA #0
STA :CARRY
STA ERRCARRY
JMP :Z
:C1 LDA #1
STA :CARRY
STA ERRCARRY
JMP :Z
:Z1 LDA #1
STA :ZERO
STA ERRZERO
JMP :N
:Z0 LDA #0
STA :ZERO
STA ERRZERO
JMP :N
:N1 LDA #1
STA :NEGATIVE
STA ERRNEG
JMP :O
:N0 LDA #0
STA :NEGATIVE
STA ERRNEG
JMP :O
:O0 LDA #0
STA :OVERFLOW
JMP :RDUMP
STA ERROVF
JMP :EXIT
:O1 LDA #1
STA :OVERFLOW
STA ERROVF
:EXIT
RTS
*
:RDUMP
*``````````````````````````````*
* __RDMP: REGISTRY DUMP *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
__RDMP
_PRNT " ",8D8D
_PRNT "REGISTRY DUMP",8D
_PRNT "=============",8D
_PRNT "A: "
LDA :A
LDA ERRA
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA :A
LDA ERRA
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
@ -269,14 +275,14 @@ __RDMP
JSR $FDF0
_PRNT " ",8D
_PRNT "X: "
LDA :X
LDA ERRX
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA :X
LDA ERRX
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
@ -287,14 +293,14 @@ __RDMP
JSR $FDF0
_PRNT " ",8D
_PRNT "Y: "
LDA :Y
LDA ERRY
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA :Y
LDA ERRY
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
@ -307,26 +313,26 @@ __RDMP
_PRNT "STATUS FLAGS",8D
_PRNT "============",8D8D
LDA #0
CMP :CARRY
CMP ERRCARRY
BEQ :CARCLR
_PRNT "CARRY: SET",8D
JMP :TESTN
:CARCLR _PRNT "CARRY: CLEAR",8D
:TESTN LDA #0
CMP :NEGATIVE
CMP ERRNEG
BEQ :NEGCLR
_PRNT "NEGATIVE: SET",8D
JMP :TESTZ
:NEGCLR _PRNT "NEGATIVE: CLEAR",8D
:TESTZ LDA #0
CMP :ZERO
CMP ERRZERO
BEQ :ZCLR
_PRNT "ZERO: SET",8D
JMP :TESTO
:ZCLR _PRNT "ZERO: CLEAR",8D
:TESTO
LDA #0
CMP :OVERFLOW
CMP ERROVF
BEQ :OCLR
_PRNT "OVERFLOW: SET",8D
JMP :FIN
@ -336,38 +342,112 @@ __RDMP
*
** DATA
*
:A DS 1
:X DS 1
:Y DS 1
:LEFT DS 1
:RIGHT DS 1
:OVERFLOW DS 1
:NEGATIVE DS 1
:CARRY DS 1
:ZERO DS 1
HEXTAB ASC "0123456789ABCDEF"
*
*``````````````````````````````*
* __ERR: ERROR HANDLING SUB *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
********************************
* *
* GLOBAL VARIABLES *
* *
********************************
__ERR
*
** 256 BYTES DEDICATED TO RETURN
** VALUES OF VARIABLE LENGTH; CAN BE
** MODIFIED TO SUIT SMALLER OR LARGER
** NEEDS.
JSR __RSAV
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :DUMPLEN ; LENGTH OF DUMP
PLA
STA :DUMP ; DUMP ADDRESS LO
PLA
STA :DUMP+1 ; DUMP HI
PLA
STA :DMPMSG
PLA
STA :DMPMSG+1
PLA
STA :MESG ; ERROR MESSAGE ADDR LO
PLA
STA :MESG+1 ; HI
PLA
STA :SRID ; SUBROUTINE ID ADDR LO
PLA
STA :SRID+1 ; SUB ID HI
*
_PRNT " ",87878787878D8D
_PRNT "ERROR!",8D8D
_PRNT "SUBROUTINE: "
LDY #0
LDA :SRID
STA ADDR1
LDA :SRID+1
STA ADDR1+1
:LP1
LDA (ADDR1),Y
BEQ :LPX1
JSR $FDF0
INY
BNE :LP1
:LPX1
_PRNT " ",8D
_PRNT "MESSAGE: "
LDY #0
LDA :MESG
STA ADDR1
LDA :MESG+1
STA ADDR1+1
:LP2
LDA (ADDR1),Y
BEQ :LPX2
JSR $FDF0
INY
BNE :LP2
:LPX2
_PRNT " ",8D8D
_WAIT
LDY #0
LDA :DMPMSG
STA ADDR1
LDA :DMPMSG+1
STA ADDR1+1
:LP3
LDA (ADDR1),Y
BEQ :LPX3
JSR $FDF0
INY
BNE :LP3
:LPX3
_PRNT " ",8D
LDA :DUMP+1
PHA
LDA :DUMP
PHA
LDA :DUMPLEN
PHA
JSR __DUMP
_WAIT
LDA RETADR+1
PHA
LDA RETADR
PHA
_PRNT " ",8D8D
_WAIT
_RDUMP
_WAIT
LDA ERRSTOP
CMP #1
BEQ :KILL
RTS
:KILL
JMP $3D0
*
RETLEN DS 1 ; RETURN VALUE BYTE LENGTH
RETURN DS 256
** DATA
*
** 256 BYTE VALUE DEDICATED TO LARGE
** OR VARIABLE LENGTH PARAMETERS. THIS
** CAN ALSO BE CHANGED TO FIT SMALLER OR
** LARGER BOUNDS.
*
PARLEN DS 1
PARAM DS 256
:DUMPLEN DS 1
:DUMP DS 2
:DMPMSG DS 2
:MESG DS 2
:SRID DS 2
*

View File

@ -133,10 +133,10 @@ __P
__W
JSR $FD0C
RTS
__RDMP
STA :A
STX :X
STY :Y
__RSAV
STA ERRA
STX ERRX
STY ERRY
:C BCC :C0
BCS :C1
:Z BEQ :Z1
@ -145,43 +145,45 @@ __RDMP
BPL :N0
:O BVC :O0
BVS :O1
JMP :RDUMP
JMP :EXIT
:C0 LDA #0
STA :CARRY
STA ERRCARRY
JMP :Z
:C1 LDA #1
STA :CARRY
STA ERRCARRY
JMP :Z
:Z1 LDA #1
STA :ZERO
STA ERRZERO
JMP :N
:Z0 LDA #0
STA :ZERO
STA ERRZERO
JMP :N
:N1 LDA #1
STA :NEGATIVE
STA ERRNEG
JMP :O
:N0 LDA #0
STA :NEGATIVE
STA ERRNEG
JMP :O
:O0 LDA #0
STA :OVERFLOW
JMP :RDUMP
STA ERROVF
JMP :EXIT
:O1 LDA #1
STA :OVERFLOW
:RDUMP
STA ERROVF
:EXIT
RTS
__RDMP
_PRNT " ",8D8D
_PRNT "REGISTRY DUMP",8D
_PRNT "=============",8D
_PRNT "A: "
LDA :A
LDA ERRA
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA :A
LDA ERRA
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
@ -192,14 +194,14 @@ __RDMP
JSR $FDF0
_PRNT " ",8D
_PRNT "X: "
LDA :X
LDA ERRX
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA :X
LDA ERRX
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
@ -210,14 +212,14 @@ __RDMP
JSR $FDF0
_PRNT " ",8D
_PRNT "Y: "
LDA :Y
LDA ERRY
AND #$F0 ; MASK RIGHT
LSR
LSR
LSR
LSR
STA :LEFT
LDA :Y
LDA ERRY
AND #$0F ; MASK LEFT
STA :RIGHT
LDX :LEFT
@ -230,43 +232,127 @@ __RDMP
_PRNT "STATUS FLAGS",8D
_PRNT "============",8D8D
LDA #0
CMP :CARRY
CMP ERRCARRY
BEQ :CARCLR
_PRNT "CARRY: SET",8D
JMP :TESTN
:CARCLR _PRNT "CARRY: CLEAR",8D
:TESTN LDA #0
CMP :NEGATIVE
CMP ERRNEG
BEQ :NEGCLR
_PRNT "NEGATIVE: SET",8D
JMP :TESTZ
:NEGCLR _PRNT "NEGATIVE: CLEAR",8D
:TESTZ LDA #0
CMP :ZERO
CMP ERRZERO
BEQ :ZCLR
_PRNT "ZERO: SET",8D
JMP :TESTO
:ZCLR _PRNT "ZERO: CLEAR",8D
:TESTO
LDA #0
CMP :OVERFLOW
CMP ERROVF
BEQ :OCLR
_PRNT "OVERFLOW: SET",8D
JMP :FIN
:OCLR _PRNT "OVERFLOW: CLEAR",8D8D8D
:FIN
RTS
:A DS 1
:X DS 1
:Y DS 1
:LEFT DS 1
:RIGHT DS 1
:OVERFLOW DS 1
:NEGATIVE DS 1
:CARRY DS 1
:ZERO DS 1
HEXTAB ASC "0123456789ABCDEF"
RETLEN DS 1 ; RETURN VALUE BYTE LENGTH
RETURN DS 256
PARLEN DS 1
PARAM DS 256
__ERR
JSR __RSAV
PLA
STA RETADR
PLA
STA RETADR+1
PLA
STA :DUMPLEN ; LENGTH OF DUMP
PLA
STA :DUMP ; DUMP ADDRESS LO
PLA
STA :DUMP+1 ; DUMP HI
PLA
STA :DMPMSG
PLA
STA :DMPMSG+1
PLA
STA :MESG ; ERROR MESSAGE ADDR LO
PLA
STA :MESG+1 ; HI
PLA
STA :SRID ; SUBROUTINE ID ADDR LO
PLA
STA :SRID+1 ; SUB ID HI
_PRNT " ",87878787878D8D
_PRNT "ERROR!",8D8D
_PRNT "SUBROUTINE: "
LDY #0
LDA :SRID
STA ADDR1
LDA :SRID+1
STA ADDR1+1
:LP1
LDA (ADDR1),Y
BEQ :LPX1
JSR $FDF0
INY
BNE :LP1
:LPX1
_PRNT " ",8D
_PRNT "MESSAGE: "
LDY #0
LDA :MESG
STA ADDR1
LDA :MESG+1
STA ADDR1+1
:LP2
LDA (ADDR1),Y
BEQ :LPX2
JSR $FDF0
INY
BNE :LP2
:LPX2
_PRNT " ",8D8D
_WAIT
LDY #0
LDA :DMPMSG
STA ADDR1
LDA :DMPMSG+1
STA ADDR1+1
:LP3
LDA (ADDR1),Y
BEQ :LPX3
JSR $FDF0
INY
BNE :LP3
:LPX3
_PRNT " ",8D
LDA :DUMP+1
PHA
LDA :DUMP
PHA
LDA :DUMPLEN
PHA
JSR __DUMP
_WAIT
LDA RETADR+1
PHA
LDA RETADR
PHA
_PRNT " ",8D8D
_WAIT
_RDUMP
_WAIT
LDA ERRSTOP
CMP #1
BEQ :KILL
RTS
:KILL
JMP $3D0
:DUMPLEN DS 1
:DUMP DS 2
:DMPMSG DS 2
:MESG DS 2
:SRID DS 2

View File

@ -140,3 +140,28 @@ _RDUMP MAC
JSR __RDMP
<<<
*
*``````````````````````````````*
* _ERR: ERROR-HANDLING ROUTINE *
*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,*
*
_ERR MAC
LDA #>]1
PHA
LDA #<]1
PHA
LDA #>]2
PHA
LDA #<]2
PHA
LDA #>]3
PHA
LDA #<]3
PHA
LDA #>]4
PHA
LDA #<]4
PHA
LDA ]5
PHA
JSR __ERR
<<<

View File

@ -71,3 +71,24 @@ _WAIT MAC
_RDUMP MAC
JSR __RDMP
<<<
_ERR MAC
LDA #>]1
PHA
LDA #<]1
PHA
LDA #>]2
PHA
LDA #<]2
PHA
LDA #>]3
PHA
LDA #<]3
PHA
LDA #>]4
PHA
LDA #<]4
PHA
LDA ]5
PHA
JSR __ERR
<<<

View File

@ -0,0 +1,72 @@
*
********************************
* *
* VARIABLES AND SETTINGS *
* *
********************************
*
* VARIABLE DECLARATIONS ********
*
** JUMP TABLE SETUP. THIS IS FOR LOADING
** SUBROUTINES INTO MEMORY FOR ACCESS BY
** EXTERNAL EXECUTIONS. NOTE THAT THIS
** SHOULD ALWAYS BE THE VERY FIRST BIT OF
** CODE IN THE PROGRAM SO THAT ITS
** LOCATION IN MEMORY IS EASILY KNOWN.
*
JUMPTBL JMP MAIN_START ; ** ALWAYS ** START WITH
; JUMP TO MAIN_START
DS 60 ; 20 MORE ENTRIES
*
** 256 BYTES DEDICATED TO RETURN
** VALUES OF VARIABLE LENGTH; CAN BE
** MODIFIED TO SUIT SMALLER OR LARGER
** NEEDS.
*
RETLEN DS 1 ; RETURN VALUE BYTE LENGTH
RETURN DS 256
*
** 256 BYTE VALUE DEDICATED TO LARGE
** OR VARIABLE LENGTH PARAMETERS. THIS
** CAN ALSO BE CHANGED TO FIT SMALLER OR
** LARGER BOUNDS.
*
PARLEN DS 1
PARAM DS 256
*
** ERROR HANDLING
*
ERRSTOP DS 1
ERRCTRL DS 1
ERRA DS 1
ERRX DS 1
ERRY DS 1
ERRCARRY DS 1
ERRNEG DS 1
ERRZERO DS 1
ERROVF DS 1
*
* SETTINGS *********************
*
MAIN_START
*
** ERROR HANDLING
*
** SET ERRSTOP TO 1 IF YOU WANT THE PROGRAM TO
** HALT WHEN AN ERROR IS CAUGHT
*
LDA #1
STA ERRSTOP
*
** SET ERRCTRL TO 1 IF YOU WANT ERROR CATCHING ON
** IN THE FIRST PLACE. HAVING THIS TURNED OFF WILL
** SAVE A FEW CYCLES, BUT POSSIBLY AT THE EXPENSE
** OF YOUR FRUSTRATION. CAN BE TURNED ON LATER THOUGH.
*
LDA #1
STA ERRCTRL
*
*
*
*
*

View File

@ -1,6 +1,4 @@
*
ZMLOAD
*
PLA
STA :RETADR
PLA
@ -9,9 +7,9 @@ ZMLOAD
STA ADDR1
PLA
STA ADDR1+1
LDY #2
LDA (ADDR1),Y
STA $08
LDY #2 ; START 2 AHEAD
LDA (ADDR1),Y ; AND PUT ADDR1
STA $08 ; AREA LAST
INY
LDA (ADDR1),Y
STA $09

View File

@ -1,18 +1,16 @@
*
ZMSAVE
*
LDX ADDR1
LDY ADDR1+1
PLA
STA :RETADR
PLA
STA :RETADR ; LOCAL BECAUSE RETADDR
PLA ; IS STORED ON ZERO PAGE
STA :RETADR+1
PLA
STA ADDR1
PLA
STA ADDR1+1
TYA
LDY #1
TYA ; STORE ADDR1 VALS
LDY #1 ; FIRST
STA (ADDR1),Y
LDY #0
TXA