; CISC 221 Assignment 3 ; A small Java class is provided, with static methods, and translated ; to Pep/6 assembler language to illustrate the relationship between ; language levels, ; The given program essentially uses no object-oriented features, and ; the translation makes no attempt to simulate those. ; The class is assumed pre-loaded and so static data is preallocated. ; The main method is treated as a method. It could also be treated as ; a program, as we do in class. ; Boolean constants: FALSE: .EQUATE h#0000 TRUE: .EQUATE h#FFFF ; All the arguments and vars in this program are two-bytes long, so the ; following defines are always used. 'Parameter' means a formal ; argument in a subroutine. 'Argument' means an actual argument ; supplied by a caller. The subroutine calling protocol is exactly ; as in Warford's text. ; To allocate space for arguments ; (The return value, if any, is treated as the first argument.) PUSH1ARG: .EQUATE d#-2 PUSH2ARG: .EQUATE d#-4 POP1ARG: .EQUATE d#+2 POP2ARG: .EQUATE d#+4 ; ; To refer to arguments when building call Arg1: .EQUATE d#-2 Arg2: .EQUATE d#-4 ; ; To allocate local variables in called routine. ; (Offsets are given names in the routine code.) PUSH1VAR: .EQUATE d#-2 PUSH2VAR: .EQUATE d#-4 PUSH3VAR: .EQUATE d#-6 POP1VAR: .EQUATE d#+2 POP2VAR: .EQUATE d#+4 POP3VAR: .EQUATE d#+6 ; The next few lines simulate the behaviour of the 'java' command, by ; calling the main method. The arguments of the main method are ; unavailable because Pep/6 doesn't provide command-line arguments. ; It would also be acceptable to ignore the main method parameters ; entirely and to "BR main" instead. LOADA StringA0,d ; arg = empty String array STOREA Arg1,s ADDSP PUSH1ARG,i ; adjust stack JSR main ; call main method ADDSP POP1ARG,i ; pop args STOP ; might as well stop now ; ; empty string array: .WORD d#0 StringA0: .WORD h#0000 ;actually don't need any storage at all! ; ; ; class Asst3 ; ; { ; ; // This class simulates a simple data monitoring ; ; // Input 'readings' are lines of the form * NNN MMM, ; ; // NNN and MMM are considered as readings in the range ; ; // The output, for each input, is the -max- and -min- ; ; // NNN values, and the -max- and -min- of the last ; ; These don't need any memory. Since they're final short, they can be .EQUATE's. QSIZE: .EQUATE d#32 ; static final short QSIZE = 32; // must be power of 2 RANGE: .EQUATE d#25 ; static final short RANGE = 25; // must be <= QSIZE ; ; // These arrays are the data for NNN values and MMM Ns: .ADDRSS shortAr1 ; static short [] Ns = new short [QSIZE]; .WORD d#32 ;Can't write QSIZE here, assembler won't allow it. shortAr1: .BLOCK d#64 ;Can't write symbolic expression QSIZE*2, unfortunately. Ms: .ADDRSS shortAr2 ; static short [] Ms = new short [QSIZE]; .WORD d#32 shortAr2: .BLOCK d#64 ; ; ; // These variables record how many data items are ; ; // stored and which is the first one. numData: .WORD d#0 ; static short numData = 0; queueHea: .WORD d#0 ; static short queueHead = 0; ; ; ; // This method reads the next line of data, and ; ; // returns true if there was one, false if not. ; ; // It also echoes input. readLine: ADDSP PUSH2VAR,i ; static boolean readLine () returnRe: .EQUATE d#6 ;stack offset of return value ; ; { queueFre: .EQUATE d#0 ; short queueFree; temp1: .EQUATE d#2 ;temporary for reading a byte ; ; ; ; // Check if there's any more data. CHARI temp1,s ; if (Io. charInput () != '*') if1: LOADA h#0000,i ;clear before byte compare LDBYTA temp1,s COMPA c#/*/,i BREQ endif1 LOADA FALSE,i ; return false; STOREA returnRe,s ADDSP POP2VAR,i RTS endif1: CHARO c#/*/,i ; Io. charOutput ('*'); ; ; ; // Read data into the queue. LOADA queueHea,d ADDA numData,d ;A = (queueHead + numData) ANDA h#001F,i ;A = A % QSIZE because QSIZE is a power of 2 STOREA queueFre,s ; queueFree = (short) ((queueHead + numData) % QSIZE); LOADB Ns,d ;prepare to access array Ns LOADX queueFre,s ;load index ASLX ;*2 -> offset DECI ,x ; Ns [queueFree] = Io. decimalInput (); LOADB Ms,d ;prepare to access array Ms, same offset! DECI ,x ; Ms [queueFree] = Io. decimalInput (); ; CHARO c#/ /,i ; Io. charOutput (' '); LOADB Ns,d DECO ,x ; Io. decimalOutput (Ns [queueFree]); CHARO c#/ /,i ; Io. charOutput (' '); LOADB Ms,d DECO ,x ; Io. decimalOutput (Ms [queueFree]); CHARO h#0D,i ; Io. charOutput ('\n'); ; ; ; // If there are already 25 data, remove the head of the if2: LOADA numData,d ; if (numData >= RANGE) COMPA RANGE,i BRLE else2 LOADA queueHea,d ; queueHead = (short) ((queueHead + 1) % QSIZE); ADDA d#1,i ANDA h#001F,i STOREA queueHea,d BR endif2 ; ; // Otherwise increase the size else2: LOADA numData,d ; else ADDA d#1,i ; ++ numData; STOREA numData,d ; endif2: LOADA TRUE,i ; return true; STOREA returnRe,s ADDSP POP2VAR,i RTS ; ; } ; main: ADDSP PUSH1VAR,i ; public static void main (String [] args) temp2: .EQUATE d#0 ;displacement of a temporary local variable ; ; { while1: ADDSP PUSH1ARG,i ; while (readLine ()) JSR readLine ADDSP POP1ARG,i ;pop return value LOADA Arg1,s ;load return value COMPA TRUE,i BRNE endw1 ; { LOADA Ns,d ; Io. decimalOutput (maxArray (Ns)); STOREA Arg2,s ;(Arg1 is return value) ADDSP PUSH2ARG,i JSR maxArray ADDSP POP2ARG,i ;adjust stack LOADA Arg1,s ;load return value STOREA temp2,s DECO temp2,s CHARO c#/ /,i ; Io. charOutput (' '); LOADA Ns,d ; Io. decimalOutput (minArray (Ns)); STOREA Arg2,s ;(Arg1 is return value) ADDSP PUSH2ARG,i JSR minArray ADDSP POP2ARG,i ;adjust stack LOADA Arg1,s ;load return value STOREA temp2,s DECO temp2,s CHARO c#/ /,i ; Io. charOutput (' '); LOADA Ms,d ; Io. decimalOutput (maxArray (Ms)); STOREA Arg2,s ;(Arg1 is return value) ADDSP PUSH2ARG,i JSR maxArray ADDSP POP2ARG,i ;adjust stack LOADA Arg1,s ;load return value STOREA temp2,s DECO temp2,s CHARO c#/ /,i ; Io. charOutput (' '); LOADA Ms,d ; Io. decimalOutput (minArray (Ms)); STOREA Arg2,s ;(Arg1 is return value) ADDSP PUSH2ARG,i JSR minArray ADDSP POP2ARG,i ;adjust stack LOADA Arg1,s ;load return value STOREA temp2,s DECO temp2,s CHARO h#0D,i ; Io. charOutput ('\n'); BR while1 ; } endw1: ADDSP POP1VAR,i ; } RTS ; minArray: ADDSP PUSH3VAR,i ; static short minArray (short [] x) xarg1: .EQUATE d#8 returnMi: .EQUATE d#10 ; ; { ivar1: .EQUATE d#0 ; short i; minVal: .EQUATE d#2 ; short minVal = +32767; LOADA d#+32767,i STOREA minVal,s index1: .EQUATE d#4 ; short index; LOADB xarg1,s ;prepare to access array x for1: LOADA d#0,i ; for (i = 0; STOREA ivar1,s loop1: COMPA numData,d ; i < numData; BRGE endl1 ; { LOADX queueHea,d ; index = (short) ((queueHead + i) % QSIZE); ADDX ivar1,s ANDX h#001F,i STOREX index1,s ASLX ;compute offset if3: LOADA minVal,s ; if (minVal > x [index]) COMPA ,x BRV test3 ;see cs.queensu.ca/~cisc221/solution03/Assignment3Note.html BRGT true3 BR endif3 test3: BRGT endif3 true3: LOADA ,x ; minVal = x [index]; STOREA minVal,s endif3: LOADA ivar1,s ; ++i) ADDA d#1,i STOREA ivar1,s BR loop1 ; } endl1: LOADA minVal,s ; return minVal; STOREA returnMi,s ADDSP POP3VAR,i RTS ; } ; maxArray: ADDSP PUSH3VAR,i ; static short maxArray (short [] x) xarg2: .EQUATE d#8 returnMa: .EQUATE d#10 ; ; { ivar2: .EQUATE d#0 ; short i; maxVal: .EQUATE d#2 ; short maxVal = -32768; LOADA d#-32768,i STOREA maxVal,s index2: .EQUATE d#4 ; short index; LOADB xarg2,s ;prepare to access array x for2: LOADA d#0,i ; for (i = 0; STOREA ivar2,s loop2: COMPA numData,d ; i < numData; BRGE endl2 ; { LOADX queueHea,d ; index = (short) ((queueHead + i) % QSIZE); ADDX ivar2,s ANDX h#001F,i STOREX index2,s ASLX ;compute offset if4: LOADA maxVal,s ; if (maxVal < x [index]) COMPA ,x BRV test4 ;signed compare, see note BRLT true4 BR endif4 test4: BRLT endif4 true4: LOADA ,x ; maxVal = x [index]; STOREA minVal,s endif4: LOADA ivar2,s ; ++i) ADDA d#1,i STOREA ivar2,s BR loop2 ; } endl2: LOADA maxVal,s ; return maxVal; STOREA returnMa,s ADDSP POP3VAR,i RTS ; } .END