home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 455.lha / BPD / BPD.asm < prev    next >
Assembly Source File  |  1990-12-10  |  10KB  |  391 lines

  1. *\  :ts=8 bk=0
  2. *
  3. * BPD.asm:    Stands for "Boot PAL, Dammit!"  Written as an alternative to
  4. *        all those other programs that attempt to set PAL mode, and
  5. *        never get it right.
  6. *
  7. *        See, in order for PAL mode to *truly* take effect, you have
  8. *        to convince graphics.library that it's running PAL.  To do
  9. *        that, you have to get in before graphics configures itself
  10. *        and set the PAL bit in the ECS agnus.  And in order to do
  11. *        *that*, you have to be part of the boot sequence.
  12. *
  13. *        So this program does precisely that by creating and
  14. *        installing a resident RomTag into the system that survives
  15. *        reboots.
  16. *
  17. *        Usage:  BPD [ '?' | 'REMOVE' | 'NTSC' ]
  18. *
  19. *        Thanks to Bryce Nesbitt for providing me with an example
  20. *        of how to create resident RomTags.
  21. *
  22. * Leo L. Schwab,  Silent Software, Inc.            9010.20
  23. * NTSC hack added (inspired by Nico Francois)        9011.11
  24. */
  25.         include    'exec/types.i'
  26.         include    'exec/execbase.i'
  27.         include    'exec/resident.i'
  28.         include    'exec/memory.i'
  29.  
  30.         xref    _LVOFindResident
  31.         xref    _LVOAllocMem
  32.         xref    _LVOCopyMem
  33.         xref    _LVOSumKickData
  34.         xref    _LVODisable
  35.         xref    _LVOEnable
  36.         xref    _LVOOpenLibrary
  37.         xref    _LVOCloseLibrary
  38.  
  39.         xref    _LVOOutput
  40.         xref    _LVOWrite
  41.  
  42.         xref    _vposr        ; Custom chip register
  43.  
  44. TAG_PRI        EQU    100        ; Above graphics.library.
  45.  
  46.  
  47. ****************
  48. * And we're off!
  49. *
  50.         SECTION    BPD,CODE
  51. Hello:
  52.         movea.l    a0,a3        ; Save argument pointer
  53.         movea.l    4.w,a6        ; ExecBase
  54.         lea    dosname(pc),a1
  55.         moveq    #0,d0
  56.         jsr    _LVOOpenLibrary(a6)
  57.         moveq    #20,d2
  58.         move.l    d0,d6
  59.         beq    openfailed
  60.  
  61.         lea    Name(pc),a1
  62.         jsr    _LVOFindResident(a6)
  63.  
  64. * See if ECS Agnus is installed.  We check for ID's 0x20 and 0x30.  Anything
  65. * else is considered something we don't know how to deal with.
  66. *
  67.         move.w    _vposr,d1    ; Get ID bits
  68.         andi.w    #$3F00,d1    ; Mask off extraneous stuff.
  69.         cmpi.w    #$3000,d1    ; Is it NTSC ECS Agnus?
  70.         beq.s    1$
  71.         cmpi.w    #$2000,d1    ; Is it PAL ECS Agnus?
  72.         bne    notecs
  73.  
  74. * Scan command line to see what the user wants to do.
  75. *
  76. 1$        move.b    (a3)+,d1
  77.         cmpi.b    #' ',d1
  78.         beq.s    1$        ; Skip past leading blanks.
  79.         cmpi.b    #'?',d1        ; Usage line
  80.         beq    usage
  81.         cmpi.b    #'r',d1        ; Remove
  82.         beq    remove
  83.         cmpi.b    #'R',d1
  84.         beq    remove
  85.         cmpi.b    #'n',d1        ; NTSC
  86.         beq.s    2$
  87.         cmpi.b    #'N',d1
  88.         bne.s    install
  89.  
  90. * Exceedingly cheap hack to support PAL machines that want to boot into
  91. * NTSC mode (inspired by Nico Francois' NTSC-PAL programs).  This will
  92. * cause the bootnode to stuff a 0 into the magic ECS Agnus register,
  93. * which should make the system come up in NTSC mode.
  94. *
  95. 2$        clr.w    movearg
  96.  
  97.  
  98. * No meaningful command line arguments supplied, so we'll assume s/he wants
  99. * to install it.
  100. *
  101. install        tst.l    d0
  102.         bne    installed    ; Already installed
  103.  
  104. * Allocate memory to survive reboot.
  105. *
  106.         move.l    #RESIDENT_SIZ,d0
  107.         move.l    #MEMF_CHIP!MEMF_PUBLIC,d1
  108.         jsr    _LVOAllocMem(a6)
  109.         tst.l    d0
  110.         beq    nomem
  111.         move.l    d0,a2        ; Save pointer
  112.  
  113. * Relocate pointers to destination.
  114. *
  115.         lea    RelTable(pc),a0
  116.         lea    ResStart(pc),a1
  117.         sub.l    a1,d0        ; Compute relocation difference
  118.         move.l    d0,d7        ; Save it for later
  119.  
  120. 2$        move.l    (a0)+,d0    ; Fetch address of thing to relocate
  121.         beq.s    3$        ; NULL-terminated array
  122.         move.l    d0,a1
  123.         add.l    d7,(a1)        ; Add offset to thing
  124.         bra.s    2$
  125. 3$:
  126.  
  127. * Set a few more things atomically.
  128. *
  129.         jsr    _LVODisable(a6)
  130.  
  131. * Insert MemList into system KickMem list.  (I would have used AddHead(),
  132. * but SysBase.KickMemPtr is not a struct List.  Oh well...
  133. *
  134.         lea    MyMemList(pc),a0    ; Address of our memlist
  135.         move.l    KickMemPtr(a6),d0
  136.         move.l    d0,(a0)        ; Append current system entry to us
  137.         add.l    d7,a0        ; Add relocation offset
  138.         move.l    a0,KickMemPtr(a6)    ; Add us to system
  139.  
  140. * Insert into Resident module list.  This is done so that running BPD twice
  141. * before rebooting will not cause it to be installed twice (that would be
  142. * bad, you see...).
  143. *
  144.         lea    MyResModule(pc),a0    ; Our ResModule array
  145.         move.l    ResModules(a6),d0    ; Already ResModules here?
  146.         beq.s    4$
  147.         bset.l    #31,d0        ; Yes, set special indirection flag
  148.         move.l    d0,4(a0)    ;  and store pointer.
  149. 4$:
  150.         add.l    d7,a0        ; Add relocation offset
  151.         move.l    a0,ResModules(a6)    ; Insert us into Exec list
  152.  
  153. * Insert into KickTagPtr list.
  154. *
  155.         lea    MyKickTagPtr(pc),a0    ; Our KickTagPtr array
  156.         move.l    KickTagPtr(a6),d0    ; Already KickTagPtrs here?
  157.         beq.s    5$
  158.         bset.l    #31,d0        ; Yep...
  159.         move.l    d0,4(a0)
  160. 5$:
  161.         add.l    d7,a0        ; Relocate...
  162.         move.l    a0,KickTagPtr(a6)    ; Insert us into Exec list
  163.  
  164. * Copy resident code and data into allocated memory.
  165. *
  166.         lea    ResStart(pc),a0    ; src
  167.         movea.l    a2,a1        ; dest
  168.         move.l    #RESIDENT_SIZ,d0
  169.         jsr    _LVOCopyMem(a6)
  170.  
  171. * Recompute KickCheckSum.
  172. *
  173.         jsr    _LVOSumKickData(a6)
  174.         move.l    d0,KickCheckSum(a6)
  175.  
  176. * Return to reality.
  177. *
  178.         jsr    _LVOEnable(a6)
  179.         lea    BPD.msg(pc),a2
  180.         bsr    climsg
  181.         lea    installed.msg(pc),a2
  182.         bsr    climsg
  183.  
  184. exit        lea    change.msg(pc),a2
  185.         bsr    climsg
  186. eexit        movea.l    d6,a1
  187.         jsr    _LVOCloseLibrary(a6)
  188. openfailed    move.l    d2,d0        ; D2 usually set to 0 by climsg
  189.         rts
  190.  
  191. errexit        moveq    #20,d2
  192.         bra.s    eexit
  193.  
  194.  
  195. ****************
  196. * User wants to remove the goodie.
  197. *
  198. remove        tst.l    d0
  199.         beq.s    nothere        ; Nothing to remove
  200.  
  201. * Remove ourselves from the system lists.  First the KickMemPtr list.
  202. *
  203.         lea    KickMemPtr(a6),a1
  204. 1$        movea.l    a1,a0
  205.         move.l    (a0),d1
  206.         beq.s    nothere        ; Couldn't find MemList entry.
  207.  
  208.         movea.l    d1,a1
  209.         cmp.l    ML_ME+ME_ADDR(a1),d0    ; See if it's us.
  210.         bne.s    1$
  211.  
  212.         move.l    (a1),(a0)    ; Pull us from the list.
  213.  
  214. * Now try to find us in the KickTagPtr list.
  215. *
  216.         lea    KickTagPtr(a6),a0
  217. tablehop    move.l    (a0),d1
  218.         beq.s    nothere        ; End of tables;  Couldn't find us.
  219.         bclr.l    #31,d1
  220.         movea.l    d1,a1
  221.  
  222. tableloop    move.l    (a1)+,d1
  223.         bgt.s    2$
  224.         lea    -4(a1),a0    ; Indirection, get pointer to it
  225.         bra.s    tablehop    ;  and loop to next table
  226.  
  227. 2$        cmp.l    d1,d0        ; Is it us?
  228.         bne.s    tableloop
  229.  
  230. * We found ourselves.  Now perform remove.  (Since I know the format of
  231. * the table I installed, I can make assumptions about the data I'm zapping.)
  232. *
  233.         move.l    (a1),d1        ; Get pointer to next table.
  234.         btst.b    #7,(a0)        ; Did we get here by indirection?
  235.         bne.s    3$
  236.         bclr.l    #31,d1        ; No, clear indirection bit.
  237. 3$        move.l    d1,(a0)        ; Patch to jumper over us.
  238.  
  239. * Reset KickCheckSum.
  240. *
  241.         jsr    _LVOSumKickData(a6)
  242.         move.l    d0,KickCheckSum(a6)
  243.  
  244.         lea    BPD.msg(pc),a2
  245.         bsr.s    climsg
  246.         lea    removed.msg(pc),a2
  247.         bsr.s    climsg
  248.         bra.s    exit
  249.  
  250.  
  251. ****************
  252. * Diagnostic messages.
  253. *
  254. installed    lea    BPD.msg(pc),a2
  255.         bsr.s    climsg
  256.         lea    already.msg(pc),a2
  257.         bsr.s    climsg
  258.         bra.s    errexit
  259.  
  260. nomem        lea    nomem.msg(pc),a2
  261.         bsr.s    climsg
  262.         bra.s    errexit
  263.  
  264. notecs        lea    notecs.msg(pc),a2
  265.         bsr.s    climsg
  266.         bra.s    errexit
  267.  
  268. nothere        lea    BPD.msg(pc),a2
  269.         bsr.s    climsg
  270.         lea    not.msg(pc),a2
  271.         bsr.s    climsg
  272.         lea    installed.msg(pc),a2
  273.         bsr.s    climsg
  274.         bra    errexit
  275.  
  276. usage        lea    ID(pc),a2
  277.         bsr.s    climsg
  278.         lea    usage.msg(pc),a2
  279.         bsr.s    climsg
  280.         bra    exit
  281.  
  282. ****************
  283. * Routine to print to CLI.
  284. *
  285. climsg        exg    d6,a6        ; Error string pointer in A2
  286.         jsr    _LVOOutput(a6)
  287.         move.l    d0,d1
  288.         beq.s    noout        ; No output channel
  289.  
  290.         move.l    a2,d2        ; Compute string length
  291. 1$        tst.b    (a2)+
  292.         bne.s    1$
  293.         suba.l    d2,a2
  294.         move.l    a2,d3
  295.         subq.l    #1,d3
  296.         jsr    _LVOWrite(a6)    ; Write string
  297. noout        exg    d6,a6
  298.         moveq    #0,d2
  299.         rts
  300.  
  301.  
  302. ****************
  303. * Relocation table.  Contains pointers to addresses to be moved.
  304. *
  305. RelTable    dc.l    RL0,RL1,RL2,RL3,RL4,RL5,RL6,RL7,RL8,0
  306.  
  307. * Diagnostic strings.
  308. *
  309. dosname        dc.b    'dos.library',0
  310. BPD.msg        dc.b    'BPD ',0
  311. already.msg    dc.b    'already '
  312. installed.msg    dc.b    'installed.',10,0
  313. not.msg        dc.b    'not ',0
  314. notecs.msg    dc.b    'ECS Agnus not present.',10,0
  315. nomem.msg    dc.b    'No memory for resident RomTag.',10,0
  316. removed.msg    dc.b    'removed.',10,0
  317. usage.msg    dc.b    'This program may be freely distributed.',10,10
  318.         dc.b    'Usage: BPD [REMOVE | NTSC]',10,0
  319. change.msg    dc.b    'Change will take effect on next reboot.',10,0
  320.  
  321.  
  322. ************************************************************************
  323. * The resident stuff intended to survive reboot.
  324. *
  325. ResStart:    cnop    0,2
  326.  
  327. * The Resident structure.
  328. *
  329. RomTag:                    ;STRUCTURE RT,0
  330.         dc.w    RTC_MATCHWORD    ;   UWORD RT_MATCHWORD
  331. RL0:        dc.l    RomTag        ;   APTR  RT_MATCHTAG
  332. RL1:        dc.l    ResEnd        ;   APTR  RT_ENDSKIP
  333.         dc.b    RTF_COLDSTART    ;   UBYTE RT_FLAGS
  334.         dc.b    1        ;   UBYTE RT_VERSION
  335.         dc.b    NT_BOOTNODE    ;   UBYTE RT_TYPE
  336.         dc.b    TAG_PRI        ;   BYTE  RT_PRI
  337. RL2:        dc.l    Name        ;   APTR  RT_NAME
  338. RL3:        dc.l    ID        ;   APTR  RT_IDSTRING
  339. RL4:        dc.l    PALTrick    ;   APTR  RT_INIT
  340.  
  341.  
  342. * The MemList.
  343. *
  344. MyMemList:                ; STRUCTURE ML,LN_SIZE
  345.                     ;    STRUCTURE  LN,0
  346.         dc.l    0        ;       APTR    LN_SUCC
  347.         dc.l    0        ;       APTR    LN_PRED
  348.         dc.b    NT_MEMORY    ;       UBYTE   LN_TYPE
  349.         dc.b    0        ;       BYTE    LN_PRI
  350. RL5:        dc.l    Name        ;       APTR    LN_NAME
  351.         dc.w    1        ;    UWORD   ML_NUMENTRIES
  352.                     ; STRUCTURE ME,0
  353. RL6:        dc.l    ResStart    ;    APTR    ME_ADDR
  354.         dc.l    RESIDENT_SIZ    ;    ULONG   ME_LENGTH
  355.  
  356.  
  357. * Array of pointers to RomTag structures describing things to be made
  358. * resident.  If the entry in the array has bit 31 set (0x80000000), then
  359. * the pointer (sans high bit) is in fact a pointer to *another* array of
  360. * RomTag pointers.  A NULL terminates the array.
  361. * (These also need relocation.)
  362. *
  363. RL7:
  364. MyKickTagPtr    dc.l    RomTag,0
  365. RL8:
  366. MyResModule    dc.l    RomTag,0
  367.  
  368.  
  369. * Name and ID strings.  (I wonder if Xoper will show these?)
  370. *
  371. Name        dc.b    'BPD.resident',0
  372. ID        dc.b    'BPD (Boot PAL, Dammit!) v1.1 by Leo L. Schwab  '
  373.         dc.b    '(11 Nov 1990)',13,10,0
  374.  
  375. ****************
  376. * Why we went to all this trouble.  Kind of anti-climactic, isn't it?
  377. * (PAL Now Brown Cow)
  378. *
  379. PALTrick:    btst.b    #6,$BFE001    ; Check mouse button
  380.         beq.s    palexit        ; If pressed, let user boot normally
  381.  
  382. movearg        EQU    *+2        ; The immediate argument to the MOVE
  383.         move.w    #$0020,$DFF1DC    ; Turn on PAL bit in ECS Agnus
  384. palexit:    moveq    #0,d0
  385.         rts
  386.  
  387. ResEnd        EQU    *
  388. RESIDENT_SIZ    EQU    ResEnd-ResStart    ; Size of preserved block.
  389.  
  390.         END
  391.