microprofessor-1 monitor program assembly source

27
;************************************************************************************************************* ;* **** MICROPROFESSOR-1 MONITOR PROGRAM ASSEMBLY SOURCE **** * ;* * ;* COPYRIGHT , MULTITECH INDUSTRIAL CORP. 1981 * ;* All rights reserved. * ;* No part of this software may be copied without * ;* the express written consent of MULTITECH * ;* INDUSTRIAL CORP. * ;* * ;* NOTE: This is the original uPF-1 monitor program source code. The binary output of the assembled code * ;* has been compared byte to byte with the original ROM and it's guaranteed to be 100% OK * ;* * ;* ASSEMBLY PROCEDURE: TASM -80 <ThisFileNameWithExtension> * ;* (Download TASM from: http://home.comcast.net/~tasm/tasmdnl.htm * ;************************************************************************************************************* .EXPORT SCAN,HEX7SG P8255 .EQU 03H ;8255 I control port DIGIT .EQU 02H ;8255 I PORT C SEG7 .EQU 01H ;8255 I PORT B KIN .EQU 00H ;8255 I PORT A PWCODE .EQU 0A5H ;Power-up code ZSUM .EQU 71H ;This will make the sum of all monitor codes to be zero ; The following EQUATEs are used for timing. Their values depend on the CPU clock frequency. ; The uPF--1 clock frequency is 1.79 MHz. COLDEL .EQU $C9 ;Column delay time for routine SCAN and SCAN1 F1KHZ .EQU $41 ;Delay count for 1KHz square wave, used by routine TONE1K F2KHZ .EQU $1F ;Delay count for 2KHz square wave, used by routine TONE2K MPERIOD .EQU $2A ;1KHz and 2KHz threshold, used by tape input routine PERIOD ; The following EQUATEs are used for tape routines. If the quality of the tape recorder is good, the user may ; change '4 4 2 8' to '2 2 1 4'. This will in fact double the tape data rate. If the quality of tape recorder ; is poor, the user may change '4 4 2 8' to '6 6 3 12'. This will improve error performance but will slow down ; data rate. Although the data format is changed, the tape is still compatible in each case because only the ; ratio is detected in the tape read. ONE_1K .EQU 4 ONE_2K .EQU 4 ZERO_1K .EQU 2 ZERO_2K .EQU 8 ;************************************************************************************************************* ; I/O port assignment (8255 PIO) ; ; PORT A (Address 00H) ; ; bit 7 ----- Tape Input ; bit 6 ----- 'USER KEY' on keyboard, active low ; bits 5,4,3,2,1,0 = Rows of the keyboard matrix (active low inputs) ; ; PORT B (Address 01H): 7 segments (+ decimal point) of display LEDs, active high ; ; bit 7 -- segment d ; bit 6 -- decimal point ; bit 5 -- segment c ; bit 4 -- segment b ; bit 3 -- segment a ; bit 2 -- segment f ; bit 1 -- segment g ; bit 0 -- segment e ; ; PORT C (Address 02H): ; ; bit 7 -- Tape and tone output ; bit 6 -- BREAK enable. NMI (CPU pin 17) will go to low five M1's ; (M1 = Machine Cycle 1) after this bit goes to low. ; This bit is connected to the RESET input of an external counter ; bit 5,4,3,2,1,0 = Columns of the keyboard matrix and also the display matrix, ; they are active high. (bit 5 is the leftmost column) ; ;************************************************************************************************************* ; - CPU RESET - ; There are two cases that will generate a RESET signal: ; (i) Power-up ; (ii) 'RS' key pressed ;

Upload: jose-luis-abasolo-mayor

Post on 29-Nov-2014

291 views

Category:

Documents


8 download

DESCRIPTION

Microprofessor-1 Monitor Program Assembly Source, MULTITECH

TRANSCRIPT

Page 1: Microprofessor-1 Monitor Program Assembly Source

;************************************************************************************************************* ;* **** MICROPROFESSOR-1 MONITOR PROGRAM ASSEMBLY SOURCE **** * ;* * ;* COPYRIGHT , MULTITECH INDUSTRIAL CORP. 1981 * ;* All rights reserved. * ;* No part of this software may be copied without * ;* the express written consent of MULTITECH * ;* INDUSTRIAL CORP. * ;* * ;* NOTE: This is the original uPF-1 monitor program source code. The binary output of the assembled code * ;* has been compared byte to byte with the original ROM and it's guaranteed to be 100% OK * ;* * ;* ASSEMBLY PROCEDURE: TASM -80 <ThisFileNameWithExtension> * ;* (Download TASM from: http://home.comcast.net/~tasm/tasmdnl.htm * ;************************************************************************************************************* .EXPORT SCAN,HEX7SG P8255 .EQU 03H ;8255 I control port DIGIT .EQU 02H ;8255 I PORT C SEG7 .EQU 01H ;8255 I PORT B KIN .EQU 00H ;8255 I PORT A PWCODE .EQU 0A5H ;Power-up code ZSUM .EQU 71H ;This will make the sum of all monitor codes to be zero ; The following EQUATEs are used for timing. Their values depend on the CPU clock frequency. ; The uPF--1 clock frequency is 1.79 MHz. COLDEL .EQU $C9 ;Column delay time for routine SCAN and SCAN1 F1KHZ .EQU $41 ;Delay count for 1KHz square wave, used by routine TONE1K F2KHZ .EQU $1F ;Delay count for 2KHz square wave, used by routine TONE2K MPERIOD .EQU $2A ;1KHz and 2KHz threshold, used by tape input routine PERIOD ; The following EQUATEs are used for tape routines. If the quality of the tape recorder is good, the user may ; change '4 4 2 8' to '2 2 1 4'. This will in fact double the tape data rate. If the quality of tape recorder ; is poor, the user may change '4 4 2 8' to '6 6 3 12'. This will improve error performance but will slow down ; data rate. Although the data format is changed, the tape is still compatible in each case because only the ; ratio is detected in the tape read. ONE_1K .EQU 4 ONE_2K .EQU 4 ZERO_1K .EQU 2 ZERO_2K .EQU 8 ;************************************************************************************************************* ; I/O port assignment (8255 PIO) ; ; PORT A (Address 00H) ; ; bit 7 ----- Tape Input ; bit 6 ----- 'USER KEY' on keyboard, active low ; bits 5,4,3,2,1,0 = Rows of the keyboard matrix (active low inputs) ; ; PORT B (Address 01H): 7 segments (+ decimal point) of display LEDs, active high ; ; bit 7 -- segment d ; bit 6 -- decimal point ; bit 5 -- segment c ; bit 4 -- segment b ; bit 3 -- segment a ; bit 2 -- segment f ; bit 1 -- segment g ; bit 0 -- segment e ; ; PORT C (Address 02H): ; ; bit 7 -- Tape and tone output ; bit 6 -- BREAK enable. NMI (CPU pin 17) will go to low five M1's ; (M1 = Machine Cycle 1) after this bit goes to low. ; This bit is connected to the RESET input of an external counter ; bit 5,4,3,2,1,0 = Columns of the keyboard matrix and also the display matrix, ; they are active high. (bit 5 is the leftmost column) ; ;************************************************************************************************************* ; - CPU RESET - ; There are two cases that will generate a RESET signal: ; (i) Power-up ; (ii) 'RS' key pressed ;

Page 2: Microprofessor-1 Monitor Program Assembly Source

; In both cases, the following actions are taken: ; a) Interrupts are disabled and set to mode '0' (IM0). ; Register I is set to 00 ; b) Initial user's PC is set to the lowest RAM address. ; c) User's SP is set to 1F90H ; d) User's I register is set to 00 and user's interrupt flip-flop is disabled ; e) BREAKPOINT is disabled ; f) The contents of 0x1FEE and 0x1FEF (which store an address) are set to 0x0066 ; this will make instruction RST 38h (Opcode FFh) have the same effect as BREAK. ; ; Memory location POWERUP is used to distinguish power-up from RESET key. Location (POWERUP) ; contains random data when the uPF-1 is powered-up, but contains PWCODE (0xA5) thereafter. ;************************************************************************************************************* .ORG 0 ;Z80 begins execution at 0000h LD B,0 DJNZ $ ;Power-up delay LD A,90H ;Set 8255 chip as: PORT_A=Input, PORT_B & PORT_C=Output. OUT (P8255),A ;The control word to send to command port is 0x90 ; When the control word is sent out to 8255 all output ports are cleared to 0. It is necessary to disable ; BREAK and deactivate all I/O by sending 0xC0 to PORT_C LD A,$C0 OUT (DIGIT),A LD SP,SYSSTK ;Setup initial system's stack LD A,(POWERUP) ;If the content of location POWERUP is not equal to PWCODE CP PWCODE ;then call subroutine INI, otherwise is a 'hot' reset and CALL NZ,INI ;the program continues. ;************************************************************************************************************* ; Here, lowest RAM address are determined by checking wether address 0x1000 is RAM. ; If test is true then user's PC is set to 0x1000, otherwise is set to 0x1800. LD HL,1000H CALL RAMCHK JR Z,PREPC LD H,18H PREPC: LD (USERPC),HL LD H,0 ; Address 28h and 30h are reserved for BREAK (RST 28H) and software BREAK (RST 30h) so ; we must skip the following memory area and resume execution of monitor at location RESET1. JR RESET1 ;************************************************************************************************************* .ORG 28H ; Address 28H is the entry point of BREAK trap. If a location is set as a breakpoint using key 'SBR', what the ; monitor does is change the content of this location with 0xC7 (Opcode for RST28H) BEFORE transfering ; control to the user's program. In this way, when the user's program passes over the breakpoint address the ; monitor takes control of the user's program restoring the original content of the breakpoint location and ; making everything look transparent to the user. The following instructions make the stack manipulation to ; achieve this. RST28: EX (SP),HL DEC HL EX (SP),HL LD (HLTEMP),HL JR CONT28 ;************************************************************************************************************* .ORG 30H ; Instruction RST 30H (Opcode 0xF7) is usually used as software break or as a terminator of user's program. ; The effect of this instruction is to save all user's registers and return control to monitor program. RST30: JR NMI ;************************************************************************************************************* ; Reset resumes here. As stated before a jump was necessary to skip locations for handling RST 28H & 30H RESET1: LD (USERIF),HL ;Set user's I reg. and user's interrupt flip-flop both to 00 JR RESET2 ;Again, reset routine must skip reserved memory area.

Page 3: Microprofessor-1 Monitor Program Assembly Source

