/******************************************************************* Plotter Controller Program -- Assembler 68008 DKM 1997 by Tor-Åke Fransson and Jens Svensson, students of Mech. Eng./Comp. Sci. at LiTH ********************************************************************/ .text .even .globl _main /* defines for the PIA */ piaa = 0xf0200 ddra = 0xf0200 cra = 0xf0201 piab = 0xf0202 ddrb = 0xf0202 crb = 0xf0203 /* start addresses of the step-motor pulse train */ ptx_start = 0x1F000 pty_start = 0x1F010 ptxn_start = 0x1f020 ptyn_start = 0x1f030 /* position related addresses */ current_x = 0x1f040 current_y = 0x1f044 goto_x = 0x1f048 goto_y = 0x1f04c bcd_one = 0x1f050 bcd_ten = 0x1f051 bcd_hun = 0x1f052 /* movement related addresses */ delta_x = 0x1f060 delta_y = 0x1f064 kvot = 0x1f068 rest = 0x1f06a i = 0x1f06c kvot_add = 0x1f070 move_major = 0x1f074 /* the pen position stored here */ pen_state = 0x1f078 /* adresses of the HP 8-char display */ disp0 = 0xf0100 disp1 = 0xf0101 disp2 = 0xf0102 disp3 = 0xf0103 disp4 = 0xf0104 disp5 = 0xf0105 disp6 = 0xf0106 disp7 = 0xf0107 letter_A = 0x41 letter_B = 0x42 letter_C = 0x43 letter_D = 0x44 letter_E = 0x45 letter_F = 0x46 letter_G = 0x47 letter_H = 0x48 letter_I = 0x49 letter_L = 0x4c letter_N = 0x4e letter_O = 0x4f letter_P = 0x50 letter_Q = 0x51 letter_R = 0x52 letter_S = 0x53 letter_T = 0x54 letter_U = 0x55 letter_X = 0x58 letter_Y = 0x59 letter_Z = 0x5a letter_kolon = 0x3a letter_blank = 0x20 letter_que = 0x01 letter_1 = 0x31 letter_2 = 0x32 letter_3 = 0x33 letter_4 = 0x34 letter_5 = 0x35 letter_6 = 0x36 letter_7 = 0x37 letter_8 = 0x38 letter_9 = 0x39 letter_0 = 0x30 /* main program */ _main: jsr pia_init jsr plotter_init jsr clear_disp jsr show_usage c_reset: jsr pen_up jsr goto_zero movl #200000, a0 jsr def_wait wait_event: jsr show_pos /* main loop starts here */ movl #200000, a0 jsr def_wait jsr read_key cmpb #0xf, d2 beq main_end cmpb #0xc, d2 beq help cmpb #0xa, d2 beq c_reset bpl wait_event jsr clear_disp jsr read_x jsr read_key cmpb #0xf, d2 beq main_end cmpb #0xa, d2 beq c_reset bpl wait_event jsr read_y jsr clear_disp pen_que: jsr ask_pen /* coordinates entered, ready to draw */ jsr read_key cmpb #0xf, d2 beq main_end cmpb #0xb, d2 beq wait_event cmpb #0xe, d2 beq no cmpb #0xd, d2 beq yes cmpb #0xc, d2 beq help jmp pen_que no: jsr pen_up jmp movit yes: jsr pen_down movit: movl goto_x, d0 /* classify the movement type and */ subl current_x, d0 /* envoke drawing subroutines */ beq only_y movl d0, delta_x movl goto_y, d1 subl current_y, d1 beq only_x movl d1, delta_y jmp live_xy only_y: movl goto_y, d1 subl current_y, d1 movl d1, a2 cmpl #0, a2 bmi y_neg movl #pty_start, a0 jmp move_yo y_neg: movl #ptyn_start, a0 negl d1 movl d1, a2 move_yo: jsr move_xy jmp wait_event only_x: movl d0, a2 cmpl #0, a2 bmi x_neg movl #ptx_start, a0 jmp move_xo x_neg: movl #ptxn_start, a0 negl d0 movl d0, a2 move_xo: jsr move_xy jmp wait_event live_xy: clrl d5 movl d0, d2 movl d1, d3 jsr abs_bel divu d3, d2 cmpw #0, d2 beq y_greater cmpl #0, d0 blt negate_x movl #ptx_start, a0 movl #ptx_start, a2 jmp check_y negate_x: movl #ptxn_start, a0 movl #ptxn_start, a2 negl d0 check_y: cmpl #0, d1 blt negate_y movl #pty_start, a1 movl #pty_start, a3 jmp calcx negate_y: movl #ptyn_start, a1 movl #ptyn_start, a3 negl d1 calcx: movl d0, move_major divu d1, d0 movw d0, kvot lsrl #8, d0 lsrl #8, d0 movw d0, rest mulu #20, d0 divu d1, d0 movw d0, i clrw kvot_add jsr move_diagonal movl goto_x, current_x movl goto_y, current_y jmp wait_event y_greater: cmpl #0, d1 blt negate_y2 movl #pty_start, a0 movl #pty_start ,a2 jmp check_x negate_y2: movl #ptyn_start, a0 movl #ptyn_start, a2 negl d1 check_x: cmpl #0, d0 blt negate_x2 movl #ptx_start, a1 movl #ptx_start, a3 jmp calcy negate_x2: movl #ptxn_start, a1 movl #ptxn_start, a3 negl d0 calcy: movl d1, move_major divu d0, d1 movw d1, kvot lsrl #8, d1 lsrl #8, d1 movw d1, rest mulu #20, d1 divu d0, d1 movw d1, i clrw kvot_add jsr move_diagonal movl goto_x, current_x movl goto_y, current_y jmp wait_event help: jsr show_usage jmp wait_event main_end: rts /*********************** Subroutines ***********************/ /* in: d2, d3 long words out: absolute value d2,d3 */ abs_bel: cmpl #0, d2 blt negate_d2 chk_d3: cmpl #0, d3 blt negate_d3 jmp abs_bel_end negate_d2: negl d2 jmp chk_d3 negate_d3: negl d3 abs_bel_end: rts /* subroutine for 2-axis movement in: a0,a2, start adresses for pulse train kvot, rate of movement axis1/axis2 move_major, movement along greater axis out: nothing */ move_diagonal: clrl d0 movw kvot, d0 addw kvot_add, d0 cmpw #1, kvot_add bne diagonal_loop subw #20, d5 clrw kvot_add diagonal_loop: addl #1, a0 movl a2, d1 addl #0x08, d1 cmpl a0, d1 bne move_diag_y movl a2, a0 move_diag_y: cmpl #1, d0 bne diagonal_xy addl #1, a1 movl a3, d1 addl #0x08, d1 cmpl a1, d1 bne diagonal_xy movl a3, a1 diagonal_xy: jsr set_pen movb a0@, d3 addb a1@, d3 movb d3, piaa subl #1, move_major cmpl #0, move_major beq diag_tot_end jsr jiffy_wait /* wait for motors to catch up */ addw i, d5 cmpw #20, d5 blt diagonal_end movw #1, kvot_add diagonal_end: subl #1, d0 beq move_diagonal jmp diagonal_loop diag_tot_end: rts /* subroutine for single axis movement in: a2, moving distance a0, pulse train start address out: current_x || current_y, current position */ move_xy: movl a2, d0 addl #1, d0 movl a0, a1 lapxy: subl #1, d0 beq endxy movl a0, d1 addl #0x08, d1 cmpl a1, d1 bne rotatexy movl a0, a1 rotatexy: movb a1@+, piaa jsr jiffy_wait /* wait for motors to catch up */ cmpl #ptx_start, a0 beq add_one_x cmpl #pty_start, a0 beq add_one_y cmpl #ptxn_start, a0 beq sub_one_x subl #1, current_y jmp lapxy sub_one_x: subl #1, current_x jmp lapxy add_one_y: addl #1, current_y jmp lapxy add_one_x: addl #1, current_x jmp lapxy endxy: rts /* show the current position in mm on the display in: current_x, current_y, the position out: nothing */ show_pos: movb #letter_X, disp0 movl current_x, d2 jsr to_bcd movb bcd_hun, disp1 movb bcd_ten, disp2 movb bcd_one, disp3 movb #letter_Y, disp4 movl current_y, d2 jsr to_bcd movb bcd_hun, disp5 movb bcd_ten, disp6 movb bcd_one, disp7 rts /* write 'PEN?' o the display in: nothing out: nothing */ ask_pen: movb #letter_P, disp0 movb #letter_E, disp1 movb #letter_N, disp2 movb #letter_que, disp3 rts /* move the pen towards negative coords in: nothing out: nothing */ goto_zero: jsr clear_disp movb #letter_E, disp1 movb #letter_R, disp2 movb #letter_O, disp3 movb #letter_que, disp4 movb #letter_Z, disp0 zero_loopx: movl #16, a2 movl #ptxn_start, a0 movl #ptxn_start, a5 jsr get_key /* if key pressed, switch moving axis */ cmpb #0xd, d2 beq zero_loopy jsr move_xy jmp zero_loopx zero_loopy: movl #16, a2 movl #ptyn_start, a0 movl #ptyn_start, a5 jsr get_key /* if key pressed, return */ cmpb #0xd, d2 beq zero_end jsr move_xy jmp zero_loopy zero_end: clrl current_x clrl current_y rts /* sets up the PIA data directions in: nothing out: nothing */ pia_init: clrb cra clrb crb movb #0xff, ddra movb #0x03, ddrb movb #0x04, cra movb #0x04, crb rts /* reads the entered x-coords feedbacking them on display in: d2, the keypress triggering this function out: goto_x, the coordinate entered (in hex) */ read_x: movb d2, bcd_hun movb #letter_X, disp0 addb #0x30, d2 movb d2, disp1 read_x_l: jsr read_key cmpb #0xa, d2 bpl read_x_l movb d2, bcd_ten addb #0x30, d2 movb d2, disp2 read_x_ll: jsr read_key cmpb #0xa, d2 bpl read_x_ll movb d2, bcd_one addb #0x30, d2 movb d2, disp3 jsr to_hex movl d2, goto_x rts /* reads the entered y-coords feedbacking them on display in: d2, the keypress triggering this function out: goto_y, the coordinate entered (in hex) */ read_y: movb d2, bcd_hun movb #letter_Y, disp4 addb #0x30, d2 movb d2, disp5 read_y_l: jsr read_key cmpb #0xa, d2 bpl read_y_l movb d2, bcd_ten addb #0x30, d2 movb d2, disp6 read_y_ll: jsr read_key cmpb #0xa, d2 bpl read_y_ll movb d2, bcd_one addb #0x30, d2 movb d2, disp7 jsr to_hex movl d2, goto_y rts /* reads keyboard, blocking in: nothing out: d2, the key pressed */ read_key: movb piab, D2 bpl read_key wait: movb piab, D3 bmi wait lslb #1, d2 lsrb #4, d2 rts /* reads keyboard, non-blocking in: nothing out: d2, the key pressed (if any) */ get_key: movb piab, d2 bmi get_keylap movl #0x100, d2 jmp get_end get_keylap: movb piab, d3 bmi get_keylap lslb #1, d2 lsrb #4, d2 get_end: rts /* lifts the pen in: nothing out: pen_state, the pen position (up) */ pen_up: clrb crb movb #0xff, ddrb movb #0x04, crb movb #0x00, piab movb #0x00, pen_state clrb crb movb #0x03, ddrb movb #0x04, crb rts /* lowers the pen in: nothing out: pen_state, the pen position (down) */ pen_down: clrb crb movb #0xff, ddrb movb #0x04, crb movb #0x01, piab movb #0x01, pen_state clrb crb movb #0x03, ddrb movb #0x04, crb rts /* set the pen position up/down in: pen_state, pen position up/down out: nothing */ set_pen: clrb crb movb #0xff, ddrb movb #0x04, crb movb pen_state, piab clrb crb movb #0x03, ddrb movb #0x04, crb rts /* clear the display in: nothing out: nothing */ clear_disp: movl #10000, a0 jsr def_wait movb #0x20, disp0 movb #0x20, disp1 movb #0x20, disp2 movb #0x20, disp3 movb #0x20, disp4 movb #0x20, disp5 movb #0x20, disp6 movb #0x20, disp7 movl #10000, a0 jsr def_wait rts /* convert hex position to bcd in: d2, the position out: bcd_hun, bcd_ten, bcd_one , the position in bcd notation */ to_bcd: clrb bcd_hun clrb bcd_ten clrb bcd_one divu #20, d2 clrl d3 movw d2, d3 divu #100, d3 movb d3, bcd_hun lsrl #8, d3 lsrl #8, d3 divu #10, d3 movb d3, bcd_ten lsrl #8, d3 lsrl #8, d3 movb d3, bcd_one bcd_end: addb #0x30, bcd_one addb #0x30, bcd_ten addb #0x30, bcd_hun rts /* converts bcd to hex position in: bcd_hun, bcd_ten, bcd_one position in bcd notation out: d2, the hexadecimal value */ to_hex: clrl d2 movb bcd_hun, d2 mulu #2000, d2 clrl d3 movb bcd_ten, d3 mulu #200, d3 addl d3, d2 clrl d3 movb bcd_one, d3 mulu #20, d3 addl d3, d2 rts /* set up the pulse trains in: nothing out: ptx_start, pty_start, pulse trains for positive movement ptxn_start, ptyn_start, pulse trains for neg. movement */ plotter_init: movb #0x02, piab movb #0x00, piab movl #ptx_start, a1 movb #0x01, a1@+ movb #0x09, a1@+ movb #0x08, a1@+ movb #0x0a, a1@+ movb #0x02, a1@+ movb #0x06, a1@+ movb #0x04, a1@+ movb #0x05, a1@+ movl #ptyn_start, a1 movb #0x50, a1@+ movb #0x40, a1@+ movb #0x60, a1@+ movb #0x20, a1@+ movb #0xa0, a1@+ movb #0x80, a1@+ movb #0x90, a1@+ movb #0x10, a1@+ movl #ptxn_start, a1 movb #0x05, a1@+ movb #0x04, a1@+ movb #0x06, a1@+ movb #0x02, a1@+ movb #0x0a, a1@+ movb #0x08, a1@+ movb #0x09, a1@+ movb #0x01, a1@+ movl #pty_start, a1 movb #0x10, a1@+ movb #0x90, a1@+ movb #0x80, a1@+ movb #0xa0, a1@+ movb #0x20, a1@+ movb #0x60, a1@+ movb #0x40, a1@+ movb #0x50, a1@+ rts /* writes a short usage help on the display in: nothing out: nothing */ show_usage: jsr clear_disp movl #10000, a0 movb #letter_A, disp0 movb #letter_kolon, disp1 movb #letter_R, disp2 movb #letter_E, disp3 movb #letter_S, disp4 movb #letter_E, disp5 movb #letter_T, disp6 movl #200000, a0 jsr def_wait /* wait for user to read */ jsr clear_disp movb #letter_L, disp7 movb #letter_E, disp6 movb #letter_C, disp5 movb #letter_N, disp4 movb #letter_A, disp3 movb #letter_C, disp2 movb #letter_kolon, disp1 movb #letter_B, disp0 movl #200000, a0 jsr def_wait jsr clear_disp movb #letter_C, disp0 movb #letter_kolon, disp1 movb #letter_H, disp2 movb #letter_E, disp3 movb #letter_L, disp4 movb #letter_P, disp5 movl #200000, a0 jsr def_wait jsr clear_disp movb #letter_D, disp0 movb #letter_kolon, disp1 movb #letter_Y, disp2 movb #letter_E, disp3 movb #letter_S, disp4 movl #200000, a0 jsr def_wait jsr clear_disp movb #letter_E, disp0 movb #letter_kolon, disp1 movb #letter_N, disp2 movb #letter_O, disp3 movb #letter_N, disp2 movl #200000, a0 jsr def_wait jsr clear_disp movb #letter_F, disp0 movb #letter_kolon, disp1 movb #letter_U, disp3 movb #letter_Q, disp2 movb #letter_T, disp5 movb #letter_I, disp4 movb #letter_F, disp0 movb #letter_I, disp4 movb #letter_Q, disp2 movl #200000, a0 jsr def_wait jsr clear_disp rts /* user defined time wait loop in: a0, the time to wait out: nothing */ def_wait: movl a0, d4 def_loop: subl #1, d4 bmi def_end jmp def_loop def_end: rts /* predefined wait loop in: nothing out: nothing */ jiffy_wait: clrl d4 movl #200, d4 jiffy_loop: subl #1, d4 bmi jiffy_end jmp jiffy_loop jiffy_end: rts