home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / basic / interpre / movbasic / movbasic.asm < prev    next >
Assembly Source File  |  1987-11-13  |  37KB  |  758 lines

  1. ;
  2. Title   MOVBASIC        3-3-86  [9-17-86] [11-13-87 (Yes, FRIDAY the 13TH)]
  3. Page    80,132
  4.  
  5. ;******************************************************************************
  6. ;     This is version 5.0 of MOVBASV4.ARC that was circulating on the BBSs
  7. ;******************************************************************************
  8. ;                            by JP (Orlando Fl)
  9. ;------------------------------------------------------------------------------
  10. ;  Even though the BBS description said it was Version 4 , this programs
  11. ; internal messages indicate that it is Version 3.1
  12. ;
  13. ;            !!!!!  THIS VERSION HAS SEVERAL BUG FIXES   !!!!!
  14. ;
  15. ;
  16. ;          1). THIS VERSION TRULY SUPPORTS A 80x86 PROCESSORS
  17. ;
  18. ;               as written  (and a truly innovative and inspired work!!)
  19. ;              the program uses "self modifying code". On a PC or 8086/88
  20. ;              the program would work because the 808x has a hardware
  21. ;              4 byte intruction pre-fetch buffer.
  22. ;
  23. ;              HOWEVER.. the 80x86 based cpus have a larger prefetch
  24. ;              queue, 6-8 bytes (depending on 80x86). When you have
  25. ;              an instruction modifying code immediately after the
  26. ;              modifying instruction, THIS WILL NOT WORK, because the
  27. ;              the next instruction is not in memory but in the pre-fetch
  28. ;              queue (SEE!).. The FIX is a few NOPS so that the instructions
  29. ;              to be modified are STILL in memory and CAN be modified.
  30. ;
  31. ;
  32. ;                 **  THE RULE : DON'T WRITE SELF-MODIFYING CODE **
  33. ;
  34.  
  35. ;          2). This modified version INCREASES the stack so you can trace
  36. ;             the startup IPL code. The stack in version 3.1 was 1 byte
  37. ;             above the startup code and since the stack writes down in
  38. ;             memory, a trace would overwrite startup code before you got
  39. ;             going good.
  40.  
  41. ;          3). ALSO, code was added to initialize the program work areas
  42. ;             to zeros. If you did not , then each time you ran MOVBASIC
  43. ;             the first few bytes of each SBASICx would be garbage and
  44. ;             would not cause an equal compare to a previous SBASICx.
  45.  
  46. ;          4). The calculation of the NEGATIVE CHECKSUM for the .EXE
  47. ;             IS NOT necessary , DOS does NOT use it at all to to
  48. ;             verify the validity of the .EXE module. I believe it
  49. ;             is being calculated incorrectly anyway, SO NO LOSE.
  50.  
  51.  
  52. ;
  53. ;******************************************************************************
  54. ;This program must be run on an IBM-PC or IBM-PC/AT or PS/2 with ROMS installed
  55. ;******************************************************************************
  56. ;
  57. ;   ** BASIC.COM and BASICA.COM must reside in same directory as MOVBASIC. **
  58. ;
  59. ;    The program takes IBM BASIC.COM or BASICA.COM and combines it with the
  60. ;  ROM image to create a new file called SBASIC.COM or SBASICA.COM, and
  61. ;  it now works with files above 32k such as PC-DOS 3.2/3.3 file, BASICA.COM
  62. ;
  63. ;    Also note, that for IBM version 3.3 there is no longer a BASIC.COM.
  64. ;     There is only a BASICA.COM. The stub program BASIC.COM just loads
  65. ;    BASICA.COM instead.
  66. ;
  67. ;       So , for IBM PC DOS 3.3 DONT run MOVBASIC against BASIC.COM
  68. ;       -----------------------------------------------------------
  69. ;
  70. ;    These new programs can be run on clones with out the copyrighted IBM
  71. ;    ---------------------------------------------------------------------
  72. ;    basic ROMS, and will act as if they were running on a true IBM-PC
  73. ;    -------------------------------------------------------------------
  74. ;
  75. ;   Works great, type MOVBASIC and follow the prompts...
  76. ;
  77. ;  To generate the executable MOVBASIC.COM file, please type
  78. ;
  79. ;       MASM MOVBASIC;
  80. ;       LINK MOVBASIC;
  81. ;       EXE2BIN MOVBASIC.EXE MOVBASIC.COM
  82. ;       DEL MOVBASIC.EXE
  83. ;       DEL MOVBASIC.OBJ
  84. ;
  85. ;
  86. ;   Since "EXE2BIN" is no longer included with DOS 3.3 use the
  87. ;   "public domain" version on BBSs called : "EXE2COM". It is included
  88. ;   with this ARC version of MOVBASIC version 5.0.
  89. ;
  90.  
  91. ;
  92. lf      equ     0Ah                             ; Ascii carriage return
  93. cr      equ     0Dh                             ; Ascii line     feed
  94. ;
  95. fcb     equ     5Ch                             ; Address of FCB in PSP
  96. fixmax  equ     50h                             ; Maximum number of fixups
  97. ;
  98. ;
  99. prog    segment
  100.         assume  cs:prog ,ds:prog, es:prog ,ss:prog
  101.         org     0100h
  102. start:
  103.         jmp     main
  104. ;
  105. ;
  106. ;*****************************************************************************
  107. ; MODIFIED : 11-13-87 by JP (Orlando Fl)
  108. ;
  109. ;            Moved all data to start of program (for my own reasons.)
  110. ;
  111. ;*****************************************************************************
  112.  
  113. rommsg  db      cr,lf
  114.         db      'Please run this program on an IBM computer with'
  115.         db      ' the basic ROMS installed',cr,lf,7,'$'
  116.  
  117. tries   db      2                               ; Attempts before we give up
  118. ;
  119. banner  db      cr,lf,lf
  120.         db      '               BASIC Relocation Utility Version 5.00'
  121.         db      cr,lf,lf,
  122.         db      '                           [11-13-87]'
  123.         db      cr,lf,
  124.         db      '                        Friday the 13th'
  125.         db      cr,lf,
  126.         db      '                        JP (Orlando fl)'
  127.         db      cr,lf,lf,
  128.  
  129.         db      'This program will convert BASIC.COM or BASICA.COM into'
  130.         db      ' SBASIC[A].COM which is',cr,lf
  131.         db      'usable on CLONE COMPUTERs that do not have IBM`s patented '
  132.         db      'BASIC ROMs installed',cr,lf,lf
  133.         db      'If you have BASIC[A].COM on non-default drive',2Ch
  134.         db      'then specify that in the command ',cr,lf
  135.         db      'line. For ex. MOVBASIC A:BASIC B: will create SBASIC.'
  136.         db      'COM on the B: drive. ',cr,lf,lf
  137.         db      'Select BASIC to patch for CLONE (non-IBM) computer'
  138.         db      cr,lf,lf
  139.         db      '              1. BASIC.COM   -->  SBASIC.COM',cr,lf
  140.         db      '              2. BASICA.COM  -->  SBASICA.COM',cr,lf
  141.         db      '        -->   $'
  142. ;
  143. filmsg  db      cr,lf,'Cannot find specified file.  Please retry.',7,'$'
  144. ;
  145. ifile   db      0                               ; Disk number
  146.         db      'BASIC'                         ;  ...filename
  147. ifpat   db      '   '                           ;  ...possibly 'A'
  148.         db      'COM'                           ;  ...extension
  149. ;
  150. ; *** Start of real FCB structure for output file
  151. ;
  152. ofile   db      0                               ; Disk number
  153.         db      'SBASIC'                        ;  ...filename
  154. ofpat   db      ' '                             ;  ...possibly 'A'
  155.         db      ' COM'                          ;  ...extension
  156.         dw      0                               ; Current record in FCB
  157. orecl   dw      0                               ; Output record size
  158.         db      11h dup(0)                      ;  ...rest of FCB
  159. orecn   dw      0,0                             ; Output record number
  160. ;
  161. ; *** End of real FCB structure for output file
  162. ;
  163. bigmsg  db      cr,lf
  164.         db      'Your BASIC file is too big',cr,lf,7,'$'
  165. commsg  db      cr,lf
  166.         db      'Not COM file',cr,lf,7,'$'
  167. cremsg  db      cr,lf
  168.         db      'Can',27h,'t create SBASIC',cr,lf,7,'$'
  169. dskmsg  db      cr,lf
  170.         db      'Output disk full',cr,lf,7,'$'
  171. fulmsg  db      cr,lf
  172.         db      'Too many fixups',cr,lf,7,'$'
  173.  
  174. ;
  175. ;
  176. Main    proc    near                            ;Main procedure
  177. ;
  178. ; MODIFIED 11-13-87 : turn interrupts off during stack switch  (to be safe)
  179. ;
  180.         cli
  181.         mov     sp,offset start                 ; ..use   local stack
  182.         sti
  183. ;
  184. ; MODIFIED 11-13-87 : following call added to clear progarm memory
  185. ;
  186.         call    clear                           ; ..clear rest of our segment
  187.  
  188.         call    copy                            ; ..read  ROM
  189.         call    rfile                           ; ..read  BASICx.COM
  190.         call    fixup                           ; ..scan  BASICx.COM for Fixups
  191.         call    sizit                           ; ..find  size, save in HDR
  192. ;
  193. ; MODIFIED 11-13-87 :the call to chksum was commented out (not necessary)
  194. ;
  195.         call    chksum                          ; ..save  chksum     in HDR
  196.         call    wfile                           ; ..write Fixups+ROM+BASICx.COM
  197.         int     20h                             ; ..all done, back to DOS
  198. main    endp                                    ; ..end of main procedure
  199.  
  200. ;
  201. ;
  202. subttl  clear - procedure to clear programs working memory (good housekeeping)
  203. clear   proc    near                            ; zero the rest of our segment
  204.         push    ax                              ; save some regs
  205.         push    cx
  206.         push    di
  207.         cld                                     ; set forward reference
  208.         xor     ax,ax                           ; figure difference from top
  209.         mov     bx,0ffffh                       ; of program to end of working
  210.         mov     di,offset fixups                ; code AND zero it out
  211.         sub     bx,di
  212.         repz    stosb
  213.         pop     di                              ; restore regs
  214.         pop     cx
  215.         pop     ax
  216.         ret
  217. clear   endp
  218.  
  219. ;
  220. ;
  221. subttl  copy - procedure to make copy of hardware 'ROM' basic
  222. copy    proc    near                            ; Makes copy of ROM
  223.         xor     ax,ax                           ; ...get bios data
  224.         mov     ds,ax                           ; ...area in ds seg
  225.         mov     bx,60h                          ; ...BX --> basic in 'ROM's
  226.         mov     ax,[bx+0]                       ; Check ibm ROM vector offset
  227.         or      ax,ax                           ; ...offset must be zero
  228.         jnz     badrom                          ; ...else no IBM roms
  229.  
  230.         mov     ax,[bx+2]                       ; Check ibm ROM vector segment
  231.         cmp     ax,0F600h                       ; ...must begin at F600
  232.         jnz     badrom                          ; ...else no IBM roms
  233.  
  234.         mov     ds,ax                           ; AX --> IBM rom segment
  235.  
  236.         mov     cx,8000h                        ; CX ==  size of ROM basic
  237.         mov     di,offset ibmbas                ; DI --> Private 'ROM' offset
  238.         mov     si,0                            ; SI --> IBM     'ROM' offset
  239.         cld                                     ;  ...direction forwards
  240.         repz    movsb                           ; Copy IBM rom into 'ROM' area
  241.         push    cs                              ;  ...then restore
  242.         pop     ds                              ;  ...data segment
  243.         ret                                     ; All done, back to caller
  244. ;
  245. badrom:
  246.         push    cs                              ; Restore the
  247.         pop     ds                              ;  ...data segment
  248.         mov     dx,offset rommsg                ; DX --> error message
  249.         jmp     near ptr errxit                 ;  ...print and expire
  250. copy    endp                                    ; End of copy procedure
  251.  
  252. ;
  253. ;
  254. ;
  255. subttl  rfile - procedure to read contents of original ibm BASICx.COM file
  256. rfile   proc    near                            ; Procedure reads BASICx.COM
  257.         mov     al,byte ptr ds:fcb+01h          ; AL = First char of filename
  258.         cmp     al,20h  ;' '                    ;  ...was filename specified
  259.         jz      menu                            ;  ...no, then prompt for it
  260.  
  261.         mov     al,byte ptr ds:fcb+10h          ; Was a disk number specified?
  262.         cmp     al,0Fh                          ;  ...valid only up to 0Fh
  263.         jb      disk                            ; Else force default disk
  264.  
  265.         xor     al,al                           ;  ...by zeroing disk number
  266. ;
  267. disk:
  268.         mov     ofile,al                        ; Save disk number in FCB
  269.         jmp     short   try                     ;  ...try to open file
  270. ;
  271. menu:
  272.         call    prompt                          ; Print selection for user
  273. try:
  274.         mov     di,offset fcb+09h               ; DI --> extension in FCB
  275.         mov     ax,04F43h                       ; AX ==  'CO'
  276.         cld                                     ;  ...clear direction
  277.         stosw                                   ;  ...save 'CO' in extension
  278.         mov     al,4Dh  ;'M'                    ; AL ==  'M'
  279.         stosb                                   ;  ...save 'M' in extension
  280.         mov     cx,1Eh                          ; CX == byte count for reset
  281.         xor     al,al                           ; AL == what to put in bytes
  282.         repz    stosb                           ;  ...reset remainder of FCB
  283.         mov     ah,0Fh                          ; AH == open existing file
  284.         mov     dx,offset fcb                   ; DX --> fcb for this file
  285.         int     21h                             ;  ...try to open the file
  286.         or      al,al                           ;Test the return code from DOS
  287.         jz      opened                          ;  ...all is ok
  288.  
  289.         mov     dx,offset filmsg                ; Else DX --> nasty message
  290.         mov     ah,09h                          ;  ... AX ==  DOS print request
  291.         int     21h                             ;  ... let DOS complain
  292.         dec     byte ptr tries                  ; One less retry (began with 2)
  293.         jnz     menu                            ;  ... has second chance
  294.  
  295.         int     20h                             ; Else call the terminator
  296. ;
  297. opened:
  298.         mov     word ptr ds:fcb+0Eh,01h         ; Records are 1h bytes long
  299.         push    ds                              ; Save data segment
  300.         mov     ah,1Ah                          ; AH == set disk xfer address
  301.         mov     bx,ds                           ; Get current segment
  302.         add     bx,800h                         ;  ...point beyond ROMs
  303.         mov     ds,bx                           ; Load into DS segment
  304.         mov     dx,offset ibmbas                ;  ...xfer address = 'ROM'end
  305.         int     21h                             ;  ...tell DOS to set address
  306.         pop     ds                              ; Restore data segment
  307.         mov     ah,27h                          ; Attempt to read entire file
  308.         mov     cx,offset 0FFFFh                ;  ...only up to 64k bytes
  309.         mov     dx,offset fcb                   ;  ...with this FCB
  310.         int     21h                             ;  ...into disk xfer address
  311.         cmp     al,01h                          ; Must return end_of_file
  312.         jnz     huge                            ;  ...else file is oversize
  313.  
  314.         cmp     ds:ibmbas+8000h,5A4Dh           ; Is file a COM file?
  315.         je      exefil                          ;  ...no, can't move it
  316.  
  317.         mov     word ptr ds:ifsize,cx           ; Save size in 1h byte blocks
  318.         ret                                     ;  ...all done read, return
  319. ;
  320. huge:
  321.         jmp     near ptr toobig                 ;  ...else can't convert
  322. exefil:
  323.         jmp     near ptr notcom                 ;  ...not a COM file
  324. rfile   endp                                    ; End of read file procedure
  325. ;
  326. ;
  327. subttl  prompt - procedure to get filename from user
  328. prompt  proc    near                            ; Prompt for BASICx file name
  329.         mov     dx,offset banner                ; DX --> display
  330.         mov     ah,09h                          ; AH ==  print string
  331.         int     21h                             ;  ...ask DOS to print prompt
  332.         mov     ah,01h                          ; Read reply from console
  333.         int     21h                             ;  ...this DOS request
  334.         sub     al,31h                          ; Was it choice #1?
  335.         jz      newnam                          ;  ...yup
  336.  
  337.         cmp     al,01h                          ; Was it choice #2?
  338.         jnz     prompt                          ;  ...nope, must be 1 or 2
  339.  
  340.         mov     byte ptr ifpat,41h      ;'A'    ; Add 'A' to end of filename
  341. ;
  342. newnam:
  343.         mov     si,offset ifile                 ; Pack explicit name
  344.         mov     di,offset fcb                   ;  ...into input FCB
  345.         mov     cx,0Ch                          ;  ...length of name
  346.         cld                                     ; Clear direction flag
  347.         repz    movsb                           ; ...copy name there
  348.         mov     cx,18h                          ; ...reset input FCB
  349.         xor     al,al                           ; ...write zero to it
  350.         repz    stosb                           ; ...with instruction
  351.         ret                                     ; Back to caller
  352. prompt  endp                                    ; ...end of procedure
  353. ;
  354. ;
  355. subttl  fixup - procedure to build table of fixup offsets
  356. fixup   proc    near                            ; Revector ROM references
  357.         mov     bx,offset ibmbas                ; BX => BASICx.COM in memory
  358.         mov     cx,word ptr ds:ifsize           ; CX == Size in 1h byte blocks
  359.         mov     dx,0F600h                       ; DX == hardware (ROM) address
  360.         push    ds                              ; Save data segment
  361.         mov     ax,ds                           ; Get data segment
  362.         add     ax,800h                         ;  ...move beyond ROMs
  363.         mov     ds,ax                           ; Load into data  segment
  364.         mov     di,offset fixups                ; DI -> start of fixup table
  365.         cld                                     ; ...clear direction flag
  366. ;
  367. fixing:
  368.         cmp     dx,[bx]                         ; BASICx.COM want ROM segment?
  369.         jnz     next                            ;  ...no, do not alter
  370.  
  371.         call    lookup                          ; Should seg. ref. be fixed up?
  372.         jnz     next                            ;  ...flag 'Z' clear if no
  373.  
  374.         mov     ax,bx                           ; Get address that needs fixup
  375.         sub     ax,offset ibmbas                ;  ...find BASICx.COM offset
  376.         stosw                                   ; Store offset in fixups table
  377.         inc     word ptr cs:nfixes              ;  ...one more offset in table
  378. next:
  379.         inc     bx                              ; Scan the next byte
  380.         loop    fixing                          ;  ...until done BASICx.COM
  381.  
  382.         pop     ds                              ; Restore Data segment
  383.         cmp     word ptr ds:nfixes,fixmax       ; Did fixup table overflow?
  384.         ja      loaded                          ;  ...jump if so
  385.  
  386.         ret                                     ; Else end of fixup procedure
  387. ;
  388. loaded:
  389.         jmp     near ptr tooful                 ; Fixup table overloaded
  390. ;
  391. fixup   endp                                    ;  ...show end
  392.  
  393. ;
  394. subttl  lookup - find if offset into BASICx.COM needs fixup
  395. ;
  396. ; Lookup - procedure sets 'Z' flag if this F600h reference needs a fixup
  397. ;
  398. lookup  proc    near                            ; See if reference needs fixup
  399.         cmp     byte ptr [bx-3],0EAh
  400.         jz      found
  401.         cmp     byte ptr [bx-1],0B8h
  402.         jz      found
  403.         cmp     byte ptr [bx-1],0BBh
  404.         jz      found
  405.         cmp     byte ptr [bx-1],0BEh
  406.         jz      found
  407.         cmp     byte ptr [bx-1],0BAh
  408.         jz      found
  409.         cmp     byte ptr [bx-1],0BFh
  410.         jz      found
  411.         cmp     byte ptr [bx-1],0B9h
  412.         jz      found
  413.         cmp     byte ptr [bx-3],09Ah
  414.         jz      found
  415.         cmp     word ptr [bx-4],06C7h
  416.         jz      found
  417.         cmp     word ptr [bx-4],87C7h
  418.         jz      found
  419.         cmp     word ptr [bx-4],84C7h
  420.         jz      found
  421.         cmp     word ptr [bx-4],85C7h
  422.         jz      found
  423.         cmp     word ptr [bx-4],86C7h
  424.         jz      found
  425.         cmp     word ptr [bx-3],46C7h
  426.         jz      found
  427.         cmp     word ptr [bx-3],47C7h
  428.         jz      found
  429.         cmp     word ptr [bx-3],44C7h
  430.         jz      found
  431.         cmp     word ptr [bx-3],45C7h
  432.         jz      found
  433.         cmp     word ptr [bx-2],07C7h
  434.         jz      found
  435.         cmp     word ptr [bx-2],04C7h
  436.         jz      found
  437.         cmp     word ptr [bx-2],05C7h
  438. found:
  439.         ret                                     ; Return, result in Z flag
  440. lookup  endp                                    ;  ...end of procedure
  441.  
  442. ;
  443. ;
  444. subttl  sizit - procedure to find size of SBASIC.COM and save in HDR
  445. sizit   proc    near
  446.         mov     ax,offset ibmbas-hdr            ; Get header size into AX
  447.         add     ax,8000h                        ;  ...add size of ROM set
  448.         add     ax,word ptr ifsize              ;  ...and input file size
  449.         push    ax                              ; Save copy of file size
  450.         mov     cl,09h                          ;  ...find number of blocks
  451.         rcr     ax,cl                           ;  ...by 9 bit right shift
  452.         and     ax,0FFh                         ;  ...0FFh blocks maximum
  453.         inc     ax                              ; I dunno, but DOS wants it
  454.         mov     word ptr hdr+04h,ax             ; Save number of blocks in hdr
  455.         pop     ax                              ;  ...get low order 16 bits
  456.         and     ax,01FFh                        ; Isolate the block fraction
  457.         mov     word ptr hdr+02h,ax             ;  ...and save in hdr word
  458.         ret                                     ;  ...return to caller
  459. sizit   endp
  460. ;
  461.  
  462. ;
  463. subttl  chksum - procedure to calculate and store negative checksum of file
  464. chksum  proc    near
  465.         xor     ax,ax                           ; Prepare a zero
  466.         mov     dx,word ptr hdr+04h             ; Load block count
  467. chks01:
  468.         mov     si,offset movrom                ; si --> blk start
  469.         dec     dx                              ;  ...show one less
  470.         js      chks03                          ; Negative if done
  471.  
  472.         mov     cx,0100h                        ;  ...words in block
  473. chks02:
  474.         sub     ax,[si]                         ; Subtract word
  475.         add     si,02h                          ;  ...point to next
  476.         loop    chks02                          ;  ...go until done
  477.  
  478.         mov     bx,ds                           ;  ...get a copy
  479.         add     bx,0020h                        ;  ...Go to next blk
  480.         mov     ds,bx                           ;  ...and save in ds
  481.         jmp     chks01                          ;  ...back for next
  482.  
  483. chks03:
  484.         mov     cx,offset hdr+02h               ; Get fraction blk
  485.         shr     cx,01h                          ;  ...into words
  486.         jcxz    chks05                          ; Zero if all done
  487.  
  488. chks04:
  489.         sub     ax,[si]                         ; Subtract word
  490.         add     si,02h                          ;  ...point to next
  491.         loop    chks04                          ;  ...go until done
  492.  
  493. chks05:
  494.         push    cs                              ; Get code segment
  495.         pop     ds                              ;  ...restore ds
  496.         mov     word ptr hdr+12h,ax             ; Negative chksum
  497.         ret                                     ;  ...return caller
  498. chksum  endp
  499. ;
  500.  
  501. ;
  502. subttl  wfile - procedure to write new SBASICx.COM file
  503. wfile   proc    near                            ; Procedure writes BASICx.COM
  504.         mov     al,byte ptr ds:fcb+06h          ; Last character of filename
  505.         cmp     al,41h                          ;  ...does it end in 'A'?
  506.         jnz     around                          ;  ...no, leave it alone
  507.  
  508.         mov     ofpat,al                        ;  ...else copy 'A'
  509. around:
  510.         mov     ah,16h                          ; Create output file
  511.         mov     dx,offset ofile                 ;  ...with (patched) FCB
  512.         int     21h                             ;  ...with system call
  513.         or      al,al                           ; Did the create work?
  514.         jnz     dskcre                          ;  ...say disk is full
  515.  
  516.         mov     word ptr orecl,01h              ; Records are 1 byte long
  517.         mov     cx,offset ibmbas-hdr            ;  ...overhead in bytes
  518.         add     cx,8000h                        ;  ...rom size in bytes
  519.         jc      toobig                          ; Out of memory, complain(?!)
  520.  
  521.         mov     ah,1Ah                          ; Set disk transfer address
  522.         mov     dx,offset hdr                   ;  ...to our start-up code
  523.         int     21h                             ;  ...with this call
  524.         mov     dx,offset ofile                 ; DX --> Output FCB
  525.         mov     ah,28h                          ;  ...write patched file
  526.         int     21h                             ;  ...with system call
  527.         or      al,al                           ; Did the write succeed?
  528.         jnz     dskful                          ;  ...no, say disk is full
  529.  
  530.         mov     word ptr orecn,cx               ; Point to next record
  531.         push    ds                              ;  ...save a copy
  532.         mov     ax,ds                           ; Get data segment
  533.         add     ax,800h                         ;  ...go beyond roms
  534.         mov     ds,ax                           ;  ...reload new segment
  535.         mov     ah,1Ah                          ; Set disk transfer address
  536.         mov     dx,offset ibmbas                ;  ...where to set it to
  537.         int     21h                             ; Set disk transfer address
  538.         pop     ds                              ;  ...restore old segment
  539.         mov     ah,28h                          ; Write unpatched BASICx.COM
  540.         mov     cx,word ptr ifsize              ;  ...input file (bytes)
  541.         mov     dx,offset ofile                 ; Write more stuff out
  542.         int     21h                             ;  ...with this call
  543.         or      al,al                           ; Did the write succeed?
  544.         jnz     dskful                          ;  ...no, say disk is full
  545.  
  546.         mov     ah,10h                          ; Worked, then close file
  547.         mov     dx,offset ofile                 ; DX --> output FCB
  548.         int     21h                             ; Issue the dos call
  549.         or      al,al                           ;  ...did it close?
  550.         jnz     dskful                          ; No, complain
  551.  
  552.         ret                                     ;  ...else back to caller
  553. ;
  554. tooful:
  555.         mov     dx,offset fulmsg                ; Fixup table overflowed
  556.         jmp     short   errxit                  ;  ...on terminal
  557. ;
  558. toobig:
  559.         mov     dx,offset bigmsg                ;Complain, file is too big
  560.         jmp     short   errxit                  ; ...jump to print message
  561. ;
  562. notcom:
  563.         mov     dx,offset commsg                ;Not a COM file, complain
  564.         jmp     short   errxit                  ; ...jump to print message
  565. ;
  566. dskcre:
  567.         mov     dx,offset cremsg                ;Complain about open error
  568.         jmp     short   errxit                  ;  ...jump to print message
  569. ;
  570. dskful:
  571.         mov     dx,offset dskmsg                ;Complain about disk full
  572. ;
  573. errxit:
  574.         mov     ah,09h                          ; Function = print message
  575.         int     21h                             ;  ...ask DOS to type it
  576.         int     20h                             ; Then call the terminator
  577. wfile   endp                                    ;  ...end write file procedure
  578.  
  579. ;
  580.  
  581. subttl  hdr - everything beyond here added to SBASICx.COM image file
  582.  
  583. ;******************************************************************************
  584. ;
  585. ;
  586. ;
  587. ;
  588. ;
  589. ;
  590. ;******************************************************************************
  591. ;
  592. extra   equ     27FFh                           ; Minimum paragraphs to run
  593. ;
  594. hdr     label   byte                            ; Header for SBASICs.COM
  595.         db      4Dh,5Ah                         ;  ...image .EXE type
  596.         dw      ?                               ; Fraction of block
  597.         dw      ?                               ; Blocks in image
  598.         dw      0h                              ; Number of relocations
  599.         dw      (0Fh+base-hdr)/10h              ; Header size in paragraphs
  600.         dw      (0Fh+fixups-ipl)/10h+extra      ; Minimum paragraphs to run
  601.         dw      0FFFFh                          ; Maximum paragraphs to run
  602.         dw      0h                              ; Offset for SS register
  603.         dw      tos-base                        ;  ...value  SP register
  604. ;
  605. ; MODIFIED 11-13-87 : initialized negative checksum to zeros
  606. ;
  607.         dw      0h                              ; Negative checksum
  608.  
  609.         dw      0h                              ; Offset for IP register
  610.         dw      0h                              ;  ...value  CS register
  611.         dw      ?                               ; Byte disp of reloc. list
  612.         dw      0                               ;  ...not an overlay
  613. ;
  614.         dw      2 dup(?)                        ; Align on paragraph boundary
  615. ;
  616. ;
  617. subttl  img - everything beyond here will appear in memory when image is loaded
  618. ;******************************************************************************
  619. ;
  620. ; Everything below this line will appear in the output SBASICx.COM image, and
  621. ; will appear in memory when this image is loaded.  Memory offsets as follows
  622. ;
  623. ;
  624. ; MODIFIED 11-13-87 :  the following address may/will no longer be correct
  625. ;                     as MOVBASIC restructured, to MY my.. JP.
  626. ;
  627. ;       0000h  ==  Start of PSP  (Program Segment Prefix - not part of image )
  628. ;base:  0100h  ==  Symbol GO     (Setup COM environment in CS,DS and go there)
  629. ;       0111h  ==  Symbol MOVROM (check memory, copy basic ROM to high memory)
  630. ;       0139h  ==  Symbol RUNFIX (apply fixups to original BASICx.COM  image )
  631. ;       0152h  ==  Symbol MOVIPL (moves IPL code to stack area for execution )
  632. ;       0169h  ==  Symbol IPL    (moves ibm BASICx.COM to 0100h and starts it)
  633. ;       0192h  ==  Symbol FIXUPS (list of offsets into BASICx.COM for fixups )
  634. ;       0232h  ==  Symbol IBMBAS (copy  of ibm basic ROM set, without patches)
  635. ;       8232h  ==                (original ibm BASICx.COM without fixups done)
  636. ;end:   ????h  ==                (end BASICx.COM  May not exceed 96k in total)
  637. ;
  638. ;*****************************************************************************
  639.  
  640. base    label   byte                            ; At run-time appears at 0100h
  641.  
  642. ;
  643. go      proc    far                             ; Setup regs like COM file
  644.         cli                                     ; No interrupts for now !!!
  645.         mov     ax,cs                           ;  ...get code segment
  646.         sub     ax,10h                          ;  ...then point to PSP
  647.         mov     ds,ax                           ;  ...load into Data Segment
  648.         mov     ds:(100h+goseg-base),ax         ;  ...save copy for CS
  649. ;
  650. ; MODIFIED 11-13-87 : nops added to keep code to be modified in memory
  651. ;
  652.         db      8d DUP(90H)                     ; keeps following code in memory
  653.  
  654.         db      0EAh                            ; Jump far
  655. gooff   dw      100h+movrom-base                ;  ...offset  for IP
  656. goseg   dw      ?                               ;  ...segment for CS
  657. go      endp
  658.  
  659. ;
  660. ; MODIFIED 11-13-87 : stack space increased to allow traceing of startup code
  661. ;
  662.         EVEN                                    ; force to even address boundry
  663.         dw      20h  dup(0)                     ; Bootstrap  32 words for stack
  664.  
  665. tos     label   word                            ; Procedure GO becomes stack
  666.  
  667. ;
  668. ;
  669. movrom  proc    near                            ; Routine relocates ROM up hi
  670.         sti
  671.         mov     si,offset ibmbas+100h-base      ; SI -> where 'ROM's live now
  672.         mov     di,0                            ; DI -> where 'ROM's will  be
  673.         mov     ax,cs                           ; Get our code segment
  674.         add     ax,extra-8FFh                   ;   + minimum memory required
  675.         xor     al,al                           ;  ...round down to even 4K
  676.         push    ax                              ; Run-time segment for ROM set
  677.         mov     es,ax                           ;  ...load into es for movsb
  678.         mov     cx,8000h                        ; Bytes in basic 'ROM' set
  679.         cld                                     ;  ...clear the direction
  680.         repz    movsb                           ; Move ROMs from BASIC data area
  681.         mov     di,si                           ; DI -> where BASICx.COM is now
  682.         xor     ax,ax                           ; Prepare es segment to
  683.         mov     es,ax                           ;  ...access vector area
  684.         mov     bx,60h                          ; BX --> Basic vector into ROM
  685.         pop     dx                              ; DX --> run-time 'ROM' segment
  686.         mov     es:[bx+2],dx                    ;  ...save 'ROM' seg. in vector
  687.         mov     es:[bx+0],ax                    ;  ...the  'ROM' offset is zero
  688. movrom  endp                                    ; End of copy_rom procedure
  689.  
  690. ;
  691. ;
  692. runfix  proc    near                            ; Routine does runtime fixups
  693.         mov     cx,0000h                        ; CX == number of fixups
  694. nfixes  =$ - 02h                                ;  ...self-modifying code, ugh!
  695.         mov     si,offset fixups+100h-base      ; SI -> fixup table
  696.         mov     ax,ds                           ; Get data segment
  697.         add     ax,800h                         ;  ...go beyond ROMs
  698.         mov     es,ax                           ;  ...and save it
  699.         sub     di,8000h                        ; do this to avoid
  700. fixer:
  701.         lodsw                                   ; AX == offset into BASICx.COM
  702.         mov     bx,ax                           ;       copy offset into BX
  703.         mov     es:[bx+di],dx                   ; Fixup ROM ref. in BASICx.COM
  704.         loop    fixer                           ;  ..loop until all fixups done
  705.  
  706. runfix  endp                                    ; End of run-time fixup routine
  707.  
  708. ;
  709. ;
  710. movipl  proc    far                             ; Move IPL code to scratch area
  711.         mov     ax,cs                           ; Get code segment
  712.         add     ax,offset extra-9FFh            ;  ...find scratch area
  713.         xor     al,al                           ;  ...even boundary
  714.         push    ax                              ; Save scratch segment
  715.         pop     es                              ;  ...load into ES reg.
  716.         push    ax                              ; Save scratch segment
  717.         mov     di,0h                           ; DI -> where IPL code will run
  718.         push    di                              ; Save offset to IPL code
  719.         mov     si,offset ipl+100h-base         ; SI -> where IPL code  is  now
  720.         mov     cx,offset fixups-ipl            ; CX == size of IPL code, bytes
  721.         repz    movsb                           ;  ...copy IPL code to ipl area
  722.         ret                                     ;  ...start final IPL sequence
  723. movipl  endp                                    ; End of IPL relocate procedure
  724.  
  725. ;
  726. ;
  727. ipl     proc    far                             ; IPL code runs in  high memory
  728.         mov     cx,0000h                        ; CX == size of BASICx.COM file
  729. ifsize  =$ - 02h                                ;  ...self-modifying code, ugh!
  730.         mov     ax,ds                           ; Save code segment copy
  731.         mov     es,ax                           ;  ...load into extra seg
  732.         mov     word ptr cs:(iplseg-ipl),ax     ; Save code segment for ipl
  733.         add     ax,800h                         ;  ...skip over 32K roms
  734.         mov     ds,ax                           ; DS register --> ROM now
  735.         mov     si,offset ibmbas+100h-base      ; SI -> area BASICx.COM is now
  736.         mov     di,100h                         ; DI -> area BASICx.COM must go
  737.         repz    movsb                           ; Copy BASICx.COM to low memory
  738.         mov     ax,es                           ; Restore data segment
  739.         mov     ds,ax                           ;  ...equal to extra seg
  740.         mov     ss,ax                           ; Set stack seg for COM
  741.         mov     sp,0FFFEh                       ;  ...stack reg for COM
  742.         sti                                     ;  ...interrupts now safe
  743.  
  744.         db      0EAh                            ; JMP FAR segment:offset
  745. iploff  dw      100h                            ;  ...offset for COM file
  746. iplseg  dw      ?                               ;  ...Start  seg COM file
  747. ipl     endp                                    ;  ..end of IPL procedure
  748.  
  749. ;
  750. ;
  751.  
  752. fixups  label   word                            ; Fixups as offset in BASIC.COM
  753. ibmbas  equ     fixups + (2 * fixmax)           ; Contents of 'ROM's saved here
  754.  
  755. prog    ends
  756. ;
  757. end     start
  758.