;************************************************************************************************************* ; The following byte makes the sum of the monitor's ROM to be zero. Is used in self-test routine ROMTEST .BYTE ZSUM ;************************************************************************************************************* .ORG 38H ; Entry point of RST 38H (Opcode 0xFF) or MODE 1 Interrupt. This routine fetches the address stored at ; 0x1FEE,0x1FEF and then jumps to this address. At the begining of the monitor program, this address is set to ; 0x0066 which is the address for NMI service, in that way software break with RST 38H instruction has the ; same effect as pressing the MONI key, wich also causes a hardware break via NMI. By changing the contents ; of 0x1FEE,0x1FEF the user can define his own service routine. The next 3 instructions push the contents of ; this two locations onto the stack. RST38: PUSH HL LD HL,(IM1AD) EX (SP),HL ; At this point the top of the stack contains the address of the user-defined service routine, so the ; following RET instruction retrieves this address from stack and jumps to it. RET ;************************************************************************************************************* ; This is the continuation of the BREAK service routine, or RST28h CONT28: LD (ATEMP),A ; Since the monitor has changed the contents of user's program at break address (remember the previous ; explanation of what happens when 'SBR' key is pressed) the next 3 instructions restore the original content ; at breakpoint address. BRAD contains the break address and BRDA contains the original data at break address. LD HL,(BRAD) LD A,(BRDA) LD (HL),A ; The following OUT instruction enables the hardware break circuitry (see schematic for further details). ; Enabling it will have the inmediate effect of causing a NMI after 5 M1's. (M1=Machine Cycle 1, which is a ; physical Z80 signal that activates once per each CPU instruction) LD A,10000000B OUT (DIGIT),A LD A,(ATEMP) ;1st M1 LD HL,(HLTEMP) ;2nd M1 NOP ;3rd M1 RET ;4th M1 ; Here the control returns to user's program and the instruction at previously set breakpoint is executed. ; After finishing executing this instruction, a NMI is generated and control is then transfered again to the ; monitor. RESET2: LD HL,USERSTK LD (USERSP),HL ;Set user's SP ; The TEST address contains a general purpose flag for monitor's own use. Illegal key-in error handling ; routine and automatic zero leading uses this flag. In the next 2 instruction this flag is cleared. XOR A LD (TEST),A ; Data shown in the uPF1 display is stored in a 6 byte data area (one byte for each digit) pointed to by IX. ; In the following instruction, IX is set to show 'upF--1' LD IX,MPF_I ; At this point we are near address 0066h (NMI service address) so we must skip this area. Monitor resumes ; execution at SESSTO JP SETST0 ;************************************************************************************************************* .ORG 66H ; Entry point for NMI. NMI will occur when MONI key is pressed (Hardware break) or when user program is ; software-breaked The following instructions save all user's registers and also checks the validity of ; user's stack pointer. NMI: LD (ATEMP),A ;Save A register

Page 4: Microprofessor-1 Monitor Program Assembly Source

LD A,90H ;Control word to be sent to 8255 OUT (P8255),A ;PORT_A as input, PORT_B and PORT_C as output. LD A,$C0 ;Disable break and all LEDs. OUT (DIGIT),A LD A,(ATEMP) ;Restore A register RGSAVE: LD (HLTEMP),HL ;Save HL register POP HL ;Load HL with return address fetched from stack LD (ADSAVE),HL ;Save this return address also in ADSAVE address LD (USERPC),HL ;Set user's PC to this return address LD HL,(HLTEMP) ;and restore HL original content. LD (USERSP),SP ;Set user's SP to current SP LD SP,USERIY+2 ;Save other registers by pushing them onto the stack PUSH IY PUSH IX EXX PUSH HL PUSH DE PUSH BC EXX EX AF,AF' PUSH AF EX AF,AF' PUSH HL PUSH DE PUSH BC PUSH AF ; The next 2 instructions save the I (Interrupt Vector) register. The interrupt flip-flop (IFF2) is copied ; into the parity flag (P/V). The current interrupt status (enabled or disabled) can be determined by testing ; this parity flag LD A,I LD (USERIF+1),A ; The next 4 instructions save IFF2 into the user's interrupt flip-flop LD A,0 JP PO,SETIF ;If PO=true then flag P/V is zero LD A,1 SETIF: LD (USERIF),A LD SP,SYSSTK ;Set SP to system stack ; The next 8 instructions check user's SP. If the user's SP points to a location which is not in RAM, then ; 'eRR-SP' is displayed. LD HL,(USERSP) LD IX,ERR_SP DEC HL CALL RAMCHK JR NZ,SETST0 DEC HL CALL RAMCHK JR NZ,SETST0 ; If the user's stack and system's stack are overlayed then display 'SYS-SP'. This checking is done by the ; following instructions: LD IX,SYS_SP NOP NOP LD DE,-USERSTK+1 ADD HL,DE JR C,SETST0 LD IX,DISPBF SCF ;Set carry flag to indicate the user's SP is OK. JR BRRSTO ; STATE is a memory location that contains the current monitor status. It will be described in detail later. ; STATE 0 means 'fixed display pattern'. 'uPF--1' or 'SYS-SP' messages belong to this category. ; The next 2 instructions set this variable to zero. SETST0: XOR A ;Clears A register and also sets Carry flag = 0 LD (STATE),A BRRSTO: LD A,(BRDA) ;Restore the data at break address LD HL,(BRAD)

Page 5: Microprofessor-1 Monitor Program Assembly Source

LD (HL),A ; If the user's SP is legal (i.e. the carry flag is set) then dispaly user's PC and data at this address ; Otherwise display one of this fixed messages: "uPF--1" , "eRR-SP" or "SYS-SP" CALL C,MEMDP2 ;************************************************************************************************************* ; This is what monitor program does all the time: scan display and keyboard and when a key is pressed take ; the proper action. MAIN: LD SP,SYSSTK ;Set SP to system stack CALL SCAN ;Scan display and input keys (SCAN will not return until ;a key is pressed) CALL BEEP ;After a key is pressed a small beep will sound. JR MAIN ;keep doing this all the time ;************************************************************************************************************* ; Routine KEYEXEC takes the proper action according the key pressed. It uses the code returned by SCAN, ; which is stored in A. There are 32 posible key codes rangibg from 00 to 0x1F. ; Three cases will be considered depending on the value of the key returned. ; ; Case 1: Codes between 0x00 and 0x0F which correspond to HEXADECIMAL KEYS (0,1...D,E,F). This keys are ; processed in routine KHEX. ;************************************************************************************************************* KEYEXEC: CP $10 JR C,KHEX ; If the key pressed is NOT hexadecimal then it must be a FUNCTION or SUB-FUNCTION key, this means that ; the previous numeric entry has finished. ; Bit 0 of TEST flag (mentioned earlier) must be set at the beginning of a new numeric entry. If bit 0 of TEST ; is set then the data buffer will be automatically cleared when a hexadecimal key is entered. ; This is acomplished by the next two instructions. LD HL,TEST SET 0,(HL) ; Case 2: Codes between 0x10 & 0x17 ( +, -, GO, STEP, DATA, SBR, INS, DEL) ; There is no specific state corresponding to these keys, the response to them depends on the current value of ; "state" and "minor-state". (e.g. the response to '+' depends on the current context, it is illegal when ; the display is showing 'uPF--1' but is legal when the display is in the 'address-data' form.) In this ; monitor program the keys ( +, -, GO, STEP,DATA, SBR, INS,DEL) keys are called SUB-FUNCTION keys. All of them ; are branched by table KSUBFUN and routine BRANCH. SUB $10 CP 8 LD HL,KSUBFUN JP C,BRANCH ; Case 3: Codes between 0x18 & 0x1F (PC, ADDR, CBR, SBR, REG, MOVE, RELA, TAPE WR, TAPE RD) ; These keys are named FUNCTION-KEYS, since they are acceptable at any time. When one of this keys is pressed ; the monitor will unconditionally enter a new state. STMINOR will contain the "minor-state", which is ; required to process some sub-function keys (e.g. +,-) LD IX,DISPBF SUB 8 LD HL,STATE LD (HL),A ;Set the STATE to key-code minus 18H. The STATE is updated ;here and will be modified later by local service routines ;if the function is PC, ADDR or CBR. For other function keys ;STATE will not be modified later. LD HL,STMINOR LD (HL),0 ;Set STMINOR to 0 LD HL,KFUN ;KFUN is the base address of the branch table and A has JP BRANCH ; a table offset. ;************************************************************************************************************* ; The possible values of STATE and their meaning are: ; ; 0 = FIXED ; Display a fixed pattern, i.e. 'uPF--1' ; 1 = ADDRESS ; The hex key entered is interpreted as a memory address. ; 2 = DATA ; The hex key entered is interpreted as a memory data. ; 3 = REG ; Display the pattern 'Reg- ' and expect a register name to be entered. ; 4 = MOVE ; Expect parameters for MOVE function ; 5 = RELA ; Expect parameters for RELA function ; 6 = TAPEWR ; Expect parameters for TAPE WRITE function ; 7 = TAPERD ; Expect parameters for TAPE READ function ; 8 = RGADDR ; Entered Hex key will be interpreted as address name for registers ; 9 = RGDATA ; Entered Hex key will be interpreted as data for registers

Page 6: Microprofessor-1 Monitor Program Assembly Source

