home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 211.lha / ECPM / ecpm1.asm < prev    next >
Encoding:
Assembly Source File  |  1996-02-14  |  73.3 KB  |  1,941 lines

  1. vermaj   equ    $02     ;Major version number
  2. vermin   equ    $01     ;Minor version number
  3. revyear  equ    $88     ;Year last assembled
  4. revmonth equ    $06     ;Month last assembled
  5. revday   equ    $29     ;Day last assembled
  6. *************************************************************************
  7. *                                                                       *
  8. *                                                                       *
  9. *       8080/Z80 Simulator for MC68000                                  *
  10. *                                                                       *
  11. *       With CP/M 2.2 call support, and optional tracing                *
  12. *                                                                       *
  13. *                                                                       *
  14. *       Converted to AmigaDOS September 1987 by Charlie Gibbs           *
  15. *       (after painstakingly typing it all in from Dr. Dobbs            *
  16. *       Journal, January through March 1986).  Improvements             *
  17. *       described by Jim Cathey in his letter in the June 1986          *
  18. *       DDJ have been included.  Repetitive code is generated           *
  19. *       by macros whenever it would save my fingers.                    *
  20. *                                                                       *
  21. *                                                                       *
  22. *       Version 2.1 6/29/88 by Willi Kusche                             *
  23. *               Fixed a number of bugs                                  *
  24. *                 in existing Z80 op code emulation.                    *
  25. *               Added enough new Z80 op codes and BDOS calls            *
  26. *                 to allow Turbo Pascal V3.01A to be run.               *
  27. *                                                                       *
  28. *       Version 1.2 1/21/85 JEC                                         *
  29. *               Fixed Extent bug in OPEN logic.                         *
  30. *               Sped up code, sample MAC from 2:13 to 1:40              *
  31. *               Now runs at a 1.4 MHz equivalent based on MAC sample.   *
  32. *                                                                       *
  33. *       Version 1.1 8/29/84 JEC                                         *
  34. *               Fixed BIOS call #6 bug.                                 *
  35. *                                                                       *
  36. *       Version 1.0 05/25/84 by Jim Cathey                              *
  37. *                                                                       *
  38. *       This program has been written for speed whenever possible,      *
  39. *       as such tends to be large because of the separate subroutine    *
  40. *       for each and every opcode of the target processor.              *
  41. *                                                                       *
  42. *       On an 8MHz 68000 (Compupro) system the simulation speed is      *
  43. *       a little better than a 1MHz Z-80 when running MAC.  The time    *
  44. *       for a sample assembly was 2:13 for the simulation vs. 0:35      *
  45. *       on a 4MHz Z-80, both systems used identical hard disk systems.  *
  46. *                                                                       *
  47. *       It is not a complete simulation, as some flag handling          *
  48. *       isn't quite right, but it is enough to run the program          *
  49. *       I wrote for it (DDT, LU, MAC, and Morrow's FORMATW).            *
  50. *                                                                       *
  51. *************************************************************************
  52.         code
  53.         page
  54. *************************************************************************
  55. *                                                                       *
  56. *       This file contains the startup routines, the simulator core,    *
  57. *       tracing code, and the CP/M 2.2 simulation.                      *
  58. *                                                                       *
  59. *************************************************************************
  60.  
  61.         xref    optabl,flags,mloop,traceit,tracesad,traceead,traceflg
  62.         xdef    illegl,service,dump
  63.  
  64. * Changing this 'equ' to 0 will cause assembly errors
  65. h19     equ     1               ;Non-zero for H19 emulation
  66.  
  67. *
  68. * ASCII character values
  69. *
  70. bel     equ     $07             ;Bell (or beep or whatever)
  71. bs      equ     $08             ;Backspace
  72. ht      equ     $09             ;Horizontal tab
  73. lf      equ     $0A             ;Line feed
  74. ff      equ     $0C             ;Form feed
  75. cr      equ     $0D             ;Carriage return
  76. so      equ     $0E             ;Shift out
  77. si      equ     $0F             ;Shift in
  78. esc     equ     $1B             ;Escape
  79.  
  80.         INCLUDE   "ecpmdefs.i"
  81.         page
  82. *--------------------------------
  83. *
  84. * Some commonly used macros
  85. *
  86. *--------------------------------
  87.  
  88. sys     MACRO                   ;Call a system routine.
  89.         jsr     _LVO\1(a6)
  90.         ENDM
  91.  
  92. *----------------------------
  93. * Target system Mnemonics
  94. *----------------------------
  95. tHLT    EQU    $76
  96. tJMP    EQU    $C3
  97. tRET    EQU    $C9
  98.  
  99. *----------------------
  100. * Equates
  101. *----------------------
  102.  
  103. Absbase              EQU    4
  104. MODE_OLDFILE         EQU    1005
  105. MODE_NEWFILE         EQU    1006
  106. SHARED_LOCK          EQU    -2
  107. OFFSET_CURRENT       EQU    0
  108. ;
  109. ;  File Information Block Sructure
  110. ;
  111. fib_DiskKey          EQU    0
  112. fib_DirEntryType     EQU    4
  113. fib_FileName         EQU    8
  114. fib_Protection       EQU    116
  115. fib_EntryType        EQU    120
  116. fib_Size             EQU    124
  117. fib_NumBlocks        EQU    128
  118. fib_DateStamp        EQU    132
  119. fib_Comment          EQU    144
  120. fib_SIZEOF           EQU    260
  121.  
  122. *----------------------
  123. * External references
  124. *----------------------
  125.  
  126.         XREF    _LVOOpenLibrary
  127.         XREF    _LVOClose
  128.         XREF    _LVOCloseLibrary
  129.         XREF    _LVOCurrentDir
  130.         XREF    _LVODeleteFile
  131.         XREF    _LVODupLock
  132.         XREF    _LVOExamine
  133.         XREF    _LVOExNext
  134.         XREF    _LVOInput
  135.         XREF    _LVOIoErr
  136.         XREF    _LVOLock
  137.         XREF    _LVOOpen
  138.         XREF    _LVOOutput
  139.         XREF    _LVORead
  140.         XREF    _LVORename
  141.         XREF    _LVOSeek
  142.         XREF    _LVOUnLock
  143.         XREF    _LVOWaitForChar
  144.         XREF    _LVOWrite
  145.         page
  146. *************************************************************************
  147. *                                                                       *
  148. *       Initialization                                                  *
  149. *                                                                       *
  150. *************************************************************************
  151.  
  152. start:  move.l  sp,savesp       ;Save the stack pointer.
  153.         move.b  #1,testdol      ;"pstring" should test for leading $.
  154.         clr.w   esclen          ;No partial escape sequence is saved.
  155.         clr.b   insflag         ;We're not in insert mode.
  156.         clr.b   btrcflg         ;Turn off BIOS/BDOS call tracing.
  157.         clr.b   quitflg         ;Clear the quit flag.
  158.         clr.b   bufflag         ;Disable output buffering.
  159.         clr.b   listopn         ;The list device is closed.
  160.         move.l  #strbuf,strptr  ;Initialize output buffer pointer.
  161.  
  162.         lea     handles,a1
  163.         moveq   #(handlen-handles)/4-1,d1
  164. clrhand clr.l   (a1)+           ;Clear file handles.
  165.         dbra    d1,clrhand
  166.         clr.l   rawhand         ;Clear RAW: handle too.
  167.  
  168. *
  169. * Copy the command line to "cmdline", stripping out leading switches if any.
  170. *
  171.         lea     cmdline,a1
  172.         subq    #1,d0
  173. * Skip over leading blanks, if any.
  174. leadblk cmpi.b  #' ',(a0)+      ;Leading blank?
  175.         bne.s   bufparm         ;No.
  176.         dbra    d0,leadblk      ;Skip over leading blank.
  177. *  If the first parameter is "-b", skip over it but activate output buffering.
  178. bufparm subq.l  #1,a0           ;Back onto the first non-blank.
  179.         cmpi.b  #'-',(a0)       ;Possible buffer switch?
  180.         bne.s   savecmd         ;No - start saving the command line.
  181.         cmpi.b  #'B',1(a0)      ;Activate output buffering?
  182.         beq.s   setbuff         ;Yes.
  183.         cmpi.b  #'b',1(a0)
  184.         bne.s   skipsw          ;No.
  185. setbuff move.b  #1,bufflag      ;Set buffered-output flag.
  186. skipsw  cmpi.b  #' ',(a0)+      ;Skip over the switch.
  187.         beq.s   skipswx         ; and look for start of command line.
  188.         dbra    d0,skipsw
  189.         addq.l  #1,a1           ;Adjust A1.
  190.         bra.s   gotcmd          ;There is no command line left.
  191. skipswx subq.l  #1,a0           ;Back onto the first blank.
  192.         bra.s   leadblk         ;Look for the next non-blank.
  193. * Save the command line (except for leading switches).
  194. savecmd move.b  (a0)+,(a1)+     ;Save the command line, if any.
  195.         dbra    d0,savecmd
  196. gotcmd  move.b  #0,-1(a1)       ;Replace the newline with a null.
  197.         move.b  cmdline,cmdflag ;Save command-line flag.
  198.  
  199. *
  200. * Open libraries and set up a RAW: window.
  201. *
  202.         move.b  #1,quitflg      ;Quit immediately if failure below.
  203.         move.l  Absbase,a6      ;Find library
  204.         lea     dosname,a1      ;'dos.library'
  205.         moveq   #0,d0           ;Any version
  206.         sys     OpenLibrary     ;Open dos.library.
  207.         move.l  d0,a6           ;Point to doslib for next operation.
  208.         move.l  d0,dosbase      ;Save it for future reference.
  209.         sys     Input           ;Get file handle for keyboard.
  210.         move.l  d0,stdin        ;Save it here.
  211.         beq     quitprg         ;Couldn't get keyboard handle.
  212.         sys     Output          ;Get file handle for screen.
  213.         move.l  d0,stdout       ;Save it here.
  214.         beq     quitprg         ;Couldn't get screen handle.
  215.         move.l  #rawspec,d1
  216.         move.l  #MODE_NEWFILE,d2
  217.         sys     Open            ;Open a RAW: window.
  218.         move.l  d0,rawhand      ;Save the file handle here.
  219.         bne.s   opened          ;We succeeded.
  220.         move.l  #rawerr,d1
  221.         bsr     pstring         ;Display error message...
  222.         sys     IoErr
  223.         move.l  d0,d1
  224.         bsr     plong           ; and error code.
  225.         bsr     pcrlf
  226.         bra     quitprg
  227. opened  move.b  cmdflag,quitflg ;If we have a command, execute it and quit.
  228.         move.l  #setwin,d1
  229.         bsr     pstring         ;Set the window to 24 by 80.
  230.  
  231. *
  232. * Come back here to load another program.
  233. *
  234. nextprg lea     target,targbase ;Start of target memory
  235.         clr.b   insflag         ;Reset insert mode.
  236.         move.l  #simsg,d1
  237.         bsr     pstring         ;In case last program sent SHIFT OUT
  238.         clr.b   dumpcnt         ;Reset dump pause counter.
  239.         bsr     entrads         ;Enter trace delimiting addresses.
  240.         bsr     lodfdos         ;Load up the fake FDOS in target memory.
  241.         bsr     lodregs         ;Load the remaining simulation registers.
  242.         bsr     loadcom         ;Load the .COM program.
  243.  
  244.         jmp     mloop           ;Execute simulation.
  245.         page
  246. *************************************************************************
  247. *                                                                       *
  248. *       Illegal instructions and dumping                                *
  249. *                                                                       *
  250. *************************************************************************
  251.  
  252. illegl  move.l  #illgmsg,d1     ;Illegal opcode, say what & where,
  253.         bsr     pstring
  254.         subq.l  #1,pseudopc
  255.         move.b  (pseudopc),d1
  256.         lsl.w   #8,d1
  257.         move.b  1(pseudopc),d1
  258.         bsr     pword
  259.         move.l  #ilgmsg2,d1
  260.         bsr     pstring
  261.         move.l  pseudopc,d1
  262.         sub.l   targbase,d1
  263.         bsr     pword
  264.         move.l  #ilgmsg3,d1
  265.         bsr     pstring
  266.         move.l  #dumpmsg,d1
  267.         bsr     pstring
  268.         clr.b   dumpcnt
  269.         bsr     dump            ; and spill guts.
  270.         bra     quitprg         ;Quit simulation.
  271.  
  272. dump    movem.l d0-d3,-(sp)
  273.         bsr     pcrlf
  274.         move.b  regf,d0
  275.         bsr     setflags
  276.         move.b  #'A',(a0)+
  277.         move.b  #'=',(a0)+
  278.         move.b  rega,d1         ;Accumulator
  279.         bsr     ubyte
  280.         move.b  #' ',(a0)+
  281.         move.b  #'B',(a0)+
  282.         move.b  #'=',(a0)+
  283.         move.w  regb(regs),d1   ;BC
  284.         bsr     uword
  285.         move.b  #' ',(a0)+
  286.         move.b  #'D',(a0)+
  287.         move.b  #'=',(a0)+
  288.         move.w  regd(regs),d1   ;DE
  289.         bsr     uword
  290.         move.b  #' ',(a0)+
  291.         move.b  #'H',(a0)+
  292.         move.b  #'=',(a0)+
  293.         move.w  regh(regs),d1   ;HL
  294.         bsr     uword
  295.         move.b  #' ',(a0)+
  296.         move.b  #'S',(a0)+
  297.         move.b  #'=',(a0)+
  298.         move.l  pseudosp,d1     ;SP
  299.         sub.l   targbase,d1
  300.         bsr     uword
  301.         move.b  #' ',(a0)+
  302.         move.b  #'P',(a0)+
  303.         move.b  #'=',(a0)+
  304.         move.l  pseudopc,d1     ;PC
  305.         sub.l   targbase,d1
  306.         bsr     uword
  307.         move.b  #' ',(a0)+
  308.         move.l  a1,-(sp)
  309.         move.l  pseudosp,a1
  310.         move.w  #3,d2
  311.         move.b  #'0',d3
  312. tosloop move.b  #'S',(a0)+      ;Display the top 4 stack entries.
  313.         move.b  d3,(a0)+
  314.         addq.b  #1,d3
  315.         move.b  #'=',(a0)+
  316.         move.b  1(a1),d1 
  317.         ror.w   #8,d1
  318.         move.b  0(a1),d1
  319.         bsr     uword
  320.         move.b  #' ',(a0)+
  321.         addq.l  #2,a1
  322.         dbra    d2,tosloop
  323.         move.b  #'$',(a0)+
  324.         move.l  (sp)+,a1
  325.         move.l  #workbuf,d1
  326.         bsr     pstring         ;Displaying as a single string is much faster.
  327.         bsr     pcrlf
  328.         move.b  regaaf+1(regs),d0
  329.         bsr     setflags
  330.         move.b  #'A',(a0)+
  331.         move.b  #$27,(a0)+
  332.         move.b  regaaf(regs),d1 ;Alternate accumulator
  333.         bsr     ubyte
  334.         move.b  #' ',(a0)+
  335.         move.b  #'B',(a0)+
  336.         move.b  #$27,(a0)+
  337.         move.w  regabc(regs),d1 ;Alternate BC
  338.         bsr     uword
  339.         move.b  #' ',(a0)+
  340.         move.b  #'D',(a0)+
  341.         move.b  #$27,(a0)+
  342.         move.w  regade(regs),d1 ;Alternate DE
  343.         bsr     uword
  344.         move.b  #' ',(a0)+
  345.         move.b  #'H',(a0)+
  346.         move.b  #$27,(a0)+
  347.         move.w  regahl(regs),d1 ;Alternate HL
  348.         bsr     uword
  349.         move.b  #' ',(a0)+
  350.         move.b  #'X',(a0)+
  351.         move.b  #'=',(a0)+
  352.         move.w  regix(regs),d1  ;IX
  353.         bsr     uword
  354.         move.b  #' ',(a0)+
  355.         move.b  #'Y',(a0)+
  356.         move.b  #'=',(a0)+
  357.         move.w  regiy(regs),d1  ;IY
  358.         bsr     uword
  359.         move.b  #' ',(a0)+
  360.         move.b  #' ',(a0)+
  361.         move.b  (pseudopc),d1   ;Current opcode byte
  362.         bsr     ubyte
  363.         move.b  #' ',(a0)+
  364.         move.b  #' ',(a0)+
  365.         move.b  #'$',(a0)+
  366.         move.l  #workbuf,d1
  367.         bsr     pstring         ;Displaying as a single string is much faster.
  368.         moveq   #0,d0
  369.         move.b  (pseudopc),d0   ;Opcode
  370.         mulu    #9,d0           ;Offset into opcode table
  371.         lea     mnops,a0
  372.         move.l  a0,d1
  373.         add.l   d0,d1           ;D1 -> opcode name
  374.         move.l  d1,-(sp)
  375.         addq.l  #1,d1
  376.         bsr     pstring         ;Display opcode name.
  377.         move.l  (sp)+,a0
  378.         cmpi.b  #' ',(a0)
  379.         beq.s   nooprnd         ;There are no operands.
  380.         cmpi.b  #'C',(a0)
  381.         bne.s   notcons
  382.         move.b  1(pseudopc),d1  ;Display single-byte operand.
  383.         bsr     pbyte
  384.         bra.s   nooprnd
  385. notcons cmpi.b  #'A',(a0)
  386.         bne.s   nooprnd
  387.         move.b  2(pseudopc),d1  ;Display two-byte operand.
  388.         bsr     pbyte
  389.         move.b  1(pseudopc),d1
  390.         bsr     pbyte
  391. nooprnd bsr     pcrlf
  392.         addq.b  #1,dumpcnt      ;Count the number of times dumped.
  393.         cmpi.b  #8,dumpcnt      ;Is the screen full of dumps?
  394.         bmi     dumpx           ;No - exit.
  395.         move.l  #dmpmsg3,d1
  396.         bsr     pstring         ;Ask for operator action.
  397.         bsr     dmpstr          ;Make sure the prompt gets out!
  398.         movem.l d3/a0-a1/a6,-(sp)
  399.         move.l  rawhand,d1      ;Console input
  400.         move.l  #dumpcnt,d2
  401.         move.l  dosbase,a6
  402.         moveq   #1,d3
  403.         sys     Read            ;Get the operator's reply.
  404.         movem.l (sp)+,d3/a0-a1/a6
  405.         bsr     pcrlf
  406.         cmpi.b  #'Q',dumpcnt    ;Does he want to quit?
  407.         beq     quitprg         ;Yes.
  408.         cmpi.b  #'q',dumpcnt
  409.         beq     quitprg
  410.         cmpi.b  #'S',dumpcnt    ;Stop tracing?
  411.         beq.s   dumpnt          ;Yes.
  412.         cmpi.b  #'s',dumpcnt
  413.         beq.s   dumpnt
  414.         cmpi.b  #'C',dumpcnt    ;Change trace address?
  415.         beq.s   gettr           ;Yes.
  416.         cmpi.b  #'c',dumpcnt
  417.         bne.s   dmpcont
  418. gettr   bsr     gtrange
  419. dumpnt  clr.b   traceflg        ;Disable tracing and continue.
  420. dmpcont clr.b   dumpcnt         ;Reset the counter.
  421. dumpx   movem.l (sp)+,d0-d3
  422.         rts
  423.  
  424. setflags:
  425.         lea     workbuf,a0
  426.         move.b  #'-',d1
  427.         btst    #0,d0
  428.         beq     1$
  429.         move.b  #'C',d1
  430. 1$      move.b  d1,(a0)+
  431.         move.b  #'-',d1
  432.         btst    #6,d0
  433.         beq     2$
  434.         move.b  #'Z',d1
  435. 2$      move.b  d1,(a0)+
  436.         move.b  #'-',d1
  437.         btst    #7,d0
  438.         beq     3$
  439.         move.b  #'M',d1
  440. 3$      move.b  d1,(a0)+
  441.         move.b  #'-',d1
  442.         btst    #2,d0
  443.         beq     4$
  444.         move.b  #'E',d1
  445. 4$      move.b  d1,(a0)+
  446.         move.b  #'-',d1
  447.         btst    #4,d0
  448.         beq     5$
  449.         move.b  #'I',d1
  450. 5$      move.b  d1,(a0)+
  451.         move.b  #' ',(a0)+
  452.         rts
  453.         page
  454. *************************************************************************
  455. *                                                                       *
  456. *       Initialization subroutines                                      *
  457. *                                                                       *
  458. *************************************************************************
  459.  
  460. *
  461. * Load up the fake FDOS.
  462. *
  463. lodfdos move.l  a6,-(sp)
  464.         lea     fdos,a6
  465.         move.l  targbase,pseudosp
  466.         adda.l  #$10000,pseudosp
  467.         lea     -256(pseudosp),a0
  468.         move.w  #fdoslen,d0
  469. lodloop move.b  (a6)+,(a0)+
  470.         dbra    d0,lodloop
  471.         lea     -256(pseudosp),a0
  472.         move.l  a0,d0
  473.         sub.l   targbase,d0
  474.         move.b  #tJMP,0(targbase)        ;Build BIOS and BDOS jumps.
  475.         move.b  #tJMP,5(targbase)
  476.         move.b  d0,6(targbase)
  477.         rol.w   #8,d0
  478.         move.b  d0,7(targbase)
  479.         rol.w   #8,d0
  480.         addq.w  #3,d0
  481.         move.b  d0,1(targbase)
  482.         rol.w   #8,d0
  483.         move.b  d0,2(targbase)
  484.         clr.w   -(pseudosp)     ;Set up a return stack to exit simulation.
  485.         move.l  (sp)+,a6
  486.         rts
  487.  
  488. *
  489. * Set up working registers.
  490. *
  491. lodregs lea     optabl,opptr    ;Point base reg. to opcode dispatch table.
  492.         lea     mloop,return
  493.         lea     flags,flagptr
  494.         move.l  targbase,pseudopc
  495.         adda.l  #$100,pseudopc  ;Start execution at 0100H in target space.
  496.         moveq   #$E,regcon0e    ;Set up quick constants.
  497.         moveq   #$1,regcon01
  498.         moveq   #$F,regcon0f
  499.         move.l  #$FF,regconff
  500.         moveq   #0,rega
  501.         moveq   #0,regf
  502.         rts
  503.         page
  504. *
  505. * Get start and end addresses for tracing.
  506. *
  507. entrads tst.b   traceit         ;Is tracing required?
  508.         beq     entradx         ;No.
  509.         bsr     gtrange         ;get trace range
  510. * Find out whether BIOS/BDOS calls are to be traced.
  511.         move.l  #btrcmsg,d1
  512.         bsr     pstring
  513.         lea     workbuf,a0
  514.         move.b  #10,(a0)
  515.         bsr     getline
  516.         move.b  #1,btrcflg
  517.         cmpi.b  #'Y',workbuf+2
  518.         beq.s   entradx
  519.         cmpi.b  #'y',workbuf+2
  520.         beq.s   entradx
  521.         clr.b   btrcflg
  522. entradx clr.b   traceflg        ;Start with tracing turned off.
  523.         rts
  524.  
  525. gtrange:
  526.         move.l  #tracemsg,d1    ;Enter trace address if necessary.
  527.         bsr     pstring
  528.         lea     workbuf,a0
  529.         move.b  #workbufn-workbuf-2,(a0)
  530.         bsr     getline         ;Get the string.
  531.         moveq   #0,d0
  532.         move.b  1(a0),d0        ;Number of bytes read
  533.         addq.l  #2,a0           ;Skip over length information.
  534.         clr.b   0(a0,d0)        ;Insert string terminator.
  535.         bsr     atol            ;Get trace start address.
  536.         and.l   #$FFFF,d1
  537.         add.l   targbase,d1
  538.         move.l  d1,tracesad
  539. * Now get the ending address.
  540.         move.l  #tracemg2,d1
  541.         bsr     pstring
  542.         lea     workbuf,a0
  543.         move.b  #workbufn-workbuf-2,(a0)
  544.         bsr     getline
  545.         moveq   #0,d0
  546.         move.b  1(a0),d0
  547.         addq.l  #2,a0
  548.         clr.b   0(a0,d0)
  549.         bsr     atol
  550.         and.l   #$FFFF,d1
  551.         add.l   targbase,d1
  552.         move.l  d1,traceead
  553.         bsr     pcrlf
  554.         rts
  555.  
  556. *
  557. * Open the file to be loaded, and load it into
  558. *  target space if successful.
  559. *
  560. loadcom movem.l d1-d3/a1-a2/a6,-(sp)    ;Save registers.
  561.         lea     cmdline,a0
  562.         tst.b   cmdflag         ;Do we have a command already?
  563.         bne.s   scancmd         ;Yes - process it.
  564. prompt  move.l  #aprompt,d1
  565.         bsr     pstring         ;Display the command prompt.
  566.         lea     cmdline,a0
  567.         move.b  #cmdlinen-cmdline-2,(a0)
  568.         bsr     getline         ;Get a command line.
  569.         moveq   #0,d0
  570.         move.b  1(a0),d0        ;Length of command line
  571.         beq.s   prompt          ;Zero - try again.
  572.         addq.l  #2,a0           ;Skip over length information.
  573.         clr.b   0(a0,d0)        ;Insert command line terminator.
  574.         cmpi.b  #3,(a0)         ;Control-C?
  575.         bne.s   scancmd         ;No.
  576.         move.b  #1,quitflg      ;Set quit flag.
  577.         bra     quitprg         ;Exit the simulator.
  578. scancmd lea     comname,a2
  579.         moveq   #comnamen-comname-6,d1 ;Adjust length for DBcc.
  580. loadnam move.b  (a0)+,d0        ;Convert file name to upper case.
  581.         bsr     ucase
  582.         move.b  d0,(a2)+
  583.         cmpi.b  #' ',(a0)       ;End of name?
  584.         beq     gotname         ;Yes.
  585.         tst.b   (a0)            ;End of command string?
  586.         dbeq    d1,loadnam      ;No - keep on going.
  587. gotname move.l  a0,comend       ;Save position in command line.
  588.         move.b  #'.',(a2)+      ;Mash file name to .COM.
  589.         move.b  #'C',(a2)+
  590.         move.b  #'O',(a2)+
  591.         move.b  #'M',(a2)+
  592.         clr.b   (a2)
  593.         clr.b   cmdline         ;Ask for a new command next time.
  594.         move.l  #comname,d1
  595.         move.l  #MODE_OLDFILE,d2
  596.         move.l  dosbase,a6
  597.         sys     Open            ;Open the file.
  598.         tst.l   d0              ;Did the open fail?
  599.         bne.s   comopen         ;No.
  600.         lea     comname,a0
  601. openerr cmpi.b  #'.',(a0)+      ;Find end of file name.
  602.         bne.s   openerr
  603.         move.b  #'?',-1(a0)
  604.         move.b  #cr,(a0)+
  605.         move.b  #lf,(a0)+
  606.         move.b  #'$',(a0)
  607.         move.l  #comname,d1
  608.         bsr     pstring         ;Echo "name?"
  609.         bra     prompt          ;Try again.
  610.  
  611. comopen move.l  d0,-(sp)        ;Save the file handle.
  612.         move.l  d0,d1
  613.         move.l  pseudopc,d2     ;Start loading at $0100 in target.
  614.         move.l  #65536-512,d3   ;Maximum number of bytes to load
  615.         move.l  dosbase,a6
  616.         sys     Read            ;Load the .COM file.
  617.         move.l  (sp)+,d1
  618.         move.l  dosbase,a6
  619.         sys     Close           ;Close the .COM file.
  620.  
  621. * The program has now been loaded.
  622.         movem.l (sp)+,d1-d3/a1-a2/a6    ;Refresh registers.
  623.         movem.l d1-d3/a1-a2/a6,-(sp)
  624.         lea     $80(targbase),a0        ;Set up target's base page.
  625.         move.l  a0,dmaaddr
  626.  
  627. * Set up FCBs and command line tail.
  628.         lea     $5C(targbase),a0
  629.         lea     $6C(targbase),a2
  630.         clr.b   (a0)+
  631.         clr.b   (a2)+
  632.         moveq   #10,d0
  633. clrfcb  move.b  #' ',(a0)+      ;Clear FCBs.
  634.         move.b  #' ',(a2)+
  635.         dbra    d0,clrfcb
  636.         clr.b   $80(targbase)   ;Clear the command line tail.
  637.  
  638.         move.l  comend,a0       ;Restore position in command line.
  639. fcb1    tst.b   (a0)            ;End of command line?
  640.         beq     loaded          ;Yes.
  641.         cmpi.b  #' ',(a0)+      ;Skip over to first file name
  642.         beq.s   fcb1
  643.         subq.l  #1,a0           ;Back onto start of file name.
  644.         move.l  a0,-(sp)        ;Save position on command line.
  645.         lea     $81(targbase),a2;A2 loads the command line tail.
  646. gettail move.b  (a0)+,d0        ;Copy the command tail.
  647.         bsr     ucase
  648.         move.b  d0,(a2)+
  649.         tst.b   d0
  650.         bne.s   gettail
  651.         move.l  a2,d0
  652.         lea     $82(targbase),a0;Don't count null terminator!
  653.         sub.l   a0,d0
  654.         move.b  d0,$80(targbase);Length of command line tail
  655.         move.l  (sp)+,a0        ;Go back to the first file name.
  656.  
  657.         lea     $5C(targbase),a2;Address of current FCB
  658. getfcb  move.l  a2,fcbptr       ;Save pointer to current FCB.
  659.         cmpi.b  #':',1(a0)      ;Is a drive specified?
  660.         bne.s   getfcbf         ;No.
  661.         move.b  (a0),d0         ;Get drive letter.
  662.         bsr     ucase
  663.         move.b  d0,(a2)
  664.         subi.b  #'A'-1,(a2)     ;Convert to drive code.
  665.         addq.l  #2,a0           ;Skip over drive designator.
  666.         tst.b   (a0)            ;End of command line?
  667.         beq.s   loaded          ;Yes - we're done.
  668.         cmpi.b  #' ',(a0)       ;End of file name?
  669.         beq.s   getfcbx         ;Yes.
  670. getfcbf addq.l  #1,a2           ;Start of file name in FCB
  671. getfcbl move.b  (a0)+,d0        ;Copy file name to FCB.
  672.         bsr     ucase
  673.         move.b  d0,(a2)+
  674. getfcbt tst.b   (a0)            ;End of command?
  675.         beq.s   loaded          ;Yes.
  676.         cmpi.b  #' ',(a0)       ;End of file name?
  677.         beq.s   getfcbx         ;Yes.
  678.         cmpi.b  #'.',(a0)       ;Start of file name extension?
  679.         bne.s   getfcbl         ;No - continue loading file name.
  680.         move.l  fcbptr,a2       ;Copy original pointer
  681.         adda.l  #9,a2           ;Skip over to extension field.
  682.         addq.l  #1,a0           ;Skip over the period.
  683.         bra.s   getfcbt
  684. getfcbx tst.b   (a0)            ;End of command line?
  685.         beq.s   loaded          ;Yes.
  686.         cmpi.b  #' ',(a0)+      ;Look for another file name.
  687.         beq.s   getfcbx
  688.         subq.l  #1,a0           ;Back onto start of file name.
  689.         move.l  fcbptr,d0
  690.         lea     $5C(targbase),a2
  691.         cmp.l   d0,a2           ;Was this the first FCB?
  692.         bne.s   loaded          ;No - stop after two FCBs.
  693.         adda.l  #16,a2          ;Skip over to the next FCB.
  694.         bra.s   getfcb          ;Load the next FCB.
  695.  
  696. loaded  movem.l (sp)+,d1-d3/a1-a2/a6    ;Restore registers.
  697.         rts                     ;Exit.
  698.  
  699. *
  700. * Subroutine to convert a character to upper case
  701. *
  702. ucase   cmpi.b  #'a',d0
  703.         blt.s   ucasex
  704.         cmpi.b  #'z',d0
  705.         bgt.s   ucasex
  706.         subi.b  #'a'-'A',d0
  707. ucasex  rts
  708.         page
  709. *************************************************************************
  710. *                                                                       *
  711. *       BDOS / BIOS service routines                                    *
  712. *                                                                       *
  713. *************************************************************************
  714. service movem.l a1/a6,-(sp)
  715.         move.b  rega,newrega    ;Save 8080 accumulator (D2)
  716.         move.l  dosbase,a6      ;Get dos.library pointer
  717. * Decode the byte following the HLT instruction (BIOS call type).
  718.         moveq   #0,d0           ;Handle BIOS/BDOS service request
  719.         move.b  (pseudopc)+,d0  ; of form HLT DB opcode.
  720.         cmp     #(biostabn-biostab)/4,d0
  721.         blt.s   dobios          ;Function number is within range.
  722. badbios move.b  d0,-(sp)        ;Flag illegal BIOS call
  723.         move.l  #ilgbios,d1     ; and spill guts.
  724.         bsr     pstring
  725.         move.b  (sp)+,d1
  726.         bsr     pbyte
  727.         bsr     pcrlf
  728.         bsr     dump
  729.         bra     quitprg
  730. dobios  move.l  d0,-(sp)        ;Save BIOS function number.
  731.         beq.s   biostrx         ;Zero - it's a BDOS call.
  732.         tst.b   btrcflg         ;Trace BIOS calls?
  733.         beq.s   biostrx         ;No.
  734.         move.l  #biosmsg,d1
  735.         bsr     pstring
  736.         move.l  (sp),d1
  737.         bsr     pbyte
  738.         move.l  #atmsg,d1
  739.         bsr     pstring
  740.         move.b  1(pseudosp),d1  ;Address where called (top stack entry)
  741.         ror.w   #8,d1
  742.         move.b  0(pseudosp),d1
  743.         bsr     pword
  744.         bsr     pcrlf
  745.         move.l  (sp),d0
  746. biostrx asl     #2,d0           ;Multiply function number by 4.
  747.         addi.l  #biostab,d0     ;Point at address table entry.
  748.         movea.l d0,a0
  749.         movea.l (a0),a0         ;Point to appropriate service routine.
  750.         move.l  (sp)+,d0        ;Restore BIOS function number.
  751.         jmp     (a0)            ;Jump to the routine.
  752. * If the BIOS code is zero, it's a BDOS call.
  753. *  Decode register C using a similar routine to the BIOS decoding above.
  754. bdosfn  moveq   #0,d0
  755.         move.b  regc(regs),d0   ;Get BDOS function number.
  756.         cmp     #(bdostabn-bdostab)/4,d0
  757.         blt.s   dobdos          ;Function number is within range.
  758. badbdos move.b  d0,-(sp)
  759.         move.l  #ilgbdos,d1     ;Illegal or unsupported BDOS call
  760.         bsr     pstring
  761.         move.b  (sp)+,d1
  762.         bsr     pbyte
  763.         bsr     pcrlf
  764.         bsr     dump
  765.         bra     quitprg
  766. dobdos  move.l  d0,-(sp)        ;Save BDOS function number.
  767.         tst.b   btrcflg         ;Trace BDOS calls?
  768.         beq.s   bdostrx         ;No.
  769.         move.l  #bdosmsg,d1
  770.         bsr     pstring
  771.         move.l  (sp),d1
  772.         bsr     pbyte
  773.         move.l  #atmsg,d1
  774.         bsr     pstring
  775.         move.b  1(pseudosp),d1
  776.         ror.w   #8,d1
  777.         move.b  0(pseudosp),d1
  778.         bsr     pword
  779.         bsr     pcrlf
  780.         move.l  (sp),d0
  781. bdostrx cmpi.b  #10,d0          ;BDOS function 10 or higher?
  782.         blt.s   bdosjmp         ;No.
  783.         bsr     dmpstr          ;Dump any outstanding console output.
  784.         move.l  (sp),d0         ;Restore BDOS function number.
  785. bdosjmp asl     #2,d0           ;Multiply function number by 4.
  786.         addi.l  #bdostab,d0     ;Point at address table entry.
  787.         movea.l d0,a0
  788.         movea.l (a0),a0         ;Point to appropriate service routine.
  789.         move.l  (sp)+,d0        ;Restore BDOS function number.
  790.         moveq   #0,d1
  791.         move.w  regd(regs),d1   ;Get argument.
  792.         jmp     (a0)            ;Jump to the routine.
  793. * Return here after performing the BDOS function.
  794. results movem.l (sp)+,a1/a6
  795.         moveq   #0,rega
  796.         move.b  newrega,rega    ;Get new accumulator value.
  797. * We have finished processing the BDOS function.
  798.         move.b  rega,d0         ;Set flags.
  799.         and.w   regconff,d0
  800.         move.b  0(flagptr,d0.w),regf
  801.         rts
  802. *
  803. * Individual BDOS service routines
  804. *
  805. bdos00  bra     quitprg          ;Exit program.
  806.  
  807. bdos01  bsr     dmpstr           ;Console input
  808.         move.l  rawhand,d1
  809.         move.l  #newrega,d2
  810.         moveq   #1,d3
  811.         sys     Read
  812.         bra     results
  813.  
  814. bdos02  move.b  rege(regs),d1    ;Console output
  815.         clr.b   testdol          ;Allow dollar signs
  816.         bsr     pchar
  817.         bra     results
  818.  
  819. bdos03  equ     badbdos          ;Reader input
  820.  
  821. bdos04  equ     badbdos          ;Punch output
  822.  
  823. bdos05  pea     rege(regs)       ;List output byte
  824. bdos05t tst.b   listopn          ;Is the printer already open?
  825.         bne.s   bdos05w          ;Yes.
  826.         move.l  #prtname,d1
  827.         move.l  #MODE_NEWFILE,d2
  828.         sys     Open             ;Open the printer.
  829.         move.l  d0,prthand       ;Save the file handle.
  830.         bne.s   bdos05o          ;The open was successful.
  831.         move.l  #badprt,d1
  832.         bsr     pstring          ;Indicate an unsuccessful open.
  833.         bsr     dump             ;Spill guts...
  834.         bra     quitprg          ; and exit.
  835. bdos05o move.b  #1,listopn       ;Indicate that the list device is open.
  836. bdos05w move.l  prthand,d1
  837.         move.l  (sp)+,d2         ;Character to send to the list device
  838.         moveq   #1,d3            ;Just send one byte.
  839.         sys     Write            ;Send the byte to the list device.
  840.         bra     results
  841.         
  842. bdos06  cmpi.b  #$FF,rege(regs)  ;Direct console I/O
  843.         bne.s   bdos02           ;Send the byte.
  844.         bsr     dmpstr           ;Dump any outstanding output.
  845.         move.l  rawhand,d1
  846.         moveq   #1,d2            ;Wait for one microsecond.
  847.         sys     WaitForChar      ;Check whether a character is ready.
  848.         tst.l   d0               ;Is a character ready?
  849.         bne     bdos01           ;Yes - get it.
  850.         clr.b   newrega          ;Indicate that nothing is ready.
  851.         bra     results
  852.  
  853. bdos07  move.b  3(targbase),newrega     ;Get IOBYTE
  854.         bra     results
  855.  
  856. bdos08  move.b  rege(regs),3(targbase)  ;Set IOBYTE
  857.         bra     results
  858.                              
  859. bdos09  add.l   targbase,d1      ;Console output string
  860.         bsr     pstring
  861.         bra     results
  862.  
  863. bdos10  add.l   targbase,d1      ;Console input line
  864.         movea.l d1,a0            ;The buffer is here.
  865.         bsr     getline          ;Get a line.
  866.         cmpi.b  #3,2(a0)         ;Was it a control-C?
  867.         bne     results          ;No - continue processing.
  868.         bra     quitprg          ;Terminate the program.
  869.  
  870. bdos11  move.l  rawhand,d1       ;Console status check
  871.         moveq   #1,d2            ;Wait for one microsecond.
  872.         sys     WaitForChar      ;Check whether a character is ready.
  873.         move.b  d0,newrega       ;Result is compatible with CP/M.
  874.         bra     results
  875.  
  876. bdos12  clr.b   regh(regs)       ;Get system identification
  877.         move.b  #$22,regl(regs)  ;Pretend we're CP/M 2.2.
  878.         move.b  #$22,newrega     ;Some programs use undocumented return reg
  879.         bra     results
  880.  
  881. bdos13  equ     results          ;Reset all drives (ignored)
  882.  
  883. bdos14  move.b  rege(regs),4(targbase)  ;Select drive
  884.         bra     results
  885.  
  886. bdos15  move.l  #MODE_OLDFILE,d2 ;Open existing file
  887. bdos15o add.l   targbase,d1
  888.         movea.l d1,a0            ;The FCB is here.
  889.         move.l  d1,-(sp)
  890.         lea     opnname,a1       ;Build AmigaDOS file name here.
  891.         move.l  a1,d1            ;We'll need it here.
  892.         bsr     convfn           ;Make a file name.
  893.         sys     Open             ;Open the file.
  894.         move.l  (sp)+,a1         ;The FCB is here.
  895.         lea     handles,a0
  896.         moveq   #(handlen-handles)/4-1,d1
  897.         clr.b   newrega          ;Assume the open succeeded.
  898.         tst.l   d0               ;Did it fail?
  899.         bne     bdos15s          ;No.
  900.         move.b  #$FF,newrega     ;Set failure code.
  901.         bra     results
  902. bdos15s tst.l   (a0)+            ;Find an available handle slot.
  903.         dbeq    d1,bdos15s
  904.         tst     d1               ;Did we find a slot?
  905.         bmi     bdos15e          ;No - error!
  906.         move.l  d0,-4(a0)        ;Save file handle address.
  907.         moveq   #(handlen-handles)/4-1,d0
  908.         sub.l   d1,d0
  909.         move.b  d0,13(a1)        ;Save handle number in FCB.
  910.         bra     results
  911. bdos15e move.l  #fullmsg,d1      ;File handle table overflow!
  912.         bsr     pstring          ;Display an error message
  913.         bra     quitprg          ; and forget the whole thing.
  914.  
  915. bdos16  move.b  #$FF,newrega     ;Close file
  916.         bsr     gethand          ;Get the file handle.
  917.         beq     results          ;The file is not open.
  918.         clr.l   0(a1,d0.w)       ;Clear the handle table entry.
  919.         sys     Close            ;Close the file.
  920.         clr.b   newrega          ;Indicate success.
  921.         bra     results
  922.         page
  923. bdos17  movem.l a1-a2/a6/d2,-(sp)   ;Search for first file
  924.         add.l   targbase,d1
  925.         lea     scanname,a1
  926.         bsr     setname
  927.         clr.l   d1
  928.         sys     CurrentDir
  929. * looks as this next line can be deleted
  930.         move.l  d0,CurDir
  931.         move.l  d0,d1
  932.         sys     DupLock
  933.         move.l  d0,lockaddr
  934.         bsr     ffirst
  935.         beq     badbdos
  936.         bra     NameLoop
  937.  
  938. bdos18  movem.l a1-a2/a6/d2,-(sp)   ;Search for next file
  939. ;
  940. ;       Find next entry in directory
  941. ;
  942. NameLoop:
  943.         move.l  lockaddr,d1
  944.         move.l  #FileInfo,d2
  945.         movea.l dosbase,a6
  946.         sys     ExNext
  947. ;
  948. ;       Branch if no more entries
  949. ;
  950.         tst.l   d0
  951.         beq     EndDir
  952. ;
  953. ;       Bypass sub-directory entry
  954. ;
  955.         tst.l   FileInfo+fib_DirEntryType
  956.         bpl     NameLoop
  957. ;
  958. ;       Clear destination area
  959. ;
  960.         movea.l #DirFName,a0
  961.         movea.l #DirFExt,a1
  962.         move.w  #7,d0
  963.         move.b  #' ',d1
  964. 1$      move.b  d1,(a0)+
  965.         move.b  d1,(a1)+
  966.         dbra    d0,1$
  967. ;
  968. ;       Move file name while collecting data
  969. ;
  970.         movea.l #FileInfo+fib_FileName,a0
  971.         movea.l #DirFName,a2
  972.         clr.l   d0           ;char count
  973.         clr.l   d1           ;period count
  974. 2$      move.b  (a0)+,d2
  975.         beq     4$
  976.         cmpi.b  #'.',d2
  977.         beq     3$
  978.         move.b  d2,(a2)+
  979.         addq.w  #1,d0
  980.         bra     2$
  981. 3$      movea.l #DirFExt,a2
  982.         movea.l a0,a1
  983.         addq.w  #1,d1
  984.         bra     2$
  985. ;
  986. ;       Bypass entry if name not in CP/M format
  987. ;
  988. 4$      cmpi.w  #1,d1
  989.         bgt     NameLoop
  990.         beq     5$
  991.         moveq   #8,d2
  992.         bra     6$
  993. 5$      cmpa.l  #FileInfo+fib_FileName+9,a1
  994.         bgt     NameLoop
  995.         moveq   #11,d2
  996. 6$      cmp.w   d2,d0
  997.         bgt     NameLoop
  998. ;
  999. ;       Bypass entry if file names do not match
  1000. ;
  1001.         movea.l fcbptr,a1
  1002.         addq    #1,a1
  1003.         movea.l #DirFName,a0
  1004.         moveq   #7,d2
  1005.         bsr     matchpart
  1006.         bne     NameLoop
  1007. ;
  1008. ;       Bypass entry if file name extensions do not match
  1009. ;
  1010.         movea.l fcbptr,a1
  1011.         adda.l  #9,a1
  1012.         movea.l #DirFExt,a0
  1013.         moveq   #2,d2
  1014.         bsr     matchpart
  1015.         bne     NameLoop
  1016. ;
  1017. ;       Move file name
  1018. ;
  1019.         movea.l #DirFName,a0
  1020.         move.l  dmaaddr,a1
  1021.         addq.l  #1,a1
  1022.         moveq   #7,d0
  1023. 7$      move.b  (a0)+,(a1)+
  1024.         dbra    d0,7$
  1025. ;
  1026. ;       Move file name extension
  1027. ;
  1028.         movea.l #DirFExt,a0
  1029.         move.l  dmaaddr,a1
  1030.         adda.l  #9,a1
  1031.         moveq   #7,d0
  1032. 8$      move.b  (a0)+,(a1)+
  1033.         dbra    d0,8$
  1034. ;
  1035. ;
  1036. ;
  1037.         clr.b   newrega
  1038.         movem.l (sp)+,a1-a2/a6/d2
  1039.         bra     results
  1040. ;
  1041. ;
  1042. ;
  1043. EndDir:
  1044.         bsr     unlock
  1045.         move.b  regconff,newrega
  1046.         movem.l (sp)+,a1-a2/a6/d2
  1047.         bra     results
  1048. ;
  1049. ;       Subroutine to match part of file name
  1050. ;
  1051. matchpart:
  1052.         move.b  (a0),d0
  1053.         bsr     ucase
  1054.         move.b  (a1),d1
  1055.         cmp.b   d0,d1
  1056.         beq     CharMatch
  1057.         cmpi.b  #'?',d1
  1058.         beq     CharMatch
  1059.         cmpi.b  #'*',d1
  1060.         bne     nomatch
  1061.         beq     match
  1062. CharMatch:
  1063.         addq.l  #1,a1
  1064.         addq.l  #1,a0
  1065.         dbra    d2,matchpart
  1066. match:
  1067.         clr.l   d0   ;insure zero flag is set
  1068.         rts
  1069. nomatch:
  1070.         moveq   #1,d0  ;insure zero flag reset
  1071.         rts
  1072.         page
  1073. bdos19  add.l   targbase,d1      ;Delete file
  1074.         movea.l d1,a0            ;The FCB is here.
  1075.         lea     opnname,a1       ;Build AmigaDOS file name here.
  1076.         move.l  a1,d1            ;We'll need it here.
  1077.         bsr     convfn           ;Make a file name.
  1078.         sys     DeleteFile       ;Delete the file.
  1079.         bra     results          
  1080.  
  1081. bdos20  clr.b   newrega          ;Sequential read
  1082.         bsr     gethand
  1083.         move.l  dmaaddr,d2
  1084.         move.l  #128,d3
  1085.         sys     Read
  1086.         tst.l   d0               ;Were we successful?
  1087.         bgt     results          ;Yes.
  1088.         move.b  #$FF,newrega     ;Set failure (EOF) flag.
  1089.         bra     results
  1090.  
  1091. bdos21  clr.b   newrega          ;Sequential write
  1092.         bsr     gethand
  1093.         move.l  dmaaddr,d2
  1094.         move.l  #128,d3
  1095.         sys     Write
  1096.         tst.l   d0               ;Were we successful?
  1097.         bgt     results          ;Yes.
  1098.         move.b  #$FF,newrega     ;Set failure flag.
  1099.         bra     results
  1100.  
  1101. bdos22  move.l  #MODE_NEWFILE,d2        ;Make new file
  1102.         bra     bdos15o                 ;Use BDOS 15 open routine
  1103.  
  1104. bdos23  add.l   targbase,d1             ;Rename file
  1105.         movea.l d1,a0
  1106.         lea     opnname,a1
  1107.         bsr     convfn                  ;Convert old file name.
  1108.         movea.l d1,a0
  1109.         adda.l  #16,a0
  1110.         lea     renname,a1
  1111.         bsr     convfn                  ;Convert new file name.
  1112.         move.l  #opnname,d1
  1113.         move.l  #renname,d2
  1114.         sys     Rename                  ;Rename the file.
  1115.         bra     results
  1116.  
  1117. bdos24  equ     badbdos                 ;Get active drive map
  1118.  
  1119. bdos25  move.b  4(targbase),newrega     ;Get default drive number
  1120.         bra     results
  1121.  
  1122. bdos26  add.l   targbase,d1             ;Set file buffer address
  1123.         move.l  d1,dmaaddr
  1124.         bra     results
  1125.  
  1126. bdos27  move.w  #$FF6B,regh(regs)       ;Get allocation vector
  1127.         bra     results
  1128.  
  1129. bdos28  equ     badbdos                 ;Protect drive
  1130.  
  1131. bdos29  equ     badbdos                 ;Get read-only map
  1132.  
  1133. bdos30  equ     badbdos                 ;Set file attributes
  1134.  
  1135. bdos31  move.w  #$FF63,regh(regs)       ;Get disk parameter block
  1136.         bra     results
  1137.  
  1138. bdos32  equ     badbdos                 ;Get or set user code
  1139.  
  1140. bdos33  pea     _LVORead(a6)            ;Direct access read
  1141.         bra.s   bdos34c                 ;Use common read/write routine.
  1142.  
  1143. bdos34  pea     _LVOWrite(a6)           ;Direct access write
  1144. bdos34c clr.b   newrega                 ;Common read/write routine
  1145.         bsr     gethand
  1146.         move.l  d1,-(sp)                ;Save file handle.
  1147.         moveq   #0,d2
  1148.         move.b  35(a0),d2               ;Get seek address.
  1149.         rol.l   #8,d2
  1150.         move.b  34(a0),d2
  1151.         rol.l   #8,d2
  1152.         move.b  33(a0),d2
  1153.         rol.l   #7,d2                   ;Convert record number to byte displacement.
  1154.         move.b  33(a0),32(a0)           ;Set up current record number in extent.
  1155.         andi.b  #$7F,32(a0)
  1156.         moveq   #14,d0
  1157.         ror.l   d0,d2
  1158.         move.b  d2,12(a0)               ;Current extent number
  1159.         rol.l   d0,d2
  1160.         moveq   #-1,d3
  1161.         sys     Seek                    ;Seek to desired position.
  1162.         move.l  (sp)+,d1                ;Get the file handle again.
  1163.         move.l  (sp)+,a0                ;Address of read or write routine
  1164.         tst.l   d0                      ;Were we successful?
  1165.         bmi     bdos34e                 ;No.
  1166.         move.l  dmaaddr,d2
  1167.         move.l  #128,d3
  1168.         jsr     (a0)                    ;Read or write the desired record.
  1169.         tst.l   d0                      ;Were we successful?
  1170.         bgt     results                 ;Yes.
  1171. bdos34e move.b  #6,newrega              ;Set failure (invalid address) flag.
  1172.         bra     results
  1173.  
  1174. bdos35  movem.l a1/a6/d2,-(sp)          ;Get file end address
  1175.         add.l   targbase,d1
  1176.         lea     opnname,a1
  1177.         bsr     setname
  1178.         moveq   #SHARED_LOCK,d2
  1179.         move.l  dosbase,a6
  1180.         sys     Lock
  1181.         move.l  d0,lockaddr
  1182.         tst.l   d0
  1183.         beq     quitprg
  1184.         bsr     ffirst
  1185.         beq     quitprg
  1186.         lea     FileInfo,a0
  1187.         move.l  fib_Size(a0),d0
  1188.         move.l  d0,-(sp)
  1189.         lsr.l   #7,d0
  1190.         and.l   #$7F,(sp)+
  1191.         beq     1$
  1192.         addq.l  #1,d0
  1193. 1$      bsr     storn
  1194.         bsr     unlock
  1195.         movem.l (sp)+,a1/a6/d2
  1196.         bra     results
  1197.  
  1198. bdos36  movem.l a1/a6,-(sp)      ;Get direct address
  1199.         bsr     gethand
  1200.         move.l  a0,fcbptr
  1201.         clr.l   d2
  1202.         move.l  #OFFSET_CURRENT,d3
  1203.         move.l  dosbase,a6
  1204.         sys     Seek
  1205.         lsr.l   #7,d0
  1206.         bsr     storn
  1207.         movem.l (sp)+,a1/a6
  1208.         bra     results
  1209.  
  1210. setname movea.l d1,a0
  1211.         move.l  d1,fcbptr
  1212.         move.l  a1,d1
  1213. *       bsr     convfn
  1214. *       rts
  1215.         jmp     convfn
  1216.  
  1217. ffirst  move.l  d0,d1
  1218.         move.l  #FileInfo,d2
  1219.         sys     Examine
  1220.         tst.l   d0
  1221.         rts
  1222.  
  1223. unlock  move.l  lockaddr,d1
  1224.         sys     UnLock
  1225.         rts
  1226.  
  1227. storn   move.l  fcbptr,a0
  1228.         move.b  d0,33(a0)
  1229.         lsr.l   #8,d0
  1230.         move.b  d0,34(a0)
  1231.         lsr.l   #8,d0
  1232.         move.b  d0,35(a0)
  1233.         rts
  1234.  
  1235. *
  1236. * Individual BIOS service routines
  1237. *
  1238. bios01  bra     quitprg         ;Warm boot
  1239.  
  1240. bios02  equ     bdos11          ;Console status check
  1241.  
  1242. bios03  equ     bdos01          ;Console input byte
  1243.  
  1244. bios04  move.b  regc(regs),d1   ;Console output byte
  1245.         clr.b   testdol         ;Allow dollar signs
  1246.         bsr     pchar
  1247.         bra     results
  1248.  
  1249. bios05  pea     regc(regs)      ;List output byte
  1250.         bra     bdos05t
  1251.  
  1252. bios06  equ     badbios         ;Punch output byte
  1253.  
  1254. bios07  equ     badbios         ;Reader input byte
  1255.  
  1256. bios08  equ     badbios         ;Home disk
  1257.  
  1258. bios09  equ     badbios         ;Select disk
  1259.  
  1260. bios10  equ     badbios         ;Set track
  1261.  
  1262. bios11  equ     badbios         ;Set sector
  1263.  
  1264. bios12  equ     badbios         ;Set DMA address
  1265.  
  1266. bios13  equ     badbios         ;Read disk
  1267.  
  1268. bios14  equ     badbios         ;Write disk
  1269.  
  1270. bios15  move.b  #$FF,newrega    ;List status
  1271.         bra     results
  1272.  
  1273.  
  1274. *
  1275. * End of program, one way or another
  1276. *
  1277. quitprg move.l  savesp,sp       ;Restore stack pointer.
  1278.         bsr     dmpstr          ;Dump any outstanding console output.
  1279. * If the list device was used, close it.
  1280.         tst.b   listopn         ;Is the printer open?
  1281.         beq.s   closprt         ;No.
  1282.         move.l  prthand,d1
  1283.         sys     Close           ;Close the printer.
  1284. closprt clr.b   listopn         ;Reset the "printer-open" flag.
  1285. * If any files were left open by the last program, close them.
  1286.         lea     handles,a0
  1287.         moveq   #(handlen-handles)/4-1,d0
  1288. closall move.l  (a0)+,d1
  1289.         beq.s   closnxt         ;This file isn't open.
  1290.         clr.l   -4(a0)          ;Make sure it isn't closed again
  1291.         movem.l a0/d0,-(sp)
  1292.         move.l  dosbase,a6
  1293.         sys     Close           ;Close this file.
  1294.         movem.l (sp)+,a0/d0
  1295. closnxt dbra    d0,closall
  1296. * Check whether we should quit the simulation.
  1297.         tst.b   quitflg         ;Exit the simulator?
  1298.         bne.s   exitsim         ;Yes.
  1299.         tst.b   cmdflag         ;Was .COM file loaded from command line?
  1300.         beq     nextprg         ;No - re-display the command prompt.
  1301. * Terminate execution of the simulator.
  1302. exitsim move.l  rawhand,d1      ;Is RAW: open?
  1303.         beq.s   closlib         ;No.
  1304.         move.l  dosbase,a6
  1305.         sys     Close           ;Close RAW:
  1306. closlib move.l  Absbase,a6
  1307.         move.l  dosbase,a1
  1308.         sys     CloseLibrary    ;Close dos.library.
  1309.         moveq   #0,d0           ;Return with no error.
  1310.         rts                     ;All done
  1311.         page
  1312. *************************************************************************
  1313. *                                                                       *
  1314. *       AmigaDOS interface routines                                     *
  1315. *                                                                       *
  1316. *************************************************************************
  1317.  
  1318. *
  1319. * Get a line from the console.  CP/M BDOS 10 conventions are used.
  1320. *  A0 is assumed to point to the start of the buffer.
  1321. *  If the first character encountered is a control-C, this routine
  1322. *  exits, leaving just the control-C in the buffer.
  1323. *
  1324. getline movem.l d2-d3/a0-a1/a6,-(sp)
  1325.         bsr     dmpstr          ;Flush the screen buffer first.
  1326.         move.l  dosbase,a6
  1327.         movea.l a0,a1
  1328.         addq.l  #2,a1           ;The current character loads here.
  1329.         clr.b   1(a0)           ;Clear character count.
  1330. getlinl move.l  rawhand,d1      ;Read from RAW:
  1331.         move.l  a1,d2           ; into current position
  1332.         moveq   #1,d3           ;  for a length of one byte.
  1333.         movem.l d1-d3/a0-a1,-(sp)
  1334.         sys     Read            ;Get a character.
  1335.         movem.l (sp)+,d1-d3/a0-a1
  1336.         cmpi.b  #cr,(a1)        ;Did we get a carriage return?
  1337.         beq.s   getlinc         ;Yes - stop here.
  1338.         cmpi.b  #lf,(a1)        ;Stop on a line feed too.
  1339.         beq.s   getlinc
  1340.         cmpi.b  #bs,(a1)        ;Backspace?
  1341.         bne.s   getlinp         ;No.
  1342.         tst.b   1(a0)           ;Do we have anything yet?
  1343.         beq.s   getlinl         ;No - ignore the backspace.
  1344.         subq.l  #1,a1           ;Back over the previous character.
  1345.         subq.b  #1,1(a0)        ;Decrement character count.
  1346.         movem.l a0-a1,-(sp)
  1347.         move.l  #bsmsg,d1
  1348.         jsr     pstring         ;Erase the previous character on the screen.
  1349.         movem.l (sp)+,a0-a1
  1350.         bra.s   getlinl
  1351. getlinp movem.l a0-a1,-(sp)
  1352.         sys     Write           ;Echo the current character.
  1353.         movem.l (sp)+,a0-a1
  1354. getlinn addq.b  #1,1(a0)        ;Bump character count.
  1355.         move.b  1(a0),d0        ;Number of bytes read so far.
  1356.         cmpi.b  #3,(a1)+        ;Did we get a control-C?
  1357.         bne.s   getlinf         ;No.
  1358.         cmpi.b  #1,d0           ;Is is the first character?
  1359.         beq.s   getlinx         ;Yes - exit now.
  1360. getlinf cmp.b   (a0),d0         ;Is the buffer full?
  1361.         bne.s   getlinl         ;No - try for another character.
  1362.         bra.s   getlinx
  1363. getlinc bsr     pcrlf           ;Carriage return or line feed
  1364. getlinx movem.l (sp)+,d2-d3/a0-a1/a6
  1365.         rts                     ;Exit.
  1366.  
  1367. *
  1368. * Display the message pointed to by D1.
  1369. *  The message must be terminated by a dollar sign.
  1370. *
  1371. pstring movem.l d2-d3/a1-a2,-(sp)       ;Save work registers.
  1372.         move.l  d1,a0           ;A0 scans the message.
  1373.         bset    #0,testdol      ;Suppress $ test?
  1374.         beq.s   pstrs           ;Yes (used by BDOS/BIOS character output)
  1375.         cmpi.b  #'$',(a0)       ;Null string?
  1376.         beq     pstrx           ;Yes - do nothing.
  1377. pstrs   move.l  strptr,a1       ;A1 loads the output buffer.
  1378.         move.l  #strbufn,d3
  1379.         sub.l   a1,d3           ;Number of bytes left in buffer
  1380.         ifne    h19
  1381.         moveq   #0,d0
  1382.         move.w  esclen,d0       ;Is a partial escape sequence saved?
  1383.         beq.s   pstrl           ;No.
  1384.         lea     escbuf,a2
  1385.         adda.l  d0,a2           ;Continue loading it here.
  1386.         clr.w   esclen          ;Reset "saved length" counter.
  1387.         cmpi.w  #2,d0           ;Did we just save one byte?
  1388.         blt.s   pstresc         ;Yes - get the remainder.
  1389.         bhi     pstreY2         ;Get the last cursor positioning byte.
  1390.         subq.l  #1,a2           ;Back over dummy byte.
  1391.         bra     pstreY1         ;Get both cursor positioning bytes.
  1392.         endc
  1393. pstrl:  cmpi.b  #lf,(a0)        ;Line feed?
  1394.         bne.s   notlf           ;No.
  1395.         lea     escbuf,a2       ;Translate it to a cursor-down sequence.
  1396.         move.b  #$9B,(a2)+
  1397.         move.b  #'B',(a2)+
  1398.         addq.l  #1,a0
  1399.         bra     pstrsub
  1400. notlf:
  1401.         ifne    h19
  1402. * Optional H19 escape sequence translation
  1403.         cmpi.b  #esc,(a0)       ;Escape character?
  1404.         bne     pstrm           ;No - treat it normally.
  1405.         lea     escbuf,a2       ;Build translated escape sequence here.
  1406.         move.b  #$9B,(a2)+      ;Start with an AmigaDOS escape character.
  1407.         addq.l  #1,a0           ;Check the next character.
  1408.         cmpi.b  #'$',(a0)       ;End of string?
  1409.         bne.s   pstresc         ;No - analyze the sequence.
  1410.         move.w  #1,esclen       ;We've saved one byte for next time.
  1411.         bra     pstrw           ;Write everything up to the ESC character.
  1412. pstresc move.b  (a0)+,d0
  1413.         cmpi.b  #'[',d0         ;ANSI escape sequence?
  1414.         beq     pstrsub         ;Yes - pass the sequence with $9B header.
  1415.         cmpi.b  #'Y',d0
  1416.         beq.s   pstreY          ;Set cursor position.
  1417.         cmpi.b  #'@',d0
  1418.         beq.s   pstrein         ;Set insert mode.
  1419.         cmpi.b  #'A',d0
  1420.         blt.s   pstreun         ;Unknown code - copy it as is.
  1421.         cmpi.b  #'O',d0
  1422.         beq.s   pstreO          ;Reset insert mode.
  1423.         bhi.s   pstreun         ;Unknown code
  1424.         move.l  a0,-(sp)
  1425.         lea     esctran,a0      ;Translation table with offset
  1426.         move.b  -'A'(a0,d0.w),d2;Get the translated code.
  1427.         move.l  (sp)+,a0
  1428.         btst    #6,d2           ;Does the translated code stand alone?
  1429.         bne.s   pstresb         ;No.
  1430.         subq.l  #1,a2           ;Back over stored CSI character.
  1431. pstresb move.b  d2,(a2)+        ;Get the translated code.
  1432.         bra.s   pstrsub
  1433. pstrein move.b  #1,insflag      ;Set insert mode.
  1434.         bra.s   pstrsbx
  1435. pstreO  clr.b   insflag         ;Reset insert mode.
  1436.         bra.s   pstrsbx
  1437. pstreY  cmpi.b  #'Y',d0         ;Set cursor position
  1438.         bne.s   pstreun
  1439.         cmpi.b  #'$',(a0)       ;End of string?
  1440.         bne.s   pstreY1         ;No.
  1441.         move.w  #2,esclen       ;Indicate we need both position bytes.
  1442.         bra     pstrw           ;Finish the sequence next time.
  1443. pstreY1 moveq   #0,d0
  1444.         move.b  (a0)+,d0        ;Get the first position byte.
  1445.         bsr     pstrcvd         ;Convert to decimal in save area.
  1446.         move.b  #';',(a2)+      ;Add the separator character.
  1447.         cmpi.b  #'$',(a0)       ;End of string?
  1448.         bne.s   pstreY2         ;No.
  1449.         sub.l   #escbuf,a2      ;Number of bytes saved
  1450.         move.w  a2,esclen
  1451.         bra     pstrw           ;Get the last byte next time.
  1452. pstreY2 moveq   #0,d0
  1453.         move.b  (a0)+,d0        ;Get the last position byte.
  1454.         bsr     pstrcvd         ;Convert to decimal in save area.
  1455.         move.b  #'H',(a2)+      ;Terminate the sequence.
  1456.         bra.s   pstrsub
  1457. pstreun move.b  #esc,escbuf     ;Unidentified escape sequence -
  1458.         move.b  d0,(a2)+        ; pass it through as is.
  1459. * The translated escape sequence is now in "escbuf" -
  1460. *  copy it to the output buffer.
  1461. pstrsub move.l  a2,d0
  1462.         lea     escbuf,a2       ;A2 scans translated escape sequence.
  1463.         sub.l   a2,d0           ;Length of translated escape sequence
  1464.         subq.l  #1,d0
  1465. pstrsbl move.b  (a2)+,(a1)+     ;Copy substitution to output string.
  1466.         subq.w  #1,d3           ;Count down remaining length.
  1467.         dbra    d0,pstrsbl
  1468. pstrsbx cmpi.b  #'$',(a0)       ;End of string?
  1469.         beq     pstrw           ;Yes - write it out.
  1470.         tst.w   d3              ;Is the buffer full?
  1471.         bmi     pstrw           ;Yes - write out what we have.
  1472.         cmpi.b  #lf,-1(a0)      ;Line feed?
  1473.         bne     pstrl           ;No.
  1474.         tst.b   bufflag         ;Is console buffering in effect?
  1475.         beq     pstrl           ;No.
  1476.         move.l  a1,strptr
  1477.         bsr     dmpstr          ;Dump the buffer.
  1478.         move.l  strptr,a1
  1479.         bra     pstrl           ;Check for another escape sequence.
  1480. * Subroutine to convert the byte in D0 to a character string at (A2)+
  1481. pstrcvd subi.b  #' '-1,d0       ;Convert to binary row or column number.
  1482.         divu    #10,d0          ;Convert to tens and units.
  1483.         tst.w   d0              ;Is the number 10 or greater?
  1484.         beq.s   pstrcv1         ;No - just create a one-digit number.
  1485.         addi.b  #'0',d0         ;Convert the tens digit to ASCII.
  1486.         move.b  d0,(a2)+        ;Move it to the result field.
  1487. pstrcv1 swap    d0              ;Get the units digit.
  1488.         addi.b  #'0',d0         ;Convert it to ASCII.
  1489.         move.b  d0,(a2)+
  1490.         rts
  1491.         endc
  1492. * Normal character processing
  1493. pstrm   tst.b   insflag         ;Are we in insert mode?
  1494.         beq.s   pstrmv          ;No.
  1495.         lea     escbuf,a2
  1496.         move.b  #$9B,(a2)+      ;Build an insert-character sequence.
  1497.         move.b  #'@',(a2)+
  1498.         move.b  (a0)+,(a2)+     ;Here's the character to insert.
  1499.         bra.s   pstrsub         ;Use the substitution routine.
  1500. pstrmv  move.b  (a0)+,(a1)+     ;Move one character.
  1501.         tst.b   bufflag         ;Is console buffering in effect?
  1502.         beq.s   pstreos         ;No.
  1503.         cmpi.b  #cr,-1(a0)      ;Carriage return?
  1504.         beq.s   pstrseg         ;Yes - dump the current segment.
  1505.         cmpi.b  #bel,-1(a0)     ;Bell?
  1506.         bne.s   pstreos         ;No - continue buffering.
  1507. pstrseg move.l  a1,strptr
  1508.         bsr     dmpstr          ;Dump the buffer.
  1509.         move.l  strptr,a1
  1510. pstreos cmpi.b  #'$',(a0)       ;Test for end of string.
  1511.         dbeq    d3,pstrl        ;Loop until we get there or buffer is full.
  1512. pstrw   move.l  a1,strptr
  1513.         tst     d3              ;Is the buffer full?
  1514.         bmi.s   pstrdmp         ;Yes - dump it regardless.
  1515.         tst.b   bufflag         ;Is console buffering in effect?
  1516.         bne.s   pstrnxt         ;Yes - don't write anything yet.
  1517. pstrdmp bsr     dmpstr          ;Dump the buffer.
  1518.         move.l  strptr,a1
  1519. pstrnxt tst     d3              ;Did the output buffer overflow?
  1520.         bmi     pstrs           ;Yes - get another section of the message.
  1521. pstrx   movem.l (sp)+,d2-d3/a1-a2       ;Restore registers
  1522.         rts
  1523. *
  1524. * Write the contents of "strbuf" to RAW: if possible, or stdout if not.
  1525. *  The number of bytes to be written is calculated from "strptr".
  1526. *
  1527. dmpstr  movem.l d2-d3/a0-a1/a6,-(sp)
  1528.         move.l  strptr,d3
  1529.         move.l  #strbuf,d2      ;Address of buffer
  1530.         move.l  d2,strptr       ;Reset the buffer pointer.
  1531.         sub.l   d2,d3           ;Length of output string
  1532.         beq.s   dmpstrx         ;Zero - don't write anything.
  1533.         move.l  rawhand,d1      ;Assume we're writing to RAW:
  1534.         bne.s   dmpstrp
  1535.         move.l  stdout,d1       ;We don't have RAW: - use stdout.
  1536. dmpstrp move.l  dosbase,a6
  1537.         sys     Write           ;Display the line.
  1538. dmpstrx movem.l (sp)+,d2-d3/a0-a1/a6
  1539.         rts
  1540.  
  1541. *
  1542. * Convert the file name in the FCB pointed to by A0
  1543. *  to an AmigaDOS-format file name in the field pointed to by A1.
  1544. *  D0 is the only other register used by this routine.
  1545. *
  1546. convfn  move.l  a1,-(sp)
  1547.         move.l  a0,-(sp)        ;Save start address of FCB.
  1548.         tst.b   (a0)+           ;Skip over drive code for now.
  1549.         moveq   #7,d0           ;Maximum of 8 characters for file name
  1550. convfn1 cmpi.b  #' ',(a0)       ;End of file name?
  1551.         beq.s   convfnz         ;Yes
  1552.         move.b  (a0)+,(a1)+     ;Move one character of file name.
  1553.         dbra    d0,convfn1      ;Try for more.
  1554. convfnz movea.l (sp)+,a0        ;Back to start of FCB.
  1555.         adda.l  #9,a0           ;Go to start of file name extension.
  1556.         cmpi.b  #' ',(a0)       ;Do we have an extension?
  1557.         beq.s   convfnx         ;No.
  1558.         move.b  #'.',(a1)+      ;Insert extension separator.
  1559.         moveq   #2,d0           ;Maximum of 3 characters for extension.
  1560. convfn2 cmpi.b  #' ',(a0)       ;End of extension?
  1561.         beq.s   convfnx         ;Yes.
  1562.         move.b  (a0)+,(a1)+     ;Move one character of extension.
  1563.         dbra    d0,convfn2      ;Try for more.
  1564. convfnx clr.b   (a1)            ;Terminate file name string.
  1565.         move.l  (sp)+,a1
  1566.         rts
  1567.  
  1568. *
  1569. * Get the file handle indicated by the number inserted into the
  1570. *  CP/M FCB by the open routine.  It is copied from the file handle
  1571. *  table entry (whose address is set up as 0(A1,D0.W)) to D1.
  1572. *  The Z flag will be set if the handle is zero (i.e. file not open).
  1573. *  A0 points to the FCB.
  1574. *
  1575. gethand add.l   targbase,d1     ;The FCB is here.
  1576.         movea.l d1,a0
  1577.         lea     handles,a1
  1578.         moveq   #0,d0
  1579.         move.b  13(a0),d0       ;Get handle number from FCB.
  1580.         asl.w   #2,d0           ;Convert to table offset.
  1581.         move.l  0(a1,d0.w),d1   ;Get the file handle.
  1582.         rts
  1583.         page
  1584. *************************************************************************
  1585. *                                                                       *
  1586. *       Miscellaneous service routines                                  *
  1587. *       (Inelegant, but rarely used so they stand as is.)               *
  1588. *                                                                       *
  1589. *************************************************************************
  1590.  
  1591. *
  1592. * Display the contents of D1 in hex.
  1593. *
  1594. pbyte   move.l  #$20018,d0      ;2 nybbles, 24-bit shift first
  1595.         bra.s   phex
  1596. pword   move.l  #$40010,d0      ;4 nybbles, 16-bit shift first
  1597.         bra.s   phex
  1598. paddr   move.l  #$60008,d0      ;6 nybbles, 8-bit shift first
  1599.         bra.s   phex
  1600. plong   move.l  #$80000,d0      ;8 nybbles, no shift first
  1601. phex    lea     workbuf,a0
  1602.         move.l  a0,-(sp)
  1603.         bsr     pdigits
  1604.         move.b  #'$',(a0)+
  1605.         move.l  (sp)+,d1
  1606.         bsr     pstring
  1607.         rts
  1608. *
  1609. * Convert the contents of D1 to hex at (A0).
  1610. *  On exit, A0 points to the next available byte.
  1611. *
  1612. ubyte   move.l  #$20018,d0      ;2 nybbles, 24-bit shift first
  1613.         bra.s   pdigits
  1614. uword   move.l  #$40010,d0      ;4 nybbles, 16-bit shift first
  1615.         bra.s   pdigits
  1616. uaddr   move.l  #$60008,d0      ;6 nybbles, 8-bit shift first
  1617.         bra.s   pdigits
  1618. ulong   move.l  #$80000,d0      ;8 nybbles, no shift first
  1619. pdigits rol.l   d0,d1           ;Do shift.
  1620.         bra.s   pdigent
  1621. pdiglop swap    d0              ;Save nybble count.
  1622.         rol.l   #4,d1           ;Print variable in d1.
  1623.         move.l  d1,-(sp)
  1624.         and     #$F,d1          ;Isolate the current nybble.
  1625.         cmp     #$A,d1
  1626.         blt.s   ntoa2
  1627.         add.b   #'A'-'9'-1,d1   ;Adjust for digits A through F.
  1628. ntoa2   add.b   #'0',d1         ;Convert to ASCII.
  1629.         move.b  d1,(a0)+        ;Add to the result string.
  1630.         move.l  (sp)+,d1
  1631. pdigent swap    d0              ;Get nybble count.
  1632.         dbra    d0,pdiglop
  1633.         rts
  1634.  
  1635. pchar   move.b  d1,workbuf      ;Print the character in D1.
  1636.         move.b  #'$',workbuf+1
  1637.         move.l  #workbuf,d1
  1638.         bsr     pstring
  1639.         rts
  1640.  
  1641. pspace  move.l  #spacemsg,d1    ;Print a space.
  1642.         bsr     pstring
  1643.         rts
  1644.  
  1645. pcrlf   move.l  #crlfmsg,d1     ;Print a carriage return and line feed.
  1646.         bsr     pstring
  1647.         rts
  1648.  
  1649. *
  1650. * Convert the hex string pointed to by A0 to long in d1.
  1651. *  Stops on the first invalid hex digit, which is returned in d0.
  1652. *  A0 is left pointing to this first invalid digit.
  1653. *  d2 = 1 if any valid digits were found, 0 otherwise.
  1654. *
  1655. atol    moveq   #0,d1
  1656.         moveq   #0,d2
  1657. atol1   move.b  (a0)+,d0        ;Get the current byte.
  1658.         cmpi.b  #$40,d0
  1659.         blt.s   atol2
  1660.         and     #$5F,d0         ;Mask to upper case.
  1661. atol2   cmpi.b  #'0',d0         ;Check range (0..9,A..F).
  1662.         blt.s   atolend
  1663.         cmpi.b  #'F',d0
  1664.         bhi.s   atolend
  1665.         cmpi.b  #'9',d0
  1666.         ble.s   atol3
  1667.         cmpi.b  #'A'-1,d0
  1668.         bhi.s   atol3
  1669.         bra.s   atolend
  1670. atol3   moveq   #1,d2           ;Valid characters entered, set flag.
  1671.         sub.b   #'0',d0         ;Convert to binary
  1672.         cmp.b   #$9,d0          ;Digit in range 0..9?
  1673.         ble.s   atol4           ;Yes - conversion is complete
  1674.         sub.b   #'A'-'9'-1,d0   ;Adjust digits A..F.
  1675. atol4   ext     d0              ;Convert to long.
  1676.         ext.l   d0
  1677.         asl.l   #4,d1           ;Tack it onto d1.
  1678.         add.l   d0,d1
  1679.         bra.s   atol1           ;Try for another digit.
  1680. atolend subq.l  #1,a0           ;Back onto the first invalid digit.
  1681.         rts
  1682.         page
  1683. *************************************************************************
  1684. *                                                                       *
  1685. *       This table contains the mnemonic strings for the 8080           *
  1686. *       opcodes.  These are used in tracing.  The first character       *
  1687. *       flags operands.  Blank is nothing, A is an address (i.e.        *
  1688. *       a 16-bit value), and C is a constant (i.e. an 8-bit value).     *
  1689. *                                                                       *
  1690. *************************************************************************
  1691.  
  1692.         data    data
  1693.  
  1694. mnops:
  1695.         dc.b    ' NOP$    ALXI B,$  STAX B$  INX B$  '  ;00-03
  1696.         dc.b    ' INR B$   DCR B$  CMVI B,$  RLC$    '  ;04-07
  1697.         dc.b    ' ILLEGAL$ DAD B$   LDAX B$  DCX B$  '  ;08-0B
  1698.         dc.b    ' INR C$   DCR C$  CMVI C,$  RRC$    '  ;0C-0F
  1699.         dc.b    ' ILLEGAL$ALXI D,$  STAX D$  INX D$  '  ;10-13
  1700.         dc.b    ' INR D$   DCR D$  CMVI D,$  RAL$    '  ;14-17
  1701.         dc.b    ' JR$      DAD D$   LDAX D$  DCX D$  '  ;18-1B
  1702.         dc.b    ' INR E$   DCR E$  CMVI E,$  RAR$    '  ;1C-1F
  1703.         dc.b    ' JRNZ$   ALXI H,$ ASHLD $   INX H$  '  ;20-23
  1704.         dc.b    ' INR H$   DCR H$  CMVI H,$  DAA$    '  ;24-27
  1705.         dc.b    ' JRZ$     DAD H$  ALHLD $   DCX H$  '  ;28-2B
  1706.         dc.b    ' INR L$   DCR L$  CMVI L,$  CMA$    '  ;2C-2F
  1707.         dc.b    ' JRNC$   ALXI SP,$ASTA $    INX SP$ '  ;30-33
  1708.         dc.b    ' INR M$   DCR M$  CMVI M,$  STC$    '  ;34-37
  1709.         dc.b    ' JRC$     DAD SP$ ALDA $    DCX SP$ '  ;38-3B
  1710.         dc.b    ' INR A$   DCR A$  CMVI A,$  CMC$    '  ;3C-3F
  1711.         dc.b    ' MOV B,B$ MOV B,C$ MOV B,D$ MOV B,E$'  ;40-43
  1712.         dc.b    ' MOV B,H$ MOV B,L$ MOV B,M$ MOV B,A$'  ;44-47
  1713.         dc.b    ' MOV C,B$ MOV C,C$ MOV C,D$ MOV C,E$'  ;48-4B
  1714.         dc.b    ' MOV C,H$ MOV C,L$ MOV C,M$ MOV C,A$'  ;4C-4F
  1715.         dc.b    ' MOV D,B$ MOV D,C$ MOV D,D$ MOV D,E$'  ;50-53
  1716.         dc.b    ' MOV D,H$ MOV D,L$ MOV D,M$ MOV D,A$'  ;54-57
  1717.         dc.b    ' MOV E,B$ MOV E,C$ MOV E,D$ MOV E,E$'  ;58-5B
  1718.         dc.b    ' MOV E,H$ MOV E,L$ MOV E,M$ MOV E,A$'  ;5C-5F
  1719.         dc.b    ' MOV H,B$ MOV H,C$ MOV H,D$ MOV H,E$'  ;60-63
  1720.         dc.b    ' MOV H,H$ MOV H,L$ MOV H,M$ MOV H,A$'  ;64-67
  1721.         dc.b    ' MOV L,B$ MOV L,C$ MOV L,D$ MOV L,E$'  ;68-6B
  1722.         dc.b    ' MOV L,H$ MOV L,L$ MOV L,M$ MOV L,A$'  ;6C-6F
  1723.         dc.b    ' MOV M,B$ MOV M,C$ MOV M,D$ MOV M,E$'  ;70-73
  1724.         dc.b    ' MOV M,H$ MOV M,L$ HLT$     MOV M,A$'  ;74-77
  1725.         dc.b    ' MOV A,B$ MOV A,C$ MOV A,D$ MOV A,E$'  ;78-7B
  1726.         dc.b    ' MOV A,H$ MOV A,L$ MOV A,M$ MOV A,A$'  ;7C-7F
  1727.         dc.b    ' ADD B$   ADD C$   ADD D$   ADD E$  '  ;80-83
  1728.         dc.b    ' ADD H$   ADD L$   ADD M$   ADD A$  '  ;84-87
  1729.         dc.b    ' ADC B$   ADC C$   ADC D$   ADC E$  '  ;88-8B
  1730.         dc.b    ' ADC H$   ADC L$   ADC M$   ADC A$  '  ;8C-8F
  1731.         dc.b    ' SUB B$   SUB C$   SUB D$   SUB E$  '  ;90-93
  1732.         dc.b    ' SUB H$   SUB L$   SUB M$   SUB A$  '  ;94-97
  1733.         dc.b    ' SBB B$   SBB C$   SBB D$   SBB E$  '  ;98-9B
  1734.         dc.b    ' SBB H$   SBB L$   SBB M$   SBB A$  '  ;9C-9F
  1735.         dc.b    ' ANA B$   ANA C$   ANA D$   ANA E$  '  ;A0-A3
  1736.         dc.b    ' ANA H$   ANA L$   ANA M$   ANA A$  '  ;A4-A7
  1737.         dc.b    ' XRA B$   XRA C$   XRA D$   XRA E$  '  ;A8-AB
  1738.         dc.b    ' XRA H$   XRA L$   XRA M$   XRA A$  '  ;AC-AF
  1739.         dc.b    ' ORA B$   ORA C$   ORA D$   ORA E$  '  ;B0-B3
  1740.         dc.b    ' ORA H$   ORA L$   ORA M$   ORA A$  '  ;B4-B7
  1741.         dc.b    ' CMP B$   CMP C$   CMP D$   CMP E$  '  ;B8-BB
  1742.         dc.b    ' CMP H$   CMP L$   CMP M$   CMP A$  '  ;BC-BF
  1743.         dc.b    ' RNZ$     POP B$  AJNZ $   AJMP $   '  ;C0-C3
  1744.         dc.b    'ACNZ $    PUSH B$ CADI $    RST 0$  '  ;C4-C7
  1745.         dc.b    ' RZ$      RET$    AJZ $     ILLEGAL$'  ;C8-CB
  1746.         dc.b    'ACZ $    ACALL $  CACI $    RST 1$  '  ;CC-CF
  1747.         dc.b    ' RNC$     POP D$  AJNC $   COUT $   '  ;D0-D3
  1748.         dc.b    'ACNC $    PUSH D$ CSUI $    RST 2$  '  ;D4-D7
  1749.         dc.b    ' RC$      EXX$    AJC $    CIN $    '  ;D8-DB
  1750.         dc.b    'ACC $     ILLEGAL$CSBI $    RST 3$  '  ;DC-DF
  1751.         dc.b    ' RPO$     POP H$  AJPO $    XTHL$   '  ;E0-E3
  1752.         dc.b    'ACPO $    PUSH H$ CANI $    RST 4$  '  ;E4-E7
  1753.         dc.b    ' RPE$     PCHL$   AJPE $    XCHG$   '  ;E8-EB
  1754.         dc.b    'ACPE $    ILLEGAL$CXRI $    RST 5$  '  ;EC-EF
  1755.         dc.b    ' RP$      POP PSW$AJP $     DI$     '  ;F0-F3
  1756.         dc.b    'ACP $     PUSH P$ CORI $    RST 6$  '  ;F4-F7
  1757.         dc.b    ' RM$      SPHL$   AJM $     EI$     '  ;F8-FB
  1758.         dc.b    'ACM $     ILLEGAL$CCPI $    RST 7$  '  ;FC-FF
  1759.         page
  1760. *************************************************************************
  1761. *                                                                       *
  1762. *       Fake FDOS                                                       *
  1763. *                                                                       *
  1764. *************************************************************************
  1765.  
  1766. *
  1767. * Fake BDOS for target system
  1768. *
  1769. fdos    dc.b    tHLT,0,tRET       ;BIOS jump table
  1770.         dc.b    tJMP,$33,$FF     ;Warm boot
  1771.         dc.b    tJMP,$36,$FF     ;Console status
  1772.         dc.b    tJMP,$39,$FF     ;Console input
  1773.         dc.b    tJMP,$3C,$FF     ;Console output
  1774.         dc.b    tJMP,$3F,$FF     ;List output
  1775.         dc.b    tJMP,$42,$FF     ;Punch output
  1776.         dc.b    tJMP,$45,$FF     ;Reader input
  1777.         dc.b    tJMP,$48,$FF     ;Home disk
  1778.         dc.b    tJMP,$4B,$FF     ;Select disk
  1779.         dc.b    tJMP,$4E,$FF     ;Set track
  1780.         dc.b    tJMP,$51,$FF     ;Set sector
  1781.         dc.b    tJMP,$54,$FF     ;Set DMA address
  1782.         dc.b    tJMP,$57,$FF     ;Read
  1783.         dc.b    tJMP,$5A,$FF     ;Write
  1784.         dc.b    tJMP,$5D,$FF     ;Get list device status
  1785.         dc.b    tJMP,$60,$FF     ;Sector translation
  1786. *
  1787. * Fake BIOS for target system
  1788. *
  1789.         dc.b    tHLT,1,tRET       ;Warm boot
  1790.         dc.b    tHLT,2,tRET       ;Console status
  1791.         dc.b    tHLT,3,tRET       ;Console input
  1792.         dc.b    tHLT,4,tRET       ;Console output
  1793.         dc.b    tHLT,5,tRET       ;List output
  1794.         dc.b    tHLT,6,tRET       ;Punch output
  1795.         dc.b    tHLT,7,tRET       ;Reader input
  1796.         dc.b    tHLT,8,tRET       ;Home disk *
  1797.         dc.b    tHLT,9,tRET       ;Select disk *
  1798.         dc.b    tHLT,10,tRET      ;Set track *
  1799.         dc.b    tHLT,11,tRET      ;Set sector *
  1800.         dc.b    tHLT,12,tRET      ;Set DMA address *
  1801.         dc.b    tHLT,13,tRET      ;Read *
  1802.         dc.b    tHLT,14,tRET      ;Write *
  1803.         dc.b    tHLT,15,tRET      ;Get list device status *
  1804.         dc.b    tHLT,16,tRET      ;Sector translation *
  1805. *
  1806. * Fake Disk Parameter Block
  1807. *
  1808.         dc.b    26,0,3,$07,0,242,0,$3f
  1809. *
  1810. * Fake Disk Block Allocation Table
  1811. *
  1812.         dcb.b   21,$FF
  1813.         dc.b    %11111100
  1814.         dcb.b   10,0
  1815.  
  1816. fdoslen equ     *-fdos
  1817.  
  1818. *
  1819. * BDOS function vector table
  1820. *
  1821.         cnop    0,4
  1822. bdostab dc.l    bdos00,bdos01,bdos02,bdos03,bdos04,bdos05,bdos06,bdos07
  1823.         dc.l    bdos08,bdos09,bdos10,bdos11,bdos12,bdos13,bdos14,bdos15
  1824.         dc.l    bdos16,bdos17,bdos18,bdos19,bdos20,bdos21,bdos22,bdos23
  1825.         dc.l    bdos24,bdos25,bdos26,bdos27,bdos28,bdos29,bdos30,bdos31
  1826.         dc.l    bdos32,bdos33,bdos34,bdos35,bdos36
  1827. bdostabn:
  1828.  
  1829. *
  1830. * BIOS function vector table
  1831. *
  1832.         cnop    0,4
  1833. biostab dc.l    bdosfn,bios01,bios02,bios03,bios04,bios05,bios06,bios07
  1834.         dc.l    bios08,bios09,bios10,bios11,bios12,bios13,bios14,bios15
  1835. biostabn:
  1836.         page
  1837. *************************************************************************
  1838. *                                                                       *
  1839. *       Messages                                                        *
  1840. *                                                                       *
  1841. *************************************************************************
  1842.  
  1843. dosname dc.b    'dos.library',0
  1844. aprompt dc.b    'A>$'
  1845. crlfmsg dc.b    cr,lf,'$'
  1846. spacemsg dc.b   ' $'
  1847. bsmsg   dc.b    bs,' ',bs,'$'   ;Erases the previous character
  1848. simsg   dc.b    si,'$'          ;Resets MSB of each output character
  1849. rawspec dc.b    'RAW:0/0/640/200/CP/M Emulator'
  1850.         dc.b    ' by J. Cathey, C. Gibbs & W. Kusche - V'
  1851.         dc.b    vermaj&15+'0','.'
  1852.         dc.b    vermin/16+'0',vermin&15+'0',' ('
  1853.         dc.b    revmonth/16+'0',revmonth&15+'0','/'
  1854.         dc.b    revday/16+'0',revday&15+'0','/'
  1855.         dc.b    revyear/16+'0',revyear&15+'0',')',0
  1856. rawerr  dc.b    'Unable to open RAW: - code $'
  1857. setwin  dc.b    $9B,'0x',$9B,'8y',$9B,'24t',$9B,'80u',$9B,'H',$9B,'J$'
  1858. fullmsg dc.b    'Too many files are open!',cr,lf,'$'
  1859. illgmsg dc.b    cr,lf,'Illegal instruction $'
  1860. ilgmsg2 dc.b    ' at $'
  1861. ilgmsg3 dc.b    '.$'
  1862. dumpmsg dc.b    cr,lf,'Register contents:$'
  1863. dmpmsg3 dc.b    '(Q)uit, (C)hange trace address, (S)top tracing, '
  1864.         dc.b    'any other key to continue: $'
  1865. ilgbios dc.b    cr,lf,'Illegal BIOS call $'
  1866. ilgbdos dc.b    cr,lf,'Illegal BDOS call $'
  1867. tracemsg dc.b   cr,lf,'Start trace at >$'
  1868. tracemg2 dc.b   '  End trace at >$'
  1869. btrcmsg dc.b    'Trace BIOS/BDOS calls? >$'
  1870. biosmsg dc.b    'BIOS call $'
  1871. bdosmsg dc.b    'BDOS call $'
  1872. atmsg   dc.b    ' at $'
  1873. esctran dc.b    'ABCD',ff,so,si,'H',$8D,'JKLMP' ;Escape sequence translation
  1874. prtname dc.b    'PRT:RAW',0
  1875. badprt  dc.b    'Unable to open the list device!$'
  1876.         page
  1877. *************************************************************************
  1878. *                                                                       *
  1879. *       Variable storage                                                *
  1880. *                                                                       *
  1881. *************************************************************************
  1882.  
  1883.         bss     bss
  1884.  
  1885. savesp  ds.l    1               ;Stack pointer save area
  1886. dosbase ds.l    1               ;Pointer to dos.library
  1887. stdin   ds.l    1               ;Keyboard handle (stdin)
  1888. stdout  ds.l    1               ;Screen handle (stdout)
  1889. rawhand ds.l    1               ;RAW: file handle
  1890. prthand ds.l    1               ;PRT:RAW file handle
  1891. lockaddr:
  1892.         ds.l    1               ;Lock address - for retrieving file size
  1893. CurDir  ds.l    1               ;Old lock - current directory
  1894. handles ds.l    8               ;File handles for opened files (or zero)
  1895. handlen:                        ;End of file handle table
  1896. dmaaddr ds.l    1               ;Current DMA address
  1897. comend  ds.l    1               ;End of .COM file name on command line
  1898. FileInfo:
  1899.         ds.l    32              ;FileInfoBlock
  1900. cmdline ds.b    128             ;Command line
  1901. cmdlinen:                       ;End of command line
  1902. comname ds.b    13              ;Name of file to load
  1903. comnamen:                       ;End of file name
  1904. opnname ds.b    17              ;File name for OPEN or RENAME
  1905. renname ds.b    17              ;New file name for RENAME
  1906. scanname:
  1907.         ds.b    17              ;File name for directory scan
  1908. newrega ds.b    1               ;BIOS/BDOS accumulator work area
  1909. workbuf ds.b    80              ;Work buffer for "pstring" (including $)
  1910. workbufn:                       ;End of work buffer
  1911. DirFName:
  1912.         ds.b    80              ;Last 72 bytes leave room for non-CP/M names
  1913. DirFExt ds.b    80              ;Last 77 bytes leave room for non-CP/M names
  1914. strbuf  ds.b    2048            ;String output buffer
  1915. strbufn ds.b    8               ;"strbuf" overflow area - must follow "strbuf"!
  1916. strptr  ds.l    1               ;Current position in "strbuf"
  1917. escbuf  ds.b    8               ;Translated escape sequence
  1918. esclen  ds.w    1               ;Number of bytes saved in "escbuf"
  1919. cmdflag ds.b    1               ;Take program name from command line.
  1920. quitflg ds.b    1               ;"quitprg" exit flag
  1921. testdol ds.b    1               ;"pstring" should test for leading $
  1922. insflag ds.b    1               ;We're in insert mode.
  1923. dumpcnt ds.b    1               ;"dump" counter for pausing
  1924. btrcflg ds.b    1               ;Trace BIOS/BDOS calls.
  1925. bufflag ds.b    1               ;Console output is buffered.
  1926. fcbptr  ds.l    1               ;Pointer to current FCB
  1927. listopn ds.b    1               ;The list device is open.
  1928. *************************************************************************
  1929. *                                                                       *
  1930. *       Target processor's address space                                *
  1931. *                                                                       *
  1932. *************************************************************************
  1933.  
  1934.         even
  1935.  
  1936. registers ds.b  22              ;Actual storage for Z80's other registers
  1937. target  ds.b    $10000          ;Z80's universe
  1938.  
  1939.         end
  1940.  
  1941.