Category : Assembly Language Source Code
Archive   : ASPIC.ZIP
Filename : SEGMACS.ASI

 
Output of file : SEGMACS.ASI contained in archive : ASPIC.ZIP
******************************************************************************
* Permission to use all or part of these macros in your code as long as you
* include the following comment:
******************************************************************************
* Segment handling routines by Don Lekei
******************************************************************************
* First use:
* DEFSEG ,, ;to define a memory segment
* then use:
* SEG NAME ;to change segments
*
* Other useful macros:
* PADSEG ;Pads the current segment with $FF
* OLDSEG ;Change back to the PREVIOUS SEGMENT
* FILLSEG ;Fill the rest of the segment a byte value
* SEG_REPORT ;Generate a final segment report
* PC(NAME) ;*Function* to return next address in segment
******************************************************************************

***************************************************************
* Global variables used by various SEG macros *
***************************************************************

..SEG$CNT = 0 ;Number of segments defined
..CUR$SEG = 0 ;Current segment number
..OLD$SEG = 0 ;Previous segment number

******************************************************************************
* DEFSEG --- Segment definition macro
* Usage:
* DEFSEG ,,
* where:
* is the SEG name (eg. ROM, RAM, CODE, etc.) max. 7 chrs
* is the starting address
* is the first address NOT in the segment
*
* DEFSEG creates the following labels (where name represents and
* n is the current segment # (SEG$CNT+1) as a HEX digit:
*
* S$name: The segment # of the segment
* ..SEG$n: The next address in the segment
* END$n: The value of
*
* It also defines a macro "SEGREP$n" to print the segment report line info
*
******************************************************************************

DEFSEG .MACRO *[1],[2],[3] ;Name,start,end+1
..SEG$CNT = ..SEG$CNT+1 ;get next segment #
S$[1] = ..SEG$CNT ;define the segment tag label
make$seg (S$[1]),([2]),([3]),[1] ;Define segment labels
.ENDM

******************************************************************************
* SEG --- CHANGE SEGMENTS
* Usage:
* SEG
* where:
* is the same name used in the DEFSEG statement
******************************************************************************

SEG .MACRO *[1] ;change segment to [1] (NAME)
;(S$[1]) expands to the value of label S$NAME
set$seg (S$[1]),(..CUR$SEG) ;pass #s to SET$SEG
.ENDM

******************************************************************************
* OLDSEG --- CHANGE TO PREVIOUS SEGMENT
******************************************************************************

OLDSEG .MACRO * ;change to previous segment
set$seg (..OLD$SEG),(..CUR$SEG) ;pass #s to SET$SEG
.ENDM

******************************************************************************
* PADSEG --- PAD WITH $FF TO END OF CURRENT SEGMENT
******************************************************************************

PADSEG .MACRO * ;fill rest of current segment with $FF
pad$seg (..CUR$SEG),$FF
.ENDM

******************************************************************************
* FILLSEG --- FILL WITH [1] TO END OF CURRENT SEGMENT
******************************************************************************

FILLSEG .MACRO *[1] ;fill rest of current segment with [1]
pad$seg (..CUR$SEG),[1]
.ENDM

******************************************************************************
* SEG_REPORT --- PRINT THE FINAL STATUS OF ALL SEGMENTS
* The report will print to the current ECHO device or file (at the
* end of each pass), AND will expand to the listing.
******************************************************************************

SEG_REPORT .MACRO * ;print the final status of all segments

.if ..SEG$CNT=0 ;make sure there are segments defined
.EXITM ;nothing to report
.endif

***************************************************************
* Update current segment's PC (forgets previous segment) *
***************************************************************
set$seg (..CUR$SEG),(..CUR$SEG) ;pass #s to SET$SEG
***************************************************************
* Print a nice heading. *
***************************************************************
.mxp on
echo SEGMENT START END PC USED FREE
echo ------- ----- ----- ----- ----- -----
.mxp off

.do ..SEG$CNT ;print all segment reports
seg$rep (.._index) ;report each segment
.loop

.ENDM

******************************************************************************
* PC(name) (function macro) --- Returns the current PC for named segment
* eg. PC(RAM)
******************************************************************************

PC( .MACRO [1]) ;return next PC for SEG [1]
( P$C( (S$[1]) ) ) ;pass segment # from S$NAME as a string to P$C()
.ENDM

******************************************************************************
* P$C((segnum),(CUR$SEG)) find segment PC
* Invoked with parms in parentheses to pass the values as $n
******************************************************************************

P$C( .MACRO [1]) ;find PC for use by PC() function
( ([1] == ..CUR$SEG) ? * : ..SEG[1] ) ;return PC if current SEG is requested
.ENDM

******************************************************************************
* MAKE$SEG: invoked by DEFSEG to create segment labels
* Invoked with parms 1, 2 & 3 in parentheses to pass the values as $n
******************************************************************************

MAKE$SEG .MACRO [1],[2],[3],[4] ;(segnum), (start), (end), name
..SEG[1] = [2] ;Set initial segment PC
END[1] = [3] ;Set the segment end address

***************************************************************
* Define a macro to display the segment *
* Note: [1], [2], [3], and [4] are replaced during the *
* the expansion of *** MAKE$SEG ***, while "end" is *
* replaced by the expansion of *** SEGREP *** *
***************************************************************
SEGREP[1] .macro *pc ;report on SEG [4] (# [1])
; (name,start,end,pc,used,free)
seg$echo [4],[2],[3],(pc),(pc-[2]),([3]-pc)
.endm
.ENDM

******************************************************************************
* SEG$ECHO --- Invoked by SEGREP$n TO CREATE SEGMENT REPORT LINE
* Invoked with parms in parentheses to pass the values as $n
******************************************************************************
SEG$ECHO .MACRO *name,start,end,pc,used,free ;seg report line
.mxp on
echo name start end pc used free
.mxp off
.ENDM

******************************************************************************
* SEG$REP --- Invoked by SEG_REPORT to convert seg # to SEGREP$n invovation
* Invoked with parm in parentheses to pass the value as $n
******************************************************************************
SEG$REP .MACRO *[1] ;(segnum) invoke SEGREP$n
segrep[1] ..SEG[1] ;print final report
.ENDM

******************************************************************************
* SET$SEG Invoked by SEG to set segment variables for segment change
* Invoked with parms in parentheses to pass the values as $n
******************************************************************************

SET$SEG .MACRO [1],[2] ;(new segnum),(current segnum)
.if ..CUR$SEG ;skip if first segment
..OLD$SEG = ..CUR$SEG ;SAVE PREVIOUS SEGMENT
..SEG[2] = * ;UPDATE SEGMENT POINTER
.IF (* > END[2]) && (END[2] != 0)
seg$fail [2],(*) ;PC is past end of segment
.ENDIF
.endif
*= ..SEG[1] ;SET PC TO NEW SEGMENT
..CUR$SEG = [1] ;SET CURRENT SEGMENT NUMBER
.ENDM

******************************************************************************
* SEG$FAIL --- Invoked by SET$SEG when SEGMENT OVERFLOW occurs
* Invoked with parms in parentheses to pass the values as $n
******************************************************************************
SEG$FAIL .MACRO *[1],[2]
.mxp on
echo SEGMENT START END PC USED FREE
echo ------- ----- ----- ----- ----- -----
.mxp off
.segrep[1] ([2]-1) ;print report info for this segment
.ERROR 'Segment #[1.1] overflow at PC = [2]'
.ENDM

******************************************************************************
* PAD$SEG --- Invoked by PADSEG fill rest of segment
* Invoked with parms in parentheses to pass the values as $n
******************************************************************************

PAD$SEG .MACRO [1],[2]
FILL [2],END[1]-*
.ENDM



  3 Responses to “Category : Assembly Language Source Code
Archive   : ASPIC.ZIP
Filename : SEGMACS.ASI

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/