;************************************************************************************************************* ; Subroutine name conventions: ; ; (1) K???? K stands for Key and ???? is the key name, i.e. KINS corresponds to 'INS' key. Each time a ; key with code ???? is pressed The routine with the name K???? will be executed. All this ; routines are branched by table KFUN and KSUBFUN. ; ; (2) H???? H stands for Hexadecimal and ???? is the current STATE, i.e. routine HDA will be executed if ; the entered key is hexadecimal and current STATE is 2 (DATA). All H???? routines are branched ; by table HTAB. ; ; (3) I???? I stands for increment ('+' key) and ???? is the current STATE, i.e. IMV will be executed ; when STATE is 4 (MOVE) and '+' key is entered. all I???? routines are branched by table ITAB ; ; (4) D???? D stands for decrement ('-' key) and ???? is the current STATE, i.e. all D???? routines are ; branched by table DTAB. ; ; (5) G???? G stands for GO ('GO' key) and ???? is the current STATE, i.e. all G???? routines are branched ; by table GTAB. ;************************************************************************************************************* ; Hexadecimal keys and '+', '-' or 'GO' function keys may be entered after different function keys. ; The monitor program uses branch tables and the value of STATE to determine the current function and branch ; to the proper entry point. ; ;************************************************************************************************************* ; Routine KHEX is executed when hexadecimal keys are pressed (See case 1 before). It uses HTAB and STATE ; for further branching KHEX: LD C,A ;Save A register in C (Remember: A holds the hex key code) LD HL,HTAB BR1: LD A,(STATE) JP BRANCH ;************************************************************************************************************* ; Routine KINC is branched by KSUBFUN table and executed when '+' is pressed, it uses ITAB and STATE for ; further branching KINC: LD HL,ITAB JR BR1 ;************************************************************************************************************* ; Routine KDEC is branched by KSUBFUN table and executed when '-' key is pressed. It uses DTAB and STATE ; for further branching KDEC: LD HL,DTAB JR BR1 ;************************************************************************************************************* ; Routine KGO is branched by KSUBFUN table and executed when 'GO' key is pressed. It uses GTAB and STATE ; for further branching KGO: LD HL,GTAB JR BR1 ;************************************************************************************************************* ; Routine KSTEP is branched by KSUBFUN table and executed when 'STEP' key is pressed. KSTEP: CALL TESTM ;Check if the left 4 digits of the display are memory address. ;If not, disable all LEDs as a warning to the user. This display ;blanking is done by routine IGNORE JP NZ,IGNORE LD A,10000000B ;This data will be output to port B to enable BREAK. JP PREOUT ;This is done by routine PREOUT ;************************************************************************************************************* ; Routine KDATA is branched by KSUBFUN table and executed when 'DATA' key is pressed. KDATA: CALL TESTM ;Check if the left 4 digits of the display are memory address. JR NZ,TESTRG ;If not, branch to TESTRG to check whether the display is reg. or not. CALL MEMDP2 ;If yes, display the data of that address and set STATE to (DATA) RET TESTRG: CP 8 ;Check if the status is 8 or 9 (RGAD or RGDA). JP C,IGNORE ;If not, ignore this key by blanking out the display

Page 7: Microprofessor-1 Monitor Program Assembly Source

CALL REGDP9 ;If yes, display register and set status to 9 (RGDA) RET ;************************************************************************************************************* ; Routine KSBR is branched by KSUBFUN table and executed when 'SBR' (set breakpoint) key is pressed. KSBR: CALL TESTM ;Check if the display is in ADDRESS-DATA form. JP NZ,IGNORE ;If not, ignore this key by blanking out the display LD HL,(ADSAVE) ;If yes, get the address being displayed now. CALL RAMCHK ;Check if this address is in RAM space. JP NZ,IGNORE ;If not, ignore the 'SBR' key by blanking LD (BRAD),HL ;If yes, then set this address as a breakpoint CALL MEMDP2 ;Display the data of break address and set STATE to 2 (DA). RET ;************************************************************************************************************* ; Routine KINS is branched by KSUBFUN table and executed when 'INS' (insert) key is pressed. KINS: CALL TESTM ;Check if the display is in ADDRESS-DATA form. JP NZ,IGNORE ;If not, ignore this key by blanking out the display LD HL,(ADSAVE) ;If yes, get the adress being displayed now. NOP ;? LD (STEPBF),HL ;Store this address in STEPBF and the next address in STEPBF+4 for INC HL ;later use LD (STEPBF+4),HL CALL RAMCHK ;Check if the address to be inserted is in RAM. JP NZ,IGNORE ;If not, ignore the INS key by blanking LD DE,$1DFE ;If the address to be inserted is in the range of 1800-1DFF, then ;store 1DFE into STEPBF+2 LD A,H ;Otherwise, ignore the INS key. CP $1E JR C,SKIPH1 CP $20 JP C,IGNORE LD D,$27 SKIPH1: LD (STEPBF+2),DE ;************************************************************************************************************* ; When one byte is inserted at some address, all data below this address will be shifted down one position. ; The last location will be shifted out and therefore lost. The RAM is divided into 3 blocks as long as INS ; is concerned, this blocks are: 1800-1DFF,1E00-1FFF and 2000-27FF. The second block cannot be inserted ; because it contains system data. Each block is independent from the other when shift is performed so the ; data shifted out of the first block will not be propagated to the next block. The shift is acomplished by ; block transfer instruction in subroutine GMV. This routine needs 3 parameters which are described in the ; following lines: ; STEPBF: Starting Address (2 bytes) ; STEPBF+2: Ending Adress (2 bytes) ; STEPBF+4: Destination Address (2 bytes) DOMV: CALL GMV XOR A ;After the RAM has been shifted down, the data of the address to be ;inserted is cleared to zero. LD (DE),A ;Register DE contains inserted address after GMV is performed. LD HL,(STEPBF+4) ;Copy the data in (STEPBF+4) to (ADSAVE) LD (ADSAVE),HL CALL MEMDP2 ;Display the address and its data, also set STATE to 2 RET ;************************************************************************************************************* ; Routine KDEL is branched by KSUBFUN table and executed when 'DEL' (delete) key is pressed. KDEL: CALL TESTM ;Check if display is in ADDRESS-DATA form. JP NZ,IGNORE ;If not, ignore this key by blanking out the display ;DEL is similar to INS except that the memory is shifted up ;instead of down. (See coments on routine KINS for details.) LD HL,(ADSAVE) ;Get the address being displayed now, ;(this is the address to be deleted) NOP ;??? LD (STEPBF+4),HL CALL RAMCHK ;Check if address is in RAM. JP NZ,IGNORE ;If it isn't ignore key by blanking the display LD DE,$1E00 ;The following instructions prepare the parameters for routine GMV ;in step-buffer. (See coments on routine KINS for details.) LD A,H CP $1E JR C,SKIPH2 CP $20

Page 8: Microprofessor-1 Monitor Program Assembly Source

JP C,IGNORE LD D,$28 SKIPH2: LD (STEPBF+2),DE INC HL LD (STEPBF),HL JR DOMV ;************************************************************************************************************* ; Routine KPC is branched by KFUN table and executed when 'PC' (Program Counter) key is pressed. KPC: LD HL,(USERPC) ;Store the user's PC into (ADSAVE) LD (ADSAVE),HL CALL MEMDP2 ;Routine MEMDP2 displays the address in (ADSAVE) and its ;corresponding data. Also sets variable STATE to 2 RET ;************************************************************************************************************* ; Routine KCBR is branched by KFUN table and executed when 'CBr' (Clear breakpoint) key is pressed. KCBR: CALL CLRBR ;Call subroutine CLRBR to clear breakpoint. When this routine returns, ;HL always contains FFFF. LD (ADSAVE),HL ;Store FFFF into (ADSAVE) CALL MEMDP2 ;Routine MEMDP2 displays the address in (ADSAVE) and its corresponding ;data. Also sets variable STATE to 2 RET ;************************************************************************************************************* ; Routine KREG is branched by KFUN table and executed when 'REG' (Register) key is pressed. KREG: LD IX,REG_ ;Routine SCAN uses IX as a pointer to the display buffer. Setting IX ;to REG will make SCAN display 'Reg-' and decode user's flag F ;and F' to binary display format. This format will be used later CALL FCONV ;when user requires the monitor to display decoded flag by pressing RET ;keys 'SZXH' and 'XPNC' ;************************************************************************************************************* ; Routine KADDR is branched by KFUN table and executed when 'Addr' (Address) key is pressed. KADDR: CALL MEMDP1 ;Display the address stored in (ADSAVE) and set system variable STATE RET ;to 1 (Address mode) ;************************************************************************************************************* ; Functions 'Move','Rela','Read Tape' and 'Write Tape', all require from one to three parameters. ; These parameters are stored in address STEPBF (Step Buffer). On the other hand, address STMINOR (minor ; status) contains the number of parameters that has been entered. For MOVE or RELA functions, the default ; value of the first parameter is the address stored in ADSAVE memory address. On the other hand, there is no ; default value for the first parameter (filename) of the Read and Write tape routines.When function keys are ; pressed, STMINOR is automatically reset to zero. ;************************************************************************************************************* ; Routines KMV and KRL are branched by KFUN table and executed when 'Move' or 'Rela' keys are pressed. KMV: KRL: LD HL,(ADSAVE) ;Store the contents of ADSAVE into STEPBF as default value LD (STEPBF),HL ;of first parameter. ;************************************************************************************************************* ; Routines KWT and KRT are branched by KFUN table and executed when 'WRTape' or 'RDTape' keys are pressed. KWT: KRT: CALL STEPDP ;Display the parameter that is being entered now by calling STEPDP RET ;************************************************************************************************************* ; The following subroutines, all following the format Hxxx are the service routines for hexadecimal keys ; corresponding to each STATE. They are all branched by table HTAB and STATE HFIX: JP IGNORE ;When the display is in fixed pattern, hexadecimal keys are illegal. ;IGNORE disables all LEDs as a warning to the user. HDA: LD HL,(ADSAVE) ;Get the address being displayed now from (ADSAVE) CALL RAMCHK ;Check if address is in RAM. JP NZ,IGNORE ;If not, ignore this key blanking the display

Page 9: Microprofessor-1 Monitor Program Assembly Source

CALL PRECL1 ;If this is the first hex key entered after function or subfunction, ;reset the data of that address to 00h LD A,C ;The key code is saved in C register at routine KHEX, restore it to A. RLD ;Rotate the key code (4 bits) into the address obtained above in HL CALL MEMDP2 ;Display the address and data then set STATE to 2 (DA). RET HAD: LD HL,ADSAVE CALL PRECL2 ;If this is the first hex key after function key is entered, set the ;contents of (ADSAVE) to 00h. LD A,C ;The key-code is saved in C register by routine KHEX. RLD ;Shift the address being displayed by one digit. INC HL RLD CALL MEMDP1 ;Display the address and its data. Also, set STATE to 1. RET HRGAD: HRGFIX: LD A,C LD IX,DISPBF LD HL,STMINOR ADD A,A ;The key-code is the register name. Double its value and store it LD (HL),A ;into STMINOR. CALL REGDP8 ;Display register and set STATE to 8. (RGAD) RET HRT: HWT: HRL: HMV: CALL LOCSTBF ;Use STMINOR and STEPBF to calculate the address of current parameter ;in step buffer CALL PRECL2 ;If this is the first hex key entered, clear the parameter (2 bytes) ;by calling PRECL2. LD A,C ;C contains the key code. RLD ;Rotate the key code 1 digit to the left INC HL RLD CALL STEPDP ;Display the parameter. RET HRGDA: CALL LOCRGBF ;Calculate the address of the register being modified. CALL PRECL1 ;If this is the first hex key entered, then clear the register LD A,C ;Rotate user's register 1 digit to the left. (C holds the key-code) RLD CALL REGDP9 ;Display the register and set STATE to 9 (RGDA) RET ;************************************************************************************************************* ; The following subroutines, all following the format Ixxx are the service routines for '+' ; corresponding to each STATE. They are all branched by table ITAB and STATE IFIX: IRGFIX: JP IGNORE ;'+' key is illegal for state FIX or RGFIX, so ignore it. IAD: IDA: LD HL,(ADSAVE) INC HL ;Increase the address being displayed now (In ADSAVE) by 1. LD (ADSAVE),HL CALL MEMDP2 ;Display the address and data the set state to 2. RET IRT: IWT: IRL: IMV: LD HL,STMINOR ;STMINOR contains the parameter count, increment it by one. INC (HL) CALL LOCSTNA ;Check if the count is overflowed. JR NZ,ISTEP ;If not overflowed, continue at ISTEP. DEC (HL) ;Otherwise, restore the count and ignore the '+' key. JP IGNORE ISTEP: CALL STEPDP ;Display the parameter at step buffer. RET

