CW PROG2.S

From Atari Wiki
Jump to navigation Jump to search
;---------------------------------------------------------------------
; THE ST ASSEMBLY LANGUAGE WORKSHOP, VOLUME 2
; PROGRAM 2
;
; COPYRIGHT 1992 BY CLAYTON WALNUM
;---------------------------------------------------------------------

PTERM0          equ     0
CCONIN          equ     1
CCONWS          equ     9
APPL_INIT       equ     10
APPL_EXIT       equ     19
DGETDRV         equ     25
DGETPATH        equ     71
MSHRINK         equ     74
FSEL_INPUT      equ     90
AES_OPCODE      equ     200

;--------------------------------------------------------------------
; MACROS
;--------------------------------------------------------------------

;--------------------------------------------------------------------
; This macro gets a single character from the keyboard, using the
; Cconin GEMDOS function.
;--------------------------------------------------------------------
get_char macro
        move    #CCONIN,-(sp)
        trap    #1
        addq.l  #2,sp
        endm

;--------------------------------------------------------------------
; MAIN PROGRAM
;--------------------------------------------------------------------
        text

; Calculate the size of the program area.

        move.l  a7,a5                   ; Save addr of TPA.
        lea     stack,sp                ; Load addr of our stack.
        
        move.l  4(a5),a5                ; Get addr of TPA.              
        move.l  12(a5),d0               ; Get len of text segment.
        add.l   20(a5),d0               ; Add len of data segment.
        add.l   28(a5),d0               ; Add len of BSS segment.
        add.l   #$100,d0                ; Add len of TPA. 

; Release unused memory back to the system.
        
        move.l  d0,-(sp)                ; Push size of program on stack.
        move.l  a5,-(sp)                ; Push program addr on stack.
        clr     -(sp)                   ; Clear dummy word on stack.    
        move    #MSHRINK,-(sp)          ; Push Mshrink opcode.
        trap    #1                      ; Call GEMDOS.
        add.l   #12,sp                  ; Reset stack pointer.

; Clear some fields of the global array.

        clr.l   ap_ptree        
        clr.l   ap_1resv
        clr.l   ap_2resv
        clr.l   ap_3resv
        clr.l   ap_4resv

; Call appl_init to initialize application.

        move    #APPL_INIT,control0     ; Place opcode in control array.
        clr     control1                ; Load length of init_in. 
        move    #1,control2             ; Load length of int_out.
        clr     control3                ; Load length of addr_in.
        clr     control4                ; Load length of addr_out.
        jsr     aes                     ; Call the AES.
        cmpi    #$FFFF,ap_id            ; Error?
        beq     end                     ; Yep.  Outta here.

; Get current drive letter.

        move    #DGETDRV,-(sp)          ; Call Dgetdrv function.
        trap    #1
        addq.l  #2,sp
        add     #'A',d0                 ; Convert drive to ASCII.
        move.b  d0,pathname             ; Move drive letter to pathname.
        move.b  #':',pathname+1         ; Add colon to pathname.

; Get current path.

        move    #0,-(sp)                ; Call Dgetpath function.
        move.l  #pathname+2,-(sp)
        move    #DGETPATH,-(sp)
        trap    #1
        addq.l  #8,sp

; Add *.* to end of pathname.

        move    #127,d5                 ; Init loop counter.
        lea     pathname,a5             ; Get address of pathname.
loop1:
        tst.b   (a5)+                   ; Is character a null?
        beq     add_filespec            ; Yep. Found end of pathname.
        dbra    d5,loop1                ; Nope. Try next character.
add_filespec:
        subq.l  #1,a5                   ; Set addr to proper byte.
        move.b  #'\',(a5)+              ; Add \*.* to path.
        move.b  #'*',(a5)+
        move.b  #'.',(a5)+
        move.b  #'*',(a5)
        
