home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / developm / source / assembly.txt < prev    next >
Encoding:
Text File  |  1992-11-05  |  19.6 KB  |  478 lines

  1.  ; io.asm
  2.  ;  "Frame" program and I/O subroutines for general purpose assembly language
  3.  ;  programs.  To use this package:
  4.  ;  1. The first line in your file should be "include iodefs.txt".
  5.  ;  2. Your main program must begin with the label "main" and end with rts.
  6.  ;  3. Your .ld file should look like this, if your source file is called
  7.  ;     myprog.asm:
  8.  ;                      !start
  9.  ;                      io
  10.  ;                      myprog
  11.  ;                      $
  12.  ;  4. Pass arguments to subroutines in this package, and receive return
  13.  ;     values, in D0 or A0 as specified.  All registers are preserved (but
  14.  ;     subroutine rdchar does not preserve A0).
  15.  ;  5. Always call subroutine makewindow at the beginning of your main
  16.  ;     program, passing the address of your title string in A0.
  17.  
  18.  ; Include all necessary traps files
  19.  
  20.  include        m68klib.d
  21.  include systraps.txt
  22.  include quicktraps.txt
  23.  include tooltraps.txt
  24.  
  25.  WINDWIDTH equ 492      ; window dimensions
  26.  WINDHEIGHT equ 280     
  27.  X1     equ 8           ; upper-left and lower-right coordinates
  28.  Y1     equ 48          ; for bounds rectangle for window
  29.  X2     equ X1+WINDWIDTH
  30.  Y2     equ Y1+WINDHEIGHT
  31.  LMARG  equ 6             ; text margins - left,
  32.  RMARG  equ WINDWIDTH-10  ; right,
  33.  TMARG  equ 15            ; top,
  34.  BMARG  equ WINDHEIGHT-15 ; bottom
  35.  CR     equ 13          ; ascii carriage return
  36.  BS     equ 8           ; ascii backspace
  37.  DASH   equ 45          ; ascii minus sign
  38.  ZERO   equ 48          ; ascii character for digit zero
  39.  NINE   equ 57          ; ascii character for digit nine
  40.  PROGFONT equ 4         ; Monaco font code
  41.  ASCENT equ 0           ; offsets of fields in fontinfo record
  42.  DESCENT        equ 2
  43.  WIDMAX equ 4
  44.  LEADING        equ 6
  45.  BUFSIZE equ 256                ; size of input buffer
  46.  
  47.  xdef   start
  48.  xref   main
  49.  
  50.  ;  Preserve registers in safe place; initialize graphics, font manager,
  51.  ;  windows, cursor, and textedit; call main program; restore registers
  52.  ;  and exit.
  53.  
  54.  start: movem.l D0-D7/A0-A6, -(SP)      ; save all registers
  55.         lea     saveregs, A0
  56.         move.l  A6, (A0)
  57.         move.l  A7, 4(A0)
  58.         
  59.         move.l  A5, D0                  ; set up quickdraw
  60.         sub.l   #4, D0
  61.         move.l  D0, -(SP)
  62.         _INITGRAF
  63.         _INITFONT
  64.         _INITWINDOW
  65.         _INITCURSOR
  66.         _TEINIT
  67.         
  68.         bsr main                        ; call the main program
  69.         
  70.         lea     saveregs, A0
  71.         move.l  (A0), A6
  72.         move.l  4(A0), A7
  73.         movem.l (SP)+, D0-D7/A0-A6
  74.         _EXITTOSHELL
  75.         
  76.  
  77.  ; Subroutine makewindow ( StringAddress )
  78.  ;  Receives argument in A0
  79.  ;      Creates and displays a desk-accessory style window with title
  80.  ;      specified by string whose address is passed; flushes event queue
  81.  ;      and initializes cursor position for text I/O
  82.  
  83.  xdef   makewindow
  84.  
  85.  makewindow:
  86.         movem.l D0-D2/A0-A1, -(SP)      ; save registers
  87.         clr.l   -(SP)                   ; space for return window pointer
  88.         clr.l   -(SP)                   ; nil wstorage pointer - window 
  89.                                         ;  record storage will be allocated
  90.                                         ;  on heap
  91.         pea     boundsrect              ; determines window size and loc
  92.         move.l  A0, -(SP)               ; window title
  93.         st      -(SP)                   ; visible flag true - draw window
  94.         move    #16, -(SP)              ; procid - desk accessory type window
  95.         move.l  #-1, -(SP)              ; behind pointer -1 means in front
  96.                                         ;  of all other windows
  97.         sf      -(SP)                   ; goaway flag false - no goaway box
  98.         clr.l   -(SP)                   ; refcon (not used)
  99.         _NEWWINDOW
  100.         move.l  (SP), window(A5)
  101.         _SETPORT
  102.         clr.l   -(SP)
  103.         _NEWRGN                         ; create a region
  104.         lea     scrollrgnh, A0
  105.         move.l  (SP), (A0)
  106.         pea     scrollrect              ; with same bounds as boundsrect
  107.         _RECTRGN                        ; (required later for scrolling)
  108.         move.w  #PROGFONT, -(SP)        ; set font to Geneva (monofont)
  109.         _TEXTFONT
  110.         pea     fontinfo                ; get information on font
  111.         _GETFONTINFO                    ;  dimension parameters
  112.         clr.w   D0                      ; accumulate line height in D0
  113.         add.w   fontinfo+ASCENT, D0
  114.         add.w   fontinfo+DESCENT, D0
  115.         add.w   fontinfo+LEADING, D0
  116.         lea     lnht, A0
  117.         move.w  D0, (A0)                ; store in lnht
  118.         move.l  D0, -(SP)               ; flush event queue
  119.         move.l  #$0000FFFF, D0
  120.         _FLUSHEVENTS
  121.         move.l  (SP)+, D0
  122.         move    #LMARG, -(SP)           ; initialize cursor position
  123.         move    #TMARG, -(SP)
  124.         _MOVETO
  125.         movem.l (SP)+, D0-D2/A0-A1      ; restore registers
  126.         rts
  127.         
  128.  ; Subroutine clearwindow
  129.  ;      Erases contents of window and 'homes' pen to original position in
  130.  ;      upper left corner.
  131.  
  132.  xdef   clearwindow
  133.  
  134.  clearwindow:
  135.         movem.l D0-D2/A0-A1, -(SP)      ; save registers
  136.         pea     scrollrect              ; erase window contents
  137.         _ERASERECT
  138.         move.w  #LMARG, -(SP)           ; home pen
  139.         move.w  #TMARG, -(SP)
  140.         _MOVETO
  141.         movem.l (SP)+, D0-D2/A0-A1      ; restore registers
  142.         rts
  143.         
  144.  ; Subroutine rdchar 
  145.  ;   Returns single character result in D0.
  146.  ;      Waits for next keyboard character from event queue, echoes it on
  147.  ;      screen and returns it in D0.  If character is CR or right margin has
  148.  ;      been reached, moves cursor to left margin one line down.
  149.  
  150.  xdef   rdchar
  151.  
  152.  rdchar: lea    regbufe, A0
  153.         movem.l D1-D2/A1, -(A0)         ; save registers (but not A0)
  154.         move.w  #40, -(SP)              ; mask for key-down or auto-key event
  155.         pea     evbuf                   ; pass address of event buffer
  156.         _GETNEXTEVENT
  157.         lea     evbuf, A0               ; any characters?
  158.         tst.w   (A0)
  159.         beq     rdchar                  ; if not, keep waiting
  160.         clr.l   D0
  161.         move.b  5(A0), D0               ; pass character to wrtchar
  162.         jsr     wrtchar
  163.         lea     regbuf, A0
  164.         movem.l (A0)+, D1-D2/A1         ; restore registers
  165.         rts
  166.         
  167.  ; Subroutine wrtchar ( character )
  168.  ;   Receives single character argument in D0
  169.  ;      Draws character on screen; if character is CR or right margin has
  170.  ;      been reached, moves pen to left margin one line down; if bottom
  171.  ;      has been reached, scrolls up one line.
  172.  
  173.  xdef   wrtchar
  174.  
  175.  wrtchar:
  176.         movem.l D1-D2/D5-D7/A0-A1, -(SP) ; save registers
  177.         move.l  D0, D5                  ; store character in D5
  178.         pea     penloc                  ; check pen location
  179.         _GETPEN
  180.         move.w  penloc+2, D7            ; store x value of pen in D7
  181.         move.w  penloc, D6              ; store y value of pen in D6
  182.         cmp.b   #BS, D5                 ; backspace typed?
  183.         bne     wrtchar1                ; if not, skip code to erase char.
  184.         cmp.w   #LMARG, D7              ; already at left margin?
  185.         beq     wrtchar4                ; if so, skip code to erase char.
  186.         lea     fontinfo, A0            ; compute and push inverse of
  187.         move.w  WIDMAX(A0), D0          ; character width
  188.         neg.w   D0
  189.         move.w  D0, -(SP)
  190.         move.w  #0, -(SP)               ; don't change pen's y coord
  191.         _MOVE                           ; move pen back one character pos.
  192.         move.w  D7, -(SP)               ; push x coord for lower right corner
  193.         move.w  D6, D0                  ; add descent amount to y coord
  194.         add.w   fontinfo+DESCENT, D0    ;  of lower right corner
  195.         move.w  D0, -(SP)               ; of erase rect.
  196.         sub.w   fontinfo+ASCENT, D6     ; compute coords for upper left
  197.         sub.w   fontinfo+WIDMAX, D7     ; corner of erase rect
  198.         move.w  D7, -(SP)               ; and push them
  199.         move.w  D6, -(SP)               
  200.         move.l  SP, A0                  ; push addr of erase rect
  201.         move.l  A0, -(SP)
  202.         _ERASERECT                      ; erase deleted character
  203.         add     #8, SP                  ; remove rectangle coords from stack
  204.         bra     wrtchar4                ; skip ahead to return backspace
  205.  wrtchar1:
  206.         cmp.b   #CR, D5                 ; carriage return?
  207.         beq     wrtchar2                        ; if so, skip to new-line generation
  208.         cmp.w   #RMARG, D7              ; past right margin?
  209.         blt     wrtchar3                        ; if not, skip new-line generation
  210.  wrtchar2:                              ; generate new line
  211.         sub.w   #LMARG, D7              ; compute delta x
  212.         neg.w   D7
  213.         move.w  D7, -(SP)
  214.         lea     lnht, A0
  215.         move.w  (A0), -(SP)
  216.         _MOVE                           ; position cursor for new line
  217.         cmp.w   #BMARG, D6              ; past bottom margin?
  218.         blt     wrtchar3                        ; if not, skip past code for scroll
  219.         pea     scrollrect
  220.         move.w  #0, -(SP)
  221.         lea     lnht, A0
  222.         move.w  (A0), -(SP)
  223.         neg.w   (SP)
  224.         lea     scrollrgnh, A0
  225.         move.l  (A0), -(SP)             ; else, scroll up by one
  226.         _SCROLLRECT                     ; line height
  227.         move.w  #0, -(SP)
  228.         lea     lnht, A0
  229.         move.w  (A0), -(SP)             ; move pen up accordingly
  230.         neg.w   (SP)
  231.         _MOVE
  232.  wrtchar3:
  233.         move.w  D5, -(SP)
  234.         _DRAWCHAR                       ; display character
  235.  wrtchar4:
  236.         move.l  D5, D0                  ; return character in D0
  237.         movem.l (SP)+, D1-D2/D5-D7/A0-A1 ; restore registers
  238.         rts
  239.         
  240.  ; Subroutine wrtdec ( num: integer )
  241.  ;   Receives integer argument in D0.
  242.  ;      If argument is negative, negates it and outputs a minus sign; calls
  243.  ;      subroutine prtdec to output digits of number
  244.  
  245.  xdef   wrtdec
  246.  
  247.  wrtdec:        movem.l D0-D2/A0-A1, -(SP)      ; save registers
  248.         tst.w   D0                      ; negative?
  249.         bge     wrtdec1                 
  250.         neg.w   D0                      ; if so, negate num
  251.         move.w  D0, -(SP)               ; save num
  252.         ;clr.w  D0
  253.         move.b  #DASH, D0               ; output minus sign
  254.         jsr     wrtchar
  255.         move.w  (SP)+, D0               ; restore num to D0
  256.  wrtdec1:
  257.         swap    D0
  258.         clr.w   D0
  259.         swap    D0
  260.         bsr     prtdec                  ; output num
  261.         movem.l (SP)+, D0-D2/A0-A1      ; restore registers
  262.         rts
  263.         
  264.  ; Subroutine prtdec (num: integer)
  265.  ;   Receives integer argument in D0.
  266.  ;      Recursively outputs digits of integer in decimal to terminal.
  267.  
  268.  prtdec:        divs    #10, D0                 ; num <- num DIV 10
  269.         tst.w   D0                      ; result equals zero?
  270.         beq     prtdec1
  271.         move.l  D0, -(SP)               ; if not, call prtdec recursively
  272.         swap    D0
  273.         clr.w   D0                      ; (first getting rid of remainder)
  274.         swap    D0
  275.         bsr     prtdec                  ; with num DIV 10
  276.         move.l  (SP)+, D0
  277.  prtdec1:
  278.         swap    D0                      ; num MOD 10
  279.         add.b   #ZERO, D0               ; compute ascii code for digit
  280.         jsr     wrtchar                 ; output digit
  281.         rts
  282.         
  283.  ; Subroutine rddec 
  284.  ;   Returns integer result in D0.
  285.  ;      Inputs signed word integer value (decimal), ignores all non-numeric
  286.  ;      characters except for minus sign, returns result on encountering
  287.  ;      CR.
  288.  
  289.  xdef   rddec
  290.  
  291.  rddec: movem.l D1-D5/A0-A1, -(SP)      ; save registers
  292.         lea     inbuf, A0
  293.         jsr     rdstrz                  ; input line to buffer
  294.         clr.w   D0                      ; sum = 0
  295.         clr.w   D3                      ; character holder = 0
  296.         clr.b   D4                      ; digits read = false
  297.         move.w  #1, D5                  ; sign = +
  298.  rddec1: move.b (A0)+, D3               ; end of input line?
  299.         beq     rddec3                  ; if so, return result
  300.         cmp.b   #DASH, D3               ; minus sign?
  301.         bne     rddec2
  302.         tst.b   D4                      ; if so, any digits read yet?
  303.         bne     rddec1                  ; if so, ignore minus sign
  304.         neg.w   D5                      ; else, sign = -
  305.         bra     rddec1
  306.  rddec2: cmp.b  #ZERO, D3               ; less than '0'?
  307.         blt     rddec1                  ; if so, ignore
  308.         cmp.b   #NINE, D3               ; greater than '9'?
  309.         bgt     rddec1                  ; if so, ignore
  310.         move.b  #1, D4                  ; digits read = true
  311.         muls    #10, D0                 ; sum = sum * 10
  312.         sub.w   #ZERO, D3               ; subtract ascii code for 0 from char
  313.                                         ;  to get digit value
  314.         add.w   D3, D0                  ; sum = sum + digit
  315.         bra     rddec1                  ; get next character
  316.  rddec3:        muls    D5, D0                  ; sum = sum * sign
  317.         movem.l (SP)+, D1-D5/A0-A1      ; restore registers
  318.         rts
  319.         
  320.  ; Subroutine rdstrz ( BufferAddress )
  321.  ;   Receives address of destination buffer in A0.
  322.  ;      Inputs characters to buffer specified by destination address
  323.  ;      until CR is read; terminates string with zero byte; if backspace
  324.  ;      encountered, deletes last character in buffer, backspace not stored.
  325.  ;      Inputs maximum of 255 characters to buffer (plus zero byte), flushes
  326.  ;      excessive input until next CR encountered (for buffers less than
  327.  ;      256 bytes long, buffer overflow is a possibility).
  328.  
  329.  xdef   rdstrz
  330.  
  331.  rdstrz:        movem.l D0-D3/A0-A2, -(SP)      ; save registers
  332.         clr.w   D3                      ; initialize counter
  333.         movea.l A0, A2                  ; save addr of buffer in A2
  334.  rdstrz1:
  335.         jsr     rdchar                  ; input next character
  336.         cmp.b   #CR, D0                 ; CR?
  337.         beq     rdstrz5                 ; if so, terminate string
  338.         cmp.b   #BS, D0                 ; backspace?
  339.         bne     rdstrz2 
  340.         tst.w   D3                      ; if so, is buffer empty?
  341.         beq     rdstrz1                 ; if so, get next character
  342.         clr.b   -(A2)                   ; else, delete last character
  343.         sub.w   #1, D3                  ; decrement counter
  344.         bra     rdstrz1                 ; input another character
  345.  rdstrz2:
  346.         cmp.w   #BUFSIZE-1, D3          ; buffer full?
  347.         bne     rdstrz4
  348.  rdstrz3:
  349.         jsr     rdchar                  ; if so,
  350.         cmp.b   #CR, D0                 ; discard input characters till
  351.         bne     rdstrz3                 ; CR found
  352.         bra     rdstrz5                 ; and terminate string
  353.  rdstrz4:
  354.         add.w   #1, D3                  ; else, increment character count
  355.         move.b  D0, (A2)+               ; and move input character to
  356.                                         ;  next buffer position
  357.         bra     rdstrz1                 ; input another character
  358.  rdstrz5:
  359.         clr.b   (A2)                    ; zero terminate
  360.         movem.l (SP)+, D0-D3/A0-A2      ; restore registers
  361.         rts
  362.         
  363.  ; Subroutine wrtstrz ( BufferAddress )
  364.  ;   Receives address of zero-terminated string in A0.
  365.  ;      Outputs characters of string on screen until zero byte is reached.
  366.  
  367.  xdef   wrtstrz
  368.  
  369.  wrtstrz:
  370.         movem.l D0/A0, -(SP)            ; save registers
  371.  wrtstrz1:
  372.         move.b  (A0)+, D0               ; pass char to wrtchar
  373.         beq     wrtstrz2                ; return when zero byte reached
  374.         jsr     wrtchar                 ; output character
  375.         bra     wrtstrz1                ; get next byte
  376.  wrtstrz2:
  377.         movem.l (SP)+, D0/A0            ; restore registers
  378.         rts
  379.         
  380.  ; Subroutine rdstrc ( BufferAddress )
  381.  ;   Receives address of destination buffer in A0.
  382.  ;      Inputs characters to buffer specified by destination address
  383.  ;      until CR is read; places count byte at start of string; if backspace
  384.  ;      encountered, deletes last character in buffer, backspace not stored.
  385.  ;      Inputs maximum of 255 characters to buffer (plus count byte), flushes
  386.  ;      excessive input until next CR encountered (for buffers less than
  387.  ;      256 bytes long, buffer overflow is a possibility).
  388.  
  389.  xdef   rdstrc
  390.  
  391.  rdstrc:        movem.l D0-D3/A0-A3, -(SP)      ; save registers
  392.         movea.l A0, A2                  ; save addr of buffer in A2
  393.         movea.l A0, A3                  ; and A3
  394.         tst.b   (A2)+                   ; increment pointer past count byte
  395.         clr.b   D3                      ; initialize counter
  396.  rdstrc1:
  397.         jsr     rdchar                  ; input next character
  398.         cmp.b   #CR, D0                 ; CR?
  399.         beq     rdstrc5                 ; if so, terminate string
  400.         cmp.b   #BS, D0                 ; backspace?
  401.         bne     rdstrc2 
  402.         tst.b   D3                      ; if so, is buffer empty?
  403.         beq     rdstrc1                 ; if so, get next character
  404.         clr.b   -(A2)                   ; else, delete last character
  405.         sub.b   #1, D3                  ; decrement counter
  406.         bra     rdstrc1                 ; input another character
  407.  rdstrc2:
  408.         cmp.b   #BUFSIZE-1, D3          ; buffer full?
  409.         bne     rdstrc4
  410.  rdstrc3:
  411.         jsr     rdchar                  ; if so,
  412.         cmp.b   #CR, D0                 ; discard input characters till
  413.         bne     rdstrc3                 ; CR found
  414.         bra     rdstrc5                 ; and terminate string
  415.  rdstrc4:
  416.         add.b   #1, D3                  ; else, increment character count
  417.         move.b  D0, (A2)+               ; and move input character to
  418.                                         ;  next buffer position
  419.         bra     rdstrc1                 ; input another character
  420.  rdstrc5:
  421.         move.b  D3, (A3)                ; insert count byte
  422.         movem.l (SP)+, D0-D3/A0-A3      ; restore registers
  423.         rts
  424.         
  425.  ; Subroutine wrtstrc ( BufferAddress )
  426.  ;   Receives address of count string in A0.
  427.  ;      Outputs number of characters specified by count-byte.
  428.  
  429.  xdef   wrtstrc
  430.  
  431.  wrtstrc:
  432.         movem.l D0/D3/A0, -(SP)         ; save registers
  433.         move.b  (A0)+, D3               ; store count in D3
  434.  wrtstrc1:
  435.         tst.b   D3                      ; all characters output?
  436.         beq     wrtstrc2                ; then quit
  437.         move.b  (A0)+, D0               ; pass char to wrtchar
  438.         jsr     wrtchar                 ; output character
  439.         sub.b   #1, D3                  ; decrement counter
  440.         bra     wrtstrc1                ; get next byte
  441.  wrtstrc2:
  442.         movem.l (SP)+, D0/D3/A0         ; restore registers
  443.         rts
  444.         
  445.  
  446.  ; data for shell program
  447.  
  448.  saveregs: dcb.l        2, 0    ; space for storing saved registers
  449.  evbuf: dcb.l   4, 0    ; event buffer
  450.  
  451.  ; data for subroutine makewindow
  452.  
  453.  boundsrect:    dc.w    Y1, X1, Y2, X2          ; the window rectangle in
  454.                                                 ;  global coordinates
  455.  scrollrect:    dc.w    0, 0, WINDHEIGHT, WINDWIDTH ; the window rectangle
  456.                                                 ;  in local coordinates
  457.  scrollrgnh:    dc.l    0                       ; handle for scroll region
  458.  fontinfo:      dcb.w   4, 0                    ; buffer for record returned
  459.                                                 ;  by _GETFONTINFO
  460.  lnht:          dc.w    0                       ; buffer for height of line
  461.                                                 ;  of text
  462.  ; data for subroutine rdchar
  463.  
  464.  penloc:        dc.l    0               ; storage for pen location coordinates
  465.  regbuf:        dcb.l   3, 0            ; storage for saved registers
  466.  regbufe:
  467.  
  468.  ; data for subroutine rddec
  469.  
  470.  inbuf: dcb.b   BUFSIZE, 0      ; input buffer
  471.  
  472.  ; global storage
  473.  
  474.  window:        ds.l    1
  475.  
  476.         end
  477.  
  478.