Page 10: Microprofessor-1 Monitor Program Assembly Source

IRGAD: IRGDA: LD HL,STMINOR ;In these states, the STMINOR contains the register name. INC (HL) ;Increase it by 1. LD A,$1F CP (HL) JR NC,IRGNA LD (HL),0 ;If it reaches the last one, reset it to the first one (00h). IRGNA: CALL REGDP9 ;Display the register contents and set STATE to 9. RET ;************************************************************************************************************* ; The following subroutines, all following the format Dxxx are the service routines for '-' ; corresponding to each STATE. They are all branched by table DTAB and STATE DFIX: DRGFIX: JP IGNORE ;'-' key is illegal for these states. Ignore it. DAD: DDA: LD HL,(ADSAVE) ;Decrease the address being displayed now (in ADSAVE) by one. DEC HL LD (ADSAVE),HL CALL MEMDP2 ;Display the address and data and set STATE to 2 (DA). RET DRT: DWT: DRL: DMV: LD HL,STMINOR ;In these states, STMINOR contains the parameter count. Decrease it ;by one. DEC (HL) CALL LOCSTNA JR NZ,DSTEP ;If overflow occurs, restore STMINOR and ignore the '-' key. Otherwise INC (HL) ;continue at DSTEP. JP IGNORE DSTEP: CALL STEPDP ;Display the parameter. RET DRGAD: DRGDA: LD HL,STMINOR ;In this state, STMINOR contains the register name. DEC (HL) ;Decrease register name by one LD A,$1F CP (HL) ;If it goes below zero, set it to the highest value (1Fh) JR NC,DRGNA LD (HL),$1F DRGNA: CALL REGDP9 ;Display the register and set STATE to 9 RET ;************************************************************************************************************* ; The following subroutines, all following the format Gxxx are the service routines for 'GO' ; corresponding to each STATE. They are all branched by table GTAB and STATE GFIX: GRGFIX: GRGAD: GRGDA: JP IGNORE ;'GO' key is illegal for these states, so ignore it. GAD: GDA: LD HL,(BRAD) ;Get the breakpoint address. LD (HL),$EF ;0EFh is the op-code for RST28H ;The contents of breakpoint address is changed to RST 28H ;before the control is transfered to user's program. This will ;cause a trap when the user's program passes this point. LD A,$FF ;Load 0FFh in memory location TEMP. PREOUT: LD (TEMP),A LD A,(USERIF) BIT 0,A ;Test the user's IFF (interrupt FlipFlop), depending on result ;two opcodes will be inserted at address TEMP+1 and TEMP+2 LD HL,$C9FB ;if IFF=0, then the instructions are 'EI' and 'RET' ;(0C9h is the opcode for RET, and 0FBh is for 'EI') JR NZ,EIDI ;if IFF=1, then the instructions are 'DI' and 'RET' LD L,$F3 ;0F3h is the opcode for 'DI', since H hasn't changed, modify L EIDI: LD (TEMP+1),HL LD SP,REGBF ;Restore user's register by setting SP to REGBF (Reg. buffer) ;and continuosly popping the stack. POP AF POP BC

Page 11: Microprofessor-1 Monitor Program Assembly Source

POP DE POP HL EX AF,AF' POP AF EX AF,AF' EXX POP BC POP DE POP HL EXX POP IX POP IY LD SP,(USERSP) ;Restore user's SP. LD (USERAF+1),A ;Temporarily save A LD A,(USERIF+1) ;Restore user's I LD I,A PUSH HL ;The next 3 instructions push the address being displayed now LD HL,(ADSAVE) ;(which is in ADSAVE) This address will be treated as ;user's new PC. EX (SP),HL LD A,(TEMP) ;Output 0FFh to port B of 8255. when A=10111111 break is ;enabled, when A=FF then break is disabled. When break is ;enabled, a non-maskable interrupt (NMI) will occur 5 M1's OUT (DIGIT),A ;after the out instruction. LD A,(USERAF+1) ;1st M1, Restore A JP TEMP+1 ;2nd M1, ;Execute the two instructions stored in RAM. They are: ; EI (or DI) ;3rd M1 ; RET ;4th M1 ;The starting address of user's program has been pushed onto ;the top of the stack. RET pops out this address and transfers ;Control to it. The first M1 of user's program will be the 5th ;M1 after OUT. If breakpoint is enabled, NMI will occur after ;this instructions is completed. This is how the single-step ;functionality is achieved. GMV: LD HL,STEPBF CALL GETP ;Load parameters from step buffer into registers. ;Also check if the parameters are legal. After GETP we have: ;HL = start address of source ;BC = Lenght to MOVE. JR C,ERROR ;Jump to ERROR if the parameters are illegal (i.e. ending ;address is lower than starting address) LD DE,(STEPBF+4) ;Load destination address into DE SBC HL,DE ;Compare HL and DE to determine move direction (up or down) JR NC,MVUP ;Move down: EX DE,HL ;HL = destination address ADD HL,BC ;HL = destination address + length DEC HL ;HL= end address of destination EX DE,HL ;DE = end address of destination LD HL,(STEPBF+2) ;HL = end address of source LDDR ;Block transfer instruction INC DE ;DE = Last address move JR ENDFUN ;Continue at ENDFUN. MVUP: ADD HL,DE ;Move up. HL is destroyed by SBC HL,DE so we must restore HL. LDIR ;block transfer instruction DEC DE ;DE = last address moved JR ENDFUN ;Continue at ENDFUN GRL: LD DE,(STEPBF) ;Load starting address into DE. INC DE ;Increase this address twice. This is because relative jumps INC DE ;are 2 bytes long. LD HL,(STEPBF+2) ;Load destination address into HL OR A SBC HL,DE ;Calculate difference between starting and destination address LD A,L ;Check if the offset is between +127 (007Fh) and -128 (FF80h). ;If the offset is positive, both H and bit 7 of L must be zero ;If offset is negative then H and bit 7 of L must be FF and 1. ;In both cases, adding H with bit 7 of L results in 0 RLA ;Rotate bit 7 of L into carry flag. LD A,H ADC A,0 ;ADD H and bit 7 of L. JR NZ,ERROR ;Branch to ERROR if the result is nonzero. LD A,L DEC DE LD (DE),A ;Save the offset into the next byte of opcode. (DJNZ or JR)

Page 12: Microprofessor-1 Monitor Program Assembly Source

ENDFUN: LD (ADSAVE),DE ;Save DE into ADSAVE. CALL MEMDP2 ;Display this address and its data.Set STATE to 2 RET ;*********************************************************************************************************************** GWT: CALL SUM1 ;Load parameters from step buffer into registers. ;Check if the parameters are legal. If legal, calculate the ;sum of all data to be output to tape JR C,ERROR ;Branch to ERROR if the parameters are illegal. (i.e.lenght is ;negative) LD (STEPBF+6),A ;Store the checksum into STEPBF+6 LD HL,4000 ;Output 1KHz square wave for 4000 cycles (This is a leading CALL TONE1K ;sync signal) LD HL,STEPBF ;Output 7 bytes starting at STEPBF: ; 2 BYTES = filename ; 2 BYTES = Starting address ; 2 BYTES = Ending address ; 1 BYTE = Checksum LD BC,7 ; (TOTAL = 7 bytes) CALL TAPEOUT ;Writes the data to tape LD HL,4000 ;Output 2KHz square wave for 4000 cycles. This is the middle ;sync signal, during this middle sync, the file name CALL TONE2K ;will be displayed CALL GETPTR ;Load parameters into registers. (Starting,ending and lenght) CALL TAPEOUT ;Output user's data. LD HL,4000 ;Output 4000 cycles of 2KHz square wave, this is the trailing CALL TONE2K ;sync signal. ENDTAPE: LD DE,(STEPBF+4) ;DE=last address JR ENDFUN ;Continue at ENDFUN ERROR: LD IX,ERR_ ;IX points to '-Err' buffer JP SETST0 ;Set state to 0. ;************************************************************************************************************* GRT: LD HL,(STEPBF) ;Temporarily save filename. LD (TEMP),HL LEAD: LD A,01000000B ;The 7th bit is connected to display's decimal point OUT (SEG7),A ;When searching for the filename, the display is initially ;blank. If the data read from MIC is an acceptable 0 or 1, ;then the displays becomes '.... ..' LD HL,1000 LEAD1: CALL PERIOD ;At the return of routine PERIOD the carry flag has a value ;depending on the data read: ;If C=0, then the tape input is 1Khz, ;If C=1 then the tape input isn't 1Khz JR C,LEAD ;So program must loop until 1Khz leading sync is detected. DEC HL ;Decrease HL by one when one 1KHz period is detected. LD A,H OR L ;Check if both H and L are 0. JR NZ,LEAD1 ;Do the loop for 1000 periods. ;The leading sync is accepted if it is longer than 1000 cycles LEAD2: CALL PERIOD ;(1000 cycles = 1 second) JR NC,LEAD2 ;Wait until the complete leading sync signal pass over. LD HL,STEPBF ;Load 7 bytes from tape into STEPBF LD BC,7 CALL TAPEIN JR C,LEAD ;Jump to LEAD if input is not successful LD DE,(STEPBF) ;Input was OK, so get the filename from STEPBF CALL ADDRDP ;Convert filename into display format. LD B,150 ;Display it for 1,5 sec. FILEDP: CALL SCAN1 DJNZ FILEDP LD HL,(TEMP) ;Check if the input filename equals to the specified filename OR A SBC HL,DE JR NZ,LEAD ;If not, find the leading sync of next file LD A,00000010B ;Filename was found, so prepare segment '-' and OUT (SEG7),A ;display '---- --' CALL GETPTR ;The parameters (start and end address + checksum) have been ;loaded into STEPBF, so load them back into registers, ;calculate the block lenght and check if they are legal. JR C,ERROR ;Jump to error if the parameters are illegal, CALL TAPEIN ;Input user's data JR C,ERROR ;Jump to ERROR if input was not successful. CALL SUM1 ;Calculate the sum of all input data. LD HL,STEPBF+6