; Bring up the file selector.

        move    #FSEL_INPUT,control0    ; Load fsel_input opcode.
        move    #0,control1             ; Load length of int_in.
        move    #2,control2             ; Load length of int_out.
        move    #2,control3             ; Load length of addr_in.
        move    #0,control4             ; Load length of addr_out.
        move.l  #pathname,addr_in       ; Load addr of path string.
        move.l  #filename,addr_in+4     ; Load addr of filename string.
        jsr     aes                     ; Call the AES.

        cmpi    #1,int_out+2            ; Chose OK button?
        bne     exit                    ; No, exit program.
        tst.b   filename                ; Do we have a filename?
        beq     exit                    ; No, exit program.

; Construct final pathname.

        move    #127,d5                 ; Init loop counter.
        lea     pathname,a5             ; Get addr of pathname.
loop2:
        tst.b   (a5)+                   ; Is character a null?
        beq     found_null              ; Yep.
        dbra    d5,loop2                ; Nope. Try next character.

found_null:
        move    #14,d5                  ; Init loop counter.
loop3:
        cmpi.b  #'\',-(a5)              ; Found backslash?
        beq     add_filename            ; Yes. Go tack on filename.
        dbra    d5,loop3                ; No. Try next character.

add_filename:
        addq.l  #1,a5                   ; Set addr to char after \.
        move    #14,d5                  ; Init loop counter.
        lea filename,a6                 ; Get addr of filename.
loop4:
        move.b  (a6),(a5)+              ; Add character to path.
        tst.b   (a6)+                   ; Test for null.
        beq     got_filename            ; If null, all done.
        dbra    d5,loop4                ; Copy next character.

; Show final pathname.

got_filename:
        move.l  #pathname,-(sp)         ; call Cconws to show...
        move    #CCONWS,-(sp)           ; the final pathname.
        trap    #1
        addq.l  #6,sp
        get_char                        ; Wait for keypress.
        
; Close down application.

exit:
        move    #APPL_EXIT,control0     ; Load appl_exit opcode.
        move    #0,control1             ; Load length of int_in.
        move    #1,control2             ; Load length of int_out.
        move    #0,control3             ; Load length of addr_in.
        move    #0,control4             ; Load length of addr_out.
        jsr     aes                     ; Call the AES.
        
end:
        move.w  #PTERM0,-(sp)           ; Back to desktop.
        trap    #1

;--------------------------------------------------------------------
; This subroutine calls the AES.  Before calling this subroutine, the
; program must have correctly initialized the AES control, int_in,
; and addr_in arrays.
;
; Input:        Appropriate values in the int_in, addr_in, and
;               control arrays.
; Output:       Appropriate values in the int_out, addr_out, and
;               global arrays.
; Regs changed: NONE
; Uses: apb, global, int_in, int_out, addr_in, addr_out
;--------------------------------------------------------------------
aes:
        movem.l a0-a7/d0-d7,-(sp)       ; Save registers.
        move.l  #apb,d1                 ; Load addr of apb.
        move.l  #AES_OPCODE,d0          ; Load AES opcode.
        trap    #2                      ; Call AES.
        movem.l (sp)+,a0-a7/d0-d7       ; Restore registers.
        rts

        data
        
apb:            dc.l    control,global,int_in,int_out,addr_in,addr_out

        bss

        even

global:
ap_version:     ds.w    1
ap_count:       ds.w    1
ap_id:          ds.w    1
ap_private:     ds.l    1
ap_ptree:       ds.l    1
ap_1resv:       ds.l    1
ap_2resv:       ds.l    1
ap_3resv:       ds.l    1
ap_4resv:       ds.l    1

control:
control0:       ds.w    1
control1:       ds.w    1
control2:       ds.w    1
control3:       ds.w    1
control4:       ds.w    1

int_in:         ds.w    1
int_out:        ds.w    2
addr_in:        ds.l    2
addr_out:       ds.l    1

pathname:       ds.b    128
filename:       ds.b    13

                ds.l    255
stack:          ds.l    1


Back to CW_CHAPTER_2