home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / devcon / washington_1988 / devcon88.3 / autoboot / loadseg.asm < prev   
Assembly Source File  |  1992-08-27  |  13KB  |  600 lines

  1.  
  2. ;
  3. ; Copyright (c) 1988 Commodore-Amiga, Inc.
  4. ;
  5. ; Executables based on this information may be used in software
  6. ; for Commodore Amiga computers.  All other rights reserved.
  7. ;
  8. ; This information is provided "as is"; no warranties are made.
  9. ; All use is at your own risk, and no liability or responsibility is assumed.
  10. ;
  11.  
  12.  
  13.     INCLUDE    "exec/types.i"
  14.     INCLUDE    "exec/ables.i"
  15.     INCLUDE    "exec/memory.i"
  16.     INCLUDE    "libraries/dos.i"
  17.  
  18. ABSEXECBASE    EQU    4
  19.     
  20.     XDEF    _PrivateLoadSeg
  21.  
  22.     XREF    _intena
  23.  
  24.     XREF    _LVOAllocMem
  25.     XREF    _LVOAllocAbs
  26.     XREF    _LVOClose
  27.     XREF    _LVOCloseLibrary
  28.     XREF    _LVOFreeMem
  29.     XREF    _LVOOpen
  30.     XREF    _LVOOpenLibrary
  31.     XREF    _LVORead
  32.  
  33. MAXNAMELEN    EQU    128
  34.  
  35. HUNK_HEADER    EQU    1011
  36.  
  37.  
  38. ;------    LoadSeg ------------------------------------------------------
  39. ;
  40. ;   NAME
  41. ;    LoadSeg - load a file into memory and relocate it
  42. ;
  43. ;   SYNOPSIS
  44. ;    success = LoadSeg(allocFunc, freeFunc, readFunc,
  45. ;    d0                a0         a1        a2
  46. ;                      readHandle, dataEnviron)
  47. ;                      d1          a6
  48. ;
  49. ;    actual = readFunc(readHandle, buffer, length)
  50. ;       d0                d1          a0      d0
  51. ;
  52. ;    memory = allocFunc(size, flags)
  53. ;    d0                 d0    d1
  54. ;
  55. ;    freeFunc(memory, size)
  56. ;             a1      d0
  57. ;
  58. ;   EXCEPTIONS
  59. ;    This LoadSeg fails if resident or overlay hunks exist.
  60. ;
  61. ;---------------------------------------------------------------------
  62. lsv_DataEnviron    EQU    0        ; function argument passed in a6
  63. lsv_ReadFunc    EQU    lsv_DataEnviron-4
  64. lsv_FreeFunc    EQU    lsv_ReadFunc-4
  65. lsv_AllocFunc    EQU    lsv_FreeFunc-4
  66. lsv_ReadHandle    EQU    lsv_AllocFunc-4
  67. lsv_Segment    EQU    lsv_ReadHandle-4
  68. lsv_Name    EQU    lsv_Segment-MAXNAMELEN
  69. lsv_LINKSIZE    EQU    lsv_Name-4
  70.  
  71. ;
  72. ;   d2    various temporaries
  73. ;   d3    hunk relocation offset value
  74. ;   d4    byte limit of current hunk
  75. ;   d5    first hunk slot
  76. ;   d6    last hunk slot
  77. ;   a2    current hunk address
  78. ;   a3    segment tail
  79. ;   a4    hunk table
  80. ;   a5    lsv structure
  81. ;   a6    scratch data area
  82. ;
  83. LoadSeg:
  84.         movem.l    d2-d6/a2-a5,-(a7)
  85.         link    a6,#lsv_LINKSIZE
  86.         move.l    a6,a5
  87.  
  88.         movem.l    d1/a0/a1/a2,lsv_ReadHandle(a5)
  89.         moveq    #0,d6
  90.         move.l    d6,lsv_Segment(a5)
  91.         move.l    d6,a4
  92.  
  93.         ;-- ensure this is a valid load file
  94.         bsr    GetLong
  95.         cmp.l    #HUNK_HEADER,d0
  96.         bne    lsFail
  97.  
  98.         ;-- handle resident library header by failing if it exists
  99.         bsr    GetLong
  100.         tst.l    d0
  101.         bne    lsFail
  102.  
  103.         ;-- handle hunks
  104.         bsr    GetLong        ; get table size
  105.         bsr    GetLong        ; get first hunk slot
  106.         move.l    d0,d5
  107.         bsr    GetLong        ; get last hunk slot
  108.         move.l    d0,d6
  109.  
  110.         ;-- allocate the temporary hunk table via Exec AllocMem
  111.         addq.l    #1,d0        ; last slot + 1 long words
  112.         lsl.l    #2,d0        ; in bytes
  113.         moveq    #0,d1
  114.         move.l    ABSEXECBASE,a6
  115.         jsr    _LVOAllocMem(a6)
  116.         tst.l    d0
  117.         beq    lsFail
  118.         move.l    d0,a4
  119.  
  120.         ;-- allocate the hunks themselves
  121. lsAllocHunks:
  122.         move.w    d5,d2
  123.         lsl.w    #2,d5
  124.         lea    0(a4,d5.w),a2
  125.         lea    lsv_Segment(a5),a3
  126. lsAllocHunk:
  127.         ;-- for each entry in this file
  128.         cmp.w    d6,d2
  129.         bgt.s    lsLoadHunks
  130.         ;-- allocate space for the hunk and cache pointer in the table    
  131.         bsr    GetLong        ; get size needed
  132.         beq.s    lsEmptyHunk
  133.         bsr    GetVector    ; get memory
  134.         move.l    a0,(a2)+    ; cache pointer
  135.         move.l    a0,d0        ; convert
  136.         lsr.l    #2,d0        ;   to BPTR
  137.         move.l    d0,(a3)        ;   and link to end of segment
  138.         move.l    a0,a3        ; new tail
  139. lsNextHunk:
  140.         addq.w    #1,d2        ; count up hunk
  141.         bra.s    lsAllocHunk
  142.  
  143. lsEmptyHunk:
  144.         clr.l    (a2)+
  145.         bra.s    lsNextHunk
  146.  
  147.         ;-- read in the load image
  148. lsLoadHunks:
  149.         moveq    #-1,d4            ; byte limit: between hunks
  150. lsLoadHunk:
  151.         ;-- perform GetLong-like function, but EOF is OK here
  152.         subq.l    #4,a7
  153.         move.l    a7,a0
  154.         moveq    #4,d0
  155.         move.l    lsv_ReadHandle(a5),d1
  156.         movem.l    lsv_ReadFunc(a5),a1/a6
  157.         jsr    (a1)
  158.         tst.l    d0            ; check for EOF
  159.         beq    lsFreeHunk
  160.         cmp.l    #4,d0
  161.         bne    lsFail
  162.         ;-- switch on hunk type
  163.         move.l    (a7)+,d0
  164.         andi.l    #$3fffffff,d0
  165.         sub.l    #1000,d0
  166.         bmi    lsFail
  167.         cmp.l    #HUNKSWITCHLIMIT,d0
  168.         bge    lsFail
  169.         add.w    d0,d0
  170.         move.w    lsSwitch(pc,d0.w),d0
  171.         jsr    lsSwitch(pc,d0.w)
  172.         bra.s    lsLoadHunk
  173.  
  174. lsSwitch:
  175.         dc.w    lssHunkName-lsSwitch
  176.         dc.w    lssHunkCode-lsSwitch
  177.         dc.w    lssHunkData-lsSwitch
  178.         dc.w    lssHunkBSS-lsSwitch
  179.         dc.w    lssHunkReloc32-lsSwitch
  180.         dc.w    lssHunkReloc16-lsSwitch
  181.         dc.w    lssHunkReloc8-lsSwitch
  182.         dc.w    lssHunkExt-lsSwitch
  183.         dc.w    lssHunkSymbol-lsSwitch
  184.         dc.w    lssHunkDebug-lsSwitch
  185.         dc.w    lssHunkEnd-lsSwitch
  186.         dc.w    lssHunkHeader-lsSwitch
  187.         dc.w    lssHunkCont-lsSwitch
  188.         dc.w    lssHunkOverlay-lsSwitch
  189.         dc.w    lssHunkBreak-lsSwitch
  190.  
  191. HUNKSWITCHLIMIT    EQU    (*-lsSwitch)/2
  192.  
  193. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  194. lssHunkName:
  195.         bsr    ReadName        ; read name
  196.         rts                ; and ignore
  197.  
  198. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  199. lssHunkCode:
  200. lssHunkData:
  201.         ;-- get hunk size
  202.         bsr    GetLong
  203.         ;-- get new byte limit
  204.         lsl.l    #2,d0
  205.         move.l    d0,d4
  206.         subq.l    #4,d4
  207.         ;-- get hunk base
  208.         move.l    0(a4,d5.w),a2        ; get table entry
  209.         addq.l    #4,a2            ; skip next segment pointer
  210.         addq.l    #4,d5            ; bump hunk number
  211.         ;-- load in the code
  212.         move.l    d0,d2
  213.         beq.s    lsshdReturn
  214.         move.l    a2,a0
  215.         move.l    lsv_ReadHandle(a5),d1
  216.         movem.l    lsv_ReadFunc(a5),a1/a6
  217.         jsr    (a1)
  218.         cmp.l    d2,d0
  219.         bne    lssFail
  220. lsshdReturn:
  221.         rts
  222.  
  223. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  224. lssHunkBSS:
  225.         ;-- get hunk size
  226.         bsr    GetLong
  227.         ;-- get new byte limit
  228.         move.l    d0,d4
  229.         lsl.l    #2,d4
  230.         subq.l    #4,d4
  231.         ;-- get hunk base
  232.         move.l    0(a4,d5.w),a2        ; get table entry
  233.         addq.l    #4,a2            ; skip next segment pointer
  234.         addq.l    #4,d5            ; bump hunk number
  235.         ;-- clear the bss area
  236.         move.l    a2,a0
  237.         moveq    #0,d1
  238.         move.w    d0,d2            ; low word
  239.         swap    d0            ; high word
  240.         bra.s    lsshbssDBF
  241. lsshbssLoop:
  242.         move.l    d1,(a0)+
  243. lsshbssDBF:
  244.         dbf    d2,lsshbssLoop
  245.         dbf    d0,lsshbssLoop
  246.         rts
  247.  
  248. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  249. lssHunkReloc32:
  250.         bsr    GetLong
  251.         move.w    d0,d2
  252.         beq.s    lsshrReturn
  253.         bsr    GetLong
  254.         cmp.l    d6,d0
  255.         bgt.s    lssFail
  256.  
  257.         lsl.w    #2,d0
  258.         move.l    0(a4,d0.w),d3        ; get table entry
  259.         addq.l    #4,d3            ; skip next segment pointer
  260.         subq.w    #1,d2
  261. lsshrRelocLoop:
  262.         bsr    GetLong
  263.         ;-- ensure within hunk
  264.         bmi.s    lssFail
  265.         cmp.l    d4,d0
  266.         bgt.s    lssFail
  267.         add.l    d3,0(a2,d0.l)        ; add base to offset
  268.         dbf    d2,lsshrRelocLoop
  269.         bra.s    lssHunkReloc32
  270.  
  271. lsshrReturn:
  272.         rts
  273.  
  274. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  275. lssHunkSymbol:
  276.         bsr    ReadName        ; flush symbol name
  277.         tst.l    d0            ; check symbol length
  278.         beq.s    lsshsDone        ; end of symbol hunk if zero
  279.         bsr    GetLong            ; flush symbol value
  280.         bra.s    lssHunkSymbol
  281. lsshsDone:
  282.         rts
  283.  
  284. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  285. lssHunkDebug:
  286.         bsr    GetLong
  287.         move.w    d0,d2
  288.         bra.s    lsshdDBF
  289. lsshdLoop:
  290.         bsr    GetLong
  291. lsshdDBF:
  292.         dbf    d2,lsshdLoop
  293.         rts
  294.  
  295. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  296. lssHunkEnd:
  297.         moveq    #-1,d4        ; flag end in limit
  298.         rts            ; (it's OK to see EOF now)
  299.  
  300. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  301. lssFail:
  302. lssHunkReloc16:
  303. lssHunkReloc8:
  304. lssHunkExt:
  305. lssHunkHeader:
  306. lssHunkCont:
  307. lssHunkOverlay:
  308. lssHunkBreak:
  309.         moveq    #0,d4        ; flag error
  310.         addq.l    #4,a7        ; pop switch return address
  311.                     ; fall thru to lsFreeHunk
  312. ; . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  313.  
  314. lsFreeHunk:
  315.         move.l    a4,d0
  316.         beq.s    lsCheckOK
  317.         ;-- free the temporary hunk table via Exec FreeMem
  318.         move.l    d6,d0        ; recover last slot
  319.         addq.l    #1,d0        ; last slot + 1 long words
  320.         lsl.l    #2,d0        ; in bytes
  321.         move.l    a4,a1
  322.         move.l    ABSEXECBASE,a6
  323.         jsr    _LVOFreeMem(a6)
  324.  
  325.         ;-- check for error
  326. lsCheckOK:
  327.         cmp.l    #-1,d4
  328.         beq.s    lsOK
  329.  
  330.         ;-- unload the segment
  331.         move.l    lsv_Segment(a5),d1
  332.         move.l    lsv_FreeFunc(a5),a1
  333.         move.l    lsv_DataEnviron(a5),a6
  334.         bsr    UnLoadSeg
  335.         moveq    #0,d0
  336.         bra.s    lsReturn
  337.  
  338. lsOK:
  339.         ;-- return list head BPTR as result
  340.         move.l    lsv_Segment(a5),d0
  341.  
  342. lsReturn:
  343.         move.l    a5,a6
  344.         unlk    a6
  345.         movem.l    (a7)+,d2-d6/a2-a5
  346.         rts
  347.  
  348. lsFail:
  349.         moveq    #0,d4
  350.         bra.s    lsFreeHunk
  351.  
  352. ; - - -    GetLong - - - - - - - - - - - - - - - - - - - - - - - - - - -
  353. ;
  354. ;   INPUT
  355. ;   a4    readHandle
  356. ;   a4    readFunc
  357. ;
  358. ;   RESULT
  359. ;   d0    next longword in stream
  360. ;
  361. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  362. GetLong:
  363.         subq.l    #4,a7
  364.         move.l    a7,a0
  365.         moveq    #4,d0
  366.         move.l    lsv_ReadHandle(a5),d1
  367.         movem.l    lsv_ReadFunc(a5),a1/a6
  368.         jsr    (a1)
  369.         cmp.l    #4,d0
  370.         bne.s    gFail
  371.         move.l    (a7)+,d0
  372.         rts
  373.  
  374.  
  375. ; - - -    ReadName  - - - - - - - - - - - - - - - - - - - - - - - - - -
  376. ;
  377. ;   INPUT
  378. ;   a5    lsv structure
  379. ;
  380. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  381. ReadName:
  382.         bsr.s    GetLong
  383.         lsl.l    #2,d0
  384.         beq.s    rnReturn
  385.         cmp.l    #MAXNAMELEN,d0
  386.         bge.s    rnFail
  387.         lea    lsv_Name(a5),a0
  388.         move.l    d0,-(a7)
  389.         move.l    lsv_ReadHandle(a5),d1
  390.         movem.l    lsv_ReadFunc(a5),a1/a6
  391.         jsr    (a1)
  392.         cmp.l    (a7)+,d0
  393.         bne.s    rnFail
  394. rnReturn:
  395.         rts
  396. rnFail:
  397.         addq.l    #4,a7
  398.         bra.s    lsFail
  399.  
  400.  
  401. ; - - -    GetVector - - - - - - - - - - - - - - - - - - - - - - - - - -
  402. ;
  403. ;   INPUT
  404. ;   d0    vector size (without size prefix), in longwords, with memory
  405. ;    flags CHIP and FAST in bits 30 and 31
  406. ;
  407. ;   RESULT
  408. ;   a0    vector
  409. ;
  410. ; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  411. GetVector:
  412.         move.l    d0,d1
  413.         lsl.l    #2,d0
  414.         addq.l    #4,d0
  415.         move.l    d0,-(a7)
  416.         addq.l    #4,d0
  417.         rol.l    #3,d1
  418.         and.l    #6,d1        ; mask to MEMF_FAST+MEMF_CHIP
  419.         move.l    lsv_AllocFunc(a5),a1
  420.         move.l    lsv_DataEnviron(a5),a6
  421.         jsr    (a1)
  422.         tst.l    d0
  423.         bne.s    gvCacheSize
  424. gFail:
  425.         addq.l    #8,a7
  426.         bra    lsFail
  427. gvCacheSize:
  428.         move.l    d0,a0
  429.         move.l    (a7)+,(a0)
  430.         addq.l    #4,a0
  431.         rts
  432.  
  433.  
  434. ;------ UnLoadSeg ----------------------------------------------------
  435. ;
  436. ;    UnLoadSeg(segment, freeFunc, dataEnviron)
  437. ;              d1       a1        a6
  438. ;
  439. ;    freeFunc(memory, size)
  440. ;             a1      d0
  441. ;
  442. ;   EXCEPTIONS
  443. ;
  444. ;---------------------------------------------------------------------
  445. UnLoadSeg:
  446.         movem.l    d2/a2,-(a7)
  447.         move.l    d1,d2
  448.         move.l    a1,a2
  449.         bra.s    usNext
  450. usLoop:
  451.         ;-- free this hunk
  452.         move.l    (a1),d2        ; cache next segment
  453.         move.l    -(a1),d0    ; get size
  454.         addq.l    #4,d0
  455.         jsr    (a2)
  456. usNext:
  457.         lsl.l    #2,d2        ; get next segment
  458.         beq.s    ulDone
  459.         move.l    d2,a1
  460.         bra.s    usLoop
  461.  
  462. ulDone:
  463.         movem.l    (a7)+,d2/a2
  464.         rts
  465.  
  466. ;------    AllocRecoverable ---------------------------------------------
  467. ;
  468. ;    memory = AllocRecoverable(size, requirements)
  469. ;    d0                        d0    d1
  470. ;
  471. ;---------------------------------------------------------------------
  472. AllocRecoverable:
  473.         movem.l    d2/d3/a2/a3/a6,-(a7)
  474.         move.l    ABSEXECBASE,a6
  475.         FORBID    a0
  476.  
  477.         ;-- get first memory header
  478.         move.l    MemList(a6),a0
  479.         moveq    #0,d3            ; guess noone big enough
  480.  
  481.         ;-- cycle through memory headers
  482. nextMemHeader:
  483.         move.l    a0,a1
  484.         move.l    (a1),d2            ; check for end of list
  485.         beq    noMemory
  486.         ;-- handle requirements
  487.         move.l    d2,a0
  488.         move.w    MH_ATTRIBUTES(a1),d2
  489.         and.w    d1,d2
  490.         cmp.w    d1,d2
  491.         bne.s    nextMemHeader
  492.  
  493.         ;-- search this memory for a big enough piece at the end
  494.         move.l    MH_FIRST(a1),a2
  495. checkMemChunk:
  496.         cmp.l    MC_BYTES(a2),d0
  497.         bhi.s    memTooSmall
  498.         move.l    a2,a3            ; this is a candidate
  499.         move.l    MC_BYTES(a2),d3        ;
  500. memTooSmall:
  501.         ;-- get the next chunk
  502.         move.l    MC_NEXT(a2),d2
  503.         beq.s    noMoreChunks
  504.         move.l    d2,a2
  505.         bra.s    checkMemChunk
  506.  
  507. noMoreChunks:
  508.         tst.l    d3            ; check for candidates
  509.         bne.s    gotChunk
  510.         bra.s    nextMemHeader
  511.  
  512. gotChunk:
  513.         sub.l    d0,d3            ; determine excess capacity
  514.         and    #(~MEM_BLOCKMASK),d3    ; rounded down to even block
  515.         add.l    d3,a3            ; and adjust desired address
  516.  
  517.         move.l    a3,a1
  518.         jsr    _LVOAllocAbs(a6)
  519. allocEnd:
  520.         PERMIT    a0
  521.         movem.l    (a7)+,d2/d3/a2/a3/a6
  522.         rts
  523.  
  524. noMemory:
  525.         moveq    #0,d0
  526.         bra.s    allocEnd
  527.  
  528.  
  529. ;------ Read ---------------------------------------------------------
  530. ;
  531. ;    actual = Read(readHandle, buffer, length)
  532. ;       d0            d1          a0      d0
  533. ;
  534. ;---------------------------------------------------------------------
  535. Read:
  536.         movem.l    d2/d3,-(a7)
  537.         move.l    a0,d2
  538.         move.l    d0,d3
  539.         jsr    _LVORead(a6)
  540.         movem.l    (a7)+,d2/d3
  541.         rts
  542.  
  543. ;------ FreeHigh -----------------------------------------------------
  544. ;
  545. ;    FreeHigh(memory, size)
  546. ;             a1      d0
  547. ;
  548. ;---------------------------------------------------------------------
  549. FreeHigh:
  550.         move.l    a6,-(a7)
  551.         move.l    ABSEXECBASE,a6
  552.         jsr    _LVOFreeMem(a6)
  553.         move.l    (a7)+,a6
  554.         rts
  555.  
  556. ;****** PrivateLoadSeg ***********************************************
  557. ;    PrivateLoadSeg(fileName)
  558. ;    
  559. ;    success = LoadSeg(allocFunc, freeFunc, readFunc,
  560. ;    d0                a0         a1        a2
  561. ;                      readHandle, dataEnviron)
  562. ;                      d1          a6
  563. ;*********************************************************************
  564. _PrivateLoadSeg:
  565.         movem.l    d2/a2/a6,-(a7)
  566.         moveq    #0,d2
  567.         lea    DLName(pc),a1
  568.         moveq    #0,d0
  569.         move.l    ABSEXECBASE,a6
  570.         jsr    _LVOOpenLibrary(a6)
  571.         tst.l    d0
  572.         beq.s    plsDone
  573.         move.l    d0,a6
  574.         move.l    16(a7),d1
  575.         move.l    #MODE_OLDFILE,d2
  576.         jsr    _LVOOpen(a6)
  577.         move.l    d0,d2
  578.         beq.s    plsCloseLib
  579.         move.l    d0,d1
  580.         lea    AllocRecoverable(pc),a0
  581.         lea    FreeHigh(pc),a1
  582.         lea    Read(pc),a2
  583.         bsr    LoadSeg
  584.         move.l    d2,d1
  585.         move.l    d0,d2
  586.         jsr    _LVOClose(a6)
  587. plsCloseLib:
  588.         move.l    a6,a1
  589.         move.l    ABSEXECBASE,a6
  590.         jsr    _LVOCloseLibrary(a6)
  591. plsDone:
  592.         move.l    d2,d0
  593.         movem.l    (a7)+,d2/a2/a6
  594.         rts
  595.  
  596. DLName        dc.b    'dos.library',0
  597.         ds.w    0
  598.     
  599.     END
  600.