Page 13: Microprofessor-1 Monitor Program Assembly Source

CP (HL) ;Compare it with the checksum calculated previously and stored JR NZ,ERROR ;in tape. Jump to ERROR if they don't match (Checksum error) JR ENDTAPE ;Checksum OK, continue at ENDTAPE ;************************************************************************************************************* ; Branch table format: ; byte 1,2 : Address of the first routine in each group. ; byte 3 : Difference between the address of 1st group and 1st routine, which is 0 in this case. ; byte 4 : Difference between the address of 2nd and 1st routine. ; byte 5 : Difference between the address of 3rd and 1st routine. ; . ; . ; . ; . ; . ; HL : Contains the address of branch table. ; A : Contains the routine number in its group ;Such branch table can save table lenght and avoid page boundary problems (1 page = 256 bytes) BRANCH: LD E,(HL) ;Load the address of 1st routine in the group into DE register INC HL LD D,(HL) INC HL ;Locate the pointer of difference table. ADD A,L LD L,A LD L,(HL) ;Load the address difference into L. LD H,0 ADD HL,DE ;Get the routine's read address and JP (HL) ;Jump to it. ;************************************************************************************************************* IGNORE: LD HL,TEST SET 7,(HL) ;Routine SCAN will check bit 7 of TEST. If it is set, all LEDs ;will be disabled as a warning to the user when an illegal key ;is entered. RET ;************************************************************************************************************* ; Power-up initialization: INI: LD IX,BLANK ;Blank display is the initial pattern ;Display the following patterns sequence, each of them lasting ;0,16 secs. ; ' ' ; ' u' ; ' uP' ; ' uPF' ; ' uPF-' ; ' uPF--' ; 'uPF--1' LD C,7 ;Pattern count INI1: LD B,$10 ;This value in B produces a 0,16 sec delay for each character INI2: CALL SCAN1 DJNZ INI2 DEC IX ;Next pattern DEC C JR NZ,INI1 LD A,PWCODE JP INI3 INI4: LD HL,NMI LD (IM1AD),HL ;Setup the service routine vector for RST 38h which is also the ;service routine for NMI (NonMaskable Interrupt) used by ;single step execution and breakpoint. ;************************************************************************************************************* ; Clear Breakpoint: ; Setting breakpoint to address 0FFFFh has the effect of disabling it. CLRBR: LD HL,$FFFF LD (BRAD),HL RET ;************************************************************************************************************* ; Test Display Mode: ; This routine checks if the display is in 'address-data'form, i.e. if STATE is 1 or 2. The result is stored ; in Z flag. ; If Z=1 Display IS in 'address-data' form. ; If Z=0 Display IS NOT in 'address-data' form.

Page 14: Microprofessor-1 Monitor Program Assembly Source

TESTM: LD A,(STATE) CP 1 RET Z CP 2 RET ;************************************************************************************************************* ; Pre-clear 1 byte: ; If bit 0 of TEST is 1, load 00 into (HL), then clear this bit ; Registers destroyed: A,F PRECL1: LD A,(TEST) OR A ;Update flags according to A contents RET Z ;if bit 0 of A=0, do nothing and return LD A,0 ;bit 0 of A = 1 so reset it LD (HL),A ;Clear (HL) LD (TEST),A ;Clear (TEST) RET ;************************************************************************************************************* ; Pre-clear 2 bytes: ; If bit 0 of TEST is 1, load 00 into (HL) and (HL+1), then clear this bit ; Registers destroyed: A,F PRECL2: CALL PRECL1 RET Z INC HL LD (HL),A DEC HL RET ;************************************************************************************************************* ; Memory display format: (address-data) ; 1) A.A.A.A. D D -- State is 'AD'. 4 decimal points under the address field indicate that the numeric ; Value entered will be interpreted as a memory address. ; 2) A A A A D.D. -- State is 'DA'. 2 decimal points under the data field indicate that the monitor is ; expecting user to enter memory data. ; 3) A.A.A.A. D.D. -- Six decimal points indicate that the address being displayed is set as a breakpoint MEMDP1: LD A,1 ;Next STATE = 1 LD B,4 ;4 decimal points active LD HL,DISPBF+2 ;The 1st active decimal point is in DISPBF+2, the last is in ;DISPBF+5 JR SAV12 ;Continue at SAV12 MEMDP2: LD A,2 ;Next STATE = 2 LD B,2 ;2 active decimal points LD HL,DISPBF ;1st decimal point is in DISPBF, 2nd in DISPBF+1 SAV12: LD (STATE),A ;Update STATE EXX ;Save registers HL,BC,DE LD DE,(ADSAVE) ;Address to be displayed is allways in (ADSAVE),load it into ;DE register CALL ADDRDP ;Convert this address to display format and store it in ;the display buffer, (i.e. DISPBF+2 thru DISPBF+5) LD A,(DE) ;load data pointed by DE into A register CALL DATADP ;Then convert it to 7-segment format and store it in ;the display buffer (2 rightmost chars; DISPBF and DISPBF+1) ;************************************************************************************************************* ; The next 3 instructions serve to refresh the data at break address every time memory is displayed. BRTEST: LD HL,(BRAD) ;Get the breakpoint address LD A,(HL) ;Get the data at breakpoint address and store it in A LD (BRDA),A ;Store A in memory at breakpoint data address (BRDA) OR A SBC HL,DE ;Check if the address to be displayed is the breakpoint ;address. JR NZ,SETPT1 ;If not, jump to SETPT1 LD B,6 ;address to be displayed is the breakpoint address, so in ;order to warn the user, monitor activates ALL display's ;decimal points. LD HL,DISPBF ;The first decimal point is in DISPBF, the 6th is in DISPBF+5 EXX SETPT1: EXX ;Restore HL,BC,DE SETPT: SET 6,(HL) ;Set decimal points ;At this point the count is in B and 1st address in HL register.

Page 15: Microprofessor-1 Monitor Program Assembly Source

