// CPU Plotter // Outputs: // IOBus: Dataport // Outputs: // port0: DestX // port1: DestY // port2: Draw // port3: Move // port4: Speed // Inputs: // port0: Drawing in progress DATA // The alphabet. Table to reference each is at the end. // Format is: // Byte 0: Number of vectors in letter // n chunks where n is value of byte 0... // Chunk format: // Byte 0: Pen: (0=up, 1=down) // Byte 1: X position (0=left, 1=right) // Byte 2: Y position (0=bottom, 1=top) chr_space: DB 0 chr_exclam: DB 8 DB 0,.4,0 DB 1,.6,0 DB 1,.5,.1 DB 1,.4,0 DB 0,.5,.4 DB 1,.6,1 DB 1,.4,1 DB 1,.5,.4 chr_dblqt: DB 0 chr_hash: DB 0 chr_dlr: DB 0 chr_percent: DB 0 chr_amprsnd: DB 0 chr_snglqt: DB 0 chr_openparen: DB 0 chr_closeparen: DB 0 chr_star: DB 0 chr_comma: DB 4 DB 0,.5,.2 DB 1,.5,.1 DB 1,.4,0 DB 1,.3,0 chr_plus: DB 0 chr_period: DB 4 DB 0,.4,0 DB 1,.6,0 DB 1,.5,.2 DB 1,.4,0 chr_dash: DB 0 chr_slash: DB 0 chr_0: DB 9 DB 0,.2,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,.8 DB 1,.8,1 DB 1,.2,1 DB 1,0,.8 DB 1,0,.2 DB 1,.2,0 chr_1: DB 2 DB 0,.5,1 DB 1,.5,0 chr_2: DB 6 DB 0,0,.8 DB 1,.2,1 DB 1,.8,1 DB 1,1,.8 DB 1,0,0 DB 1,1,0 chr_3: DB 13 DB 0,0,.8 DB 1,.2,1 DB 1,.8,1 DB 1,1,.8 DB 1,1,.6 DB 1,.9,.5 DB 1,.5,.5 DB 0,.9,.5 DB 1,1,.4 DB 1,1,.2 DB 1,.8,0 DB 1,.2,0 DB 1,0,.2 chr_4: DB 5 DB 0,0,1 DB 1,0,.5 DB 1,1,.5 DB 0,1,1 DB 1,1,0 chr_5: DB 9 DB 0,1,1 DB 1,0,1 DB 1,0,.5 DB 1,.8,.5 DB 1,1,.3 DB 1,1,.2 DB 1,.8,0 DB 1,.2,0 DB 1,0,.2 chr_6: DB 12 DB 0,1,.8 DB 1,.8,1 DB 1,.2,1 DB 1,0,.8 DB 1,0,.2 DB 1,.2,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,.3 DB 1,.8,.5 DB 1,.2,.5 DB 1,0,.3 chr_7: DB 3 DB 0,0,1 DB 1,1,1 DB 1,0,0 chr_8: DB 17 DB 0,.2,1 DB 1,.8,1 DB 1,1,.8 DB 1,1,.6 DB 1,.9,.5 DB 1,.1,.5 DB 1,0,.4 DB 1,0,.2 DB 1,.2,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,.4 DB 1,.9,.5 DB 0,.1,.5 DB 1,0,.6 DB 1,0,.8 DB 1,.2,1 chr_9: DB 11 DB 0,1,.5 DB 1,.2,.5 DB 1,0,.7 DB 1,0,.8 DB 1,.2,1 DB 1,.8,1 DB 1,1,.8 DB 1,1,.2 DB 1,.8,0 DB 1,.2,0 DB 1,0,.2 chr_colon: DB 8 DB 0,.4,0 DB 1,.6,0 DB 1,.5,.2 DB 1,.4,0 DB 0,.4,.5 DB 1,.6,.5 DB 1,.5,.7 DB 1,.4,.5 chr_semicolon: DB 0 chr_lessthan: DB 0 chr_equal: DB 0 chr_greaterthan: DB 0 chr_questionmark: DB 0 chr_at: DB 0 chr_A: DB 7 DB 0, 0, 0 DB 1, 0, .5 DB 1, 1, .5 DB 1, .5 ,1 DB 1, 0, .5 DB 0, 1, .5 DB 1, 1, 0 chr_B: DB 12 DB 0, 0, 0 DB 1, 0, 1 DB 1, .8, 1 DB 1, 1, .8 DB 1, 1, .6 DB 1, .8, .5 DB 1, 0, .5 DB 0, .8, .5 DB 1, 1, .4 DB 1, 1, .2 DB 1, .8, 0 DB 1, 0, 0 chr_C: DB 10 DB 0,1,.7 DB 1,1,.8 DB 1,.8,1 DB 1,.2,1 DB 1,0,.8 DB 1,0,.2 DB 1,.2,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,.3 chr_D: DB 7 DB 0,0,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,.8 DB 1,.8,1 DB 1,0,1 DB 1,0,0 chr_E: DB 6 DB 0,1,1 DB 1,0,1 DB 1,0,0 DB 1,1,0 DB 0,0,.5 DB 1,1,.5 chr_F: DB 5 DB 0,0,0 DB 1,0,1 DB 1,1,1 DB 0,0,.5 DB 1,.8,.5 chr_G: DB 11 DB 0,1,.7 DB 1,1,.8 DB 1,.8,1 DB 1,.2,1 DB 1,0,.8 DB 1,0,.2 DB 1,.2,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,.4 DB 1,.5,.4 chr_H: DB 6 DB 0,0,0 DB 1,0,1 DB 0,1,1 DB 1,1,0 DB 0,0,.5 DB 1,1,.5 chr_I: DB 2 DB 0,.5,0 DB 1,.5,1 chr_J: DB 6 DB 0,.5,1 DB 1,.5,.1 DB 1,.4,0 DB 1,.1,0 DB 1,0,.1 DB 1,0,.2 chr_K: DB 5 DB 0,0,0 DB 1,0,1 DB 0,1,1 DB 1,0,.5 DB 1,1,0 chr_L: DB 3 DB 0,0,1 DB 1,0,0 DB 1,1,0 chr_M: DB 5 DB 0,0,0 DB 1,0,1 DB 1,.5,.25 DB 1,1,1 DB 1,1,0 chr_N: DB 4 DB 0,0,0 DB 1,0,1 DB 1,1,0 DB 1,1,1 chr_O: DB 9 DB 0,.2,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,.8 DB 1,.8,1 DB 1,.2,1 DB 1,0,.8 DB 1,0,.2 DB 1,.2,0 chr_P: DB 7 DB 0,0,0 DB 1,0,1 DB 1,.8,1 DB 1,1,.9 DB 1,1,.6 DB 1,.9,.5 DB 1,0,.5 chr_Q: DB 11 DB 0,.2,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,.8 DB 1,.8,1 DB 1,.2,1 DB 1,0,.8 DB 1,0,.2 DB 1,.2,0 DB 0,.7,.3 DB 1,1,0 chr_R: DB 9 DB 0,0,0 DB 1,0,1 DB 1,.8,1 DB 1,1,.9 DB 1,1,.6 DB 1,.9,.5 DB 1,0,.5 DB 0,.5,.5 DB 1,1,0 chr_S: DB 14 DB 0,1,.7 DB 1,1,.8 DB 1,.8,1 DB 1,.2,1 DB 1,0,.8 DB 1,0,.7 DB 1,.2,.5 DB 1,.8,.5 DB 1,1,.3 DB 1,1,.2 DB 1,.8,0 DB 1,.2,0 DB 1,0,.2 DB 1,0,.3 chr_T: DB 4 DB 0,.5,0 DB 1,.5,1 DB 0,0,1 DB 1,1,1 chr_U: DB 6 DB 0,0,1 DB 1,0,.2 DB 1,.2,0 DB 1,.8,0 DB 1,1,.2 DB 1,1,1 chr_V: DB 3 DB 0,0,1 DB 1,.5,0 DB 1,1,1 chr_W: DB 5 DB 0,0,1 DB 1,.25,0 DB 1,.5,.5 DB 1,.75,0 DB 1,1,1 chr_X: DB 4 DB 0,1,1 DB 1,0,0 DB 0,0,1 DB 1,1,0 chr_Y: DB 5 DB 0,.5,0 DB 1,.5,.5 DB 0,0,1 DB 1,.5,.5 DB 1,1,1 chr_Z: DB 4 DB 0,0,1 DB 1,1,1 DB 1,0,0 DB 1,1,0 chr_openbracket: DB 0 chr_backslash: DB 0 chr_closebracket: DB 0 chr_caret: DB 0 chr_underscore: DB 0 chr_backtick: DB 0 chr_opencurlybrace: DB 0 chr_pipe: DB 0 chr_closecurlybrace: DB 0 chr_tilde: DB 0 chrtable: DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 DB chr_space, chr_exclam, chr_dblqt, chr_hash, chr_dlr, chr_percent, chr_amprsnd, chr_snglqt, chr_openparen, chr_closeparen, chr_star, chr_plus, chr_comma DB chr_dash, chr_period, chr_slash, chr_0, chr_1, chr_2, chr_3, chr_4, chr_5, chr_6, chr_7, chr_8, chr_9, chr_colon, chr_semicolon, chr_lessthan, chr_equal DB chr_greaterthan, chr_questionmark, chr_at, chr_A, chr_B, chr_C, chr_D, chr_E, chr_F, chr_G, chr_H, chr_I, chr_J, chr_K, chr_L, chr_M, chr_N, chr_O, chr_P DB chr_Q, chr_R, chr_S, chr_T, chr_U, chr_V, chr_W, chr_X, chr_Y, chr_Z, chr_openbracket, chr_backslash, chr_closebracket, chr_caret, chr_underscore DB chr_backtick, chr_A, chr_B, chr_C, chr_D, chr_E, chr_F, chr_G, chr_H, chr_I, chr_J, chr_K, chr_L, chr_M, chr_N, chr_O, chr_P, chr_Q, chr_R, chr_S DB chr_T, chr_U, chr_V, chr_W, chr_X, chr_Y, chr_Z, chr_opencurlybrace, chr_pipe, chr_closecurlybrace, chr_tilde DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 DB 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // Variables xchar: DB 0 cursx: DB 0 cursy: DB 0 speed: DB 80 pendown: DB 0 define pagewidth,45 // In characters define pageheight,64 // In inches; how far to start the plotter up helloworld: //DB '1234567890 ' DB 'Hello, world!' DB 0 // Program begins here! CODE MOV #cursx,0 MOV #cursy,pageheight MOV EAX,helloworld // Change to 65536 to read from external memory //MOV EAX,65536 MOV EBX,32 SUB #cursy,EBX CALL printline INT 2 // Call here to print a line // Set the variables: EAX=string (nullterminated), EBX=scale // This will update cursx and cursy with its progress. // It will also pay attention to pagewidth and scroll accordingly. printline: PUSH EAX PUSH EBX PUSH ECX PUSH EDX printline_mainloop: CMP #EAX,255 JL printline_eaxinrange MOV #EAX,255 printline_eaxinrange: CMP #EAX,0 JE printline_mainloop_over CMP #EAX,10 JNE printline_notnewline MOV ECX,EBX DIV ECX,4 ADD ECX,EBX SUB #cursy,ECX MOV #cursx,0 MOV #xchar,0 INC EAX JMP printline_mainloop printline_notnewline: PUSH EAX MOV EDX,chrtable // chartable ADD EDX,#EAX // add the offset of current character MOV EAX,#EDX // convert pointer in table to beginning of letter CALL drawletter POP EAX MOV ECX,EBX DIV ECX,4 ADD ECX,EBX ADD #cursx,ECX ADD #xchar,1 CMP #xchar,pagewidth JL printline_pagewidthok MOV #xchar,0 MOV #cursx,0 SUB #cursy,ECX printline_pagewidthok: INC EAX JMP printline_mainloop printline_mainloop_over: POP EDX POP ECX POP EBX POP EAX RET // Call here to draw a letter // Set the variables: EAX=letter, EBX=scale // This will leave cursx and cursy alone but the plotter will not necesarilly // remain at that cursor, for speed boosts. EAX and EBX will be restored at // the end of execution drawletter: PUSH EAX PUSH EBX PUSH ECX PUSH EDX PUSH #speed PUSH #cursx PUSH #cursy CMP EAX,0 JZ drawletter_end MOV EDX,#EAX //Number of strokes left CMP EDX,0 JZ drawletter_end INC EAX // move into the first stroke drawletter_strokeloop: POP #cursy POP #cursx POP #speed SUB ESP,3 MOV #pendown,#EAX INC EAX CMP #pendown,0 JNZ drawletter_speedok MUL #speed,10 drawletter_speedok: MOV ECX,#EAX MUL ECX,EBX ADD #cursx,ECX INC EAX MOV ECX,#EAX MUL ECX,EBX ADD #cursy,ECX INC EAX CALL plot DEC EDX CMP EDX,0 JNE drawletter_strokeloop drawletter_end: POP #cursy POP #cursx POP #speed POP EDX POP ECX POP EBX POP EAX RET // Call here to send data to the plotter expression gate // Set the variables: cursx, cursy, speed, pendown plot: PUSH EAX PUSH EBX PUSH ECX MOV EAX,#cursx OUT 0,EAX MOV EAX,#cursy OUT 1,EAX //OUT 2,draw //OUT 3,move OUT 4,#speed CMP #pendown,0 JNE plot_pendown plot_penup: MOV EAX,3 JMP plot_penset plot_pendown: MOV EAX,2 plot_penset: TIMER EBX ADD EBX,.10 plot_wait: TIMER ECX CMP EBX,ECX JG plot_wait OUT EAX,1 TIMER EBX ADD EBX,.10 plot_wait2: TIMER ECX CMP EBX,ECX JG plot_wait2 OUT EAX,0 plot_letdraw: IN EBX,0 CMP EBX,0 JNE plot_letdraw POP ECX POP EBX POP EAX RET