home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Columbia Kermit
/
kermit.zip
/
os968ka
/
k6outf.asm
< prev
Wrap
Assembly Source File
|
2020-01-01
|
14KB
|
259 lines
nam Kermit68K
ttl Utility subroutines module
* Kermit68K: source file K68UTF
*
* Author: Roberto Bagnara (Bagnara@Iboinfn.Bitnet),
* Bologna University, Physics Department, July 1987.
*
* All rights reserved to Bologna University, Italy.
*
* Permission is granted to any individual or institution
* to use, copy, or redistribute this software so long as
* it is not sold for profit, provided this copyright
* notice is retained.
*
* Modification History:
*
* Version Date Who Comments
*
* 1.0.00 870701 Roberto Bagnara First official release
use DefsFile
Edition equ 0
psect K68UtilitySubs,0,0,Edition,0,0
********************************* CopyStr *****************************ok
* *
* Null terminated strings copy subroutine. *
* *
* Entry conditions : D0.W target string maximum length *
* A0.L pointer to target string *
* A1.L pointer to source string *
* *
* Exit conditions : A0.L pointer to target string *
* A1.L pointer to source string *
* *
***********************************************************************
CopyStr: TST.W D0 Null strings ?
BEQ.S CopyStr4 Yes, do nothing
MOVEM.L A0-A1,-(A7) Save pointers
CopyStr1 SUBQ.W #1,D0 Decrement counter
BNE.S CopyStr2 Continue copy, if there is room
MOVE.B D0,(A0) End of target string, write terminator
BRA.S CopyStr3 Restore pointers and return
CopyStr2 MOVE.B (A1)+,(A0)+ Copy a character
BNE.S CopyStr1 Repeat until end of source string
CopyStr3 MOVEM.L (A7)+,A0-A1 Restore pointers
CopyStr4 RTS
********************************* CompStr *****************************ok
* *
* Null terminated strings compare subroutine. *
* *
* Entry conditions : A0.L pointer to string 1 *
* A1.L pointer to string 2 *
* *
* Exit conditions : D0.B completion code *
* A0.L pointer to string 1 *
* A1.L pointer to string 2 *
* *
***********************************************************************
CompStr: MOVEM.L A0-A1,-(A7) Save pointers
CompStr1 MOVE.B (A0)+,D0 Get a character from string 1
CMP.B (A1)+,D0 Compare whit string 2 correspondent char
BNE.S CompStr2 Compare failed, exit loop
TST.B D0 Compare succeed, end of strings ?
BNE.S CompStr1 No, stay in loop
CompStr2 SEQ D0 Set completion code accordingly
MOVEM.L (A7)+,A0-A1 Restore pointers
RTS
********************************* DoPrity *****************************ok
* *
* Add an appropriate parity bit to a character. *
* *
* Entry conditions : D0.B 7-bit character *
* *
* Exit conditions : D0.B character with parity bit added *
* *
***********************************************************************
DoPrity: MOVEM.L D1-D2,-(A7) Save working registers
MOVE.B Parity(A6),D1 Some kind of parity enabled ?
BEQ.S DoPrity5 No, return
ANDI.B #$7F,D0 Clear bit 7
CMPI.B #'M',D1 Mark ?
BNE.S DoPrity1 No
ORI.B #$80,D0 Yes, set bit 7
BRA.S DoPrity5 Return
DoPrity1 CMPI.B #'S',D1 Space ?
BEQ.S DoPrity5 Yes, return, bit 7 already cleared
CLR.B D2 Clear the ones counter
CMPI.B #'O',D1 Odd ?
BNE.S DoPrity2 No
ADDQ.B #1,D2 Yes, the ones counter starts from 1
DoPrity2 MOVEQ #6,D1 Set up for bit addressing
DoPrity3 BTST D1,D0 Bit setted ?
BEQ.S DoPrity4 No, try the next
ADDQ.B #1,D2 Yes, increment the counter
DoPrity4 DBF D1,DoPrity3 Repeat for bits 6-0
LSL.B #7,D2 Position the parity bit
OR.B D2,D0 Ok, that's all
DoPrity5 MOVEM.L (A7)+,D1-D2 Restore working registers
RTS
****************************** HndlPar ********************************ok
* *
* Handle 8-th bit accordingly to parity selected. *
* *
* Entry conditions : D0.B character to be processed *
* *
* Exit conditions : D0.B processed character *
* *
***********************************************************************
HndlPar: TST.B Parity(A6) Parity selected ?
BEQ.S HndlPar1 No, do nothing
ANDI.B #$7F,D0 Yes, mask parity bit
HndlPar1 RTS
********************************* UDiv ********************************ok
* *
* 32-bit/16-bit unsigned division. *
* *
* Entry conditions : D2.L dividend *
* D3.W divisor *
* *
* Exit conditions : D0.L quotient *
* D1.L remainder *
* *
***********************************************************************
UDiv: MOVE.L D2,D0 Get Dividend
CLR.W D0 Clear lower part
SWAP D0 Upper Dividend
DIVU D3,D0 Divide
MOVE.W D0,-(A7) Save upper quotient
MOVE.W D2,D0 Remainder and lower Dividend
DIVU D3,D0 Divide
SWAP D0
CLR.L D1
MOVE.W D0,D1 Final remainder
MOVE.W (A7)+,D0 Lower and upper quotients
SWAP D0 Final quotient
RTS Return
******************************* IntToAs *******************************ok
* *
* Integer to ASCII string conversion routine. *
* *
* Entry conditions : A0.L pointer to string buffer end *
* D0.L number to convert *
* D1.B flag for signed or unsigned number *
* D2.L field length *
* D3.L number base *
* *
* Exit conditions : A0.L pointer to string buffer start *
* *
***********************************************************************
IntToAs: MOVEM.W D4-D6,-(A7) Save working registers
MOVE.B D1,D4 Load our flag for negative numbers
BEQ.S IntToAs1 Unsigned number processing wanted
TST.L D0 Signed, negative number ?
SLT D4 Set our flag accordingly
BGE.S IntToAs1 If positive number then continue
NEG.L D0 Else negate it
IntToAs1 MOVE.B D2,D5 Save field length
CLR.B -(A0) Mark the end of string
CLR.B D6 Clear the character counter
IntToAs2 MOVE.L D0,D2 Dividend
BSR UDiv Divide number by base (in D3)
CMPI.B #9,D1 Convert remainder to ascii
BGT.S IntToAs3
ADDI.B #$30,D1
BRA.S IntToAs4
IntToAs3 ADDI.B #$37,D1
IntToAs4 MOVE.B D1,-(A0) Store the obtained character
ADDQ.B #1,D6 Increment the character counter
TST.L D0 End of conversion ?
BNE.S IntToAs2 No, repeat
TST.B D4 Yes, was a negative number ?
BEQ.S IntToAs5 No, continue
MOVE.B #'-',-(A0) Yes, insert the minus sign
ADDQ.B #1,D6 Increment the character counter
IntToAs5 CMP.B D6,D5 Field full ?
BLE.S IntToAs6 Yes
MOVE.B #' ',-(A0) No, write a leading blank
ADDQ.B #1,D6 Increment the character counter
BRA.S IntToAs5 Continue padding until the field is full
IntToAs6 MOVEM.W (A7)+,D4-D6 Restore working registers
RTS
******************************* UppCase *******************************ok
* *
* Make a character upper-cased. *
* *
* Entry conditions : D3.B character to be converted *
* *
* Exit conditions : D3.B converted character *
* *
***********************************************************************
UppCase: CMPI.B #'a',D3 Below a ?
BCS.S UppCase1 Yes, return
CMPI.B #'z',D3 Above z ?
BHI.S UppCase1 Yes, return
SUBI.B #32,D3 No, make the character upper-cased
UppCase1 RTS
******************************* IndxJump ******************************ok
* *
* Indexed jump, extract an address from a relative addresses table *
* and jump to it. *
* *
* Entry conditions : D0.B index to jump table *
* A1.L jump table start address *
* *
* Exit conditions : none, don't return *
* *
***********************************************************************
IndxJump: ANDI.W #$FF,D0 Make sure upper byte is cleared
LSL.W #1,D0 Scale factor of 2
MOVE.W (A1,D0.W),D0 Load relative pointer
JMP (A1,D0.W) Jump to service subroutine
MacFind: BSR UppCasS Make the macro name upper-cased
LEA MacroTbl(A6),A1 Load start address of macro table
CMPA.L MTNxtChF(A6),A1 The macro table is empty ?
BEQ.S MacFind2 Yes, return a bad completion code
MacFind1 BSR CompStr Compare the two names
TST.B D0 The two names are equal ?
BNE.S MacFind3 Yes, return the macro address
BSR MacSkip No, skip to next macro name
TST.B D0 It was the last macro ?
BEQ.S MacFind1 No, so check this one
MacFind2 MOVEA.L A1,A0 Yes, this points to table end
SF D0 Return a bad completion code
RTS
MacFind3 MOVEA.L A1,A0 This is the desired macro address
ST D0 Return a positive completion code
RTS
MacSkip: TST.B (A1)+ Find the end of the macro name
BNE.S MacSkip Loop until end of macro name found
MacSkip1 TST.B (A1)+ Find the end of the macro body
BNE.S MacSkip1 Loop until end of macro body found
CMPA.L MTNxtChF(A6),A1 End of macro table ?
SEQ D0 Set the completion code accordingly
RTS
UppCasS MOVE.L A0,-(A7)
UppCasS1 MOVE.B (A0),D3
BEQ.S UppCasS2
BSR UppCase
MOVE.B D3,(A0)+
BRA.S UppCasS1
UppCasS2 MOVE.L (A7)+,A0
RTS
ends
END