INC HL DJNZ SETPT RET ;************************************************************************************************************* ; Display the Step Buffer and its parameter name. (STEPDP) ; ; Input: STATE and STMINOR (parameter count) ; Registers Destroyed: AF,BC,DE,HL ;************************************************************************************************************* ; Step display format: ; (this format is used when user is entering parameters for 'Move','Rela','Wrtape','Rdtape') ; Step display format looks like: ; P.P.P.P. - X ; ; 'P' is the digit of parameter, the four decimal points indicate that P.P.P.P. are editable at this moment. ; X can be one of the following characters: ; a) For 'Move' Function: ; -S = Starting Address ; -E = Ending Address ; -D = Destination Address ; b) For 'Rela' Function: ; -S = Source Address ; -D = Destination Address ; c) For 'WRTape' Function: ; -F = Filename ; -S = Starting Address ; -E = Ending Address ; d) For 'RDTape' Function: ; -F = Filename STEPDP: CALL LOCSTBF ;Get parameter address LD E,(HL) INC HL LD D,(HL) CALL ADDRDP ;Convert this parameter to display format (4 digits) and store ;it at DISPBF+2,DISPBF+3,DISPBF+4, and DISPBF+5 LD HL,DISPBF+2 ;Set the decimal points (from DISPBF+2 to DISPBF+5) LD B,4 CALL SETPT CALL LOCSTNA ;Get the parameter name LD L,A LD H,2 ;Pattern '-' for 2nd rightmost digit LD (DISPBF),HL RET ;************************************************************************************************************* ; Get the location of parameter (LOCSTBF) ; Input: (STMINOR) ; Output: HL has the address of this parameter. ; Registers destroyed: AF,HL LOCSTBF: LD A,(STMINOR) ;Get parameter count. ADD A,A ;multiply parameter count by 2 since Each param. has 2 bytes LD HL,STEPBF ;Get base address of parameters ADD A,L LD L,A RET ;************************************************************************************************************* ; Get the parameter name (LOCSTNA) ; Inputs: STATE,STMINOR ; Output: Parameter name in A and Z Flag ; Registers Destroyed = AF,DE LOCSTNA: LD A,(STATE) ;Get STATE. (Possible states are: 4,5,6,7 each of them ;corresponding to MOVE,RELA,WRTAPE,RDTAPE. SUB 4 ;Change 4,5,6,7 to 0,1,2,3 ADD A,A ;Each STATE has 4 bytes for names, ADD A,A ;so A <= A*4 LD DE,STEPTAB ADD A,E LD E,A ;Now DE contains the address of first name for each state. LD A,(STMINOR) ;Get parameter count ADD A,E ;DE <= DE+A LD E,A LD A,(DE) ;Get parameter name OR A ;Change zero flag. If the returned pattern in A is zero then ;the keys '+' or '-' must have been pressed beyond legal

Page 16: Microprofessor-1 Monitor Program Assembly Source

;parameter boundary. (Check if parameter name got from STEPTAB RET ;is zero) ;************************************************************************************************************* ; Register display format: ; ; 1) X X X X Y Y -- State is REGAD. The numeric data entered is interpreted as a reg. name ; YY is the register name and the data for that register pair is X X X X ; 2) X X X.X. Y Y -- ; or ; X.X.X X Y Y -- State is REGDA. The unit used here for register modification is a BYTE. ; The numeric data entered will change the byte with decimal points ; under it. Decimal points can be moved by '+' or '-' keys. ;************************************************************************************************************* ; Display register and set STATE to 8. REGDP8: LD A,8 ;STATE number in A JR RGSTIN ;************************************************************************************************************* ; Display register and set STATE to 9. REGDP9: LD A,9 ;State number in A ; Update STATE with the value previously loaded in register A, then display user's register (count is ; contained in STMINOR) ; Registers Destroyed: AF,BC,DE,HL RGSTIN: LD (STATE),A ;Update STATE. LD A,(STMINOR) ;Get the register count RES 0,A ;Registers are displayed by pair. Find the count of pair leader ;(the count of the lower one) LD B,A ;Save A temporarily. CALL RGNADP ;Find the register count and store it in DISPBF and DISPBF+1 LD A,B ;Restore A (A contains the register pair leader) CALL LOCRG ;Get the address of user's register. LD E,(HL) ;Get the register's data (2 bytes) INC HL LD D,(HL) LD (ADSAVE),DE CALL ADDRDP ;Convert data to display format and store it in display buffer LD A,(STATE) CP 9 ;If STATE is 9 (RGDA) then set 2 decimal points, otherwise return here RET NZ LD HL,DISPBF+2 LD A,(STMINOR) ;Get the register name BIT 0,A ;If this register is a group leader then set the decimal points of ;the two central digits, otherwise set the decimal points of the ;two leftmost digits. JR Z,LOCPT INC HL INC HL LOCPT: SET 6,(HL) ;Set the decimal points of (HL) and (HL+1) INC HL SET 6,(HL) CALL FCONV ;Convert user's flag (F and F') to display format RET ;************************************************************************************************************* ; Get the patterns of register names and store them into DISPBF and DISPBF+1 ; Input: A containing register count of pair leader. ; Registers Destroyed: AF,DE,HL RGNADP: LD HL,RGTAB ;Get address of pattern table ADD A,L LD L,A LD E,(HL) ;Get 1st pattern. INC HL LD D,(HL) ;Get 2nd pattern. LD (DISPBF),DE RET ;************************************************************************************************************* ; Get the address of user's register (LOCRGBF) ; Input:Register name contained in STMINOR. ; Destroys: HL,AF LOCRGBF: LD A,(STMINOR)

Page 17: Microprofessor-1 Monitor Program Assembly Source

LOCRG: LD HL,REGBF ADD A,L LD L,A RET ;************************************************************************************************************** ; Encode or decode user's flag register (FCONV) ; STMINOR contains the name of the flag being displayed now. ; Registers Destroyed: AF,BC,HL FCONV: LD A,(STMINOR) ;Get the register name. OR A ;Update flags and also clear carry flag RRA ;Name of I register = 17H,name of IFF = 16H. ;Rotate Right one bit, so both become 0BH. CP $0B JR Z,FLAGX ;Jump to FLAGX if I or IFF are being displayed now LD C,A ;Otherwise, mask out bit 1 to bit 7 of user's IFF. ;IFF is only 1 bit but monitor program uses one complete byte to ;store it. The masking of bits 1 to 7 masks out useless bits. ;This is done only when the user is not modifiying IFF. If the user is ;modifiying IFF, the monitor will display whatever he enters, even if ;bit 1 to 7 are not all zero. The contents of A is preserved after ;doing it. LD HL,USERIF LD A,(HL) AND 00000001B LD (HL),A LD A,C FLAGX: CP $0C ;If STMINOR contains the name of SZXH, XPNC, SZXH', XPNC'. After ;rotating right one byte it will be greater than or equal to 0CH ;Decode user's flag if it is not being modified now, encode it otherwise. JR NC,FCONV2 FCONV1: LD A,(USERAF) ;Get user's F register CALL DECODE ;Decode upper 4 bits. LD (FLAGH),HL CALL DECODE ;Decode lower 4 bits. LD (FLAGL),HL LD A,(UAFP) ;Get user's F' register. CALL DECODE LD (FLAGHP),HL CALL DECODE LD (FLAGLP),HL RET FCONV2: LD HL,(FLAGH) ;Get the binary form of the 4 upper bits of user's F register CALL ENCODE ;Encode it LD HL,(FLAGL) ;Encode 4 lower bits CALL ENCODE LD (USERAF),A ;Save the encoded result into USERAF LD HL,(FLAGHP) ;Encode F' register. CALL ENCODE LD HL,(FLAGLP) CALL ENCODE LD (UAFP),A RET ;************************************************************************************************************** ; Decode bits 7,6,5 & 4 of A register (DECODE) ; Each bit is extended to 4 bits, i.e. 0 becomes 0000 and 1 becomes 0001. The output is stored in HL, which is ; 16 bit in length. After execution, bits 7,6,5,4 of A becomes bits 3,2,1,0 of A before execution. ; Registers Destroyed = AF,B,HL DECODE: LD B,4 ;Loop 4 times DRL4: ADD HL,HL ;Clear the 3 rightmost bits of HL ADD HL,HL ADD HL,HL RLCA ADC HL,HL ;The 4th bit of HL is determined by carry flag, which is the ;MSB of A register DJNZ DRL4 RET ;************************************************************************************************************** ; Encode HL register ; Each 4 bits of HL are encoded to 1 bit, so 0000 becomes 0 and 0001 becomes 1. The result is stored in bits ; 3,2,1,0 of A register. After execution, bits 7,6,5,4 of A are bits 3,2,1,0 of A before execution. ; Registers Destroyed: AF,B,HL

Page 18: Microprofessor-1 Monitor Program Assembly Source

ENCODE: LD B,4 ;Loop 4 times ERL4: ADD HL,HL ;Shift HL left by 4 bits, bit 12 of HL will be shifted into ADD HL,HL ;carry flag ADD HL,HL ADD HL,HL RLA ;Rotate carry flag into A register DJNZ ERL4 RET ;************************************************************************************************************** ; Calculate the sum of a memory data block. ; Input: The starting and ending address of the block to be summed is in STEPBF+2 and STEPBF+4. ; Registers Destroyed = AF,BC,DE,HL SUM1: CALL GETPTR ;Get parameters from STEP buffer RET C ;Return if the parameters are illegal ; Calculate the sum of a memory block. HL contains the starting address and BC contains the length. The result ; is stored in A. ; Registers Destroyed: AF,BC,HL are destroyed. SUM: XOR A ;Clear A SUMCAL: ADD A,(HL) ;Add CPI JP PE,SUMCAL OR A ;Clear Flags RET ;************************************************************************************************************** ; Get parameters from step buffer (GETPTR) ; Input: (STEPBF+2) and (STEPBF+3) contains the starting address. ; (STEPBF+4) and (STEPBF+5) contains the ending address. ; Output: HL register contains the starting address. BC contains the lenght. ; Carry flag = 0 -- BC Positive ; 1 -- BC Negative ; Destroyed registers = AF,BC,DE,HL GETPTR: LD HL,STEPBF+2 GETP: LD E,(HL) ;Load starting address into DE INC HL LD D,(HL) INC HL LD C,(HL) INC HL ;Load ending address into HL. LD H,(HL) LD L,C OR A ;Clear Carry Flag SBC HL,DE ;Find difference (Carry flag is altered here) LD C,L LD B,H INC BC ;Now BC contains the length. EX DE,HL ;Now HL contains the starting address RET ;************************************************************************************************************** ; Load a memory block from tape (TAPEIN) ; Input: HL -- starting address of the block ; BC -- Length of the block ; Output: ; Cy = 1 : Read Error ; Cy = 0 : Read OK ; Destroyed registers -- AF,BC,DE,HL,AF',BC',DE',HL' TAPEIN: XOR A ;Clear Carry flag to set NO ERROR status EX AF,AF' TLOOP: CALL GETBYTE ;Read 1 byte from tape LD (HL),E ;Store it into memory CPI JP PE,TLOOP ;Loop until length is zero. EX AF,AF' RET ;************************************************************************************************************** ; Read one byte from tape (GETBYTE) ; Output: E = Data Read ; Cy of F' ==> 1 -- reading error ; 0 -- reading OK

Page 19: Microprofessor-1 Monitor Program Assembly Source

; Destroyed Registers: AF,DE,AF',BC',DE',HL' ; Byte format: ; ; start bit bit bit bit bit bit bit bit stop ; bit 0 1 2 3 4 5 6 7 bit GETBYTE: CALL GETBIT ;Get start bit. LD D,8 ;Loop 8 times. BLOOP: CALL GETBIT ;Get one data bit (Result of operation in carry flag) RR E DEC D JR NZ,BLOOP CALL GETBIT ;Get stop bit RET ;************************************************************************************************************** ; Read one bit from tape (GETBYTE) ; Output: ; Carry of F = 0 ==> Read bit is a ZERO ; Carry of F = 1 ==> Read bit is ONE ; Carry of F' = 1 ==> Read Error ; Carry of F' = 0 ==> Read OK ; ; Destroyed Registers: AF,AF',BC',DE',HL' ; Bit format: ; 0 -- 2KHz x 8cycles + 1KHz x 2cycles ; 1 -- 2KHz x 4cycles + 1KHz x 4cycles ; The tape-bit format of both 0 and 1 are of the same form: high freq part + low freq part. ; The difference between 0 and 1 is the number high freq cycles and low freq cycles. Thus, a high freq period ; has 2 meanings: ; a) It is used to count the number of high freq cycles of the current tape-bit; ; b) If a high freq period is detected immediately after a low freq period, then this period is the first cycle ; of next type bit and is used as a terminator of the last tape-bit. ; ; Bit 0 of H register is used to indicate the usage of a high freq period. If this bit is zero, high freq period ; causes counter increment for the current tape-bit. If the high freq part has passed, bit of H is set and the ; next high freq period will be used as a terminator. ; L register is used to up/down count the number of periods. When a high freq period is read, L is increased ; by 1 when a low freq period is read, L is decreased by 2. (The time duration for each count is 0,5 msec) ; At the end of a tape-bit, positive and negative L stand for 0 and 1 respectively. GETBIT: EXX ;Save HL,BC and DE Registers LD HL,0 ;Clear bit 0 of H and set L to zero. COUNT: CALL PERIOD ;Read 1 period. INC D ;This two instructions check if D=0, Carry flag is not affected DEC D JR NZ,TERR ;If D is not zero then jump to error routine TERR (Because the ;period is too much longer than that of 1KHz.) JR C,SHORTP ;If the period is short (2 KHz) then jump to SHORTP DEC L ;Period is 1KHz. DEC L ;Decrease L by 2 SET 0,H ;set bit 0 of H to indicate that this tape-bit has passed the JR COUNT ;high freq part and reaches its low freq part. SHORTP: INC L ;The period is 2KHz, increase L by 1. BIT 0,H ;If the tape-bit has passed its high freq part, high freq means ;That this bit is all over and the next bit has started. JR Z,COUNT ;L =(number of 2K periods) - 2*(number of 1K periods) RL L ;0 --- No Carry (L positive) ;1 --- Carry (L negative) ;The positive or negative sign of L corresponds to the ;tape-bit data. ;'RL L' will shift the sign bit of L into the carry flag. ;After this instruction, the carry flag contains the tape-bit. EXX ;Restore BC' DE' and HL' RET TERR: EX AF,AF' SCF ;Set carry flag of F' to indicate error. EX AF,AF' EXX RET ;************************************************************************************************************** ; Wait for the tape to pass one period. The time duration is stored in DE. The unit is loop count. Typical value ; for 2 KHz is 28 and 56 for 1 KHz. Use (56+28)/2 as threshold. The returned result is in carry flag. ; (1K -- NC, 2K -- C)

Page 20: Microprofessor-1 Monitor Program Assembly Source

; Registers Destroyed: AF,DE PERIOD: LD DE,0 LOOPH: IN A,(KIN) ;Bit 7 of 8255's port A is conected to tape input. INC DE RLA JR C,LOOPH ;Loop until input goes low. LD A,11111111B ;Echo the tape input to uPF-1's speaker. OUT (DIGIT),A LOOPL: IN A,(KIN) INC DE RLA JR NC,LOOPL LD A,01111111B ;Echo the tape input to uPF-1's speaker. OUT (DIGIT),A LD A,E ;Compare the result with the threshold. CP MPERIOD RET ;************************************************************************************************************** ; Output a memory block to tape (TAPEOUT) ; Input: HL -- Starting address of the block ; BC -- lenght of the block ; Destroyed registers: AF,BC,DE,HL,BC',DE',HL' TAPEOUT: LD E,(HL) ;Get byte to be "sent" CALL OUTBYTE ;Output to tape. CPI JP PE,TAPEOUT ;Loop until finished RET ;************************************************************************************************************** ; Output one byte to tape. For tape-byte format, see coments on GETBYTE. ; Input: E contains byte to be "sent" ; Destroyed Registers: AF,DE,BC',DE',HL' OUTBYTE: LD D,8 ;Loop 8 times OR A ;Clear Carry Flag CALL OUTBIT ;Output start bit OLOOP: RR E ;Rotate data into carry CALL OUTBIT ;Output the carry DEC D JR NZ,OLOOP SCF ;Set carry flag CALL OUTBIT ;Output stop bit RET ;************************************************************************************************************** ; Output one bit to tape (OUTBIT) ; Input: data in carry flag ; Destroyed Registers: AF,BC',DE',HL' OUTBIT: EXX ;Save BC,DE,HL LD H,0 JR C,OUT1 ;If data=1 then output 1 OUT0: LD L,ZERO_2K ;2KHz by 8 cycles, 1Khz by 2 cycles CALL TONE2K LD L,ZERO_1K JR BITEND OUT1: LD L,ONE_2K ;2KHz by 4 cycles, 1Khz by 4 cycles CALL TONE2K LD L,ONE_1K BITEND: CALL TONE1K EXX ;Restore registers RET ;************************************************************************************************************** ; U T I L I T Y S U B R O U T I N E S ;************************************************************************************************************** ;************************************************************************************************************* ; Name: TONE ; Description: Generate a tone in the uPF-1's speaker ; Input: C -- period = 2*(44+13*C) clock states ; HL -- number of periods ; Output: (none) ; Destroys: AF,BC,DE,HL ; Calls subs: (none)

Page 21: Microprofessor-1 Monitor Program Assembly Source

;************************************************************************************************************* TONE1K: LD C,F1KHZ JR TONE TONE2K: LD C,F2KHZ TONE: ADD HL,HL ;Half period: 44+13*C states. Double for half-cycle count LD DE,1 LD A,$FF SQWAVE: OUT (DIGIT),A ;Bit-7 tapeout LD B,C DJNZ $ ;Half period delay XOR $80 ;Toggle output SBC HL,DE ;Decrement one count JR NZ,SQWAVE RET ;************************************************************************************************************* ; Name: RAMCHK ; Description: Check if a given memory address is in RAM ; Input: HL contains the address to be checked ; Output: Z=0 if ROM or unmapped, Z=1 if RAM ; Destroys: AF ; Calls subs: (none) ;************************************************************************************************************* RAMCHK: LD A,(HL) CPL LD (HL),A LD A,(HL) CPL LD (HL),A CP (HL) RET ;************************************************************************************************************* ; Name: SCAN ; Description: Scan the keyboard and the display. Loop until a key is detected and if some key is already ; pressed when this routine starts execution, then return when next key is entered. ; Input: ; IX = Points to the buffer that contains display patterns. The 6 segments of the display ; requires 6 bytes of data.(IX) contains the pattern for rightmost character while ; (IX+5) contains the pattern for leftmost character. ; Output: Internal code of the key pressed in A) ;Convert the 2 byte data stored in DE to 7-segament display format. ; Output: The output is stored in the address field of DISPBF (display buffer), most significiant digit ; in DISPBF+5. This routine is usually used by monitor only. ; Destroys: AF,B,HL,AF',BC',DE' (All other registers except IY are also changed during execution, but they ; are restored before return. ; ; Calls subs: SCAN1 ;************************************************************************************************************* SCAN: PUSH IX ;Save IX. LD HL,TEST BIT 7,(HL) ;This bit is set if the use ;has entered illegal key. The ;display will be disabled as ;a warning to the user. This ;is done by replacing the display ;buffer pointer IX by BLANK. JR Z,SCPRE LD IX,BLANK ; Wait until all keys are released for 40 ms. ; (The execution time of SCAN1 is 10 ms, ; 40 = 10 * 4.) SCPRE: LD B,4 SCNX: CALL SCAN1 JR NC,SCPRE ;If any key is pressed, re-load ;the debounce counter B by 4. DJNZ SCNX RES 7,(HL) ;Clear error-flag. POP IX ;Restore original IX. ;Loop until any key is pressed. SCLOOP: CALL SCAN1 JR C,SCLOOP ; Convert the key-position-code returned by SCANl to ; key-internal-code. This is done by table-lookup. ; The table used is KEYTAB.

Page 22: Microprofessor-1 Monitor Program Assembly Source

KEYMAP: LD HL,KEYTAB ADD A,L LD L,A LD A,(HL) RET ;************************************************************************************************************* ; Name: SCAN1 ; Description: Scans both the keyboard and the display (doesn't wait for a keypress) ; Total execution time is about 10 ms (exactly 9.95 ms => 17812 clock cycles @ 1.79 MHz). ; Input: IX = Points to the buffer that contains display patterns. The 6 segments of the display ; requires 6 bytes of data.(IX) contains the pattern for rightmost character while ; (IX+5) contains the pattern for leftmost character. ; ; Output: If NO KEY was pressed, Cy=1. Otherwise Cy=0 and 'A' holds the position code of the pressed key ; (If more than one key is pressed, SCAN1 will return the highest position code.) ; ; Destroys: AF,AF',BC',DE'. ; Calls subs: None ; ; Hardware note: ; In hardware, the display and keyboard are arranged as a 6 by 6 matrix. Each cloumn corresponds to one LED ; and six key buttons. In normal operation, at most one column is active. The pattern of the active LED is the ; data output on port C of 8255. The data input from bit 0 to 5 of port A are the status of key buttons in the ; active column. All signals on I/0 port are active low. ;************************************************************************************************************* SCAN1: SCF ;Set carry flag. EX AF,AF' EXX ; Carry flag of F' is used to return the status of the keyboard. If any key is pressed during one scan, the ; flag is reset, otherwise it is set. Initially, this flag is set. A' register is used to store the position ; code of the key pressed. In this routine, 36 key positions are checked one by one. C register contains the ; code of the key being checked. The value of C is 0 at the beginning, and is increased by 1 after each ; check. So the code ranges from 0 to 23H (total 36 positions). On each check, if the input bit is 0 (key ; pressed), C register is copied into A1. The carry flag of F1 is set also. When some key is detected, the ; key positions after this key will still be checked. So if more than one key are pressed during one scan, ; the code of the last one will be returned. LD C,0 ;Initial position code LD E,11000001B ;Scan from rightmost digit. LD H,6 ;to the active column. KCOL: LD A,E OUT (DIGIT),A ;Activate one colunm. LD A,(IX) OUT (SEG7),A LD B,COLDEL DJNZ $ ;Delay 1.5 ms per digit. XOR A ;Deactivate all display segments OUT (SEG7),A LD A,E CPL OR 11000000B OUT (DIGIT),A LD B,6 ;Each column has 6 keys. At this moment, bit 0,1,2,3,4,5 of A IN A,(KIN) ;contains the status of each of the 6 keys in the active column. LD D,A ;Store A into D. KROW: RR D ;Rotate D one bit to the right, so bit 0 of D will pass to the ;carry flag. JR C,NOKEY ;Skip next 2 instructions if the key is not pressed. LD A,C ;Key-in event, so get the key position-code and store in A EX AF,AF' ;Save A & Carry in AF' (This clears carry flag of F') NOKEY: INC C ;Increase current key-code by 1. DJNZ KROW ;Loop until 6 keys in the ;active colums are all checked. INC IX LD A,E AND 00111111B RLC A OR 11000000B LD E,A

Page 23: Microprofessor-1 Monitor Program Assembly Source

DEC H JR NZ,KCOL LD DE,-6 ADD IX,DE ;Get original IX. EXX EX AF,AF' RET ;************************************************************************************************************* ; Name: ADDRDP ; Description: Convert binary data to 7-segment display format. ; Input: Convert the 2 byte data stored in DE to 7-segament display format. ; Output: The output is stored in the address field of DISPBF (display buffer), most significiant digit ; in DISPBF+5. This routine is usually used by monitor only. ; Destroys: AF,HL ; Calls subs: HEX7SG ;************************************************************************************************************* ADDRDP: LD HL,DISPBF+2 LD A,E CALL HEX7SG LD A,D CALL HEX7SG RET DATADP: LD HL,DISPBF CALL HEX7SG RET ;************************************************************************************************************* ; Name: HEX7SG ; Description: Convert binary data to 7-segment display format. ; Input: The contents of A register contains the data to be converted ; Output: Display pattern for 2 digits. Low order digit in (HL), high order digit in (HL+1). Then ; HL becomes HL+2. In this way, if a new call to HEX7SG is made with new value in A,HL points ; automatically to the correct address. ; Destroys: AF,HL ; Calls subs: HEX7 ;************************************************************************************************************* HEX7SG: PUSH AF CALL HEX7 LD (HL),A INC HL POP AF RRCA RRCA RRCA RRCA CALL HEX7 LD (HL),A INC HL RET ;************************************************************************************************************* ; Name: HEX7 ; Description: Convert binary data to 7-segment display format. ; Input: the 4 LSB bits of A contains the data to be converted ; Output: In A itself, the 7 segment data ready for the display buffer ; Destroys: AF ; Calls subs: none ;************************************************************************************************************* HEX7: PUSH HL LD HL,SEGTAB AND $0F ADD A,L LD L,A LD A,(HL) POP HL RET ;************************************************************************************************************* ; Name: RAMTEST ; Description: RAM memory self test. ; This routine tests the RAM memory between addresses 1800h thru 1FFFh (2K of 6116 Chip). ; Input: none. ; Output: none. ; Destroys: AF,BC,HL

Page 24: Microprofessor-1 Monitor Program Assembly Source

; Calls subs: RAMCHK ;************************************************************************************************************* RAMTEST: LD HL,$1800 LD BC,$800 RAMT: CALL RAMCHK JR Z,TNEXT HALT ;HALT CPU if error TNEXT: CPI JP PE,RAMT RST 00H ;Display 'uPF--1' ;************************************************************************************************************* ; Name: ROMTEST ; Description: Monitor ROM code self-check. ; This routine sums the contents of address 0000 thru 0800 (2K), if the sum equals 00 then it ; resets the monitor via RST 0 instruction, otherwise HALT the CPU. ; Input: none. ; Output: none. ; Destroys: AF,BC,HL ; Calls subs: SUM ;************************************************************************************************************* ROMTEST: LD HL,0 LD BC,800H CALL SUM JR Z,SUMOK HALT ;HALT CPU if error SUMOK: RST 00h ;Display 'uPF--1' ;************************************************************************************************************* INI3: LD (POWERUP),A ;Load power-code into (POWERUP). The monitor uses this ;location to find out if the RESET was 'cold' or 'warm' LD A,$55 LD (BEEPSET),A LD A,$44 ;This two instructions set the beep frequency when a key is LD (FBEEP),A ;pressed. LD HL,TBEEP ;This four instructions set the time duration of the beep LD (HL),$2F ;When a key is pressed (2 bytes) INC HL LD (HL),0 JP INI4 BEEP: PUSH AF LD HL,FBEEP LD C,(HL) LD HL,(TBEEP) LD A,(BEEPSET) CP $55 JR NZ,NOTONE ;If data at (BEEPSET) is not $55 then there is no beep sound ;when a key is pressed. CALL TONE NOTONE: POP AF JP KEYEXEC ;KEYEXEC determines what action should be taken when a key is ;pressed. This routine uses the following information to ;determine the proper service routine: ; 1) The key-code, ; 2) STATE ; 3) STMINOR (Minor-State). ;************************************************************************************************************* ; This are the branch tables for each key and state. The first entry of each table is a base address and ; the following entries are an offset ( 1 byte long ). In this way only one byte is needed for each jump ; instead of 2 bytes. ;************************************************************************************************************* .ORG $0737 KSUBFUN: .WORD KINC .BYTE -KINC+KINC .BYTE -KINC+KDEC .BYTE -KINC+KGO .BYTE -KINC+KSTEP .BYTE -KINC+KDATA .BYTE -KINC+KSBR

Page 25: Microprofessor-1 Monitor Program Assembly Source

.BYTE -KINC+KINS .BYTE -KINC+KDEL KFUN: .WORD KPC .BYTE -KPC+KPC .BYTE -KPC+KADDR .BYTE -KPC+KCBR .BYTE -KPC+KREG .BYTE -KPC+KMV .BYTE -KPC+KRL .BYTE -KPC+KWT .BYTE -KPC+KRT HTAB: .WORD HFIX .BYTE -HFIX+HFIX .BYTE -HFIX+HAD .BYTE -HFIX+HDA .BYTE -HFIX+HRGFIX .BYTE -HFIX+HMV .BYTE -HFIX+HRL .BYTE -HFIX+HWT .BYTE -HFIX+HRT .BYTE -HFIX+HRGAD .BYTE -HFIX+HRGDA ITAB: .WORD IFIX .BYTE -IFIX+IFIX .BYTE -IFIX+IAD .BYTE -IFIX+IDA .BYTE -IFIX+IRGFIX .BYTE -IFIX+IMV .BYTE -IFIX+IRL .BYTE -IFIX+IWT .BYTE -IFIX+IRT .BYTE -IFIX+IRGAD .BYTE -IFIX+IRGDA DTAB: .WORD DFIX .BYTE -DFIX+DFIX .BYTE -DFIX+DAD .BYTE -DFIX+DDA .BYTE -DFIX+DRGFIX .BYTE -DFIX+DMV .BYTE -DFIX+DRL .BYTE -DFIX+DWT .BYTE -DFIX+DRT .BYTE -DFIX+DRGAD .BYTE -DFIX+DRGDA GTAB: .WORD GFIX .BYTE -GFIX+GFIX .BYTE -GFIX+GAD .BYTE -GFIX+GDA .BYTE -GFIX+GRGFIX .BYTE -GFIX+GMV .BYTE -GFIX+GRL .BYTE -GFIX+GWT .BYTE -GFIX+GRT .BYTE -GFIX+GRGAD .BYTE -GFIX+GRGDA ;************************************************************************************************************* ; KEYTAB is a table to convert key-position-code into key-internal-code ;************************************************************************************************************* KEYTAB: K0: .BYTE $03 ;HEX_3 Kl: .BYTE $07 ;HEX_7 K2: .BYTE $0B ;HEX_B K3: .BYTE $0F ;HEX_F K4: .BYTE $20 ;NOT USED K5: .BYTE $21 ;NOT USED K6: .BYTE $02 ;HEX_2 K7: .BYTE $06 ;HEX_6 K8: .BYTE $0A ;HEX_A K9: .BYTE $0E ;HEX_E K0A: .BYTE $22 ;NOT USED K0B: .BYTE $23 ;NOT USED K0C: .BYTE $01 ;HEX_1 K0D: .BYTE $05 ;HEX_5 K0E: .BYTE $09 ;HEX_9 K0F: .BYTE $0D ;HEX_D K10: .BYTE $13 ;STEP

Page 26: Microprofessor-1 Monitor Program Assembly Source

K11: .BYTE $1F ;TAPERD K12: .BYTE $00 ;HEX_0 K13: .BYTE $04 ;HEX_4 K14: .BYTE $08 ;HEX_8 K15: .BYTE $0C ;HEX_C K16: .BYTE $12 ;GO K17: .BYTE $1E ;TAPEWR K18: .BYTE $1A ;CBR K19: .BYTE $18 ;PC K1A: .BYTE $1B ;REG K1B: .BYTE $19 ;ADDR K1C: .BYTE $17 ;DEL KID: .BYTE $1D ;RELA K1E: .BYTE $15 ;SBR K1F: .BYTE $11 ;- K20: .BYTE $14 ;DATA K21: .BYTE $10 ;+ K22: .BYTE $16 ;INS K23: .BYTE $1C ;MOVE MPF_I: .BYTE $30 ;'1' .BYTE $02 ;'-' .BYTE $02 ;'-' .BYTE $0F ;'F' .BYTE $1F ;'P' .BYTE $A1 ;'u' BLANK: .BYTE $00 .BYTE $00 .BYTE $00 .BYTE $00 ERR_: .BYTE $00 .BYTE $00 .BYTE $03 ;'r' .BYTE $03 ;'r' .BYTE $8F ;'E' .BYTE $02 ;'-' SYS_SP: .BYTE $1F ;'P' .BYTE $AE ;'S' .BYTE $02 ;'-' .BYTE $AE ;'S' .BYTE $B6 ;'Y' .BYTE $AE ;'S' ERR_SP: .BYTE $1F ;'P' .BYTE $AE ;'S' .BYTE $02 ;'-' .BYTE $03 ;'r' .BYTE $03 ;'r' .BYTE $8F ;'E' .BYTE $00 STEPTAB: .BYTE $AE ;'S' .BYTE $8F ;'E' .BYTE $B3 ;'D' .BYTE $00 .BYTE $AE ;'S' .BYTE $B3 ;'D' .BYTE $00 .BYTE $00 .BYTE $0F ;'F' .BYTE $AE ;'S' .BYTE $8F ;'E' .BYTE $00 .BYTE $0F ;'F' .BYTE $00 REG_: .BYTE $00 .BYTE $00 .BYTE $02 ;'-' .BYTE $BE ;'G' .BYTE $8F ;'E' .BYTE $03 ;'R' RGTAB: .WORD $3F0F ;'AF' .WORD $A78D ;'BC' .WORD $B38F ;'DE' .WORD $3785 ;'HL' .WORD $3F4F ;'AF.' .WORD $A7CD ;'BC.' .WORD $B3CF ;'DE.' .WORD $37C5 ;'HL.' .WORD $3007 ;'IX' .WORD $30B6 ;'IY'

Page 27: Microprofessor-1 Monitor Program Assembly Source

.WORD $AE1F ;'SP' .WORD $300F ;'IF' .WORD $0F37 ;'FH' .WORD $0F85 ;'FL' .WORD $0F77 ;'FH.' .WORD $0FC5 ;'FL.' SEGTAB: .BYTE $BD ;'0' .BYTE $30 ;'1' .BYTE $9B ;'2' .BYTE $BA ;'3' .BYTE $36 ;'4' .BYTE $AE ;'5' .BYTE $AF ;'6' .BYTE $38 ;'7' .BYTE $BF ;'8' .BYTE $BE ;'9' .BYTE $3F ;'A' .BYTE $A7 ;'B' .BYTE $8D ;'C' .BYTE $B3 ;'D' .BYTE $8F ;'E' .BYTE $0F ;'F' ;************************************************************************************************************* ; SYSTEM RAM AREA: ;************************************************************************************************************* .ORG $1F9F USERSTK: .BLOCK 16 .ORG $1FAF SYSSTK: STEPBF: .BLOCK 7 DISPBF: .BLOCK 6 REGBF: USERAF: .BLOCK 2 USERBC: .BLOCK 2 USERDE: .BLOCK 2 USERHL: .BLOCK 2 UAFP: .BLOCK 2 UBCP: .BLOCK 2 UDEP: .BLOCK 2 UHLP: .BLOCK 2 USERIX: .BLOCK 2 USERIY: .BLOCK 2 USERSP: .BLOCK 2 USERIF: .BLOCK 2 FLAGH: .BLOCK 2 FLAGL: .BLOCK 2 FLAGHP: .BLOCK 2 FLAGLP: .BLOCK 2 USERPC: .BLOCK 2 ADSAVE: .BLOCK 2 ;Contains the address being displayed now. BRAD: .BLOCK 2 ;Breakpoint address BRDA: .BLOCK 1 ;Data of break point address STMINOR: .BLOCK 1 ;Minor state STATE: .BLOCK 1 ;State POWERUP: .BLOCK 1 ;Power-up initialization TEST: .BLOCK 1 ;Flag, bit 0 -- set when function of subfunction key is hit ; bit 7 -- set when illegal key is entered. ATEMP: .BLOCK 1 ;Temporary storage HLTEMP: .BLOCK 2 ;Temporary storage TEMP: .BLOCK 4 ;See comments on routine GDA IM1AD: .BLOCK 2 ;Contains the address of Opcode 'FF' service routine ;(RST 38H, mode 1 interrupt, etc.) BEEPSET: .BLOCK 1 ;Default value is 55H FBEEP: .BLOCK 1 ;Beep frequency TBEEP: .BLOCK 2 ;Time duration of beep .END ;************************************************************************************************************* ; END OF MONITOR PROGRAM ;*************************************************************************************************************