From d8eb2fa83544b389a48313a72f461b76b77091f9 Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Mon, 2 Jun 2008 15:09:21 +0000 Subject: [PATCH] standalone import --- WEGA/src/cmd/standalone/sa.diags/p.gesa.s | 1784 ++++++++++++++++++++ WEGA/src/cmd/standalone/sa.diags/p.ldsd.s | 1431 ++++++++++++++++ WEGA/src/cmd/standalone/sa.diags/p.term.s | 1792 +++++++++++++++++++++ 3 files changed, 5007 insertions(+) create mode 100644 WEGA/src/cmd/standalone/sa.diags/p.gesa.s create mode 100644 WEGA/src/cmd/standalone/sa.diags/p.ldsd.s create mode 100644 WEGA/src/cmd/standalone/sa.diags/p.term.s diff --git a/WEGA/src/cmd/standalone/sa.diags/p.gesa.s b/WEGA/src/cmd/standalone/sa.diags/p.gesa.s new file mode 100644 index 0000000..68e427c --- /dev/null +++ b/WEGA/src/cmd/standalone/sa.diags/p.gesa.s @@ -0,0 +1,1784 @@ +!****************************************************************************** +******************************************************************************* + + P8000-Firmware (C) ZFT/KEAW Abt. Basissoftware - 1987 + U8000-Softwaremonitor (MON16) Modul: p_gesa + + Bearbeiter: J. Zabel + Datum: 16.11.1987 + Version: 3.0 + +******************************************************************************* +******************************************************************************! + +!============================================================================== +Inhaltsuebersicht Modul p_gesa +------------------------------ +Dieser Modul umfasst Programme fuer die Arbeit mit der +8-Bit-/16-Bit-Koppelschnittstelle (PIO-Schnittstelle) - +(Monitorroutinen GE, S, Q, QRES und den Floppytreiber fuer blockorientierte + Disketten) + +Weiterhin umfasst dieser Modul Monitorroutinen fuer die Dateiarbeit mit +einem lokalen System - (RGE, RS, RQ). +Dazu ist ein entsprechender serieller Kanal (SI) des lokalen Systems mit dem +Systemterminalein-/-ausgang des P8000 zu verbinden. Auf dem lokalen System +muss ein entsprechendes "remote"-Programm laufen. + +I-------I I----------------I I----------I +I P8000 I(T) ------------------ (SI)I lokales System I(T) -------- I Terminal I +I-------I I----------------I I----------I + +(T) - Terminalein-/-ausgang + +Prozeduren +---------- +GET +SAVE +QUIT8 +QUIT8_RESET + +FLOPPY + +RM_GET +RM_SAVE +RM_QUIT +==============================================================================! + + +p_gesa module + +$SECTION PROM + +!anfang mon16.include! +!****************************************************************************** +allgemeine Vereinbarungen (Stand: 16.11.1987) +******************************************************************************! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +externe Prozeduren und Marken +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + EXTERNAL +!INIT_CTC0_0 procedure Modul p_init! +INIT_CTC0_1 procedure !Modul p_init! +!INIT_SIO0_A procedure Modul p_init! +INIT_SIO0_B procedure !Modul p_init! +CMDLOP procedure !Modul p_init! +ERROR procedure !Modul p_init! +NMI_INT procedure !Modul p_init! + +PTY_INT procedure !Modul p_term! +PTY_ERR procedure !Modul p_term! +KOPPEL_INT procedure !Modul p_term! +INCPTR procedure !Modul p_term! +TYRD procedure !Modul p_term! +TYWR procedure !Modul p_term! +TYRD_UDOS_INT procedure !Modul p_term! +TYRD_UDOS_POL procedure !Modul p_term! +TYWR_UDOS_INT procedure !Modul p_term! +TYWR_UDOS_POL procedure !Modul p_term! +TYWR_KOPPEL_INT procedure !Modul p_term! +TYWR_KOPPEL_POL procedure !Modul p_term! +KP_OUTB procedure !Modul p_term! +KP_INB procedure !Modul p_term! +RD_LINE_BFF procedure !Modul p_term! +RD_LINE_INBFF procedure !Modul p_term! +WR_CRLF procedure !Modul p_term! +WR_MSG procedure !Modul p_term! +WR_OUTBFF_CR procedure !Modul p_term! +WR_OUTBFF procedure !Modul p_term! +HTOB procedure !Modul p_term! +BTOH16 procedure !Modul p_term! +BTOH8 procedure !Modul p_term! +GET_CHR procedure !Modul p_term! +GET_SIGN procedure !Modul p_term! +GET_SIGNW procedure !Modul p_term! +GET_SGNR procedure !Modul p_term! +GET_HEXZ procedure !Modul p_term! +GET_ADR procedure !Modul p_term! +GET_PAR procedure !Modul p_term! +RD_DATA procedure !Modul p_term! +GET_DATA procedure !Modul p_term! +WR_R5_RDDATA procedure !Modul p_term! +WR_OBF_RDDATA procedure !Modul p_term! +PUT_CHR procedure !Modul p_term! +PUT_3C procedure !Modul p_term! +PUT_2CHR procedure !Modul p_term! +PUT_SEGNR procedure !Modul p_term! +PUT_SGNR procedure !Modul p_term! + +DISPLAY procedure !Modul p_comm! +COMPARE procedure !Modul p_comm! +FILL procedure !Modul p_comm! +MOVE procedure !Modul p_comm! +PORT_READ procedure !Modul p_comm! +PORT_WRITE procedure !Modul p_comm! +PORT_READ_SPECIAL procedure !Modul p_comm! +PORT_WRITE_SPECIAL procedure !Modul p_comm! +HARD_DISK_READ procedure !Modul p_comm! +HARD_DISK_WRITE procedure !Modul p_comm! +FLOPPY_FORMAT procedure !Modul p_comm! +FLOPPY_READ procedure !Modul p_comm! +FLOPPY_WRITE procedure !Modul p_comm! + +REGISTER procedure !Modul p_brk! +SAVREG procedure !Modul p_brk! +BREAK procedure !Modul p_brk! +GO procedure !Modul p_brk! +GO_NXT procedure !Modul p_brk! +NEXT procedure !Modul p_brk! +RETI_CTC0_3 procedure !Modul p_brk! + +TEST_ procedure !Modul p_test! + +GET procedure !Modul p_gesa! +SAVE procedure !Modul p_gesa! +QUIT8 procedure !Modul p_gesa! +QUIT8_RESET procedure !Modul p_gesa! +FLOPPY procedure !Modul p.gesa! +RM_GET procedure !Modul p_gesa! +RM_SAVE procedure !Modul p_gesa! +RM_QUIT procedure !Modul p_gesa! + +OS_BOOT procedure !Modul p_boot! +AUTOBOOT procedure !Modul p_boot! + +DISK procedure !Modul p_disk! + +! +QUIT procedure Modul p_ldsd +LOAD procedure Modul p_ldsd +MCZ_INT procedure Modul p_ldsd +MCZ_ERR procedure Modul p_ldsd +TYWR_MCZ procedure Modul p_ldsd +WOCF_MCZ procedure Modul p_ldsd +SEND procedure Modul p_ldsd +! + +MON16_1H word !Modul p.crc! +N_MON16_1H word !Modul p.crc! +MON16_1L word !Modul p.crc! +N_MON16_1L word !Modul p.crc! +MON16_2H word !Modul p.crc! +N_MON16_2H word !Modul p.crc! +MON16_2L word !Modul p.crc! +N_MON16_2L word !Modul p.crc! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Werte aus dem Arbeitsspeicher (Modul p_ram) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + EXTERNAL +RAM_ANF ARRAY [%10 WORD] +NSP_OFF WORD + ARRAY [%3F WORD] !Stackbereich! +STACK WORD + ARRAY [4 WORD] +_numterm WORD !Anzahl der Terminals! +PTYPORT BYTE !Terminalkanal: + 00 - SIO0_B (16-Bit-Teil) + 01 - SIO0_B (8-Bit-Teil) ueber + Koppelschnittstelle! +XEMPTY BYTE !fuer interruptgesyeuerten Terminal- + betrieb ueber Koppelschnittstelle: + 00 - Sendepuffer SIO0_B (8-Bit-Teil) + leer + FF - Sendepuffer SIO0_B (8-Bit-Teil) + nicht leer! + BYTE +KONV BYTE !Hilfsbyte zur Konvertierung! +INBFF ARRAY [%80 BYTE] !Eingabepuffer! +OUTBFF ARRAY [%80 BYTE] !Ausgabepuffer! +PTYBFF ARRAY [%100 BYTE] !Eingabepuffer fuer interrupt- + gesteuerte Eingabe vom Terminal- + kanal! +MCZBFF ARRAY [%0EA BYTE] !Ein-/Ausgabepuffer fuer LOAD/SEND! +MAXLEN WORD !maximale Zeilenlaenge! +INPTR WORD !Zeiger fuer Eingabepuffer INBFF! +OUTPTR WORD !Zeiger fuer Ausgabepuffer OUTBFF + (Pufferlaenge)! +COUNT_PTY WORD !aktuelle Anzahl der Zeichen in PTYBFF! +INPTR_PTY WORD !Eingabezeiger fuer PTYBFF + (naechster freier Platz)! +OUTPTR_PTY WORD !Ausgabezeiger fuer PTYBFF + (naechstes auszulesende Zeichen)! +INPTR_MCZ WORD !Eingabezeiger fuer MCZBFF! +OUTPTR_MCZ WORD !Ausgabezeiger fuer MCZBFF! +B_WORD WORD !Speicherinhalt auf der BREAK-Adresse! +B_ADR_S WORD !Segmentnummer der BREAK-Adresse! +B_ADR_O WORD !Offset der BREAK-Adresse! +RR14_V LONG !VARIABLER STACK, FUER NEXT UND BREAK! +W23B4 WORD +FCW_V WORD !VARIABLES FCW FUER NEXT UND BREAK! +PORT_BF WORD !Puffer fuer gelesenen bzw. zu + schreibenden PORT-Datenwert! +PORT_IO WORD !Adresse des PORT-I/O-Programms! + WORD !unbenutzt! +SV_R ARRAY [14 WORD] !Registerrettungsbereich! +SVSTK LONG +PC_SEG WORD !Programmcounter (Segmentnummer)! +PC_OFF WORD !Programmcounter (Offsetadresse)! +FCW_ WORD !FCW im Registerrettungsbereich! +RF_CTR WORD !Merker: Refresh Control Register! +N4_ WORD !Normalstack R14! +N5_ WORD !Normalstack R15! +PS_ WORD !Program-Status-Area Segment! +PO_ WORD !Program-Status-Area Offset! + WORD !unbenutzt! +!Flags! +FLAG0 BYTE +FLAG1 BYTE +!Variablen (initialisiert bei Systemstart)! +CHRDEL BYTE !Zeichen loeschen (Backspace %08)! +LINDEL BYTE !Zeile loeschen (Line delete %7F)! +XONCHR BYTE !Terminalausgabe fortsetzen (^Q %11)! +XOFCHR BYTE !Terminalausgabe anhalten (^S %13)! +NULLCT WORD !Anzahl der Nullen nach CR bei Terminalausgabe (%0000)! +B_CODE WORD !Unterbrechungscode Z8000 (7F00)! +STKCTR WORD !Zaehler der Stackoperationen fuer NEXT (%0004)! +NXTCTR WORD !SCHRITTZAEHLER FUER NEXT (%0001)! +PROMT WORD !Promt-Zeichen (%2000)! +!---------------------------------------------------! +!Program Status Area (initialisiert bei Systemstart)! +PSAREA +! ID FCW PCSEG PCOFF! + ARRAY [4 WORD] !:= [%0000 %0000 %0000 %0000] + RESERVED! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + UNIMLEMENTED INSTRUCTIONS! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + PRIVILEGED INSTRUCTIONS! +PSA_SC ARRAY [4 WORD] !:= [%0000 %C000 %8000 SC_ENTRY] + SYSTEM_CALL INSTRUCTIONS! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 MMU_ERR] + SEGMENT TRAP! +PSA_NMI ARRAY [4 WORD] !:= [%0000 %4000 %8000 AUTOBOOT bzw. NMI_INT] + NONMASKABLE INTERRUPT + (AUTOBOOT vor erster Terminaleingabe; + NMI_INT nach erster Terminaleingabe)! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + NONVECTORED INTERRUPT! +! VECTORED INTERRUPT! + ARRAY [2 WORD] !:= [%0000 %4000] + VECTORED INTERRUPT (ID, FCW)! +! VI - Sprung-Tabelle (128 Eintraege) ! +! SEG OFFSET! +!CTC0! +VI_CTC0_0 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_1 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_2 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_3 ARRAY [2 WORD] !:= [%8000 VI_ERR bzw. GO_INT bzw. NXT_INT] + fuer GO bzw. NEXT! +!PIO1! +VI_PIO1_B ARRAY [2 WORD] !:= [%8000 KOPPEL_INT] + VI Zeichen empfangen (von Koppelschnittstelle)! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +!SIO0! +VI_SIO0_B ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 PTY_INT] + VI Zeichen empfangen (fuer Terminaleingabe)! + ARRAY [2 WORD] !:= [%8000 PTY_ERR] + VI Empfangssonderfall (fuer Empfangsfehler)! +VI_SIO0_A ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] (vorher MCZ_INT) + VI Zeichen empfangen (fuer MCZ-Eingabe)! + ARRAY [2 WORD] !:= [%8000 VI_ERR] (vorher MCZ_ERR) + VI Empfangssonderfall (fuer Empfangsfehler)! +! Rest der 128 Eintraege der VI-Sprung-Tabelle! +VI_TAB_REST ARRAY [224 WORD] !:= [%8000 VI_ERR] ! +!---------------------------------------------------! + +!Arbeitsspeicher fuer Kommando "T" (Hardwareeigentest)! +RG_FELD ARRAY [%1A WORD] !Feld zur Registerrettung! +REM_MMU_BCSR BYTE !Merker: Inhalt BUS CYCLE STATUS REGISTER! +REM_MMU_VTR BYTE !Merker: Inhalt VIOLATION TYPE REGISTER! +REM_MMU_ID WORD !Merker: MMU-Identifikation! +REM_ERR_CNT WORD !Merker: Stand Fehlerzaehler! +REM_SEGMENT_TRAP WORD !Merker: urspruengliche Offsetadresse fuer Segmenttrap! +REM_PRIVINSTR_TRAP WORD !Merker: urspruengl. Offsetadr. fuer Priv.-Instr.-Trap! +REM_MMU_SINOUT WORD !Merker: MMU-Ein-/Ausgabewerte! +ERR_CNT WORD !Fehlerzaehler! +ERR_WDC WORD !Fehlerzaehler fuer WDC-Test! +MAX_SEGNR WORD !Merker: hoechste vorhandene Segmentnummer! +REM_PARNMI WORD !Merker: Paritaets-NMI aufgetreten + (%0000-->nein / %FFFF-->ja)! +ERRPAR_ID WORD !Spezifizierung der 4 Parameter der auszugebenden + Fehlerzeile (Prozedur MSG_ERROR)! +REM_MMU1 WORD +REM_MMU2 WORD +REM_INT WORD !Merker: Interrupt aufgetreten (0-->nein)! +REM_WDC1 WORD !Speicherplatz fuer Testdatenwert! +REM_WDC2 WORD !Speicherplatz fuer rueckgelesenen datenwert! + +!Arbeitsspeicher fuer Kommandos "GE"/"S"/"O U" und Floppytreiber! +FILENAME_PTR WORD !Anfangsadresse Dateiname! +COUNT_UDOS WORD !akt. Anzahl der Zeichen in UDOSBFF! +INPTR_UDOS WORD !Eingabezeiger fuer UDOSBFF + (naechster freier Platz)! +OUTPTR_UDOS WORD !Ausgabezeiger fuer UDOSBFF + naechstes auszulesende Zeichen)! +UDOSBFF ARRAY [%100 BYTE] !Eingabepuffer fuer interrupt- + gesteuerte Eingabe bei Dateitransfer + von/zu UDOS bzw. Blocktransfer! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +System Calls +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +SC_SEGV := %01 !Modul p.term! +SC_NSEGV := %02 !Modul p.term! +SC_TYRD := %04 !Modul p.term! +SC_TYWR := %06 !Modul p.term! +SC_RD_LINE_BFF := %08 !Modul p.term! +SC_WR_CRLF := %0A !Modul p.term! +SC_WR_MSG := %0C !Modul p.term! +SC_BTOH16 := %0E !Modul p.term! +SC_WR_OUTBFF_CR := %10 !Modul p.term! +SC_BTOH8 := %12 !Modul p.term! +SC_PUT_SEGNR := %14 !Modul p.term! +SC_PUT_CHR := %16 !Modul p.term! +! +SC_WOCF_MCZ := %18 Modul p.ldsd +SC_TYWR_MCZ := %1A Modul p.ldsd +! +SC_CMDLOP := %1C !Modul p.init! +SC_DISK := %1E !Modul p.disk! +SC_TYRD_UDOS_INT := %20 !Modul p.term! +SC_TYWR_UDOS_INT := %22 !Modul p.term! +SC_FLOPPY := %24 !Modul p.gesa! +SC_WR_OUTBFF := %26 !Modul p.term! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +spezielle ASCII-Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +SOH := %01 +STX := %02 +ETX := %03 +EOT := %04 +ACK := %06 +BEL := %07 +BS := %08 +LF := %0A +CR := %0D +NAK := %15 +CAN := %18 +ESC := %1B + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Hardwareadressen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT + +!8-Bit-Teil! + +SIO0D_B_8 := %26 !SIO fuer Terminal! +SIO0C_B_8 := %27 + +!16-Bit-Teil! + +SIO0 := %FF81 !Kanal A (XB1/TTY4): unbenutzt (vorher LOAD/SEND/QUIT); + Kanal B (XB2/TTY5): Terminal, wenn 8-Bit-Teil inaktiv! +SIO0D_A := SIO0 + 0 +SIO0D_B := SIO0 + 2 +SIO0C_A := SIO0 + 4 +SIO0C_B := SIO0 + 6 + +SIO1 := %FF89 !Kanal A (XB3/TTY6): unbenutzt + Kanal B (XB4/TTY7): unbenutzt! +SIO1D_A := SIO1 + 0 +SIO1D_B := SIO1 + 2 +SIO1C_A := SIO1 + 4 +SIO1C_B := SIO1 + 6 + +PIO0 := %FF91 !Koppel-PIO zum 8-Bit-Teil + fuer Terminal und Kommandos "GE", "S", + "Q", "QRES", "O U" und Floppytreiber + Kanal A: Datenausgabe + Kanal B: Statusausgabe/Steuerport! +PIO0D_A := PIO0 + 0 +PIO0D_B := PIO0 + 2 +PIO0C_A := PIO0 + 4 +PIO0C_B := PIO0 + 6 + +PIO1 := %FF99 !Koppel-PIO zum 8-Bit-Teil + fuer Terminal und Kommandos "GE", "S", + "Q", "QRES", "O U" und Floppytreiber + Kanal A: Dateneingabe + Kanal B: Statuseingabe/Steuerport! +PIO1D_A := PIO1 + 0 +PIO1D_B := PIO1 + 2 +PIO1C_A := PIO1 + 4 +PIO1C_B := PIO1 + 6 + +PIO2 := %FFA1 !(XB5): Winchester + Kanal A: Datenein-/-ausgabe; Kanal B: Steuerport! +PIO2D_A := PIO2 + 0 +PIO2D_B := PIO2 + 2 +PIO2C_A := PIO2 + 4 +PIO2C_B := PIO2 + 6 + +CTC0 := %FFA9 +CTC0_0 := CTC0 + 0 ! Baud 0 - SIO0, Kanal A! +CTC0_1 := CTC0 + 2 ! Baud 1 - SIO0, Kanal B! +CTC0_2 := CTC0 + 4 ! Baud 2 - SIO1, Kanal A! +CTC0_3 := CTC0 + 6 ! Next ! + +CTC1 := %FFB1 +CTC1_0 := CTC1 + 0 ! Baud 3 - SIO1, Kanal B! +CTC1_1 := CTC1 + 2 +CTC1_2 := CTC1 + 4 +CTC1_3 := CTC1 + 6 + +S_BNK := %FFC1 !SWITCH-BANK: + Bit0-3 Ausgabebits; Bit4-7 Eingabebits (DIL-Schalter): + Bit 0: =0 - Monitor PROM+RAM einschalten + =1 - Monitor PROM+RAM ausschalten + Bit 1: =0 - MMU's ausschalten; =1 - MMU's einschalten + Bit 2: Seg. Usr. + Bit 3: =0 - Paritaetspruefung ausgeschaltet bzw. + Paritaetsfehler loeschen + =1 - Paritaetspruefung eingeschaltet + Bit 5,4: Baudrate Terminal (unbenutzt) + Bit 7,6: Autoboot Device (unbenutzt)! + +SBREAK := %FFC9 !System Break Register! +NBREAK := %FFD1 !Normal Break Register! +RETI_P := %FFE1 !RETI-Port fuer Schaltkreise des U880-Systems! + +ALL_MMU := %F0 +STACK_MMU := %F6 +DATA_MMU := %FA +CODE_MMU := %FC + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Moegliche Statusausgaben an 8-Bit-Teil von 16-Bit-Teil +fuer 8-Bit-/16-Bit-Koppelschnittstelle (PIO0_B) +(INT8-Bit jeweils = 0) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +STAT8_ENDE := %00 !Ende eines Write-Requests! +STAT8_READ := %02 !Read-Request an einen Peripheriebaustein 8-Bit-Teil! +STAT8_WRITE := %04 !Write-Request an einen Peripheriebaustein 8-Bit-Teil! + +STAT8_UDOS := %10 !Datenbyte ist Bestandteil eines Dateitransfers + bzw. eines Blocktransfers von/zu UDOS! +STAT8_QUIT := %1E !Rueckkehr zum 8-Bit-Teil (Datenbyte "Q" oder "R")! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Moegliche Statuseingaben von 8-Bit-Teil an 16-Bit-Teil +fuer 8-Bit-/16-Bit-Koppelschnittstelle (PIO1_B) +(INT16-Bit jeweils = 0) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +STAT16_ENDE := %00 !Beantwortung eines Read-Requests! + +STAT16_SIO0_B_R := %04 !REC INT (SIO0_B-Empfaengerinterrupt)! +STAT16_SIO0_B_X := %24 !TRANS INT (SIO0_B-Interrupt Sendepuffer leer)! +STAT16_SIO0_B_E := %44 !EXT STAT INT (SIO0_B-Externer-Statusinterrupt)! +STAT16_SIO0_B_S := %64 !SPEC REC INT (SIO0_B-Interrupt Empfangssonderfall)! + +STAT16_UDOS := %10 !Datenbyte ist Bestandteil eines Dateitransfers + bzw. eines Blocktransfers von/zu UDOS! +!ende mon16.include! + +!****************************************************************************** +modulspezifische Vereinbarungen +******************************************************************************! + + CONSTANT +FILETYP := %05 !binary file/mit Uebertragung des Dateidescriptors! +BLOCKLEN := %40 !Laenge eines Blockes bei SAVE! + + INTERNAL +TXT_ILA + WORD := 23 + ARRAY [* BYTE] := 'INCORRECT LOAD ADDRESS%0D' +TXT_ABO + WORD := 6 + ARRAY [* BYTE] := 'ABORT%0D' +TXT_EPNT + WORD := 12 + ARRAY [* BYTE] := 'ENTRY POINT ' + + +!****************************************************************************** +Prozeduren +******************************************************************************! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET +GET-Routine "8-Bit-Teil" (Monitorkommando) +Laden einer UDOS-Procedure-Datei (von 8-Bit-Teil) in RAM +(ueber 8-Bit-/16-Bit-Koppelschnittstelle) + +Kommandoeingabe: GE filename [] + (Dateiname Segmentnummer(implizit PC_SEG)) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET procedure + entry + cpb PTYPORT, #%02 !8-Bit-Teil aktiv und UDOS verfuegbar?! + jp nz, ERROR !nein --> Kommando nicht ausfuehrbar! + + clr COUNT_UDOS + clr INPTR_UDOS + clr OUTPTR_UDOS + +!Auswertung der eingegebenen Parameter! + call GET_SIGN !INPTR zeigt auf 2. Zeichen des Dateinamens! + jp z, ERROR !kein Dateinamen angegeben! + ld r2, INPTR + dec r2, #1 !r2 zeigt auf 1. Zeichen des Dateinamens! + lda r2, INBFF(r2) !r2 := Adresse des Dateinamens! + ld FILENAME_PTR, r2 !Adresse des Dateinamens merken! + + push @r15, PC_SEG + call GET_SIGN !rl0 := 1. Zeichen der Segmentangabe ('<')! + call GET_SGNR !r2 := Segmentnummer (implizit PC_SEG)! + ld PC_SEG, r2 !Segmentnummer merken! + +!Startmeldung an 8-Bit-Teil senden (Datenbyte: "S")! + ldb rl0, #'S' !Datenbyte: 8-Bit-Teil soll Datei senden! + sc #SC_TYWR_UDOS_INT + sc #SC_TYRD_UDOS_INT !acknowledge! +!Ausgabe Filetyp an 8-Bit-Teil! + ldb rl0, #FILETYP + sc #SC_TYWR_UDOS_INT + sc #SC_TYRD_UDOS_INT !acknowledge! +!Ausgabe Dateinamen an 8-Bit-Teil! + ldb rh1, #10 !retries! +GET_OPEN1: !Schleife: Ausgabe des Blockes mit dem + Dateinamen! + ldb rl1, #0 !Checksumme init! + ld r8, FILENAME_PTR !Anfangsadr. des Dateinamens in INBFF! + ldb rl0, #STX !Start of Text! + sc #SC_TYWR_UDOS_INT +GET_OPEN2: !Schleife: Ausgabe der Zeichen des Dateinamens! + ldb rl0 ,@r8 !Zeichen von filename! + inc r8, #1 + cpb rl0, #' ' !ende filename ?! + jr z, GET_OP1 !ja! + cpb rl0, #CR !ende filename ?! + jr z, GET_OP1 !ja! + xorb rl1, rl0 !Checksumme berechnen! + sc #SC_TYWR_UDOS_INT + jr GET_OPEN2 +GET_OP1: + ldb rl0, #ETX !end of text! + sc #SC_TYWR_UDOS_INT + exb rl0, rl1 + sc #SC_TYWR_UDOS_INT !Checksumme ausgeben! + sc #SC_TYRD_UDOS_INT !Warten auf Quittung! + resb rl3, #7 + cpb rl3, #ACK + jr z, GET_DESCR !filename richtig uebertragen + file vorhanden! + cpb rl3, #CAN !Abbrechen ?! + jp z, GET_ERROR !ja! + dbjnz rh1, GET_OPEN1 !naechster Versuch! + jp GET_ERROR !Abbruch! + +!UDOS-Dateidescriptor (Laenge %80 Byte) empfangen und in INBFF abspeichern! +GET_DESCR: + ld r9, #INBFF !Speicheranfangsadresse fuer Dateidescriptor! + ld r11, #%80 !Laenge des Dateidescriptors! +GET_DESCR1: !Schleife: Lesen eines Blockes! + ldb rh1, #10 !retries! +GET_DESCR2: !Schleife: Wdhl. des Lesens eines Blockes! + ldb rl1, #0 !Checksumme init! + ld r8, r9 !Stand r9/r11 fuer den Fall einer! + ld r10, r11 !Wiederholung eines Blockes retten! + sc #SC_TYRD_UDOS_INT !1. Zeichen eines Blockes! + resb rl3, #7 + cpb rl3, #EOT !Ende der Uebertragung?! + jr nz, GET_DES1 !nein! + sc #SC_TYRD_UDOS_INT !noch 1 Zeichen im Puffer! + jr GET_END !EOT empfangen --> ENDE! +GET_DES1: + cpb rl3, #CAN + jr z, GET_ERROR !Abbruch von 8-Bit-Teil! + cpb rl3, #STX !Start of text muss 1.Zeichen sein! + jr nz, GET_DESCR4 !warten auf ETX und Uebertragung wiederholen! + sc #SC_TYRD_UDOS_INT + ldb rh2, rl3 + sc #SC_TYRD_UDOS_INT + ldb rl2, rl3 !r2 := Laenge des Blockes! +GET_DESCR3: !Scheife: Eingabe aller Daten eines Blockes! + sc #SC_TYRD_UDOS_INT !Daten lesen! + test r11 + jr z,GET_DES2 !Descriptor bereits vollst. eingelsen --> + ggf. restl. Daten des Blockes ignorieren! + ldb @r9, rl3 !Datenbyte in Puffer abspeichern! + inc r9, #1 + dec r11, #1 !Zaehler decr! +GET_DES2: + xorb rl1, rl3 !Checksumme berechnen! + djnz r2, GET_DESCR3 !naechstes Datenbyte einlesen! +GET_DESCR4: !Schleife: Warten auf ETX! + sc #SC_TYRD_UDOS_INT + resb rl3, #7 + cpb rl3, #ETX + jr nz, GET_DESCR4 + + sc #SC_TYRD_UDOS_INT !Checksumme! + cpb rl3, rl1 !uebertragene = berechnete ?! + jr nz, GET_DES3 !Fehler! + + test r11 + jr z, GET_DESCR5 !Descriptor vollstaendig eingelesen! + ldb rl0, #ACK !richtig uebertragen Qittung ok geben! + sc #SC_TYWR_UDOS_INT + jr GET_DESCR1 !naechsten Block einlesen! +GET_DES3: + decb rh1, #1 + jr z, GET_ERROR !Abbruch! + + ld r9, r8 !r9/r11 auf Wert vor der Blockuebertragung! + ld r11, r10 !setzen! + ldb rl0, #NAK !n mal wiederholen! + sc #SC_TYWR_UDOS_INT + jr GET_DESCR2 !Wiederholung der Blockuebertragung! + +GET_DESCR5: !Test auf zulaessige Anfangsadresse! + ld r1, #%28 !relative Adresse der Anfangsadresse im + Dateidescriptor! + ld r5, INBFF(r1) + exb rh5, rl5 !r5 := Anfangsadresse fuer Dateidaten! + ld r0, PC_SEG + res r0, #15 + test r0 + jr nz, GET_DES4 !Segmentnummer ungleich 0! + cp r5, #%8000 !kleinste zulaessige Dateianfangsadresse + im Segment 0! + jr nc, GET_DES4 !zulaessig! + ld r2, #TXT_ILA + jr GET_ERROR1 !unzulaessige Anfangsadresse! +GET_DES4: + ldb rl0, #ACK !richtig uebertragen Qittung ok geben! + sc #SC_TYWR_UDOS_INT + +!Einlesen aller Bloecke mit den Daten der Datei! +GET_DATEI: + ld r9, r5 !r9 := Anfangsadresse fuer Dateidaten! +GET_DATEI1: !Schleife: Lesen eines Blockes! + ldb rh1, #10 !retries! +GET_DATEI2: !Schleife: Wdhl. des Lesens eines Blockes! + ldb rl1, #0 !Checksumme init! + ld r8, r9 !Buffer Pointer retten! + sc #SC_TYRD_UDOS_INT + resb rl3, #7 + cpb rl3, #EOT !Ende der Uebertragung?! + jr nz, GET_DAT1 !nein! + sc #SC_TYRD_UDOS_INT !noch 1 Zeichen im Puffer! + jr GET_EPNT !file geladen! +GET_DAT1: + cpb rl3, #CAN + jr z, GET_ERROR !Abbruch von 8-Bit-Teil! + cpb rl3, #STX !Start of text muss 1.Zeichen sein! + jr nz, GET_DATEI4 !warten auf ETX und Uebertragung wiederholen! + sc #SC_TYRD_UDOS_INT + ldb rh2, rl3 + sc #SC_TYRD_UDOS_INT + ldb rl2, rl3 !r2 := Laenge des Blockes! +GET_DATEI3: !Scheife: Eingabe aller Daten eines Blockes! + sc #SC_TYRD_UDOS_INT !Daten lesen! + push @r15, r8 + ld r8, PC_SEG + sc #SC_SEGV + ldb @r8, rl3 !Datenbyte in Speicher schreiben (segmentiert)! + sc #SC_NSEGV + pop r8, @r15 + inc r9, #1 + xorb rl1, rl3 !Checksumme berechnen! + djnz r2, GET_DATEI3 +GET_DATEI4: !Schleife: Warten auf ETX! + sc #SC_TYRD_UDOS_INT + resb rl3, #7 + cpb rl3, #ETX + jr nz, GET_DATEI4 + + sc #SC_TYRD_UDOS_INT !Checksumme! + cpb rl3, rl1 !uebertragene = berechnete ?! + jr nz, GET_DAT3 !Fehler! + + ldb rl0, #ACK !richtig uebertragen Qittung ok geben! + sc #SC_TYWR_UDOS_INT + jr GET_DATEI1 !und naechsten Block einlesen! +GET_DAT3: + decb rh1, #1 + jr z, GET_ERROR !Abbruch! + + ld r9, r8 !Buffer Pointer auf Anfang zurueck! + ldb rl0, #NAK !n mal wiederholen! + sc #SC_TYWR_UDOS_INT + jr GET_DATEI2 !Wiederholung der Blockuebertragung! + +!Ausgabe des ENTRY POINT! +GET_EPNT: + ld r2, #TXT_EPNT + sc #SC_WR_MSG !Textausgabe! + ld r1, #%14 !relat. Adr. des Entry Point im Descriptor! + ld r5, INBFF(r1) + exb rh5, rl5 !r5 := ENTRY POINT! + sc #SC_BTOH16 + sc #SC_WR_OUTBFF_CR !Ausgabe Entry Point! + jr GET_END + +!Uebertragungsfehler! +GET_ERROR: + ld r2, #TXT_ABO +GET_ERROR1: + sc #SC_WR_MSG !Textausgabe! + ldb rl0, #CAN !Abbruch senden! + sc #SC_TYWR_UDOS_INT + sc #SC_TYRD_UDOS_INT + +!Ende! +GET_END: + pop PC_SEG, @r15 + ret + end GET + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE SAVE +SAVE-Routine "8-Bit-Teil" (Monitorkommando) +Abspeichern eines Speicherinhaltes als UDOS-Procedure-Datei (8-Bit-Teil) +(ueber 8-Bit-/16-Bit-Koppelschnittstelle) + +Kommandoeingabe: S filename []offset1 offset2 [E=Entry_point] + [RL=Record_length] + (Dateiname Anfangsadresse Endadresse Eintrittspunkt + Recordlaenge) + (Segmentnummer implizit PC_SEG, + Eintrittspunkt implizit Anfangsadresse, + Recordlaenge implizit %100) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + SAVE procedure + entry + cpb PTYPORT, #%02 !8-Bit-Teil aktiv und UDOS verfuegbar?! + jp nz, ERROR !nein --> Kommando nicht ausfuehrbar! + + clr COUNT_UDOS + clr INPTR_UDOS + clr OUTPTR_UDOS + +!Auswertung der eingegebenen Parameter! +! PC_SEG := Anfangsadresse (Segmentnummer) + r9 := Anfangsadresse (Offset) + r11 := Bytezahl + r10 := Entry Point + r13 := Record Length! + call GET_SIGN !INPTR zeigt auf 2. Zeichen des Dateinamens! + jp z, ERROR !kein Dateinamen angegeben! + ld r2, INPTR + dec r2, #1 !r2 zeigt auf 1. Zeichen des Dateinamens! + lda r2, INBFF(r2) !r2 := Adresse des Dateinamens! + ld FILENAME_PTR, r2 !Adresse des Dateinamens merken! + + call GET_SIGN !rl0 := 1. Zeichen der Anfangsadresse! + jp z, ERROR !keine Anfangsadresse angegeben! + call GET_ADR !rr2 := angegebene Anfangsadresse / + rl0 := 1. Zeichen der Endadresse! + ldl rr8, rr2 !rr8 := angegebene Anfangsadresse! + jp z, ERROR !keine Offsetadresse oder kein weiterer + Parameter angegeben! + + call GET_ADR !r3 := angegebene Endadresse / + rl0 := 1. Zeichen des naechsten Parameters! + ldctlb rh0, FLAGS !Stand Z-Flag retten! + sub r3,r9 + jp c, ERROR !Endadresse < Anfangsadresse! + inc r3 + ld r11, r3 !r11:=Bytezahl! + ld r10, r9 !impliziter Wert fuer Entry Point = Anf.-Adr.! + ld r13, #%100 !impliziter Wert fuer Record length! + bitb rh0, #6 !Z-Flag testen! + jr nz, SAVE_PAR2 !kein weiterer Parameter angegeben! + + cpb rl0, #'E' + jr nz, SAVE_PAR1 !keine Entry Point-Angabe! + call GET_CHR + cpb rl0, #'=' + jp nz, ERROR !falsche Entry Point-Angabe! + call GET_SIGNW !rl0:=1. Zeichen der Entry Point-Adresse! + jp z, ERROR !keine Entry Point-Adresse angegeben (CR)! + call GET_HEXZ !r3 := angegebener Entry Point, + rl0 := 1. Zeichen der Record Length-Angabe! + ld r10, r3 !r10 := angegebener Entry Point! + jr z, SAVE_PAR2 !keine Recordlaenge angegeben! +SAVE_PAR1: + cpb rl0, #'R' + jp nz, ERROR !keine Record Length-Angabe! + call GET_CHR + cpb rl0, #'L' + jp nz, ERROR !falsche Record Length-Angabe! + call GET_CHR + cpb rl0, #'=' + jp nz, ERROR !falsche Record Length-Angabe! + call GET_SIGNW !rl0:=1. Zeichen der Recordlaengenzahl! + jp z, ERROR !keine Recordlaengenzahl angegeben (CR)! + call GET_HEXZ !r3 := angegebener Recordlaenge! + ld r13, r3 !r13 := angegebene Recordlaenge! +SAVE_PAR2: + push @r15, PC_SEG + ld PC_SEG, r8 !Segmentnummer merken! + +!Startmeldung an 8-Bit-Teil senden (Datenbyte: "L")! + ldb rl0, #'L' !Datenbyte: 8-Bit-Teil soll Datei empfangen! + sc #SC_TYWR_UDOS_INT + sc #SC_TYRD_UDOS_INT !acknowledge! +!Ausgabe Filetyp an 8-Bit-Teil! + ldb rl0, #FILETYP + sc #SC_TYWR_UDOS_INT + sc #SC_TYRD_UDOS_INT !acknowledge! +!Ausgabe Dateinamen an 8-Bit-Teil! + ldb rh1, #10 !retries! +SAVE_OPEN1: !Schleife: Ausgabe des Blockes mit dem + Dateinamen! + ldb rl1, #0 !Checksumme init! + ld r12, FILENAME_PTR !Anfangsadr. des Dateinamens in INBFF! + ldb rl0, #STX !Start of Text! + sc #SC_TYWR_UDOS_INT +SAVE_OPEN2: !Schleife: Ausgabe der Zeichen des Dateinamens! + ldb rl0 ,@r12 !Zeichen von filename! + inc r12, #1 + cpb rl0, #' ' !ende filename ?! + jr z, SAVE_OP1 !ja! + cpb rl0, #CR !ende filename ?! + jr z, SAVE_OP1 !ja! + xorb rl1, rl0 !Checksumme berechnen! + sc #SC_TYWR_UDOS_INT + jr SAVE_OPEN2 +SAVE_OP1: + ldb rl0, #ETX !end of text! + sc #SC_TYWR_UDOS_INT + exb rl0, rl1 + sc #SC_TYWR_UDOS_INT !Checksumme ausgeben! + sc #SC_TYRD_UDOS_INT !Warten auf Quittung! + resb rl3, #7 + cpb rl3, #ACK + jr z, SAVE_DESCR !filename richtig uebertragen! + cpb rl3, #CAN !Abbrechen ?! + jp z, SAVE_ERROR !ja! + dbjnz rh1, SAVE_OPEN1 !naechster Versuch! + jp SAVE_ERROR !Abbruch! + +!UDOS-Dateidescriptor in OUTBFF aufbauen! +SAVE_DESCR: + ld r4, #OUTBFF !OUTBFF loeschen! + ld r2, #OUTBFF+2 + ld r1, #%3F + ld @r4, #0 + ldir @r2, @r4, r1 + ld r1, #0 !Magic-Nr. im Descriptor abspeichern + (wird von remote-Programm benoetigt)! + ldb OUTBFF(r1), #%D6 + inc r1, #1 + ldb OUTBFF(r1), #%07 + ld r1, #%0C !Dateityp im Descriptor abspeichern! + ldb OUTBFF(r1), #%80 + ld r1, #%0F !Recordlaenge im Descriptor abspeichern! + ld r5, r13 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%14 !Entry Point im Descriptor abspeichern! + ld r5, r10 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%28 !Anfangsadresse im Descriptor abspeichern! + ld r5, r9 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%2A !Laenge im Descriptor abspeichern! + ld r5, r11 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%7A !LOW_ADDRESS im Descriptor abspeichern! + ld r5, r9 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%7C !HIGH_ADDRESS im Descriptor abspeichern! + ld r5, r9 + add r5, r11 + dec r5, #1 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%7E !STACK_SIZE im Descriptor abspeichern! + ldb OUTBFF(r1), #%80 + inc r1, #1 + ldb OUTBFF(r1), #%00 + +!UDOS-Dateidescriptor (Laenge %80 Byte) aus OUTBFF senden! + ld r12, #OUTBFF !Speicheranfangsadresse fuer Dateidescriptor! + ld r13, #%80 !Laenge des Dateidescriptors! +SAVE_DESCR1: !Schleife: Schreiben eines Blockes! + ldb rh1, #10 !retries! +SAVE_DESCR2: !Schleife: Wdhl. des Schreibens eines Blockes! + ldb rl1, #0 !Checksumme init! + ld r8, r12 !Stand r12/r13 fuer den Fall einer! + ld r10, r13 !Wiederholung eines Blockes retten! + ldb rl0, #STX !STX senden! + sc #SC_TYWR_UDOS_INT !Start of text! + ld r2, #BLOCKLEN !Blocklaenge berechnen! + sub r13, r2 !r13 := restliche Datenanzahl! + jr nc, SAVE_DES1 !Datenanzahl >= BLOCKLEN + --> Blocklaenge (r2) := BLOCKLEN! + ld r2, r10 !Datenanzahl < BLOCKLEN + --> Blocklaenge (r2) := Datenanzahl! + ld r13, #0 !restl. Datenanzahl := 0! +SAVE_DES1: + ldb rl0, rh2 !Blocklaenge senden! + sc #SC_TYWR_UDOS_INT + ldb rl0, rl2 + sc #SC_TYWR_UDOS_INT +SAVE_DESCR3: !Scheife: Ausgabe aller Daten eines Blockes! + ldb rl0, @r12 + xorb rl1, rl0 !Checksumme berechnen! + sc #SC_TYWR_UDOS_INT !Datenbyte senden! + inc r12, #1 + djnz r2, SAVE_DESCR3 !naechstes Datenbyte senden! + ldb rl0, #ETX !ETX senden! + sc #SC_TYWR_UDOS_INT + ldb rl0, rl1 !Checksumme senden! + sc #SC_TYWR_UDOS_INT + sc #SC_TYRD_UDOS_INT !acknowledge! + cpb rl3, #ACK + jr nz, SAVE_DES3 + test r13 + jr z, SAVE_DATEI !Descriptor vollst. ausgegeben! + jr SAVE_DESCR1 !naechsten Block senden! +SAVE_DES3: + cpb rl3, #CAN + jr z, SAVE_ERROR !Abbruch! + decb rh1, #1 + jr z, SAVE_ERROR !Wiederholungszaehler=0-->Abbruch! + ld r12, r8 !r12/r13 auf Wert vor der Blockuebertragung! + ld r13, r10 !setzen! + jr SAVE_DESCR2 !Wiederholung der Blockuebertragung! + +!alle Bloecke mit den Daten der Datei senden! +SAVE_DATEI: + !r9 enthaelt Speicheranfangsadresse fuer Dateidaten! + !r11 enthaelt Bytezahl! +SAVE_DATEI1: !Schleife: Schreiben eines Blockes! + ldb rh1, #10 !retries! +SAVE_DATEI2: !Schleife: Wdhl. des Schreibens eines Blockes! + ldb rl1, #0 !Checksumme init! + ld r8, r9 !Stand r9/r11 fuer den Fall einer! + ld r10, r11 !Wiederholung eines Blockes retten! + ldb rl0, #STX !STX senden! + sc #SC_TYWR_UDOS_INT !Start of text! + ld r2, #BLOCKLEN !Blocklaenge berechnen! + sub r11, r2 !r11 := restliche Datenanzahl! + jr nc, SAVE_DAT1 !Datenanzahl >= BLOCKLEN + --> Blocklaenge (r2) := BLOCKLEN! + ld r2, r10 !Datenanzahl < BLOCKLEN + --> Blocklaenge (r2) := Datenanzahl! + ld r11, #0 !restl. Datenanzahl := 0! +SAVE_DAT1: + ldb rl0, rh2 !Blocklaenge senden! + sc #SC_TYWR_UDOS_INT + ldb rl0, rl2 + sc #SC_TYWR_UDOS_INT +SAVE_DATEI3: !Scheife: Ausgabe aller Daten eines Blockes! + push @r15, r8 + ld r8, PC_SEG + sc #SC_SEGV + ldb rl0, @r8 !Datenbyte aus Speicher lesen (segmentiert)! + sc #SC_NSEGV + pop r8, @r15 + xorb rl1, rl0 !Checksumme berechnen! + sc #SC_TYWR_UDOS_INT !Datenbyte senden! + inc r9, #1 + djnz r2, SAVE_DATEI3 !naechstes Datenbyte senden! + ldb rl0, #ETX !ETX senden! + sc #SC_TYWR_UDOS_INT + ldb rl0, rl1 !Checksumme senden! + sc #SC_TYWR_UDOS_INT + sc #SC_TYRD_UDOS_INT !acknowledge! + cpb rl3, #ACK + jr nz, SAVE_DAT3 + test r11 + jr z, SAVE_END !Datei vollst. ausgegeben! + jr SAVE_DATEI1 !naechsten Block senden! +SAVE_DAT3: + cpb rl3, #CAN + jr z, SAVE_ERROR !Abbruch! + decb rh1, #1 + jr z, SAVE_ERROR !Wiederholungszaehler=0-->Abbruch! + ld r9, r8 !r9/r11 auf Wert vor der Blockuebertragung! + ld r11, r10 !setzen! + jr SAVE_DATEI2 !Wiederholung der Blockuebertragung! + +!Uebertragungsfehler! +SAVE_ERROR: + ld r2, #TXT_ABO + sc #SC_WR_MSG !Textausgabe! + +!Ende! +SAVE_END: + ldb rl0, #CAN !Abbruch senden! + sc #SC_TYWR_UDOS_INT + sc #SC_TYRD_UDOS_INT + pop PC_SEG, @r15 + ret + end SAVE + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE QUIT8 +QUIT-Routine "8-Bit-Teil" (Monitorkommando) +Rueckkehr in 8-Bit-Teil, wenn U8000-Softwaremonitor von dort gestartet wurde - +U8000-Softwaremonitor bleibt aktiv (local Mode) (kein RESET des 16-Bit-Teils) +(Rueckkehr in das System, von dem aus der U8000-Softwaremonitor gestartet wurde +(Betriebssystem UDOS bzw. U880-Softwaremonitor)) + +Kommandoeingabe: Q +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + QUIT8 procedure + entry + testb PTYPORT !8-Bit-Teil aktiv?! + jp z, ERROR !nein, d.h. Kommando nicht ausfuehrbar! + + ldb rl0, #'Q' !Datenbyte: QUIT ohne RESET U8000! + ldb rh0, #STAT8_QUIT !Status: Rueckkehr in 8-Bit-Teil! + call TYWR_KOPPEL_INT !Datenbyte+Status an Koppelschnittstelle + ausgeben! + sc #SC_TYRD_UDOS_INT !acknowledge! + ret + end QUIT8 + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE QUIT8_RESET +QUIT-Routine "8-Bit-Teil" (Monitorkommando) +Rueckkehr in 8-Bit-Teil, wenn U8000-Softwaremonitor von dort gestartet wurde - +RESET des 16-Bit-Teils +(Rueckkehr in das System, von dem aus der U8000-Softwaremonitor gestartet wurde +(Betriebssystem UDOS bzw. U880-Softwaremonitor)) + +Kommandoeingabe: QRES +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + QUIT8_RESET procedure + entry + testb PTYPORT !8-Bit-Teil aktiv?! + jp z, ERROR !nein, d.h. Kommando nicht ausfuehrbar! + + ldb rl0, #'R' !Datenbyte: QUIT mit RESET U8000! + ldb rh0, #STAT8_QUIT !Status: Rueckkehr in 8-Bit-Teil! + call TYWR_KOPPEL_INT !Datenbyte+Status an Koppelschnittstelle + ausgeben! + sc #SC_TYRD_UDOS_INT !acknowledge! + ret !danach erfolgt RESET U8000! + end QUIT8_RESET + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE FLOPPY +Treiber zur Arbeit mit einer blockorientierten Diskette auf 8-Bit-Teil - +Lesen/Schreiben eines Blockes bzw. Formatieren einer blockorientierten Diskette +(ueber 8-Bit/16-Bit Koppelschnittstelle) + +Input: r7 - Requestcode (1=Read / 2=Write / 3=Format) + r6 - Bit 0-3: Drivenummer (0-3) + Bit 4-7: Floppytyp (0-F) + rr4 - Blocknummer (r4=0) + rr8 - Pufferadresse + r10 - Laenge in Byte (<= %200) +Output: r2 - Return Code + 0 - kein Fehler + 1 - Fehler (8-Bit-Teil nicht aktiv bzw. + 8-Bit-Teil aktiv, aber UDOS nicht verfuegbar) + 2 - Fehler (falscher Requestcode) + sonst - Fehler vom 8-Bit-Teil gesendet +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + FLOPPY procedure + entry + cpb PTYPORT, #%02 !8-Bit-Teil aktiv und UDOS verfuegbar?! + ld r2, #1 !Fehler 0001: 8-Bit-Teil nicht aktiv bzw. + 8-Bit-Teil aktiv, aber UDOS nicht verfuegbar! + ret nz + + clr COUNT_UDOS + clr INPTR_UDOS + clr OUTPTR_UDOS + +!Auswertung des angegebenen Requests! + cp r7, #1 + jr z, BLOCK_READ + cp r7, #2 + jr z, BLOCK_WRITE + cp r7, #3 + jr z, BLOCK_FORMAT + ld r2, #2 !Fehler 0002: falscher Requestcode! + ret + +!Formatieren einer blockorientierten Diskette! +BLOCK_FORMAT: + !Startmeldung an 8-Bit-Teil senden (Datenbyte 'F')! + ldb rl0, #'F' + sc #SC_TYWR_UDOS_INT + !Ausgabe Floppytyp/Drive-Nr. an 8-Bit-Teil! + ldb rl0, rl6 + sc #SC_TYWR_UDOS_INT + !Warten auf Fertigstellung! + sc #SC_TYRD_UDOS_INT + cpb rl3, #ACK + ld r2, #0 !Rueckkehrcode 0000: kein Fehler! + ret z + ldb rl2, rl3 !Fehlercode vom 8-Bit-Teil! + ret + +!Lesen eines Blockes von einer blockorientierten Diskette! +BLOCK_READ: + !Startmeldung an 8-Bit-Teil senden (Datenbyte 'R')! + ldb rl0, #'R' + sc #SC_TYWR_UDOS_INT + !Ausgabe Floppytyp/Drive-Nr. an 8-Bit-Teil! + ldb rl0, rl6 + call TYWR_UDOS_POL + !Ausgabe Blocknummer an 8-Bit-Teil! + ldb rl0, rh5 !High-Byte! + call TYWR_UDOS_POL + ldb rl0, rl5 !Low-Byte! + call TYWR_UDOS_POL + !Ausgabe der Datenlaenge in Byte (max. %200)! + ld r0, r10 + ldb rl0, rh0 !High-Byte! + call TYWR_UDOS_POL + ld r0, r10 !Low-Byte! + call TYWR_UDOS_POL + !Warten auf Bereitmeldung von 8-Bit-Teil + (erfolgt, wenn Block von Diskette gelesen wurde)! + sc #SC_TYRD_UDOS_INT + cpb rl3, #ACK + ldb rl2, rl3 !Fehlercode vom 8-Bit-Teil! + ldb rh2, #0 + ret nz + !Block einlesen! +BLK_RD: + call TYRD_UDOS_POL !rl0:=eingelesenens Datenbyte! + sc #SC_SEGV + ldb @r8, rl0 !Datenbyte im Puffer abspeichern! + sc #SC_NSEGV + inc r9, #1 !Pufferadresse inc! + djnz r10, BLK_RD !Byteanzahl dec! + !Fertigstellungsmeldung senden! + ldb rl0, #ACK + call TYWR_UDOS_POL + ld r2, #0 !Rueckkehrcode 0000: kein Fehler! + ret + +!Schreiben eines Blockes auf eine blockorientierte Diskette! +BLOCK_WRITE: + !Startmeldung an 8-Bit-Teil senden (Datenbyte 'W')! + ldb rl0, #'W' + sc #SC_TYWR_UDOS_INT + !Ausgabe Floppytyp/Drive-Nr. an 8-Bit-Teil! + ldb rl0, rl6 + call TYWR_UDOS_POL + !Ausgabe Blocknummer an 8-Bit-Teil! + ldb rl0, rh5 !High-Byte! + call TYWR_UDOS_POL + ldb rl0, rl5 !Low-Byte! + call TYWR_UDOS_POL + !Ausgabe der Datenlaenge in Byte (max. %200)! + ld r0, r10 + ldb rl0, rh0 !High-Byte! + call TYWR_UDOS_POL + ld r0, r10 !Low-Byte! + call TYWR_UDOS_POL + !Block ausgeben! +BLK_WR: + sc #SC_SEGV + ldb rl0, @r8 !Datenbyte aus Puffer lesen! + sc #SC_NSEGV + call TYWR_UDOS_POL !Datenbyte ausgeben! + inc r9, #1 !Pufferadr. inc! + djnz r10, BLK_WR !Bytezahl dec! + !Warten auf Fertigstellungsmeldung von 8-Bit-Teil + (erfolgt, wenn Block auf Diskette geschrieben wurde)! + sc #SC_TYRD_UDOS_INT + cpb rl3, #ACK + ld r2, #0 !Rueckkehrcode 0000: kein Fehler! + ret z + ldb rl2, rl3 !Fehlercode vom 8-Bit-Teil! + ret + end FLOPPY + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE RM_GET +GET-Routine "Lokales System" (Monitorkommando) +Laden einer UDOS-Procedure-Datei (von lokalem System) in RAM +(ueber "remote"-Programm des lokalen Systems) + +Kommandoeingabe: RGE filename [] + (Dateiname Segmentnummer(implizit PC_SEG)) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + RM_GET procedure + entry + setb FLAG0, #0 !Abschalten von xoff! + +!Auswertung der eingegebenen Parameter! + call GET_SIGN !INPTR zeigt auf 2. Zeichen des Dateinamens! + jp z, ERROR !kein Dateinamen angegeben! + ld r2, INPTR + dec r2, #1 !r2 zeigt auf 1. Zeichen des Dateinamens! + lda r2, INBFF(r2) !r2 := Adresse des Dateinamens! + ld FILENAME_PTR, r2 !Adresse des Dateinamens merken! + + push @r15, PC_SEG + call GET_SIGN !rl0 := 1. Zeichen der Segmentangabe ('<')! + call GET_SGNR !r2 := Segmentnummer (implizit PC_SEG)! + ld PC_SEG, r2 !Segmentnummer merken! + +!Startmeldung (SOH, ESC, 'S') an local senden! + ldb rl0, #SOH + sc #SC_TYWR + ldb rl0, #ESC + sc #SC_TYWR + ldb rl0, #'S' + sc #SC_TYWR + sc #SC_TYRD !acknowledge! +!Ausgabe Filetyp an local! + ldb rl0, #FILETYP + sc #SC_TYWR + sc #SC_TYRD !acknowledge! +!Ausgabe Dateinamen an local! + ldb rh1, #10 !retries! +RGET_OPEN1: !Schleife: Ausgabe des Blockes mit dem + Dateinamen! + ldb rl1, #0 !Checksumme init! + ld r8, FILENAME_PTR !Anfangsadr. des Dateinamens in INBFF! + ldb rl0, #STX !Start of Text! + sc #SC_TYWR +RGET_OPEN2: !Schleife: Ausgabe der Zeichen des Dateinamens! + ldb rl0 ,@r8 !Zeichen von filename! + inc r8, #1 + cpb rl0, #' ' !ende filename ?! + jr z, RGET_OP1 !ja! + cpb rl0, #CR !ende filename ?! + jr z, RGET_OP1 !ja! + xorb rl1, rl0 !Checksumme berechnen! + sc #SC_TYWR + jr RGET_OPEN2 +RGET_OP1: + ldb rl0, #ETX !end of text! + sc #SC_TYWR + exb rl0, rl1 + sc #SC_TYWR !Checksumme ausgeben! + sc #SC_TYRD !Warten auf Quittung! + resb rl3, #7 + cpb rl3, #ACK + jr z, RGET_DESCR !filename richtig uebertragen + file vorhanden! + cpb rl3, #CAN !Abbrechen ?! + jp z, RGET_ERROR !ja! + dbjnz rh1, RGET_OPEN1 !naechster Versuch! + jp RGET_ERROR !Abbruch! + +!UDOS-Dateidescriptor (Laenge %80 Byte) empfangen und in INBFF abspeichern! +RGET_DESCR: + ld r9, #INBFF !Speicheranfangsadresse fuer Dateidescriptor! + ld r11, #%80 !Laenge des Dateidescriptors! +RGET_DESCR1: !Schleife: Lesen eines Blockes! + ldb rh1, #10 !retries! +RGET_DESCR2: !Schleife: Wdhl. des Lesens eines Blockes! + ldb rl1, #0 !Checksumme init! + ld r8, r9 !Stand r9/r11 fuer den Fall einer! + ld r10, r11 !Wiederholung eines Blockes retten! + sc #SC_TYRD !1. Zeichen eines Blockes! + resb rl3, #7 + cpb rl3, #EOT !Ende der Uebertragung?! + jr nz, RGET_DES1 !nein! + sc #SC_TYRD !noch 1 Zeichen im Puffer! + jr RGET_END !EOT empfangen --> ENDE! +RGET_DES1: + cpb rl3, #CAN + jr z, RGET_ERROR !Abbruch von 8-Bit-Teil! + cpb rl3, #STX !Start of text muss 1.Zeichen sein! + jr nz, RGET_DESCR4 !warten auf ETX und Uebertragung wiederholen! + sc #SC_TYRD + ldb rh2, rl3 + sc #SC_TYRD + ldb rl2, rl3 !r2 := Laenge des Blockes! +RGET_DESCR3: !Scheife: Eingabe aller Daten eines Blockes! + sc #SC_TYRD !Daten lesen! + test r11 + jr z,RGET_DES2 !Descriptor bereits vollst. eingelsen --> + ggf. restl. Daten des Blockes ignorieren! + ldb @r9, rl3 !Datenbyte in Puffer abspeichern! + inc r9, #1 + dec r11, #1 !Zaehler decr! +RGET_DES2: + xorb rl1, rl3 !Checksumme berechnen! + djnz r2, RGET_DESCR3 !naechstes Datenbyte einlesen! +RGET_DESCR4: !Schleife: Warten auf ETX! + sc #SC_TYRD + resb rl3, #7 + cpb rl3, #ETX + jr nz, RGET_DESCR4 + + sc #SC_TYRD !Checksumme! + cpb rl3, rl1 !uebertragene = berechnete ?! + jr nz, RGET_DES3 !Fehler! + + test r11 + jr z, RGET_DESCR5 !Descriptor vollstaendig eingelesen! + ldb rl0, #ACK !richtig uebertragen Qittung ok geben! + sc #SC_TYWR + jr RGET_DESCR1 !naechsten Block einlesen! +RGET_DES3: + decb rh1, #1 + jr z, RGET_ERROR !Abbruch! + + ld r9, r8 !r9/r11 auf Wert vor der Blockuebertragung! + ld r11, r10 !setzen! + ldb rl0, #NAK !n mal wiederholen! + sc #SC_TYWR + jr RGET_DESCR2 !Wiederholung der Blockuebertragung! + +RGET_DESCR5: !Test auf zulaessige Anfangsadresse! + ld r1, #%28 !relative Adresse der Anfangsadresse im + Dateidescriptor! + ld r5, INBFF(r1) + exb rh5, rl5 !r5 := Anfangsadresse fuer Dateidaten! + ld r0, PC_SEG + res r0, #15 + test r0 + jr nz, RGET_DES4 !Segmentnummer ungleich 0! + cp r5, #%8000 !kleinste zulaessige Dateianfangsadresse + im Segment 0! + jr nc, RGET_DES4 !zulaessig! + ld r2, #TXT_ILA + jr RGET_ERROR1 !unzulaessige Anfangsadresse! +RGET_DES4: + ldb rl0, #ACK !richtig uebertragen Qittung ok geben! + sc #SC_TYWR + +!Einlesen aller Bloecke mit den Daten der Datei! +RGET_DATEI: + ld r9, r5 !r9 := Anfangsadresse fuer Dateidaten! +RGET_DATEI1: !Schleife: Lesen eines Blockes! + ldb rh1, #10 !retries! +RGET_DATEI2: !Schleife: Wdhl. des Lesens eines Blockes! + ldb rl1, #0 !Checksumme init! + ld r8, r9 !Buffer Pointer retten! + sc #SC_TYRD + resb rl3, #7 + cpb rl3, #EOT !Ende der Uebertragung?! + jr nz, RGET_DAT1 !nein! + sc #SC_TYRD !noch 1 Zeichen im Puffer! + jr RGET_EPNT !file geladen! +RGET_DAT1: + cpb rl3, #CAN + jr z, RGET_ERROR !Abbruch von 8-Bit-Teil! + cpb rl3, #STX !Start of text muss 1.Zeichen sein! + jr nz, RGET_DATEI4 !warten auf ETX und Uebertragung wiederholen! + sc #SC_TYRD + ldb rh2, rl3 + sc #SC_TYRD + ldb rl2, rl3 !r2 := Laenge des Blockes! +RGET_DATEI3: !Scheife: Eingabe aller Daten eines Blockes! + sc #SC_TYRD !Daten lesen! + push @r15, r8 + ld r8, PC_SEG + sc #SC_SEGV + ldb @r8, rl3 !Datenbyte in Speicher schreiben (segmentiert)! + sc #SC_NSEGV + pop r8, @r15 + inc r9, #1 + xorb rl1, rl3 !Checksumme berechnen! + djnz r2, RGET_DATEI3 +RGET_DATEI4: !Schleife: Warten auf ETX! + sc #SC_TYRD + resb rl3, #7 + cpb rl3, #ETX + jr nz, RGET_DATEI4 + + sc #SC_TYRD !Checksumme! + cpb rl3, rl1 !uebertragene = berechnete ?! + jr nz, RGET_DAT3 !Fehler! + + ldb rl0, #ACK !richtig uebertragen Qittung ok geben! + sc #SC_TYWR + jr RGET_DATEI1 !und naechsten Block einlesen! +RGET_DAT3: + decb rh1, #1 + jr z, RGET_ERROR !Abbruch! + + ld r9, r8 !Buffer Pointer auf Anfang zurueck! + ldb rl0, #NAK !n mal wiederholen! + sc #SC_TYWR + jr RGET_DATEI2 !Wiederholung der Blockuebertragung! + +!Ausgabe des ENTRY POINT! +RGET_EPNT: + ld r2, #TXT_EPNT + sc #SC_WR_MSG !Textausgabe! + ld r1, #%14 !relat. Adr. des Entry Point im Descriptor! + ld r5, INBFF(r1) + exb rh5, rl5 !r5 := ENTRY POINT! + sc #SC_BTOH16 + sc #SC_WR_OUTBFF_CR !Ausgabe Entry Point! + jr RGET_END + +!Uebertragungsfehler! +RGET_ERROR: + ld r2, #TXT_ABO +RGET_ERROR1: + sc #SC_WR_MSG !Textausgabe! + ldb rl0, #CAN !Abbruch senden! + sc #SC_TYWR + sc #SC_TYRD + +!Ende! +RGET_END: + resb FLAG0, #0 + pop PC_SEG, @r15 + ret + end RM_GET + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE RM_SAVE +SAVE-Routine "Lokales System" (Monitorkommando) +Abspeichern eines Speicherinhaltes als UDOS-Procedure-Datei (lokales System) +(ueber "remote"-Programm des lokalen Systems) + +Kommandoeingabe: RS filename []offset1 offset2 [E=Entry_point] + [RL=Record_length] + (Dateiname Anfangsadresse Endadresse Eintrittspunkt + Recordlaenge) + (Segmentnummer implizit PC_SEG, + Eintrittspunkt implizit Anfangsadresse, + Recordlaenge implizit %100) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + RM_SAVE procedure + entry + setb FLAG0, #0 !Abschalten von xoff! + +!Auswertung der eingegebenen Parameter! +! PC_SEG := Anfangsadresse (Segmentnummer) + r9 := Anfangsadresse (Offset) + r11 := Bytezahl + r10 := Entry Point + r13 := Record Length! + call GET_SIGN !INPTR zeigt auf 2. Zeichen des Dateinamens! + jp z, ERROR !kein Dateinamen angegeben! + ld r2, INPTR + dec r2, #1 !r2 zeigt auf 1. Zeichen des Dateinamens! + lda r2, INBFF(r2) !r2 := Adresse des Dateinamens! + ld FILENAME_PTR, r2 !Adresse des Dateinamens merken! + + call GET_SIGN !rl0 := 1. Zeichen der Anfangsadresse! + jp z, ERROR !keine Anfangsadresse angegeben! + call GET_ADR !rr2 := angegebene Anfangsadresse / + rl0 := 1. Zeichen der Endadresse! + ldl rr8, rr2 !rr8 := angegebene Anfangsadresse! + jp z, ERROR !keine Offsetadresse oder kein weiterer + Parameter angegeben! + + call GET_ADR !r3 := angegebene Endadresse / + rl0 := 1. Zeichen des naechsten Parameters! + ldctlb rh0, FLAGS !Stand Z-Flag retten! + sub r3,r9 + jp c, ERROR !Endadresse < Anfangsadresse! + inc r3 + ld r11, r3 !r11:=Bytezahl! + ld r10, r9 !impliziter Wert fuer Entry Point = Anf.-Adr.! + ld r13, #%100 !impliziter Wert fuer Record length! + bitb rh0, #6 !Z-Flag testen! + jr nz, RSAVE_PAR2 !kein weiterer Parameter angegeben! + + cpb rl0, #'E' + jr nz, RSAVE_PAR1 !keine Entry Point-Angabe! + call GET_CHR + cpb rl0, #'=' + jp nz, ERROR !falsche Entry Point-Angabe! + call GET_SIGNW !rl0:=1. Zeichen der Entry Point-Adresse! + jp z, ERROR !keine Entry Point-Adresse angegeben (CR)! + call GET_HEXZ !r3 := angegebener Entry Point, + rl0 := 1. Zeichen der Record Length-Angabe! + ld r10, r3 !r10 := angegebener Entry Point! + jr z, RSAVE_PAR2 !keine Recordlaenge angegeben! +RSAVE_PAR1: + cpb rl0, #'R' + jp nz, ERROR !keine Record Length-Angabe! + call GET_CHR + cpb rl0, #'L' + jp nz, ERROR !falsche Record Length-Angabe! + call GET_CHR + cpb rl0, #'=' + jp nz, ERROR !falsche Record Length-Angabe! + call GET_SIGNW !rl0:=1. Zeichen der Recordlaengenzahl! + jp z, ERROR !keine Recordlaengenzahl angegeben (CR)! + call GET_HEXZ !r3 := angegebener Recordlaenge! + ld r13, r3 !r13 := angegebene Recordlaenge! +RSAVE_PAR2: + push @r15, PC_SEG + ld PC_SEG, r8 !Segmentnummer merken! + +!Startmeldung (SOH, ESC, 'L') an local senden! + ldb rl0, #SOH + sc #SC_TYWR + ldb rl0, #ESC + sc #SC_TYWR + ldb rl0, #'L' + sc #SC_TYWR + sc #SC_TYRD !acknowledge! +!Ausgabe Filetyp an local! + ldb rl0, #FILETYP + sc #SC_TYWR + sc #SC_TYRD !acknowledge! +!Ausgabe Dateinamen an local! + ldb rh1, #10 !retries! +RSAVE_OPEN1: !Schleife: Ausgabe des Blockes mit dem + Dateinamen! + ldb rl1, #0 !Checksumme init! + ld r12, FILENAME_PTR !Anfangsadr. des Dateinamens in INBFF! + ldb rl0, #STX !Start of Text! + sc #SC_TYWR +RSAVE_OPEN2: !Schleife: Ausgabe der Zeichen des Dateinamens! + ldb rl0 ,@r12 !Zeichen von filename! + inc r12, #1 + cpb rl0, #' ' !ende filename ?! + jr z, RSAVE_OP1 !ja! + cpb rl0, #CR !ende filename ?! + jr z, RSAVE_OP1 !ja! + xorb rl1, rl0 !Checksumme berechnen! + sc #SC_TYWR + jr RSAVE_OPEN2 +RSAVE_OP1: + ldb rl0, #ETX !end of text! + sc #SC_TYWR + exb rl0, rl1 + sc #SC_TYWR !Checksumme ausgeben! + sc #SC_TYRD !Warten auf Quittung! + resb rl3, #7 + cpb rl3, #ACK + jr z, RSAVE_DESCR !filename richtig uebertragen! + cpb rl3, #CAN !Abbrechen ?! + jp z, RSAVE_ERROR !ja! + dbjnz rh1, RSAVE_OPEN1 !naechster Versuch! + jp RSAVE_ERROR !Abbruch! + +!UDOS-Dateidescriptor in OUTBFF aufbauen! +RSAVE_DESCR: + ld r4, #OUTBFF !OUTBFF loeschen! + ld r2, #OUTBFF+2 + ld r1, #%3F + ld @r4, #0 + ldir @r2, @r4, r1 + ld r1, #0 !Magic-Nr. im Descriptor abspeichern + (wird von remote-Programm benoetigt)! + ldb OUTBFF(r1), #%D6 + inc r1, #1 + ldb OUTBFF(r1), #%07 + ld r1, #%0C !Dateityp im Descriptor abspeichern! + ldb OUTBFF(r1), #%80 + ld r1, #%0F !Recordlaenge im Descriptor abspeichern! + ld r5, r13 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%14 !Entry Point im Descriptor abspeichern! + ld r5, r10 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%28 !Anfangsadresse im Descriptor abspeichern! + ld r5, r9 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%2A !Laenge im Descriptor abspeichern! + ld r5, r11 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%7A !LOW_ADDRESS im Descriptor abspeichern! + ld r5, r9 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%7C !HIGH_ADDRESS im Descriptor abspeichern! + ld r5, r9 + add r5, r11 + dec r5, #1 + ldb OUTBFF(r1), rl5 + inc r1, #1 + ldb OUTBFF(r1), rh5 + ld r1, #%7E !STACK_SIZE im Descriptor abspeichern! + ldb OUTBFF(r1), #%80 + inc r1, #1 + ldb OUTBFF(r1), #%00 + +!UDOS-Dateidescriptor (Laenge %80 Byte) aus OUTBFF senden! + ld r12, #OUTBFF !Speicheranfangsadresse fuer Dateidescriptor! + ld r13, #%80 !Laenge des Dateidescriptors! +RSAVE_DESCR1: !Schleife: Schreiben eines Blockes! + ldb rh1, #10 !retries! +RSAVE_DESCR2: !Schleife: Wdhl. des Schreibens eines Blockes! + ldb rl1, #0 !Checksumme init! + ld r8, r12 !Stand r12/r13 fuer den Fall einer! + ld r10, r13 !Wiederholung eines Blockes retten! + ldb rl0, #STX !STX senden! + sc #SC_TYWR !Start of text! + ld r2, #BLOCKLEN !Blocklaenge berechnen! + sub r13, r2 !r13 := restliche Datenanzahl! + jr nc, RSAVE_DES1 !Datenanzahl >= BLOCKLEN + --> Blocklaenge (r2) := BLOCKLEN! + ld r2, r10 !Datenanzahl < BLOCKLEN + --> Blocklaenge (r2) := Datenanzahl! + ld r13, #0 !restl. Datenanzahl := 0! +RSAVE_DES1: + ldb rl0, rh2 !Blocklaenge senden! + sc #SC_TYWR + ldb rl0, rl2 + sc #SC_TYWR +RSAVE_DESCR3: !Scheife: Ausgabe aller Daten eines Blockes! + ldb rl0, @r12 + xorb rl1, rl0 !Checksumme berechnen! + sc #SC_TYWR !Datenbyte senden! + inc r12, #1 + djnz r2, RSAVE_DESCR3 !naechstes Datenbyte senden! + ldb rl0, #ETX !ETX senden! + sc #SC_TYWR + ldb rl0, rl1 !Checksumme senden! + sc #SC_TYWR + sc #SC_TYRD !acknowledge! + cpb rl3, #ACK + jr nz, RSAVE_DES3 + test r13 + jr z, RSAVE_DATEI !Descriptor vollst. ausgegeben! + jr RSAVE_DESCR1 !naechsten Block senden! +RSAVE_DES3: + cpb rl3, #CAN + jr z, RSAVE_ERROR !Abbruch! + decb rh1, #1 + jr z, RSAVE_ERROR !Wiederholungszaehler=0-->Abbruch! + ld r12, r8 !r12/r13 auf Wert vor der Blockuebertragung! + ld r13, r10 !setzen! + jr RSAVE_DESCR2 !Wiederholung der Blockuebertragung! + +!alle Bloecke mit den Daten der Datei senden! +RSAVE_DATEI: + !r9 enthaelt Speicheranfangsadresse fuer Dateidaten! + !r11 enthaelt Bytezahl! +RSAVE_DATEI1: !Schleife: Schreiben eines Blockes! + ldb rh1, #10 !retries! +RSAVE_DATEI2: !Schleife: Wdhl. des Schreibens eines Blockes! + ldb rl1, #0 !Checksumme init! + ld r8, r9 !Stand r9/r11 fuer den Fall einer! + ld r10, r11 !Wiederholung eines Blockes retten! + ldb rl0, #STX !STX senden! + sc #SC_TYWR !Start of text! + ld r2, #BLOCKLEN !Blocklaenge berechnen! + sub r11, r2 !r11 := restliche Datenanzahl! + jr nc, RSAVE_DAT1 !Datenanzahl >= BLOCKLEN + --> Blocklaenge (r2) := BLOCKLEN! + ld r2, r10 !Datenanzahl < BLOCKLEN + --> Blocklaenge (r2) := Datenanzahl! + ld r11, #0 !restl. Datenanzahl := 0! +RSAVE_DAT1: + ldb rl0, rh2 !Blocklaenge senden! + sc #SC_TYWR + ldb rl0, rl2 + sc #SC_TYWR +RSAVE_DATEI3: !Scheife: Ausgabe aller Daten eines Blockes! + push @r15, r8 + ld r8, PC_SEG + sc #SC_SEGV + ldb rl0, @r8 !Datenbyte aus Speicher lesen (segmentiert)! + sc #SC_NSEGV + pop r8, @r15 + xorb rl1, rl0 !Checksumme berechnen! + sc #SC_TYWR !Datenbyte senden! + inc r9, #1 + djnz r2, RSAVE_DATEI3 !naechstes Datenbyte senden! + ldb rl0, #ETX !ETX senden! + sc #SC_TYWR + ldb rl0, rl1 !Checksumme senden! + sc #SC_TYWR + sc #SC_TYRD !acknowledge! + cpb rl3, #ACK + jr nz, RSAVE_DAT3 + test r11 + jr z, RSAVE_END !Datei vollst. ausgegeben! + jr RSAVE_DATEI1 !naechsten Block senden! +RSAVE_DAT3: + cpb rl3, #CAN + jr z, RSAVE_ERROR !Abbruch! + decb rh1, #1 + jr z, RSAVE_ERROR !Wiederholungszaehler=0-->Abbruch! + ld r9, r8 !r9/r11 auf Wert vor der Blockuebertragung! + ld r11, r10 !setzen! + jr RSAVE_DATEI2 !Wiederholung der Blockuebertragung! + +!Uebertragungsfehler! +RSAVE_ERROR: + ld r2, #TXT_ABO + sc #SC_WR_MSG !Textausgabe! + +!Ende! +RSAVE_END: + ldb rl0, #CAN !Abbruch senden! + sc #SC_TYWR + sc #SC_TYRD + resb FLAG0, #0 + pop PC_SEG, @r15 + ret + end RM_SAVE + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE RM_QUIT +QUIT-Routine "Lokales System" (Monitorkommando) +Rueckkehr in lokales System (local Mode) - +U8000-Softwaremonitor (16-Bit-Teil) bleibt aktiv + +Kommandoeingabe: RQ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + RM_QUIT procedure + entry +!Quit-Meldung (SOH, ESC, 'Q') an local senden! + ldb rl0, #SOH + sc #SC_TYWR + ldb rl0, #ESC + sc #SC_TYWR + ldb rl0, #'Q' + sc #SC_TYWR + sc #SC_TYRD !acknowledge! + ret + end RM_QUIT + +end p_gesa + diff --git a/WEGA/src/cmd/standalone/sa.diags/p.ldsd.s b/WEGA/src/cmd/standalone/sa.diags/p.ldsd.s new file mode 100644 index 0000000..02278a2 --- /dev/null +++ b/WEGA/src/cmd/standalone/sa.diags/p.ldsd.s @@ -0,0 +1,1431 @@ +!****************************************************************************** +******************************************************************************* + + P8000-Firmware (C) ZFT/KEAW Abt. Basissoftware - 1989 + U8000-Softwaremonitor (MON16) Modul: p_ldsd + + Bearbeiter: J. Zabel + Datum: 04.05.1989 + Version: 3.1 + +******************************************************************************* +******************************************************************************! + +!============================================================================== +Inhaltsuebersicht Modul p_ldsd +------------------------------ +Dieser Modul umfasst die Monitorroutinen fuer die Arbeit mit dem +LOAD/SEND-System (Kopplung mit MCZ bzw. anderen Systemen, auf dem LOAD/SEND +zur Verfuegung steht (z.B. P8000-UDOS oder P8000-WEGA)) - (LOAD,SEND,QUIT). + +Als serieller Kanal (SI) wird der SIO0_PortA benutzt, d.h. dieser Kanal ist +mit dem Terminalein-/-ausgang des MCZ zu verbinden. Auf der MCZ-Systemdiskette +muessen die Kommandos "LOAD" und "SEND" verfuegbar sein oder es muss auf dem +MCZ ein entsprechendes Programm laufen, das LOAD und SEND realisiert. + +I----------I I-------------I I-------------I +I I I I I MCZ/RIO I +I Terminal I -------- (T)I P8000/MON16 I(SI) -------- (T)I P8000/UDOS I +I I I I I P8000/WEGA I +I----------I I-------------I I-------------I + +(T) - Terminalein-/-ausgang + +Prozeduren +---------- +QUIT + +LOAD +MCZ_INT +MCZ_ERR +INCPTR_MCZ +TYWR_MCZ +WR_OUTBFF_CR_MCZ +WR_OUTBFF_MCZ +IN_POI_IB +EKBL +EKTB_PST +EKBY_PSB +LDB_MEM +EKLA +SAW_MCZ +WOEOI_MCZ +WOEOS_MCZ +WOCF_MCZ +WOCF_MCZ_OI +F_IB_MCZ +O_FIB_MCZ +S_RPB +S_LAB +S_SNB + +SEND +MIOB_CON +==============================================================================! + + +p_ldsd module + +$SECTION PROM + +!anfang mon16.include! +!****************************************************************************** +allgemeine Vereinbarungen (Stand: 13.04.1989) +******************************************************************************! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +externe Prozeduren und Marken +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + EXTERNAL +INIT_CTC0_0 procedure !Modul p_init! +INIT_CTC0_1 procedure !Modul p_init! +INIT_SIO0_A procedure !Modul p_init! +INIT_SIO0_B procedure !Modul p_init! +CMDLOP procedure !Modul p_init! +ERROR procedure !Modul p_init! +NMI_INT procedure !Modul p_init! + +PTY_INT procedure !Modul p_term! +PTY_ERR procedure !Modul p_term! +KOPPEL_INT procedure !Modul p_term! +INCPTR procedure !Modul p_term! +TYRD procedure !Modul p_term! +TYWR procedure !Modul p_term! +TYRD_UDOS_INT procedure !Modul p_term! +TYRD_UDOS_POL procedure !Modul p_term! +TYWR_UDOS_INT procedure !Modul p_term! +TYWR_UDOS_POL procedure !Modul p_term! +TYWR_KOPPEL_INT procedure !Modul p_term! +TYWR_KOPPEL_POL procedure !Modul p_term! +KP_OUTB procedure !Modul p_term! +KP_INB procedure !Modul p_term! +RD_LINE_BFF procedure !Modul p_term! +RD_LINE_INBFF procedure !Modul p_term! +WR_CRLF procedure !Modul p_term! +WR_MSG procedure !Modul p_term! +WR_OUTBFF_CR procedure !Modul p_term! +WR_OUTBFF procedure !Modul p_term! +HTOB procedure !Modul p_term! +BTOH16 procedure !Modul p_term! +BTOH8 procedure !Modul p_term! +GET_CHR procedure !Modul p_term! +GET_SIGN procedure !Modul p_term! +GET_SIGNW procedure !Modul p_term! +GET_SGNR procedure !Modul p_term! +GET_HEXZ procedure !Modul p_term! +GET_ADR procedure !Modul p_term! +GET_PAR procedure !Modul p_term! +RD_DATA procedure !Modul p_term! +GET_DATA procedure !Modul p_term! +WR_R5_RDDATA procedure !Modul p_term! +WR_OBF_RDDATA procedure !Modul p_term! +PUT_CHR procedure !Modul p_term! +PUT_3C procedure !Modul p_term! +PUT_2CHR procedure !Modul p_term! +PUT_SEGNR procedure !Modul p_term! +PUT_SGNR procedure !Modul p_term! + +DISPLAY procedure !Modul p_comm! +COMPARE procedure !Modul p_comm! +FILL procedure !Modul p_comm! +MOVE procedure !Modul p_comm! +PORT_READ procedure !Modul p_comm! +PORT_WRITE procedure !Modul p_comm! +PORT_READ_SPECIAL procedure !Modul p_comm! +PORT_WRITE_SPECIAL procedure !Modul p_comm! +HARD_DISK_READ procedure !Modul p_comm! +HARD_DISK_WRITE procedure !Modul p_comm! +FLOPPY_FORMAT procedure !Modul p_comm! +FLOPPY_READ procedure !Modul p_comm! +FLOPPY_WRITE procedure !Modul p_comm! + +REGISTER procedure !Modul p_brk! +SAVREG procedure !Modul p_brk! +BREAK procedure !Modul p_brk! +GO procedure !Modul p_brk! +GO_NXT procedure !Modul p_brk! +NEXT procedure !Modul p_brk! +RETI_CTC0_3 procedure !Modul p_brk! + +TEST_ procedure !Modul p_test! + +GET procedure !Modul p_gesa! +SAVE procedure !Modul p_gesa! +QUIT8 procedure !Modul p_gesa! +QUIT8_RESET procedure !Modul p_gesa! +FLOPPY procedure !Modul p.gesa! +RM_GET procedure !Modul p_gesa! +RM_SAVE procedure !Modul p_gesa! +RM_QUIT procedure !Modul p_gesa! + +QUIT procedure !Modul p_ldsd! +LOAD procedure !Modul p_ldsd! +MCZ_INT procedure !Modul p_ldsd! +MCZ_ERR procedure !Modul p_ldsd! +TYWR_MCZ procedure !Modul p_ldsd! +WOCF_MCZ procedure !Modul p_ldsd! +SEND procedure !Modul p_ldsd! + +OS_BOOT procedure !Modul p_boot! +AUTOBOOT procedure !Modul p_boot! + +DISK procedure !Modul p_disk! + +MON16_1H word !Modul p.crc! +N_MON16_1H word !Modul p.crc! +MON16_1L word !Modul p.crc! +N_MON16_1L word !Modul p.crc! +MON16_2H word !Modul p.crc! +N_MON16_2H word !Modul p.crc! +MON16_2L word !Modul p.crc! +N_MON16_2L word !Modul p.crc! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Werte aus dem Arbeitsspeicher (Modul p_ram) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + EXTERNAL +RAM_ANF ARRAY [%10 WORD] +NSP_OFF WORD + ARRAY [%3F WORD] !Stackbereich! +STACK WORD + ARRAY [4 WORD] +_numterm WORD !Anzahl der Terminals! +PTYPORT BYTE !Terminalkanal: + 00 - SIO0_B (16-Bit-Teil) + 01 - SIO0_B (8-Bit-Teil) ueber + Koppelschnittstelle! +XEMPTY BYTE !fuer interruptgesteuerten Terminal- + betrieb ueber Koppelschnittstelle: + 00 - Sendepuffer SIO0_B (8-Bit-Teil) + leer + FF - Sendepuffer SIO0_B (8-Bit-Teil) + nicht leer! + BYTE +KONV BYTE !Hilfsbyte zur Konvertierung! +INBFF ARRAY [%80 BYTE] !Eingabepuffer! +OUTBFF ARRAY [%80 BYTE] !Ausgabepuffer! +PTYBFF ARRAY [%100 BYTE] !Eingabepuffer fuer interrupt- + gesteuerte Eingabe vom Terminal- + kanal! +MCZBFF ARRAY [%0EA BYTE] !Ein-/Ausgabepuffer fuer LOAD/SEND! +MAXLEN WORD !maximale Zeilenlaenge! +INPTR WORD !Zeiger fuer Eingabepuffer INBFF! +OUTPTR WORD !Zeiger fuer Ausgabepuffer OUTBFF + (Pufferlaenge)! +COUNT_PTY WORD !aktuelle Anzahl der Zeichen in PTYBFF! +INPTR_PTY WORD !Eingabezeiger fuer PTYBFF + (naechster freier Platz)! +OUTPTR_PTY WORD !Ausgabezeiger fuer PTYBFF + (naechstes auszulesende Zeichen)! +INPTR_MCZ WORD !Eingabezeiger fuer MCZBFF! +OUTPTR_MCZ WORD !Ausgabezeiger fuer MCZBFF! +B_WORD WORD !Speicherinhalt auf der BREAK-Adresse! +B_ADR_S WORD !Segmentnummer der BREAK-Adresse! +B_ADR_O WORD !Offset der BREAK-Adresse! +RR14_V LONG !VARIABLER STACK, FUER NEXT UND BREAK! +W23B4 WORD +FCW_V WORD !VARIABLES FCW FUER NEXT UND BREAK! +PORT_BF WORD !Puffer fuer gelesenen bzw. zu + schreibenden PORT-Datenwert! +PORT_IO WORD !Adresse des PORT-I/O-Programms! + WORD !unbenutzt! +SV_R ARRAY [14 WORD] !Registerrettungsbereich! +SVSTK LONG +PC_SEG WORD !Programmcounter (Segmentnummer)! +PC_OFF WORD !Programmcounter (Offsetadresse)! +FCW_ WORD !FCW im Registerrettungsbereich! +RF_CTR WORD !Merker: Refresh Control Register! +N4_ WORD !Normalstack R14! +N5_ WORD !Normalstack R15! +PS_ WORD !Program-Status-Area Segment! +PO_ WORD !Program-Status-Area Offset! + WORD !unbenutzt! +!Flags! +FLAG0 BYTE +FLAG1 BYTE +!Variablen (initialisiert bei Systemstart)! +CHRDEL BYTE !Zeichen loeschen (Backspace %08)! +LINDEL BYTE !Zeile loeschen (Line delete %7F)! +XONCHR BYTE !Terminalausgabe fortsetzen (^Q %11)! +XOFCHR BYTE !Terminalausgabe anhalten (^S %13)! +NULLCT WORD !Anzahl der Nullen nach CR bei Terminalausgabe (%0000)! +B_CODE WORD !Unterbrechungscode Z8000 (7F00)! +STKCTR WORD !Zaehler der Stackoperationen fuer NEXT (%0004)! +NXTCTR WORD !SCHRITTZAEHLER FUER NEXT (%0001)! +PROMT WORD !Promt-Zeichen (%2000)! +!---------------------------------------------------! +!Program Status Area (initialisiert bei Systemstart)! +PSAREA +! ID FCW PCSEG PCOFF! + ARRAY [4 WORD] !:= [%0000 %0000 %0000 %0000] + RESERVED! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + UNIMLEMENTED INSTRUCTIONS! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + PRIVILEGED INSTRUCTIONS! +PSA_SC ARRAY [4 WORD] !:= [%0000 %C000 %8000 SC_ENTRY] + SYSTEM_CALL INSTRUCTIONS! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 MMU_ERR] + SEGMENT TRAP! +PSA_NMI ARRAY [4 WORD] !:= [%0000 %4000 %8000 AUTOBOOT bzw. NMI_INT] + NONMASKABLE INTERRUPT + (AUTOBOOT vor erster Terminaleingabe; + NMI_INT nach erster Terminaleingabe)! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + NONVECTORED INTERRUPT! +! VECTORED INTERRUPT! + ARRAY [2 WORD] !:= [%0000 %4000] + VECTORED INTERRUPT (ID, FCW)! +! VI - Sprung-Tabelle (128 Eintraege) ! +! SEG OFFSET! +!CTC0! +VI_CTC0_0 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_1 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_2 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_3 ARRAY [2 WORD] !:= [%8000 VI_ERR bzw. GO_INT bzw. NXT_INT] + fuer GO bzw. NEXT! +!PIO1! +VI_PIO1_B ARRAY [2 WORD] !:= [%8000 KOPPEL_INT] + VI Zeichen empfangen (von Koppelschnittstelle)! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +!SIO0! +VI_SIO0_B ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 PTY_INT] + VI Zeichen empfangen (fuer Terminaleingabe)! + ARRAY [2 WORD] !:= [%8000 PTY_ERR] + VI Empfangssonderfall (fuer Empfangsfehler)! +VI_SIO0_A ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 MCZ_INT] + VI Zeichen empfangen (fuer MCZ-Eingabe)! + ARRAY [2 WORD] !:= [%8000 MCZ_ERR] + VI Empfangssonderfall (fuer Empfangsfehler)! +! Rest der 128 Eintraege der VI-Sprung-Tabelle! +VI_TAB_REST ARRAY [224 WORD] !:= [%8000 VI_ERR] ! +!---------------------------------------------------! + +!Arbeitsspeicher fuer Kommando "T" (Hardwareeigentest)! +RG_FELD ARRAY [%1A WORD] !Feld zur Registerrettung! +REM_MMU_BCSR BYTE !Merker: Inhalt BUS CYCLE STATUS REGISTER! +REM_MMU_VTR BYTE !Merker: Inhalt VIOLATION TYPE REGISTER! +REM_MMU_ID WORD !Merker: MMU-Identifikation! +REM_ERR_CNT WORD !Merker: Stand Fehlerzaehler! +REM_SEGMENT_TRAP WORD !Merker: urspruengliche Offsetadresse fuer Segmenttrap! +REM_PRIVINSTR_TRAP WORD !Merker: urspruengl. Offsetadr. fuer Priv.-Instr.-Trap! +REM_MMU_SINOUT WORD !Merker: MMU-Ein-/Ausgabewerte! +ERR_CNT WORD !Fehlerzaehler! +ERR_WDC WORD !Fehlerzaehler fuer WDC-Test! +MAX_SEGNR WORD !Merker: hoechste vorhandene Segmentnummer! +REM_PARNMI WORD !Merker: Paritaets-NMI aufgetreten + (%0000-->nein / %FFFF-->ja)! +ERRPAR_ID WORD !Spezifizierung der 4 Parameter der auszugebenden + Fehlerzeile (Prozedur MSG_ERROR)! +REM_MMU1 WORD +REM_MMU2 WORD +REM_INT WORD !Merker: Interrupt aufgetreten (0-->nein)! +REM_WDC1 WORD !Speicherplatz fuer Testdatenwert! +REM_WDC2 WORD !Speicherplatz fuer rueckgelesenen datenwert! + +!Arbeitsspeicher fuer Kommandos "GE"/"S"/"O U" und Floppytreiber! +FILENAME_PTR WORD !Anfangsadresse Dateiname! +COUNT_UDOS WORD !akt. Anzahl der Zeichen in UDOSBFF! +INPTR_UDOS WORD !Eingabezeiger fuer UDOSBFF + (naechster freier Platz)! +OUTPTR_UDOS WORD !Ausgabezeiger fuer UDOSBFF + naechstes auszulesende Zeichen)! +UDOSBFF ARRAY [%100 BYTE] !Eingabepuffer fuer interrupt- + gesteuerte Eingabe bei Dateitransfer + von/zu UDOS bzw. Blocktransfer! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +System Calls +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +SC_SEGV := %01 !Modul p.term! +SC_NSEGV := %02 !Modul p.term! +SC_TYRD := %04 !Modul p.term! +SC_TYWR := %06 !Modul p.term! +SC_RD_LINE_BFF := %08 !Modul p.term! +SC_WR_CRLF := %0A !Modul p.term! +SC_WR_MSG := %0C !Modul p.term! +SC_BTOH16 := %0E !Modul p.term! +SC_WR_OUTBFF_CR := %10 !Modul p.term! +SC_BTOH8 := %12 !Modul p.term! +SC_PUT_SEGNR := %14 !Modul p.term! +SC_PUT_CHR := %16 !Modul p.term! +SC_WOCF_MCZ := %18 !Modul p.ldsd! +SC_TYWR_MCZ := %1A !Modul p.ldsd! +SC_CMDLOP := %1C !Modul p.init! +SC_DISK := %1E !Modul p.disk! +SC_TYRD_UDOS_INT := %20 !Modul p.term! +SC_TYWR_UDOS_INT := %22 !Modul p.term! +SC_FLOPPY := %24 !Modul p.gesa! +SC_WR_OUTBFF := %26 !Modul p.term! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +spezielle ASCII-Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +SOH := %01 +STX := %02 +ETX := %03 +EOT := %04 +ACK := %06 +BEL := %07 +BS := %08 +LF := %0A +CR := %0D +NAK := %15 +CAN := %18 +ESC := %1B + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Hardwareadressen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT + +!8-Bit-Teil! + +SIO0D_B_8 := %26 !SIO fuer Terminal! +SIO0C_B_8 := %27 + +!16-Bit-Teil! + +SIO0 := %FF81 !Kanal A (XB1/TTY4): unbenutzt (vorher LOAD/SEND/QUIT); + Kanal B (XB2/TTY5): Terminal, wenn 8-Bit-Teil inaktiv! +SIO0D_A := SIO0 + 0 +SIO0D_B := SIO0 + 2 +SIO0C_A := SIO0 + 4 +SIO0C_B := SIO0 + 6 + +SIO1 := %FF89 !Kanal A (XB3/TTY6): unbenutzt + Kanal B (XB4/TTY7): unbenutzt! +SIO1D_A := SIO1 + 0 +SIO1D_B := SIO1 + 2 +SIO1C_A := SIO1 + 4 +SIO1C_B := SIO1 + 6 + +PIO0 := %FF91 !Koppel-PIO zum 8-Bit-Teil + fuer Terminal und Kommandos "GE", "S", + "Q", "QRES", "O U" und Floppytreiber + Kanal A: Datenausgabe + Kanal B: Statusausgabe/Steuerport! +PIO0D_A := PIO0 + 0 +PIO0D_B := PIO0 + 2 +PIO0C_A := PIO0 + 4 +PIO0C_B := PIO0 + 6 + +PIO1 := %FF99 !Koppel-PIO zum 8-Bit-Teil + fuer Terminal und Kommandos "GE", "S", + "Q", "QRES", "O U" und Floppytreiber + Kanal A: Dateneingabe + Kanal B: Statuseingabe/Steuerport! +PIO1D_A := PIO1 + 0 +PIO1D_B := PIO1 + 2 +PIO1C_A := PIO1 + 4 +PIO1C_B := PIO1 + 6 + +PIO2 := %FFA1 !(XB5): Winchester + Kanal A: Datenein-/-ausgabe; Kanal B: Steuerport! +PIO2D_A := PIO2 + 0 +PIO2D_B := PIO2 + 2 +PIO2C_A := PIO2 + 4 +PIO2C_B := PIO2 + 6 + +CTC0 := %FFA9 +CTC0_0 := CTC0 + 0 ! Baud 0 - SIO0, Kanal A! +CTC0_1 := CTC0 + 2 ! Baud 1 - SIO0, Kanal B! +CTC0_2 := CTC0 + 4 ! Baud 2 - SIO1, Kanal A! +CTC0_3 := CTC0 + 6 ! Next ! + +CTC1 := %FFB1 +CTC1_0 := CTC1 + 0 ! Baud 3 - SIO1, Kanal B! +CTC1_1 := CTC1 + 2 +CTC1_2 := CTC1 + 4 +CTC1_3 := CTC1 + 6 + +LON := %FFD9 !RUN16-Lampe ein! +LOFF := %FFB9 !RUN16-Lampe aus! + +S_BNK := %FFC1 !SWITCH-BANK: + Bit0-3 Ausgabebits; Bit4-7 Eingabebits (DIL-Schalter): + Bit 0: =0 - Monitor PROM+RAM einschalten + =1 - Monitor PROM+RAM ausschalten + Bit 1: =0 - MMU's ausschalten; =1 - MMU's einschalten + Bit 2: Seg. Usr. + Bit 3: =0 - Paritaetspruefung ausgeschaltet bzw. + Paritaetsfehler loeschen + =1 - Paritaetspruefung eingeschaltet + Bit 5,4: Baudrate Terminal (unbenutzt) + Bit 7,6: Autoboot Device (unbenutzt)! + +SBREAK := %FFC9 !System Break Register! +NBREAK := %FFD1 !Normal Break Register! +RETI_P := %FFE1 !RETI-Port fuer Schaltkreise des U880-Systems! + +ALL_MMU := %F0 +STACK_MMU := %F6 +DATA_MMU := %FA +CODE_MMU := %FC + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Moegliche Statusausgaben an 8-Bit-Teil von 16-Bit-Teil +fuer 8-Bit-/16-Bit-Koppelschnittstelle (PIO0_B) +(INT8-Bit jeweils = 0) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +STAT8_ENDE := %00 !Ende eines Write-Requests! +STAT8_READ := %02 !Read-Request an einen Peripheriebaustein 8-Bit-Teil! +STAT8_WRITE := %04 !Write-Request an einen Peripheriebaustein 8-Bit-Teil! + +STAT8_UDOS := %10 !Datenbyte ist Bestandteil eines Dateitransfers + bzw. eines Blocktransfers von/zu UDOS! +STAT8_QUIT := %1E !Rueckkehr zum 8-Bit-Teil (Datenbyte "Q" oder "R")! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Moegliche Statuseingaben von 8-Bit-Teil an 16-Bit-Teil +fuer 8-Bit-/16-Bit-Koppelschnittstelle (PIO1_B) +(INT16-Bit jeweils = 0) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +STAT16_ENDE := %00 !Beantwortung eines Read-Requests! + +STAT16_SIO0_B_R := %04 !REC INT (SIO0_B-Empfaengerinterrupt)! +STAT16_SIO0_B_X := %24 !TRANS INT (SIO0_B-Interrupt Sendepuffer leer)! +STAT16_SIO0_B_E := %44 !EXT STAT INT (SIO0_B-Externer-Statusinterrupt)! +STAT16_SIO0_B_S := %64 !SPEC REC INT (SIO0_B-Interrupt Empfangssonderfall)! + +STAT16_UDOS := %10 !Datenbyte ist Bestandteil eines Dateitransfers + bzw. eines Blocktransfers von/zu UDOS! +!ende mon16.include! + + +!****************************************************************************** +Prozeduren +******************************************************************************! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE QUIT +QUIT-Routine "MCZ" (Monitorkommando) +Uebergang vom Monitor-Mode in Transparent-Mode, d.h. in das Betriebssystem des +MCZ (P8000-Terminal arbeitet dann als Terminal fuer dss MCZ) + +Kommandoeingabe: QUIT +- im Eingabepuffer PTYBFF (Terminal) eingehende Zeichen werden an das MCZ + gesendet +- vom MCZ eingehende Zeichen werden auf dem Terminal ausgegeben +Verlassen der Routine ueber NMI-Taste +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + QUIT procedure + entry + clr INPTR_MCZ !Loeschen Eingabezeiger MCZBFF! + clr OUTPTR_MCZ !Loeschen Ausgabezeiger MCZBFF! + setb FLAG0, #%00 !kein Ruecksetzen Bit 7 bei den vom Terminal + bzw. vom MCZ eingehenden Zeichen (PTYINT bzw. + MCZINT) - (keine ASCII-Zeichen)! +Q1: + testb COUNT_PTY !Zeichen vom Terminal eingegangen?! + jr z, Q2 !nein! + + ld r0, OUTPTR_PTY + call INCPTR + ld OUTPTR_PTY, r0 + ldb rl0, PTYBFF(r2) + decb COUNT_PTY, #%01 + calr TYWR_MCZ !Ausgabe Zeichen an MCZ! + jr nz, Q1 !kein CR ausgegeben! + +Q2: + ld r0, OUTPTR_MCZ + cp r0, INPTR_MCZ !Zeichen vom MCZ eingegangen?! + JR Z, Q1 !nein! + + calr INCPTR_MCZ + ld OUTPTR_MCZ, r0 !Ausgabezeiger incr., d.h. Zeichen abgeholt! + ldb rl0, MCZBFF(r2) + call TYWR !Ausgabe Zeichen an Terminal! + jr Q2 + end QUIT + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE LOAD +LOAD-Routine "MCZ" (Monitorkommando) +Laden eines U8000-Maschinenprogramms vom MCZ in RAM + +Kommandoeingabe: LOAD filename [] + (Dateiname Segmentnummer) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + LOAD procedure + entry + calr IN_POI_IB !filename uebergehen! + push @r15, PC_SEG + call GET_SIGN !rl0:=1.Zeichen ungleich Space nach naechstem + Space im Eingaepuffer INBFF + (1. Zeichen der segnr)! + call GET_SGNR !r2:=angegebene Segmentnummer! + ld PC_SEG, r2 + setb FLAG0, #%04 !ESC wirkt als Abbruchtaste fuer LOAD! + +!'' aus INBFF entfernen (wird von WEGA-Shell als + Dateiumlenkung interpretiert! + ld r2, #INBFF + ld r1, #%80 + ldb rl0, #'<' + cpirb rl0, @r2, r1, eq + jr nz, XL2 ! '<' nicht gefunden ! + dec r2, #1 !r2 zeigt auf Anfang der Segmentangabe! + inc r1, #1 +XL1: ldb rl0, @r2 + cpb rl0, #CR + jr z, XL2 + ldb @r2, #' ' + cpb rl0, #'>' + jr z, XL2 !Ende der Segmentangabe erreicht! + inc r2, #1 + djnz r1,XL1 +XL2: + + calr SAW_MCZ !eingegebene Kommandozeile an MCZ senden und + Antwort abwarten! + jr z, LD5 !Abbruch; Fehlerausschrift vom MCZ wurde auf + Terminal ausgegeben! + +!empfangen eines Datenblockes vom MCZ (in INBFF)! +LD1: + calr F_IB_MCZ !INBFF ab empfangenen Zeichen '/' (aus- + schliesslich) von MCZ fuellen! + ld r2, #INBFF + ldb rl0, @r2 + cpb rl0, #'/' + jr nz, LD2 !erstes Zeichen in INBFF ungleich '/', + d.h. keine Fehlermeldung! + +!Fehlernachricht von MCZ empfangen ('// error_massage CR')! + ld r4, #OUTBFF + ld r1, #%007F + ldir @r4, @r2, r1 !OUTBFF mit Inhalt von INBFF (Fehlernachricht) + fuellen! + ld OUTPTR, #%007F + call WR_OUTBFF !Ausgabe OUTBFF auf Terminal / Loeschen OUTBFF! + jr LD5 !Abbruch! + +LD2: + bitb FLAG0, #%05 + jr nz, LD4 !Abbruchtaste gedrueckt (ESC)! + + calr EKBL + jr nc, LD2A + calr S_RPB + jr LD1 + +LD2A: + ldb rl0, #'.' + call TYWR + testb rh3 + jr nz, LD3 + calr S_SNB + call WR_CRLF + ldl rr0, INBFF + ldl OUTBFF + 12, rr0 + ld r4, #T_EPNT + ld r2, #OUTBFF + ld r1, #%0006 + ldir @r2, @r4, r1 + ld OUTPTR, #%0010 + call WR_OUTBFF_CR + jr LD5 + +LD3: + calr EKLA + PUSH @R15, R4 + LD R4, PC_SEG + RES R4, #15 + TEST R4 + POP R4, @R15 + JR NZ, LD3A + + cp r4, #%8000 !kleinste LOAD-Adresse in Segment 0 + (in Vs. 1.7: %4000)! + jr nc, LD3A + ld r2, #T_ILA + jr LD4A + +LD3A: + calr S_SNB + calr LDB_MEM + jr LD1 + +LD4: + ld r2, #T_ABO +LD4A: + call WR_MSG !AUSGABE : '/ABORT'! + calr S_LAB +LD5: POP PC_SEG, @R15 + ret + end LOAD + + INTERNAL +T_ILA: WORD := %0019 + ARRAY [* BYTE] := '/INCORRECT LOAD ADDRESS %0D%00' +T_ABO: WORD := %0007 + ARRAY [* BYTE] := '/ABORT%0D%00' +T_EPNT: ARRAY [* BYTE] :='ENTRY POINT ' + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE MCZ_INT +VI-Routine fuer MCZ-Eingabe +Abspeicherung des Zeichens im MCZ-Eingabepuffer MCZBFF; +Inkrementieren des Eingabezeigers INPTR_MCZ zur Kennzeichnung, dass ein Zeichen +eingegengen ist +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + MCZ_INT procedure + entry + push @r15, r0 + push @r15, r1 + push @r15, r2 + INB RL1, SIO0D_A !rl1:=eingelesenes Zeichen! + bitb FLAG0, #%00 + jr nz, MCZ1 !keine ASCII-Zeichen einlesen! + + resb rl1, #%07 !Bit 7 des ASCII-Zeichens zuruecksetzen! + +MCZ1: + ld r0, INPTR_MCZ + calr INCPTR_MCZ + ld INPTR_MCZ, r0 !MCZ-Eingabezeiger incr.! + ldb MCZBFF(r2), rl1 !Zeichen im MCZBFF abspeichern! + + ldb rl1, #%38 !RETI AN SIO SENDEN! + OUTB SIO0C_A, RL1 + + pop r2, @r15 + pop r1, @r15 + pop r0, @r15 + sc #SC_SEGV + iret + end MCZ_INT + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE MCZ_ERR +VI-Routine fuer MCZ-Empfangsfehler +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + MCZ_ERR procedure + entry + push @r15, r1 + ldb rl1, #%30 + OUTB SIO0C_A, RL1 !SIO_ERROR_RESET! + ldb rl1, #%38 !RETI AN SIO SENDEN! + OUTB SIO0C_A, RL1 !SIO_RETI_SENDEN! + pop r1, @r15 + sc #SC_SEGV + iret + end MCZ_ERR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE INCPTR_MCZ +Zeichenkettenzeiger inkrementieren und auf Ueberlauf testen +Input: r0 - Zeichenkettenzeiger +Output: r2 := alter Stand Zeichenkettenzeiger (Input-Wert) + r0 := r0+1, wenn C=1 (d.h. r0+1 < %E8) + r0 := 0, wenn C=0 (d.h. r0+1 >= %E8) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + INCPTR_MCZ procedure + entry + ld r2, r0 + inc r0, #%01 + cp r0, #%00E8 + ret c + clr r0 + ret + end INCPTR_MCZ + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYWR_MCZ +Ausgabe eines Zeichens an das MCZ +Input: rl0 - auszugebendes Zeichen +Output: Z=1, wenn Zeichen = CR +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYWR_MCZ procedure + entry + INB RH0, SIO0C_A + bitb rh0, #%02 !TRANSMIT BUFFER EMPTY ? ! + jr z, TYWR_MCZ !NO, WAIT! + OUTB SIO0D_A, RL0 !AUSGABE DES ZEICHENS! + cpb rl0, #CR + ret + end TYWR_MCZ + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_OUTBFF_CR_MCZ +Anhaengen eines CR an Zeichenkette im Ausgabepuffer OUTBFF; +Ausgabe des Inhaltes des Ausgabepuffers OUTBFF an das MCZ +(bis CR, maximal bis OUTPTR); +Loeschen des Ausgabepuffers OUTBFF +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + WR_OUTBFF_CR_MCZ procedure + entry + ld r2, OUTPTR + ldb OUTBFF(r2), #CR + inc OUTPTR, #%01 + end WR_OUTBFF_CR_MCZ !Weiterlauf bei WR_OUTBFF_MCZ! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_OUTBFF_MCZ +Ausgabe des Inhaltes des Ausgabepuffers OUTBFF an das MCZ +(bis CR, maximal bis OUTPTR); +Loeschen des Ausgabepuffers OUTBFF +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + WR_OUTBFF_MCZ procedure + entry + clr r1 +STRO1: + ldb rl0, OUTBFF(r1) + inc r1, #%01 + calr TYWR_MCZ !Ausgabe rl0 an MCZ! + jr z, STRO2 !CR ausgegeben --> Ende! + + cp r1, OUTPTR + jr c, STRO1 !noch nicht alle Zeichen ausgegeben! + +STRO2: + clr OUTPTR !Ausgabepuffer loeschen! + ld r1, #%003F + ld OUTBFF, #' ' + ld r4, #OUTBFF + ld r2, #OUTBFF + 2 + ldir @r2, @r4, r1 + ret + end WR_OUTBFF_MCZ + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE IN_POI_IB +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + IN_POI_IB procedure + entry + clr INPTR_MCZ + clr OUTPTR_MCZ + call GET_SIGN + end IN_POI_IB !Weiterlauf bei EKBL! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE EKBL +Eingabekonvertierung eines LOAD-Blockes +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + EKBL procedure + entry + clr r2 + ldb rh3, #%03 + calr EKTB_PST + ret c + ldb KONV, rl3 + testb rh3 + ret z + push @r15, r3 + calr EKTB_PST + pop r3, @r15 + ret + end EKBL + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE EKTB_PST +Eingabekonvertierung eines LOAD-Teilblockes mit Pruefsummentest +Input: r2 - Zeiger auf aktuelles Zeichen in INBFF + rh3 - Anzahl der einzulesenden Bytes aus INBFF (jedes Byte ist in INBFF + durch 2 ASCII-Zeichen kodiert (z.B. 'A','F' fuer %AF) + (nach der angegebenen Bytezahl muss die Pruefsumme (1 Byte = 2 ASCII- + Zeichen) in INBFF stehen +Output: rl3 - Pruefsumme + rh3 - letztes Byte der angeg. Anzahl (Byte vor Pruefsumme) + C=1, wenn keine Hexaziffer in INBFF bzw. falsche Pruefsumme +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + EKTB_PST procedure + entry + clrb rl3 !Pruefsumme loeschen! +EKTB1: + calr EKBY_PSB !rl0:=eingelesenes Byte aus INBFF! + !rl3:=aktuelle Pruefsumme! + ret c !Fehler: keine Hexaziffer! + dbjnz rh3, EKTB1 !naechstes Byte einlesen! + + ldb rh3, rl0 !rh3:=letztes Byte der angeg. Anzahl! + push @r15, r3 + calr EKBY_PSB !rl0:=aus INBFF eingelesene Pruefsumme! + pop r3, @r15 !r3:=berechnete Pruefsumme! + ret c !Fehler: keine Hexaziffer! + + cpb rl0, rl3 !Pruefsummenvergleich! + ret z !i.O.! + + setflg c !C=1, da Pruefsummenfehler! + ret + end EKTB_PST + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE EKBY_PSB +Eingabekonvertierung eines Bytes aus INBFF mit Pruefsummenberechnung +(in INBFF stehen die Datenbytes ASCII-kodiert, d.h. 1 Byte beansprucht +2 ASCII-Zeichen (z.B. 'A','F' fuer 'AF')) +Input: r2 - Zeiger auf aktuelles Zeichen in INBFF + rl3 - aktueller Stand der Pruefsumme +Output: rl0 - eingelesenes Byte (binaer, =2 ASCII-Zeichen aus INBFF) + rl3 - neue Pruefsumme + r2 - neuer Stand des Zeigers auf aktuelles Zeichen in INBFF + C=1, wenn keine Hexaziffer +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + EKBY_PSB procedure + entry + ldb rl0, INBFF(r2) !rl0:=1. Hexaziffer (ASCII)! + inc r2, #%01 + call HTOB !Konv. rl0 (ASCII) --> rl0 (binaer)! + ret c !keine Hexaziffer (Fehler)! + + addb rl3, rl0 !rl3:=neue Pruefsumme! + sla r0, #%0C + ldb rl0, INBFF(r2) !rl0:=2. Hexaziffer (ASCII)! + inc r2, #%01 + call HTOB !Konv. rl0 (ASCII) --> rl0 (binaer)! + ret c !keine Hexaziffer (Fehler)! + + addb rl3, rl0 !rl3:=neuer Pruefsumme! + orb rl0, rh0 !rl0 := eingelesenes Byte! + resflg c + ret + end EKBY_PSB + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE LDB_MEM +Laden des LOAD-Datenblockes in den Speicher +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + LDB_MEM procedure + entry + ldb rl1, rh3 + calr EKLA + ld r2, #%0008 +LDB_M_NB: + calr EKBY_PSB + + PUSH @R15, R4 + LD R5, R4 + LD R4, PC_SEG + SC #SC_SEGV + LDB @R4, RL0 + SC #SC_NSEGV + POP R4, @R15 + + inc r4, #%01 + dbjnz rl1, LDB_M_NB !LADE NAECHSTES BYTE! + ret + end LDB_MEM + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE EKLA +Eingabekonvertierung der Ladeadresse fuer den LOAD-Datenblock +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + EKLA procedure + entry + clr r2 + calr EKBY_PSB + ldb rh4, rl0 + calr EKBY_PSB + ldb rl4, rl0 + ret + end EKLA + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE SAW_MCZ +Senden einer Zeichenkette (Inhalt von INBFF) zum MCZ und warten auf Antwort +Output: Z=0, wenn Zeichen '9' oder '0' oder '7' vom MCZ empfangen wurde + Z=1, wenn Fehler MCZ bzw. Abbruchtaste (ESC) gedrueckt +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + SAW_MCZ procedure + entry + bitb FLAG0, #%05 + jr z, SAW0 !Abbruchtaste (ESC) nicht gedrueckt! + + setflg z !Z=1, Abbruchtaste gedrueckt! + ret + +SAW0: + ld r4, #OUTBFF + ld r2, #INBFF + ld r1, #%0040 + ldir @r4, @r2, r1 !Umspeicherung INBFF-->OUTBFF! + + ld OUTPTR, #%0080 !Zeilenlaenge OUTBFF = %80! + calr WR_OUTBFF_MCZ !Inhalt OUTBFF an MCZ senden! + + calr WOEOI_MCZ !Warten auf Antwort vom MCZ (bis CR) in MCZBFF! + calr WOCF_MCZ_OI !rl1:=naechstes Zeichen vom MCZ + (kein incr. des MCZ-Ausgabezeigers OUTPTR_MCZ)! + cpb rl1, #'L' + jr z, SAW1 !ECHO VOM MCZ: 'LOAD ...' EMPFANGEN! + jr SAW2 + +SAW1: + calr WOEOI_MCZ !ganze Zeile bis CR von MCZ einlesen! + calr WOCF_MCZ_OI !rl1:=naechstes Zeichen! +SAW2: + cpb rl1, #'9' + jr z, SAW4 + cpb rl1, #'0' + jr z, SAW4 + cpb rl1, #'7' + jr z, SAW4 + +SAW3: + calr WOCF_MCZ !rl0:=Zeichen vom MCZ! + call TYWR !Zeichen auf Terminal ausgeben! + cpb rl0, #LF + ret z !Zeichen=LF --> Ende (Z=1)! + jr SAW3 + +SAW4: + resflg z + ret + end SAW_MCZ + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WOEOI_MCZ +Warten auf das Ende der Information vom MCZ (CR empfangen); +weiter siehe WEOS_MCZ +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + WOEOI_MCZ procedure + entry + calr WOCF_MCZ !rl0:=Zeichen vom MCZ! + cpb rl0, #CR + jr nz, WOEOI_MCZ !Warten auf CR! + end WOEOI_MCZ !Weiterlauf bei WOEOS_MCZ! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WOEOS_MCZ +Warten auf das Ende des Sendens vom MCZ +(Warten auf ein Zeichen >='Space' oder bis Wartezeit abgelaufen) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + WOEOS_MCZ procedure + entry + ld r1, #%0200 !Festlegung der Wartezeit bis zur Bereit- + stellung eines Zeichens in MCZBFF! +WOEOS1: + ld r0, OUTPTR_MCZ !bestimmte Zeit auf ein Zeichen vom MCZ warten! + cp r0, INPTR_MCZ + jr nz, WOEOS2 !Zeichen steht in MCZBFF bereit! + + dec r1, #%01 !Zeitzaehler decr.! + jr nz, WOEOS1 + ret !Wartezeit abgelaufen! + +WOEOS2: + calr WOCF_MCZ_OI !rl1:=Zeichen (OUTPTR_MCZ nicht incr.)! + cpb rl1, #' ' + ret pl !Zeichen >='Space'! + + calr WOCF_MCZ !Zeichen uebergehen! + jr WOEOS_MCZ !Warten auf naechstes Zeichen! + end WOEOS_MCZ + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WOCF_MCZ +Warten, bis ein Zeichen im MCZ-Puffer MCZBFF bereitsteht +(MCZBFF wird durch empfangene Zeichen vom MCZ in MCZ_INT gefuellt) +Output: rl0 - Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + WOCF_MCZ procedure + entry + ld r0, OUTPTR_MCZ + cp r0, INPTR_MCZ + jr z, WOCF_MCZ !kein Zeichen in MCZBFF eingegangen! + +!Zeichen empfangen! + calr INCPTR_MCZ + ld OUTPTR_MCZ, r0 !Ausgabezeiger aktualisieren (Zeichen wurde + abgeholt! + ldb rl0, MCZBFF(r2) !rl0:=Zeichen! + ret + end WOCF_MCZ + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WOCF_MCZ_OI +Warten, bis ein Zeichen im MCZ-Puffer MCZBFF bereitsteht +(ohne Aktualisierung von OUTPTR_MCZ, d.h. Zeichen gilt nach Aufruf von +WOCF_MCZ_OI als noch nicht abgeholt); +(MCZBFF wird durch empfangene Zeichen vom MCZ in MCZ_INT gefuellt) +Output: rl1 - Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + WOCF_MCZ_OI procedure + entry + ld r0, OUTPTR_MCZ + cp r0, INPTR_MCZ + jr z, WOCF_MCZ_OI !kein Zeichen in MCZBFF eingegangen! + + calr INCPTR_MCZ !r2:=OUTPTR_MCZ! + ldb rl1, MCZBFF(r2) !rl1:=Zeichen! + ret + end WOCF_MCZ_OI + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE F_IB_MCZ +Fuellen von INBFF von MCZ nach empfangenen Zeichen '/' bis CR +(max. %50 Zeichen) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + F_IB_MCZ procedure + entry + calr WOCF_MCZ !rl0:=Zeichen von MCZ! + cpb rl0, #'/' + jr nz, F_IB_MCZ !Warten bis Zeichen = '/' eingegangen! + end F_IB_MCZ !Weiterlauf bei O_FIB_MCZ! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE O_FIB_MCZ +Fuellen von INBFF von MCZ bis CR (max. %50 Zeichen) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + O_FIB_MCZ procedure + entry + CLR R4 !Loeschen Zeiger Eingabepuffer! + ldb rl3, #%50 !max. %50 Zeichen einlesen! +FIB1: + calr WOCF_MCZ !rl0:=Zeichen vom MCZ! + ldb INBFF(r4), rl0 !Zeichen in INBFF abspeichern! + cpb rl0, #CR + jr nz, FIB2 !Zeichen ungleich CR! + + calr WOEOS_MCZ !Zeichen war CR --> warten auf Sendeende! + ret + +FIB2: + cpb rl0, #%20 + jr c, FIB1 !Zeichen < Space ignorieren! + + inc r4, #%01 + dbjnz rl3, FIB1 !naechstes Zeichen von MCZ einlesen! + +!%50 Zeichen vom MCZ eingelesen / restliche Zeichen bis CR ignorieren! +FIB3: + calr WOCF_MCZ !rl0:=Zeichen von MCZ! + cpb rl0, #CR + jr nz, FIB3 !Warten bis CR gelesen! + + ldb INBFF + %50, rl0 !CR als %51-stes Zeichen in INBFF + abspeichern! + ret + end O_FIB_MCZ + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE S_RPB +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + S_RPB procedure + entry + ldb rl0, #'7' !SEND TO MCZ: PLEASE REPEAT SENDET INFORMATION! + jr SAN_MCZ + end S_RPB + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE S_LAB +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + S_LAB procedure + entry + ldb rl0, #'9' !SEND TO MCZ: ABORT THE LOAD-ROUTINE! + jr SAN_MCZ + end S_LAB + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE S_SNB +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + S_SNB procedure + entry + ldb rl0, #'0' !SEND TO MCZ: RECIVED INF. IS OK (SEND NEXT)! +SAN_MCZ: + ldb OUTBFF, rl0 + ld OUTPTR, #1 + calr WR_OUTBFF_CR_MCZ + jr WOEOI_MCZ + end S_SNB + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE SEND +SEND-Routine "MCZ" (Monitorkommando) +Abspeichern eines Speicherinhaltes als Datei auf dem MCZ + +Kommandoeingabe: SEND filename []offset1 offset2 [E=Entry_point] + (Dateiname Anfangsadresse Endadresse Entrypoint) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + SEND procedure + entry + PUSH @R15, PC_SEG + SUB R1, R1 !INITIALISIERUNG! + LD R10, R1 + LD R5, R1 + LD R6, R1 + LD R11, R1 + + LD INPTR_MCZ, R1 + LD OUTPTR_MCZ, R1 + + call GET_SIGN !INPTR0 --> 1.ZEICHEN VON FILE_NAME! + call GET_SIGN !INPTR0 --> '<' oder 1.ZEICHEN DER ANF.ADR.! + call GET_SGNR !R2 := SEGMENTNR., WENN VORHANDEN! + LD PC_SEG, R2 + + jr z, ZS_ERROR !FEHLT: ANF.ADR., END-ADR. u. Entry-POINT! + calr EK2B !EINGABEKONVERTIERUNG: ANF.ADR.! + jr z, ZS_ERROR !FEHLT: END-ADR. u. ENTRY-POINT! + LD R10, R3 + calr EK2B !EINGABEKONV.: END-ADR.! + sub r3, r10 !endadr-anfadr! + jr mi, ZS_ERROR !endadr GROSSBUCHSTABEN! + CPB RL0, #'E' !RL0 = 'E' oder 'e' ?! + jr nz, ZS_ERROR + call GET_CHR !NAECHSTES ZEICHEN TESTEN! + CPB RL0, #'=' + jr nz, ZS_ERROR + call GET_CHR + calr EK2B !EINGABEKONV.: ENTRY-POINT! + LD R11, R3 + +KEPA: +!'' aus INBFF entfernen (wird von WEGA-Shell als + Dateiumlenkung interpretiert! + ld r2, #INBFF + ld r1, #%80 + ldb rl0, #'<' + cpirb rl0, @r2, r1, eq + jr nz, XS2 ! '<' nicht gefunden ! + dec r2, #1 !r2 zeigt auf Anfang der Segmentangabe! + inc r1, #1 +XS1: ldb rl0, @r2 + cpb rl0, #CR + jr z, XS2 + ldb @r2, #' ' + cpb rl0, #'>' + jr z, XS2 !Ende der Segmentangabe erreicht! + inc r2, #1 + djnz r1,XS1 +XS2: + + LD R4, #OUTBFF + LD R2, #INBFF + LD R1, #%40 + LDIR @R4, @R2, R1 + LD OUTPTR, #%80 + calr WR_OUTBFF_MCZ !SENDE BEFEHL: 'SEND ...' ANS MCZ! + +SINTE: calr O_FIB_MCZ !ZEICHENWEISES ECHO VOM MCZ UEBERSPRINGEN! + calr O_FIB_MCZ !FUELLEN DES INBFF MIT DEN VOM MCZ GESENDETEN + ZEICHEN! + LD R2, #INBFF + LDB RL0, @R2 + CPB RL0, #'0' + JR Z, SOK !SEND-BLOCK IST OK! + CPB RL0, #'7' + JR Z, SREP !SEND-BLOCK WIEDERHOLT ANS MCZ SENDEN! + CPB RL0, #'9' + JR Z, SABO !SEND-ROUTINE WURDE VOM MCZ ABGEBROCHEN! + calr MIOB_CON !MOVE INBFF IN OUTBFF AND SEND TO CONSOLE! +SABO: LD R2, #TSAB !DISPLAY: SEND ABORT! + call WR_MSG +GO_MON: POP PC_SEG, @R15 + RET !RUECKSPRUNG IN DEN MONITOR! + +ZS_ERROR: + jp ERROR + +SENDE: call WR_CRLF !SEND FEHLERFREI BEENDET! + JR GO_MON + +SOK: LD R2, R5 + TEST R2 + JR Z,SENDE + + LDB RL0, #'.' + call TYWR !'.' AN CONSOLE AUSGEBEN UND BLOCK SENDEN! + + SUB R2, R6 + LD R5, R2 + + LD R2, R10 + ADD R2, R6 + LD R10, R2 + +SREP: LD R7, R5 + TEST R7 + JR Z, SEB !SENDE ENDE-BLOCK ZUM MCZ! + SUB R7, #%1E + JR NC, SBML !SENDE BLOCK MIT MAX. LAENGE (=%1E DATENBYTE)! + ADD R7, #%1E + JR SADB !SENDE ADRESS-BLOCK! +SBML: LD R7, #%1E +SADB: LD R6, R7 + calr S_MCZ_AB !SEND ADDRESS-BLOCK TO MCZ! + + LD R8, PC_SEG !INITIALISIERUNG DER REGISTER ZUM INDIREKTEN LADEN! + LD R9, R10 + LDB RL4, #0 + +S_N_B: SC #SC_SEGV !SEND NEXT DATEN-BYTE! + LDB RL3, @R8 !LADE INDIREKT VON RR8! + SC #SC_NSEGV + + calr AK_S_MCZ !SEND DATEN-BYTE! + + INC R9, #1 + DBJNZ RL7, S_N_B + + LDB RL3, RL4 + calr AK_S_MCZ !SEND PRUEFSUMME! + +S_CR: LDB RL0, #%0D + calr TYWR_MCZ + JR SINTE + +SEB: LD R2, R11 !SEND END-BLOCK! + LD R10, R2 + LD R6, #0 + calr S_MCZ_AB + JR S_CR + + +! UNTERPROGRAMME ! + +!EINGABEKONVERTIERUNG BIS 4 ASCII-HEXA-ZIFFERN IN 2 BYTE-INTEGER (R3)! +EK2B: LDB RL4, #4 !COUNTER FUER 4 ASCII-ZEICHEN! + SUB R3, R3 !R3 := 0! +EK2BL: call HTOB + JR C, KAHZ !KEINE ASCII-HEXADEZIMAL-ZIFFER! + RLDB RL0, RL3 + RLDB RL0, RH3 + DECB RL4, #1 + BITB RL4, #0 + JR NZ, RL4UG !RL4 = UNGERADE! + CPB RL4, #2 + JP NZ, GET_SIGN !4 ZIFFERN KONV.,INPTR AUF NAECHSTES ZEICHEN + UNGLEICH SPACE SETZEN UND NACH RL0 LADEN, ENDE!!! +RL4UG: call GET_CHR + RET Z + JR EK2BL + +KAHZ: CPB RL0, #' ' + jr nz, ZS_ERROR + jp GET_SIGNW + +!SENDE ANFANGSBLOCK ZUM MCZ! +S_MCZ_AB: + LDB RL4, #0 !PRUEFSUMME := 0! + + LDB RL0, #'/' + calr TYWR_MCZ + + LD R2, R10 + LDB RL3, RH2 !H(BLOCK-ADRESSE) SENDEN! + calr AK_S_MCZ + LDB RL3, RL2 !L(BLOCK-ADRESSE) SENDEN! + calr AK_S_MCZ + + LD R2, R6 !BLOCK-LAENGE SENDEN! + LDB RL3, RL2 + calr AK_S_MCZ + + LDB RL3, RL4 !PRUEFSUMME SENDEN! + + !Weiterlauf bei AK_S_MCZ! + +!SENDEN EINES IN 2 ASCII-HEXA-ZIFFERN UMKODIERTEN BYTES ZUM MCZ! +AK_S_MCZ: + LDB RH4, #2 !SCHLEIFE FUER 2 ASCII-HEXADEZIMAL-ZIFFERN! +AKSML: LDB RL0, #0 + RLDB RL0, RL3 + + ADDB RL4, RL0 !PRUEFSUMMEN-BERECHNUNG! + ADDB RL0, #'0' !AUSGABE-KONVERTIERUNG! + CPB RL0, #%3A + JR C, BEZ !BYTE EQU ZIFFER! + ADDB RL0, #%7 +BEZ: calr TYWR_MCZ !SEND CHAR TO MCZ! + DBJNZ RH4, AKSML + RET + end SEND + + INTERNAL +TSAB: WORD := 11 + ARRAY [* BYTE] := 'SEND ABORT%0D%00' + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE MIOB_CON +Kopieren einer Zeichenkette von INBFF nach OUTBFF und Senden zur Console +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + MIOB_CON procedure + entry + LD R4, #OUTBFF + LD R2, #INBFF + LD R1, #%7F + LDIR @R4, @R2, R1 + LD OUTPTR, #%07F + jp WR_OUTBFF + end MIOB_CON + +end p_ldsd diff --git a/WEGA/src/cmd/standalone/sa.diags/p.term.s b/WEGA/src/cmd/standalone/sa.diags/p.term.s new file mode 100644 index 0000000..8ea7671 --- /dev/null +++ b/WEGA/src/cmd/standalone/sa.diags/p.term.s @@ -0,0 +1,1792 @@ +!****************************************************************************** +******************************************************************************* + + P8000-Firmware (C) ZFT/KEAW Abt. Basissoftware - 1987 + U8000-Softwaremonitor (MON16) Modul: p_term + + Bearbeiter: J. Zabel + Datum: 27.01.1989 + Version: 3.1 + +******************************************************************************* +******************************************************************************! + +!============================================================================== +Inhaltsuebersicht Modul p_term +------------------------------ +Dieser Modul umfasst: +- Routinen zur Terminalein- und -ausgabe, +- Routinen zur Ein- und Ausgabe fuer den Dateitransfer von/zu UDOS ueber + die 8-Bit-/16-Bit-Koppelschnittstelle, +- Konvertierungsroutinen (Binaer <--> ASCII-Hexa) +- Routinen zur Arbeit mit dem Eingabepuffer INBFF und dem Ausgabepuffer OUTBFF. + +Routinen, die direkte Eingaben von den Interrupt-Eingabepuffern PTYBFF/UDOSBFF +bzw. direkte Ausgaben auf den Terminal-Kanal/Koppelschnittstelle durchfuehren, +sind i.A. mit RD bzw. WR gekennzeichnet. +Routinen, die Eingaben vom Eingabepuffer INBFF bzw. Ausgaben in den +Ausgabepuffer OUTBFF durchfuehren, sind i.A. mit GET bzw. PUT gekennzeichnet. + +Prozeduren +---------- +PTY_INT +PTY_ERR +KOPPEL_INT +INCPTR +TYRD +TYWR +TYRD_UDOS_INT +TYRD_UDOS_POL +TYWR_UDOS_INT +TYWR_UDOS_POL +TYWR_KOPPEL_INT +TYWR_KOPPEL_POL +KP_OUTB +KP_INB +TYRDWR +RD_LINE_BFF +RD_LINE_INBFF +CLRCHR +WR_CRLF +WR_NULL +WR_MSG +WR_OUTBFF_CR +WR_OUTBFF + +HTOB +BTOH16 +BTOH8 +BTOH4 + +GET_CHR +GET_SIGN +GET_SIGNW +GET_SGNR +GET_HEXZ +GET_ADR +GET_PAR +RD_DATA +GET_DATA +WR_R5_RDDATA +WR_OBF_RDDATA +PUT_CHR +PUT_3C +PUT_1CHR +PUT_2CHR +PUT_SEGNR +PUT_SGNR +==============================================================================! + + +p_term module + +$SECTION PROM + +!anfang mon16.include! +!****************************************************************************** +allgemeine Vereinbarungen (Stand: 27.01.1989) +******************************************************************************! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +externe Prozeduren und Marken +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + EXTERNAL +!INIT_CTC0_0 procedure Modul p_init! +INIT_CTC0_1 procedure !Modul p_init! +!INIT_SIO0_A procedure Modul p_init! +INIT_SIO0_B procedure !Modul p_init! +CMDLOP procedure !Modul p_init! +ERROR procedure !Modul p_init! +NMI_INT procedure !Modul p_init! + +PTY_INT procedure !Modul p_term! +PTY_ERR procedure !Modul p_term! +KOPPEL_INT procedure !Modul p_term! +INCPTR procedure !Modul p_term! +TYRD procedure !Modul p_term! +TYWR procedure !Modul p_term! +TYRD_UDOS_INT procedure !Modul p_term! +TYRD_UDOS_POL procedure !Modul p_term! +TYWR_UDOS_INT procedure !Modul p_term! +TYWR_UDOS_POL procedure !Modul p_term! +TYWR_KOPPEL_INT procedure !Modul p_term! +TYWR_KOPPEL_POL procedure !Modul p_term! +KP_OUTB procedure !Modul p_term! +KP_INB procedure !Modul p_term! +RD_LINE_BFF procedure !Modul p_term! +RD_LINE_INBFF procedure !Modul p_term! +WR_CRLF procedure !Modul p_term! +WR_MSG procedure !Modul p_term! +WR_OUTBFF_CR procedure !Modul p_term! +WR_OUTBFF procedure !Modul p_term! +HTOB procedure !Modul p_term! +BTOH16 procedure !Modul p_term! +BTOH8 procedure !Modul p_term! +GET_CHR procedure !Modul p_term! +GET_SIGN procedure !Modul p_term! +GET_SIGNW procedure !Modul p_term! +GET_SGNR procedure !Modul p_term! +GET_HEXZ procedure !Modul p_term! +GET_ADR procedure !Modul p_term! +GET_PAR procedure !Modul p_term! +RD_DATA procedure !Modul p_term! +GET_DATA procedure !Modul p_term! +WR_R5_RDDATA procedure !Modul p_term! +WR_OBF_RDDATA procedure !Modul p_term! +PUT_CHR procedure !Modul p_term! +PUT_3C procedure !Modul p_term! +PUT_2CHR procedure !Modul p_term! +PUT_SEGNR procedure !Modul p_term! +PUT_SGNR procedure !Modul p_term! + +DISPLAY procedure !Modul p_comm! +COMPARE procedure !Modul p_comm! +FILL procedure !Modul p_comm! +MOVE procedure !Modul p_comm! +PORT_READ procedure !Modul p_comm! +PORT_WRITE procedure !Modul p_comm! +PORT_READ_SPECIAL procedure !Modul p_comm! +PORT_WRITE_SPECIAL procedure !Modul p_comm! +HARD_DISK_READ procedure !Modul p_comm! +HARD_DISK_WRITE procedure !Modul p_comm! +FLOPPY_FORMAT procedure !Modul p_comm! +FLOPPY_READ procedure !Modul p_comm! +FLOPPY_WRITE procedure !Modul p_comm! + +REGISTER procedure !Modul p_brk! +SAVREG procedure !Modul p_brk! +BREAK procedure !Modul p_brk! +GO procedure !Modul p_brk! +GO_NXT procedure !Modul p_brk! +NEXT procedure !Modul p_brk! +RETI_CTC0_3 procedure !Modul p_brk! + +TEST_ procedure !Modul p_test! + +GET procedure !Modul p_gesa! +SAVE procedure !Modul p_gesa! +QUIT8 procedure !Modul p_gesa! +QUIT8_RESET procedure !Modul p_gesa! +FLOPPY procedure !Modul p.gesa! +RM_GET procedure !Modul p_gesa! +RM_SAVE procedure !Modul p_gesa! +RM_QUIT procedure !Modul p_gesa! + +OS_BOOT procedure !Modul p_boot! +AUTOBOOT procedure !Modul p_boot! + +DISK procedure !Modul p_disk! + +! +QUIT procedure Modul p_ldsd +LOAD procedure Modul p_ldsd +MCZ_INT procedure Modul p_ldsd +MCZ_ERR procedure Modul p_ldsd +TYWR_MCZ procedure Modul p_ldsd +WOCF_MCZ procedure Modul p_ldsd +SEND procedure Modul p_ldsd +! + +MON16_1H word !Modul p.crc! +N_MON16_1H word !Modul p.crc! +MON16_1L word !Modul p.crc! +N_MON16_1L word !Modul p.crc! +MON16_2H word !Modul p.crc! +N_MON16_2H word !Modul p.crc! +MON16_2L word !Modul p.crc! +N_MON16_2L word !Modul p.crc! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Werte aus dem Arbeitsspeicher (Modul p_ram) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + EXTERNAL +RAM_ANF ARRAY [%10 WORD] +NSP_OFF WORD + ARRAY [%3F WORD] !Stackbereich! +STACK WORD + ARRAY [4 WORD] +_numterm WORD !Anzahl der Terminals! +PTYPORT BYTE !Terminalkanal: + 00 - SIO0_B (16-Bit-Teil) + 01 - SIO0_B (8-Bit-Teil) ueber + Koppelschnittstelle! +XEMPTY BYTE !fuer interruptgesyeuerten Terminal- + betrieb ueber Koppelschnittstelle: + 00 - Sendepuffer SIO0_B (8-Bit-Teil) + leer + FF - Sendepuffer SIO0_B (8-Bit-Teil) + nicht leer! + BYTE +KONV BYTE !Hilfsbyte zur Konvertierung! +INBFF ARRAY [%80 BYTE] !Eingabepuffer! +OUTBFF ARRAY [%80 BYTE] !Ausgabepuffer! +PTYBFF ARRAY [%100 BYTE] !Eingabepuffer fuer interrupt- + gesteuerte Eingabe vom Terminal- + kanal! +MCZBFF ARRAY [%0EA BYTE] !Ein-/Ausgabepuffer fuer LOAD/SEND! +MAXLEN WORD !maximale Zeilenlaenge! +INPTR WORD !Zeiger fuer Eingabepuffer INBFF! +OUTPTR WORD !Zeiger fuer Ausgabepuffer OUTBFF + (Pufferlaenge)! +COUNT_PTY WORD !aktuelle Anzahl der Zeichen in PTYBFF! +INPTR_PTY WORD !Eingabezeiger fuer PTYBFF + (naechster freier Platz)! +OUTPTR_PTY WORD !Ausgabezeiger fuer PTYBFF + (naechstes auszulesende Zeichen)! +INPTR_MCZ WORD !Eingabezeiger fuer MCZBFF! +OUTPTR_MCZ WORD !Ausgabezeiger fuer MCZBFF! +B_WORD WORD !Speicherinhalt auf der BREAK-Adresse! +B_ADR_S WORD !Segmentnummer der BREAK-Adresse! +B_ADR_O WORD !Offset der BREAK-Adresse! +RR14_V LONG !VARIABLER STACK, FUER NEXT UND BREAK! +W23B4 WORD +FCW_V WORD !VARIABLES FCW FUER NEXT UND BREAK! +PORT_BF WORD !Puffer fuer gelesenen bzw. zu + schreibenden PORT-Datenwert! +PORT_IO WORD !Adresse des PORT-I/O-Programms! + WORD !unbenutzt! +SV_R ARRAY [14 WORD] !Registerrettungsbereich! +SVSTK LONG +PC_SEG WORD !Programmcounter (Segmentnummer)! +PC_OFF WORD !Programmcounter (Offsetadresse)! +FCW_ WORD !FCW im Registerrettungsbereich! +RF_CTR WORD !Merker: Refresh Control Register! +N4_ WORD !Normalstack R14! +N5_ WORD !Normalstack R15! +PS_ WORD !Program-Status-Area Segment! +PO_ WORD !Program-Status-Area Offset! + WORD !unbenutzt! +!Flags! +FLAG0 BYTE +FLAG1 BYTE +!Variablen (initialisiert bei Systemstart)! +CHRDEL BYTE !Zeichen loeschen (Backspace %08)! +LINDEL BYTE !Zeile loeschen (Line delete %7F)! +XONCHR BYTE !Terminalausgabe fortsetzen (^Q %11)! +XOFCHR BYTE !Terminalausgabe anhalten (^S %13)! +NULLCT WORD !Anzahl der Nullen nach CR bei Terminalausgabe (%0000)! +B_CODE WORD !Unterbrechungscode Z8000 (7F00)! +STKCTR WORD !Zaehler der Stackoperationen fuer NEXT (%0004)! +NXTCTR WORD !SCHRITTZAEHLER FUER NEXT (%0001)! +PROMT WORD !Promt-Zeichen (%2000)! +!---------------------------------------------------! +!Program Status Area (initialisiert bei Systemstart)! +PSAREA +! ID FCW PCSEG PCOFF! + ARRAY [4 WORD] !:= [%0000 %0000 %0000 %0000] + RESERVED! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + UNIMLEMENTED INSTRUCTIONS! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + PRIVILEGED INSTRUCTIONS! +PSA_SC ARRAY [4 WORD] !:= [%0000 %C000 %8000 SC_ENTRY] + SYSTEM_CALL INSTRUCTIONS! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 MMU_ERR] + SEGMENT TRAP! +PSA_NMI ARRAY [4 WORD] !:= [%0000 %4000 %8000 AUTOBOOT bzw. NMI_INT] + NONMASKABLE INTERRUPT + (AUTOBOOT vor erster Terminaleingabe; + NMI_INT nach erster Terminaleingabe)! + ARRAY [4 WORD] !:= [%0000 %4000 %8000 VI_ERR] + NONVECTORED INTERRUPT! +! VECTORED INTERRUPT! + ARRAY [2 WORD] !:= [%0000 %4000] + VECTORED INTERRUPT (ID, FCW)! +! VI - Sprung-Tabelle (128 Eintraege) ! +! SEG OFFSET! +!CTC0! +VI_CTC0_0 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_1 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_2 ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +VI_CTC0_3 ARRAY [2 WORD] !:= [%8000 VI_ERR bzw. GO_INT bzw. NXT_INT] + fuer GO bzw. NEXT! +!PIO1! +VI_PIO1_B ARRAY [2 WORD] !:= [%8000 KOPPEL_INT] + VI Zeichen empfangen (von Koppelschnittstelle)! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! +!SIO0! +VI_SIO0_B ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 PTY_INT] + VI Zeichen empfangen (fuer Terminaleingabe)! + ARRAY [2 WORD] !:= [%8000 PTY_ERR] + VI Empfangssonderfall (fuer Empfangsfehler)! +VI_SIO0_A ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] ! + ARRAY [2 WORD] !:= [%8000 VI_ERR] (vorher MCZ_INT) + VI Zeichen empfangen (fuer MCZ-Eingabe)! + ARRAY [2 WORD] !:= [%8000 VI_ERR] (vorher MCZ_ERR) + VI Empfangssonderfall (fuer Empfangsfehler)! +! Rest der 128 Eintraege der VI-Sprung-Tabelle! +VI_TAB_REST ARRAY [224 WORD] !:= [%8000 VI_ERR] ! +!---------------------------------------------------! + +!Arbeitsspeicher fuer Kommando "T" (Hardwareeigentest)! +RG_FELD ARRAY [%1A WORD] !Feld zur Registerrettung! +REM_MMU_BCSR BYTE !Merker: Inhalt BUS CYCLE STATUS REGISTER! +REM_MMU_VTR BYTE !Merker: Inhalt VIOLATION TYPE REGISTER! +REM_MMU_ID WORD !Merker: MMU-Identifikation! +REM_ERR_CNT WORD !Merker: Stand Fehlerzaehler! +REM_SEGMENT_TRAP WORD !Merker: urspruengliche Offsetadresse fuer Segmenttrap! +REM_PRIVINSTR_TRAP WORD !Merker: urspruengl. Offsetadr. fuer Priv.-Instr.-Trap! +REM_MMU_SINOUT WORD !Merker: MMU-Ein-/Ausgabewerte! +ERR_CNT WORD !Fehlerzaehler! +ERR_WDC WORD !Fehlerzaehler fuer WDC-Test! +MAX_SEGNR WORD !Merker: hoechste vorhandene Segmentnummer! +REM_PARNMI WORD !Merker: Paritaets-NMI aufgetreten + (%0000-->nein / %FFFF-->ja)! +ERRPAR_ID WORD !Spezifizierung der 4 Parameter der auszugebenden + Fehlerzeile (Prozedur MSG_ERROR)! +REM_MMU1 WORD +REM_MMU2 WORD +REM_INT WORD !Merker: Interrupt aufgetreten (0-->nein)! +REM_WDC1 WORD !Speicherplatz fuer Testdatenwert! +REM_WDC2 WORD !Speicherplatz fuer rueckgelesenen datenwert! + +!Arbeitsspeicher fuer Kommandos "GE"/"S"/"O U" und Floppytreiber! +FILENAME_PTR WORD !Anfangsadresse Dateiname! +COUNT_UDOS WORD !akt. Anzahl der Zeichen in UDOSBFF! +INPTR_UDOS WORD !Eingabezeiger fuer UDOSBFF + (naechster freier Platz)! +OUTPTR_UDOS WORD !Ausgabezeiger fuer UDOSBFF + naechstes auszulesende Zeichen)! +UDOSBFF ARRAY [%100 BYTE] !Eingabepuffer fuer interrupt- + gesteuerte Eingabe bei Dateitransfer + von/zu UDOS bzw. Blocktransfer! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +System Calls +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +SC_SEGV := %01 !Modul p.term! +SC_NSEGV := %02 !Modul p.term! +SC_TYRD := %04 !Modul p.term! +SC_TYWR := %06 !Modul p.term! +SC_RD_LINE_BFF := %08 !Modul p.term! +SC_WR_CRLF := %0A !Modul p.term! +SC_WR_MSG := %0C !Modul p.term! +SC_BTOH16 := %0E !Modul p.term! +SC_WR_OUTBFF_CR := %10 !Modul p.term! +SC_BTOH8 := %12 !Modul p.term! +SC_PUT_SEGNR := %14 !Modul p.term! +SC_PUT_CHR := %16 !Modul p.term! +! +SC_WOCF_MCZ := %18 Modul p.ldsd +SC_TYWR_MCZ := %1A Modul p.ldsd +! +SC_CMDLOP := %1C !Modul p.init! +SC_DISK := %1E !Modul p.disk! +SC_TYRD_UDOS_INT := %20 !Modul p.term! +SC_TYWR_UDOS_INT := %22 !Modul p.term! +SC_FLOPPY := %24 !Modul p.gesa! +SC_WR_OUTBFF := %26 !Modul p.term! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +spezielle ASCII-Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +SOH := %01 +STX := %02 +ETX := %03 +EOT := %04 +ACK := %06 +BEL := %07 +BS := %08 +LF := %0A +CR := %0D +NAK := %15 +CAN := %18 +ESC := %1B + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Hardwareadressen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT + +!8-Bit-Teil! + +SIO0D_B_8 := %26 !SIO fuer Terminal! +SIO0C_B_8 := %27 + +!16-Bit-Teil! + +SIO0 := %FF81 !Kanal A (XB1/TTY4): unbenutzt (vorher LOAD/SEND/QUIT); + Kanal B (XB2/TTY5): Terminal, wenn 8-Bit-Teil inaktiv! +SIO0D_A := SIO0 + 0 +SIO0D_B := SIO0 + 2 +SIO0C_A := SIO0 + 4 +SIO0C_B := SIO0 + 6 + +SIO1 := %FF89 !Kanal A (XB3/TTY6): unbenutzt + Kanal B (XB4/TTY7): unbenutzt! +SIO1D_A := SIO1 + 0 +SIO1D_B := SIO1 + 2 +SIO1C_A := SIO1 + 4 +SIO1C_B := SIO1 + 6 + +PIO0 := %FF91 !Koppel-PIO zum 8-Bit-Teil + fuer Terminal und Kommandos "GE", "S", + "Q", "QRES", "O U" und Floppytreiber + Kanal A: Datenausgabe + Kanal B: Statusausgabe/Steuerport! +PIO0D_A := PIO0 + 0 +PIO0D_B := PIO0 + 2 +PIO0C_A := PIO0 + 4 +PIO0C_B := PIO0 + 6 + +PIO1 := %FF99 !Koppel-PIO zum 8-Bit-Teil + fuer Terminal und Kommandos "GE", "S", + "Q", "QRES", "O U" und Floppytreiber + Kanal A: Dateneingabe + Kanal B: Statuseingabe/Steuerport! +PIO1D_A := PIO1 + 0 +PIO1D_B := PIO1 + 2 +PIO1C_A := PIO1 + 4 +PIO1C_B := PIO1 + 6 + +PIO2 := %FFA1 !(XB5): Winchester + Kanal A: Datenein-/-ausgabe; Kanal B: Steuerport! +PIO2D_A := PIO2 + 0 +PIO2D_B := PIO2 + 2 +PIO2C_A := PIO2 + 4 +PIO2C_B := PIO2 + 6 + +CTC0 := %FFA9 +CTC0_0 := CTC0 + 0 ! Baud 0 - SIO0, Kanal A! +CTC0_1 := CTC0 + 2 ! Baud 1 - SIO0, Kanal B! +CTC0_2 := CTC0 + 4 ! Baud 2 - SIO1, Kanal A! +CTC0_3 := CTC0 + 6 ! Next ! + +CTC1 := %FFB1 +CTC1_0 := CTC1 + 0 ! Baud 3 - SIO1, Kanal B! +CTC1_1 := CTC1 + 2 +CTC1_2 := CTC1 + 4 +CTC1_3 := CTC1 + 6 + +LON := %FFD9 !RUN16-Lampe ein! +LOFF := %FFB9 !RUN16-Lampe aus! + +S_BNK := %FFC1 !SWITCH-BANK: + Bit0-3 Ausgabebits; Bit4-7 Eingabebits (DIL-Schalter): + Bit 0: =0 - Monitor PROM+RAM einschalten + =1 - Monitor PROM+RAM ausschalten + Bit 1: =0 - MMU's ausschalten; =1 - MMU's einschalten + Bit 2: Seg. Usr. + Bit 3: =0 - Paritaetspruefung ausgeschaltet bzw. + Paritaetsfehler loeschen + =1 - Paritaetspruefung eingeschaltet + Bit 5,4: Baudrate Terminal (unbenutzt) + Bit 7,6: Autoboot Device (unbenutzt)! + +SBREAK := %FFC9 !System Break Register! +NBREAK := %FFD1 !Normal Break Register! +RETI_P := %FFE1 !RETI-Port fuer Schaltkreise des U880-Systems! + +ALL_MMU := %F0 +STACK_MMU := %F6 +DATA_MMU := %FA +CODE_MMU := %FC + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Moegliche Statusausgaben an 8-Bit-Teil von 16-Bit-Teil +fuer 8-Bit-/16-Bit-Koppelschnittstelle (PIO0_B) +(INT8-Bit jeweils = 0) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +STAT8_ENDE := %00 !Ende eines Write-Requests! +STAT8_READ := %02 !Read-Request an einen Peripheriebaustein 8-Bit-Teil! +STAT8_WRITE := %04 !Write-Request an einen Peripheriebaustein 8-Bit-Teil! + +STAT8_UDOS := %10 !Datenbyte ist Bestandteil eines Dateitransfers + bzw. eines Blocktransfers von/zu UDOS! +STAT8_QUIT := %1E !Rueckkehr zum 8-Bit-Teil (Datenbyte "Q" oder "R")! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +Moegliche Statuseingaben von 8-Bit-Teil an 16-Bit-Teil +fuer 8-Bit-/16-Bit-Koppelschnittstelle (PIO1_B) +(INT16-Bit jeweils = 0) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + CONSTANT +STAT16_ENDE := %00 !Beantwortung eines Read-Requests! + +STAT16_SIO0_B_R := %04 !REC INT (SIO0_B-Empfaengerinterrupt)! +STAT16_SIO0_B_X := %24 !TRANS INT (SIO0_B-Interrupt Sendepuffer leer)! +STAT16_SIO0_B_E := %44 !EXT STAT INT (SIO0_B-Externer-Statusinterrupt)! +STAT16_SIO0_B_S := %64 !SPEC REC INT (SIO0_B-Interrupt Empfangssonderfall)! + +STAT16_UDOS := %10 !Datenbyte ist Bestandteil eines Dateitransfers + bzw. eines Blocktransfers von/zu UDOS! +!ende mon16.include! + + +!****************************************************************************** +Prozeduren +******************************************************************************! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE PTY_INT +VI-Routine fuer Dateneingabe vom Terminalkanal SIO0_B des 16-Bit-Teils; +Abspeicherung des Zeichens im Interrupt-Eingabepuffer PTYBFF; +Aktualisierung von INPTR_PTY und COUNT_PTY; +Test auf Sonderzeichen (^S, ^Q, ESC) bei Terminaleingaben +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + PTY_INT procedure + entry + push @r15, r0 + push @r15, r1 + push @r15, r2 +!bei erster TerminaleingabeNMI-Entry in PSAREA aendern und PROMT setzen! + cp PSA_NMI+6, #AUTOBOOT !NMI_ENTRY in PSAREA: + - nach RESET steht dort #AUTOBOOT, d.h. + bei NMI erfolgt Abarbeitung von + #AUTOBOOT + - nach Eingabe des ersten Zeichens vom + Terminal (Abarbeitung von PTY_INT oder + KOPPEL_INT) bzw. nach Abarbeitung + von #AUTOBOOT wird #AUTOBOOT durch + #NMI_INT ersetzt, d.h. bei NMI erfolgt + jetzt Abarbeitung von #NMI_INT ! + jr nz, PTY_RD + ld PROMT, #'* ' !Promt-Zeichen eintragen (d.h. die Zelle PROMT + wird erst nach der 1. Zeicheneingabe geladen)! + ld PSA_NMI+6, #NMI_INT !#AUTOBOOT durch #NMI_INT ersetzen in + PSAREA! +!Zeichen vom SIO einlesen! +PTY_RD: + inb rl1, SIO0D_B !Zeichen vom SIO einlesen! +!Test, ob eingelesenes Zeichen vom Terminalkanal als ASCII-Zeichen oder + als beliebiges Datenbyte zu interpretieren ist! + bitb FLAG0, #%00 + jr nz, PTY_WR !keine ASCII-Zeichen einzulesen + --> Zeichen in PTYBFF abspeichern! + resb rl1, #%07 !RES BIT7 DES ASCII-ZEICHENS! +!Test auf ^Q! + cpb rl1, XONCHR !Test auf ^Q (Terminalausgabe nicht gesperrt)! + jr nz, PTY1 !Zeichen nicht ^Q! + resb FLAG0, #%02 !Bit2/FLAG0=0: Terminalausgabe nicht gesperrt! + jr PTYEND +!Test auf ^S! +PTY1: + cpb rl1, XOFCHR !Test auf ^S (Terminalausgabe gesperrt)! + jr nz, PTY2 !Zeichen nicht ^S! + setb FLAG0, #%02 !Bit2/FLAG0=1: Terminalausgabe nicht gesperrt! + jr PTYEND +!Test auf ESC! +PTY2: + cpb rl1, #ESC !Test auf ESC (Abbruchtaste)! + jr nz, PTY_WR !Zeichen nicht ESC! + bitb FLAG0, #%03 !wenn Bit3/FLAG0 und Bit4/FLAG0 = 0, dann + wird ESC als normales ASCII-Zeichen in PTYBFF + abgespeichert und nicht als Abbruchtaste + behandelt! + jr nz, PTY3 + bitb FLAG0, #%04 + jr z, PTY_WR !ESC in PTYBFF eintragen! +!ESC als Abbruchtaste behandeln! +PTY3: setb FLAG0, #%05 !Bit5/FLAG0=1: Abbruchtaste gedrueckt! + jr PTYEND +!Zeichen in PTYBFF abspeichern! +PTY_WR: + ld r0, INPTR_PTY + calr INCPTR !r2:=r0; r0:=ro+1! + ld INPTR_PTY, r0 !incr Eingabezeiger (Zeiger zum naechsten + freien Platz in PTYBFF)! + ldb PTYBFF(r2), rl1 !Zeichen in PTYBFF abspeichern! + incb COUNT_PTY, #%01 !Zeichenzaehler incr.! +!SIO ruecksetzen! +PTYEND: + ldb rl1, #%38 !RETI an SIO ausgeben! + outb SIO0C_A, rl1 + + pop r2, @r15 + pop r1, @r15 + pop r0, @r15 + sc #SC_SEGV + nop + iret + end PTY_INT + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE PTY_ERR +VI-Routine fuer Empfangsfehler von Terminalkanal SIO0_B des 16-Bit-Teils +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + PTY_ERR procedure + entry + push @r15, r1 + ldb rl1, #%30 + outb SIO0C_B, rl1 !SIO-Error-Reset! + ldb rl1, #%38 + outb SIO0C_A, rl1 !RETI an SIO senden! + pop r1, @r15 + sc #SC_SEGV + iret + end PTY_ERR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE KOPPEL_INT +VI-Routine fuer Dateneingabe von Koppelschnittstelle PIO1 von Terminalkanal +SIO0_B des 8-Bit Teils bzw. bei Datei-/Blocktransfer von/zu UDOS; +Abspeicherung des Zeichens im Interrupt-Eingabepuffer PTYBFF bzw. UDOSBFF; +Aktualisierung von INPTR_PTY/COUNT_PTY bzw. INPTR_UDOS/COUNT_UDOS; +Test auf Sonderzeichen (^S, ^Q, ESC) bei Terminaleingaben +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + KOPPEL_INT procedure + entry + push @r15, r0 + push @r15, r1 + push @r15, r2 + +!Warten, bis Datenbyte anliegt! +KP_0: + inb rl1, PIO0D_B + bitb rl1, #5 !DATEN DA?! + jr nz, KP_0 !nein! +!Status/Datenbyte von Koppelschnittstelle einlesen! + inb rh1, PIO1D_B !Statuseingabe! + andb rh1, #%7E !Statusbits sind Bit1-6! + inb rl1, PIO1D_A !Dateneingabe! +!Statusauswertung! + cpb rh1, #STAT16_SIO0_B_R !REC INT! + !(SIO0_B_8 Empfaengerinterrupt)! + jr z, KOPPEL_PTY !Datenbyte fuer PTY_BFF! + + cpb rh1, #STAT16_SIO0_B_X !TRANS INT! + jr nz, KP_1 !(SIO0_B_8 Interrupt Sendepuffer leer)! + ldb XEMPTY, #0 !Kennzeichnung: Sendepuffer leer! + jr KOPPEL_END + +KP_1: + cpb rh1, #STAT16_SIO0_B_E !EXT STAT INT! + jr z, KOPPEL_END !(SIO0_B_8 externer Status-Interrupt)! + + cpb rh1, #STAT16_SIO0_B_S !SPEC REC COND INT! + jr z, KOPPEL_END !(SIO0_B_8 Int. Empfangssonderfall)! + + cpb rh1, #STAT16_UDOS !Dateitransfer bzw. Blocktransfer! + jr z, KOPPEL_UDOS !Datenbyte fuer UDOS_BFF! + + jr KOPPEL_END !falscher Status --> Zeichen wird uebergangen! + +!*** Datenbyte kam vom Terminal und ist in PTY_BFF abzuspeichern ***! +KOPPEL_PTY: +!bei erster Terminaleingabe NMI-Entry in PSAREA aendern und PROMT setzen! + cp PSA_NMI+6, #AUTOBOOT !NMI_ENTRY in PSAREA: + - nach RESET steht dort #AUTOBOOT, d.h. + bei NMI erfolgt Abarbeitung von + #AUTOBOOT + - nach Eingabe des ersten Zeichens vom + Terminal (Abarbeitung von PTY_INT oder + KOPPEL_INT) bzw. nach Abarbeitung + von #AUTOBOOT wird #AUTOBOOT durch + #NMI_INT ersetzt, d.h. bei NMI erfolgt + jetzt Abarbeitung von #NMI_INT ! + jr nz, KP_PTY_0 + ld PROMT, #'* ' !Promt-Zeichen eintragen (d.h. die Zelle PROMT + wird erst nach der 1. Zeicheneingabe geladen)! + ld PSA_NMI+6, #NMI_INT !#AUTOBOOT durch #NMI_INT ersetzen in + PSAREA! +!Test, ob eingelesenes Zeichen vom Terminalkanal als ASCII-Zeichen oder + als beliebiges Datenbyte zu interpretieren ist! +KP_PTY_0: + bitb FLAG0, #%00 + jr nz, KP_PTY_WR !keine ASCII-Zeichen einzulesen + --> Zeichen in PTYBFF abspeichern! + resb rl1, #%07 !RES BIT7 DES ASCII-ZEICHENS! +!Test auf ^Q! + cpb rl1, XONCHR !Test auf ^Q (Terminalausgabe nicht gesperrt)! + jr nz, KP_PTY_1 !Zeichen nicht ^Q! + resb FLAG0, #%02 !Bit2/FLAG0=0: Terminalausgabe nicht gesperrt! + jr KOPPEL_END +!Test auf ^S! +KP_PTY_1: + cpb rl1, XOFCHR !Test auf ^S (Terminalausgabe gesperrt)! + jr nz, KP_PTY_2 !Zeichen nicht ^S! + setb FLAG0, #%02 !Bit2/FLAG0=1: Terminalausgabe nicht gesperrt! + jr KOPPEL_END +!Test auf ESC! +KP_PTY_2: + cpb rl1, #ESC !Test auf ESC (Abbruchtaste)! + jr nz, KP_PTY_WR !Zeichen nicht ESC! + bitb FLAG0, #%03 !wenn Bit3/FLAG0 und Bit4/FLAG0 = 0, dann + wird ESC als normales ASCII-Zeichen in PTYBFF + abgespeichert und nicht als Abbruchtaste + behandelt! + jr nz, KP_PTY_3 + bitb FLAG0, #%04 + jr z, KP_PTY_WR !ESC in PTYBFF eintragen! +!ESC als Abbruchtaste behandeln! +KP_PTY_3: + setb FLAG0, #%05 !Bit5/FLAG0=1: Abbruchtaste gedrueckt! + jr KOPPEL_END +!Zeichen in PTYBFF abspeichern! +KP_PTY_WR: + ld r0, INPTR_PTY + calr INCPTR !r2:=r0; r0:=r0+1! + ld INPTR_PTY, r0 !incr Eingabezeiger (Zeiger zum naechsten + freien Platz in PTYBFF)! + ldb PTYBFF(r2), rl1 !Zeichen in PTYBFF abspeichern! + incb COUNT_PTY, #%01 !Zeichenzaehler incr! + jr KOPPEL_END + +!*** Datenbyte kam vom Dateitransfer bzw. Blocktransfer von/zu UDOS + und ist in UDOS_BFF abzuspeichern ***! +KOPPEL_UDOS: +!Zeichen in UDOSBFF abspeichern! + ld r0, INPTR_UDOS + calr INCPTR !r2:=r0; r0:=r0+1! + ld INPTR_UDOS, r0 !incr Eingabezeiger (Zeiger zum naechsten + freien Platz in UDOSBFF)! + ldb UDOSBFF(r2), rl1 !Zeichen in UDOSBFF abspeichern! + incb COUNT_UDOS, #%01 !Zeichenzaehler incr! + jr KOPPEL_END + +KOPPEL_END: +!U880-RETI (ED4D) an PIO ausgeben! + ldb rl1, #%ED + outb RETI_P, rl1 + ldb rl1, #%4D + outb RETI_P, rl1 + + pop r2, @r15 + pop r1, @r15 + pop r0, @r15 + sc #SC_SEGV + nop + iret + + end KOPPEL_INT + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE INCPTR +Pufferzeiger (der Puffer PTYBFF bzw. UDOSBFF) inkrementieren +und auf Ueberlauf testen +Input: r0 - Pufferzeiger +Output: r2 := r0 (alter Stand des Pufferzeigers) + r0 := r0 + 1, wenn C=1, d.h. r0+1 < 256 + r0 := 0, wenn C=0, d.h. r0+1 >= 256 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + INCPTR procedure + entry + ld r2, r0 + inc r0, #%01 + cp r0, #%0100 + ret c + clr r0 + ret + end INCPTR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYRD +Einlesen eines Zeichens aus Interrupt-Eingabepuffer PTYBFF +Output: rl0 - eingelesenes Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYRD procedure + entry + outb LOFF, rl0 !RUN16-Lampe aus! +TYRD1: testb COUNT_PTY !Zeichen in PTYBFF vorhanden?! + jr z, TYRD1 !nein --> warten bis Zeichen empfangen wird! + push @r15, r2 + ld r0, OUTPTR_PTY + calr INCPTR !Ausgabezeiger fuer PTYBFF incr.! + ld OUTPTR_PTY, r0 + ldb rl0, PTYBFF(r2) !rl0 := Zeichen aus PTYBFF! + decb COUNT_PTY, #%01 !Zeichenzaehler decr.! + pop r2, @r15 + outb LON, rl0 !RUN16-Lampe ein! + ret + end TYRD + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYWR +Ausgabe eines Zeichens auf Terminalkanal +(im Pollingbetrieb - Interruptbetrieb moeglich) +(ueber Koppelschnittstelle PIO0 (an SIO0_B des 8-Bit-Teils) bzw. +ueber SIO0_B des 16-Bit-Teils) +Input: rl0 - Zeichen +Output: Z=1, wenn Zeichen = CR +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYWR procedure + entry + push @r15, r0 + testb PTYPORT + jr nz, TYWR_PIO !Terminalbetrieb ueber Koppelschnittstelle! + +!Ausgabe ueber SIO0_B! +TYWR_SIO: + bitb FLAG0, #%02 !Terminal gesperrt?! + jr nz, TYWR_SIO !ja! + + inb rh0, SIO0C_B + bitb rh0, #%02 !Sendepuffer leer?! + jr z, TYWR_SIO !nein! + + outb SIO0D_B, rl0 !Datenbyte ausgeben! + jr TYWR_END + +!Ausgabe ueber Koppelschnittstelle (PIO0) an SIO0_B des 8-Bit-Teils! +TYWR_PIO: + bitb FLAG0, #%02 !Terminal gesperrt?! + jr nz, TYWR_PIO !ja! + + !Test, ob Sendepuffer SIO0_B des 8-Bit-Teils leer ist! + ! 1. bei Interruptbetrieb! + ! + testb XEMPTY |Sendepuffer leer? + (XEMPTY wird in KOPPEL_INT auf %00 gesetzt + wenn Int. "Sendepuffer leer" erfolgte)| + jr nz, TYWR_PIO |nein| + ! + ! 2. bei Pollingbetrieb! + ldb rl0, #SIO0C_B_8 !Adresse SIO0C_B auf 8-Bit-Teil! + calr KP_INB !rh0 := eingelesenes Byte von SIO0C_B! + bitb rh0, #%02 !Sendepuffer leer?! + jr z, TYWR_PIO !nein! + + !Datenbyte an SIO0D_B des 8-Bit-Teils ausgeben! + ldb XEMPTY, #%FF !Kennzeichnung: Sendepuffer nicht leer! + + pop r0, @r15 + push @r15, r0 + ldb rh0, rl0 !rh0:=auszugebendes Zeichen! + ldb rl0, #SIO0D_B_8 !Adresse SIO0D_B auf 8-Bit-Teil! + calr KP_OUTB + +TYWR_END: + pop r0, @r15 + cpb rl0, #CR !Z=1, wenn Zeichen CR war! + ret + end TYWR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYRD_UDOS_INT +Einlesen eines Zeichens von Dateitransfer von/zu UDOS bzw. Floppy-Blocktransfer +aus Interrupt-Eingabepuffer UDOSBFF (Status STAT16_UDOS) +Output: rl0 - eingelesenes Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYRD_UDOS_INT procedure + entry + testb COUNT_UDOS !Zeichen in UDOSBFF vorhanden?! + jr z, TYRD_UDOS_INT !nein --> warten bis Zeichen empfangen wird! + push @r15, r2 + ld r0, OUTPTR_UDOS + calr INCPTR !Ausgabezeiger fuer UDOSBFF incr.! + ld OUTPTR_UDOS, r0 + ldb rl0, UDOSBFF(r2) !rl0 := Zeichen aus UDOSBFF! + decb COUNT_UDOS, #%01 !Zeichenzaehler decr.! + pop r2, @r15 + ret + end TYRD_UDOS_INT + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYRD_UDOS_POL +Einlesen eines Zeichens von Dateitransfer von/zu UDOS bzw. Floppy-Blocktransfer +im Polling (Status STAT16_UDOS) +Output: rl0 - eingelesenes Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYRD_UDOS_POL procedure + entry + di vi + inb rh0, PIO0D_B + bitb rh0, #5 !DATEN DA?! + jr nz, TYRD_UDOS_POL !nein! + + inb rh0, PIO1D_B !Statuseingabe! + andb rh0, #%7E + cpb rh0, #STAT16_UDOS + jr nz, TYRD_UDOS_POL !falscher Status! + + inb rl0, PIO1D_A !Dateneingabe! + ei vi + ret + end TYRD_UDOS_POL + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYWR_UDOS_INT +Ausgabe eines Zeichens fuer Dateitransfer von/zu UDOS bzw. Floppy-Blocktransfer +(ueber Koppelschnittstelle PIO0) +--- mit Interruptausloesung auf 8-Bit-Teil (INT8-Bit=1) --- +Input: rl0 - Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYWR_UDOS_INT procedure + entry + di vi + ldb rh0, #STAT8_UDOS !Status! + calr TYWR_KOPPEL_INT !Zeichen+Status/INT8 an Koppelschnittstelle + senden! + ei vi + ret + end TYWR_UDOS_INT + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYWR_UDOS_POL +Ausgabe eines Zeichens fuer Dateitransfer von/zu UDOS bzw. Floppy-Blocktransfer +(ueber Koppelschnittstelle PIO0) +--- ohne Interruptausloesung auf 8-Bit-Teil (INT8-Bit=0) --- +Input: rl0 - Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYWR_UDOS_POL procedure + entry + di vi + ldb rh0, #STAT8_UDOS !Status! + calr TYWR_KOPPEL_POL !Zeichen+Status an Koppelschnittstelle senden! + ei vi + ret + end TYWR_UDOS_POL + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYWR_KOPPEL_INT +allgemeine Ausgabe eines Zeichens und zugehoerigen Status an +8-Bit-/16-Bit-Koppelschnittstelle (PIO0) +--- mit Interruptausloesung auf 8-Bit-Teil (INT8-Bit=1) --- +Input: rl0 - Zeichen + rh0 - Status +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYWR_KOPPEL_INT procedure + entry + push @r15, r0 +TKI1: + inb rh0, PIO0D_B + bitb rh0, #%06 !ENABLE OUTPUT?! + jr nz, TKI1 !nein! + + outb PIO0D_A, rl0 !Datenbyte ausgeben! + pop r0, @r15 + resb rh0, #0 !Bit0=0: INT8-Bit auf 0 setzen! + outb PIO0D_B, rh0 + setb rh0, #0 !Bit0=1: INT8-Bit auf 1 setzen! + outb PIO0D_B, rh0 !INT8/Status ausgeben! + ret + end TYWR_KOPPEL_INT + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYWR_KOPPEL_POL +allgemeine Ausgabe eines Zeichens und zugehoerigen Status an +8-Bit-/16-Bit-Koppelschnittstelle (PIO0) +--- ohne Interruptausloesung auf 8-Bit-Teil (INT8-Bit = 0) --- +Input: rl0 - Zeichen + rh0 - Status +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + TYWR_KOPPEL_POL procedure + entry + push @r15, r0 +TKP1: + inb rh0, PIO0D_B + bitb rh0, #%06 !ENABLE OUTPUT?! + jr nz, TKP1 !nein! + + pop r0, @r15 + resb rh0, #0 !Bit0=0: INT8-Bit auf 0 setzen! + outb PIO0D_B, rh0 !Status ausgeben! + outb PIO0D_A, rl0 !Datenbyte ausgeben! + ret + end TYWR_KOPPEL_POL + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE KP_OUTB +Ausgabe eines Bytes an einen I/O-Port des 8-Bit-Teils +(ueber 8-Bit-/16-Bit-Koppelschnittstelle (PIO0)) +Input: rl0 - Portadresse + rh0 - auszugebendes Datenbyte +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + KP_OUTB procedure + entry + di vi + push @r15, r0 + + ldb rh0, #STAT8_WRITE + calr TYWR_KOPPEL_INT !Portadresse und Write-Status ausgeben! + + pop r0, @r15 + push @r15, r0 + ldb rl0, rh0 !auszugebendes Datenbyte! + ldb rh0, #STAT8_ENDE !Ende-Status! + calr TYWR_KOPPEL_POL !Datenbyte und Ende-Status ausgeben! + + pop r0, @r15 + ei vi + ret + end KP_OUTB + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE KP_INB +Eingabe eines Bytes von einem I/O-Port des 8-Bit-Teils +(ueber 8-Bit-/16-Bit-Koppelschnittstelle (PIO1)) +Input: rl0 - Portadresse +Output: rh0 - eingelesenes Datenbyte +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + KP_INB procedure + entry + di vi + ldb rh0, #STAT8_READ + calr TYWR_KOPPEL_INT !Portadresse und Read-Status ausgeben! + +KPINB1: + inb rh0, PIO0D_B + bitb rh0, #5 !DATEN DA?! + jr nz, KPINB1 !nein! + + inb rh0, PIO1D_B !Status-Eingabe! + andb rh0, #%7E + cpb rh0, #STAT16_ENDE + jr nz, KPINB1 + + inb rh0, PIO1D_A !eingelesenes Datenbyte! + ei vi + ret + end KP_INB + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE TYRDWR +Einlesen eines Zeichens aus Interrupt-Eingabepuffer (PTYBFF) und +Ausgabe auf Terminal +Output: rl0 - eingelesenes Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + TYRDWR procedure + entry + calr TYRD + calr TYWR + ret + end TYRDWR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE RD_LINE_BFF +Zeile aus Interrupt-Eingabepuffer PTYBFF lesen, in Zwischenpuffer abspeichern +und auf Terminal ausgeben +Input: r1 - max. Zeilenlaenge + r2 - Anfangsadresse Zwischenpuffer +Output: r1 - Anzahl der uebertragenen Zeichen + r2 - zeigt auf Zeilenende + Z=1, wenn max. Zeilenlaenge erreicht wurde +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + RD_LINE_BFF procedure + entry + ld MAXLEN, r1 +RDL_NEU: + clr r1 +RDL_LOOP: + calr TYRDWR !ZEICHEN LESEN UND AUSGEBEN! + bitb FLAG1, #%03 !NUR GROSSBUCHSTABEN ERLAUBT ?! + jr nz, RDL_TST !nein! + cpb rl0, #'a' + jr c, RDL_TST + cpb rl0, #'{' + jr nc, RDL_TST + resb rl0, #%05 !KLEINBUCHST. IN GROSSBUCHST. WANDELN ! + +RDL_TST: + ldb r2(r1), rl0 !Zeichen in Zwischenpuffer abspeichern! + cpb rl0, CHRDEL + jr z, _CL + cpb rl0, LINDEL + jr z, _CR + cpb rl0, #CR + jr z, RDL_END + inc r1, #%01 + cp r1, MAXLEN !MAXIMALE ZEILENLAENGE ERREICHT ?! + JR C,RDL_LOOP !SPRUNG WENN NICHT! + setflg z + ret +_CL: + calr CLRCHR + jr pl, RDL_LOOP + ldb rl0, PROMT !PROMT-Zeichen wurde durch CHRDEL geloescht + --> PROMT-Zeichen neu ausgeben! + calr TYWR + jr RDL_NEU !ZEILE NEU EINGEBEN! +_CR: + test r1 !EINGEGEBEN ZEICHENKETTE LOESCHEN! + jr z, RDL_LOOP + ldb rl0, #BS + calr TYWR + calr CLRCHR + jr _CR +RDL_END: + ldb rl0, #LF + calr TYWR + lda r2, r2(r1) !R2 AUF Zeilenende STELLEN! + resflg z + ret + end RD_LINE_BFF + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE RD_LINE_INBFF +Einlesen einer Kommandozeile bis CR aus Interrupt-Eingabepuffer (PTYBFF) in +Eingabepuffer (INBFF) und Ausgabe auf Terminal +Output: rl0 - 1. Zeichen der Eingabezeile ungleich Space + INPTR zeigt auf dieses Zeichen + Z=1, wenn dieses Zeichen = CR +Fehler, wenn Zeile laenger als 128 Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + RD_LINE_INBFF procedure + entry + ld r2, #INBFF + ld r1, #%80 !MAXLEN LADEN! + ld INPTR, #0 !EINGABEZEIGER LOESCHEN! + calr RD_LINE_BFF !Zeile aus PTYBFF in INBFF speichern und + auf Terminal ausgeben! + jp z, ERROR !Pufferende erreicht! + + calr GET_SIGNW !rl0:=1.Zeichen aus INBFF ungleich Space! + dec INPTR, #%01 !INPTR zeigt auf dieses Zeichen! + cpb rl0, #CR !Z=1, wenn Zeichen = CR! + ret + end RD_LINE_INBFF + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE CLRCHR +Loeschen eines Zeichens +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + CLRCHR procedure + entry + ldb rl0, #' ' + calr TYWR + ldb rl0, #BS + calr TYWR + dec r1, #%01 + ret + end CLRCHR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_CRLF +Ausgabe CR LF auf Terminal +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + WR_CRLF procedure + entry + ldb rl0, #CR + calr TYWR + ldb rl0, #LF + calr TYWR + calr WR_NULL + ret + end WR_CRLF + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_NULL +Ausgabe einer bestimmten Anzahl Nullen auf Terminal (entsprechend NULLCT) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + WR_NULL procedure + entry + test NULLCT + ret z + ld r1, NULLCT + clr r0 +WR_NULL1: + calr TYWR + dec r1, #1 + jr nz, WR_NULL1 + ret + end WR_NULL + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_MSG +Zeichenketten-Ausgabe auf Terminal +Ausgabe wird bei CR beendet +Input: r2 - Adresse der Zeichenkette + (Zeichenkette beginnt mit Angabe der Laenge (WORD) gefolgt + von der Zeichenkette selbst) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + WR_MSG procedure + entry + ld r0, @r2 + cp r0, #%0 !LAENGE = 0? ! + ret z + ld OUTPTR, r0 + inc r2, #%02 !ADRESSE DES 1. CHAR.! + ld r4, #OUTBFF !OUTBFF_ADRESSE LADEN! + ldirb @r4, @r2, r0 !MESSAGE TRANSFERIEREN! + calr WR_OUTBFF + ret + end WR_MSG + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_OUTBFF_CR +Ausgabe des Inhaltes des Ausgabepuffers (OUTBFF) mit CR auf Terminal; +Loeschen des Ausgabepuffers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + WR_OUTBFF_CR procedure + entry + ld r3, OUTPTR + ldb OUTBFF(r3), #%0D + inc OUTPTR, #1 + calr WR_OUTBFF + ret + end WR_OUTBFF_CR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_OUTBFF +Ausgabe des Inhaltes des Ausgabepuffers (OUTBFF) auf Terminal; +Loeschen des Ausgabepuffers +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + WR_OUTBFF procedure + entry + clr r3 !ZEICHENZAEHLER LOESCHEN! +TX_1: + ldb rl0, OUTBFF(r3) + inc r3, #1 + calr TYWR + jr z, TX_2 !SPRUNG WENN CR AUSGEGEBEN WURDE! + cp r3, OUTPTR !ALLE ZEICHEN AUSGEBEN ? ! + jr c, TX_1 !SPRUNG WENN PUFFER NICHT LEER! + jr BF_EMPTY +TX_2: + ldb rl0, #LF !LINE FEED NACH MSG SENDEN! + calr TYWR + calr WR_NULL !NULLCT Nullen senden! + bitb FLAG1, #%04 !AUSGABE BEI CR ABBRECHEN ? ! + jr nz, TX_1 +BF_EMPTY: + ld OUTPTR, #0 ! OUTPTR RUECKSETZTEN ! + ld r0, #%0040 + ld OUTBFF, #' ' + ld r2, #OUTBFF !OUTBFF LOESCHEN ! + ld r4, #OUTBFF + 2 + ldir @r4, @r2, r0 + ret + end WR_OUTBFF + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE HTOB +Konvertierung Hexaziffer (ASCII) in Binaerwert +Input: rl0 - Hexaziffer (ASCII) +Output: rl0 - Binaerwert + C=1 --> keine Hexaziffer (Fehler) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + HTOB procedure + entry + cpb rl0, #'0' + ret c !FEHLER := KEINE ZAHL! + cpb rl0, #'9' + 1 + jr c, HTOB1 !SPRUNG WENN ZAHL! + cpb rl0, #'A' + ret c !FEHLER := KEIN BUCHSTABE! + cpb rl0, #'F' + 1 + jr nc, HTOB2 !FEHLER := KEIN BUCHSTABE A...F! + subb rl0, #%07 +HTOB1: + andb rl0, #%0F !FEHLERFREI! + resflg c + ret +HTOB2: + setflg c !FEHLER := KEINE HEXADEZIMALZAHL! + ret + end HTOB + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE BTOH16 +Konvertierung Binaer in Hexaziffern (ASCII) und Eintragung in +Ausgabepuffer (OUTBFF) +Input: r5 - 16-Bit-Wert (--> 4 Hexaziffern) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + BTOH16 procedure + entry + ldb rh0, rh5 !HIGH ADRESSE LADEN! + calr BTH + calr BTOH8 + ret + end BTOH16 + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE BTOH8 +Konvertierung Binaer in Hexaziffern (ASCII) und Eintragung in +Ausgabepuffer (OUTBFF) +Input: rl5 - 8-Bit-Wert (--> 2 Hexaziffern) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + BTOH8 procedure + entry + ldb rh0, rl5 !LOW ADRESSE ODER 8-BIT WERT LADEN! +BTH: + rldb rl0, rh0 + calr BTOH4 !BINAER TO HEX KONVERTIERUNG! + rldb rl0, rh0 + calr BTOH4 + ret + end BTOH8 + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE BTOH4 +Konvertierung Binaer in Hexaziffer (ASCII) und Eintragung in +Ausgabepuffer (OUTBFF) +Input: rl0 (Bit0-3) - 4-Bit-Wert (--> 1 Hexaziffer) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + BTOH4 procedure + entry + push @r15, r1 + andb rl0, #%0F + ldb rl1, KONV + addb rl1, rl0 + ldb KONV, rl1 + cpb rl0, #%0A + jr c, BTOH41 + addb rl0, #%07 +BTOH41: + addb rl0, #%30 + push @r15, r6 + ld r6, OUTPTR + ldb OUTBFF(r6), rl0 + inc OUTPTR, #1 + pop r6, @r15 + pop r1, @r15 + ret + end BTOH4 + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET_CHR +aus Eingabepuffer INBFF das Zeichen in rl0 bereitstellen, auf das INPTR zeigt +Output: rl0 - Zeichen + INPTR zeigt auf darauffolgendes Zeichen + Z=1 --> Zeichen=CR +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET_CHR procedure + entry + push @r15, r2 + ld r2, INPTR + ldb rl0, INBFF(r2) + inc INPTR, #1 !INPTR := INPTR + 1! + cpb rl0, #CR + pop r2, @r15 + ret + end GET_CHR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET_SIGN +aus Eingabepuffer INBFF ab Position INPTR (einschl.) Space suchen und naechstes +Zeichen ungleich Space in rl0 bereitstellen +Output: rl0 - Zeichen + INPTR zeigt auf darauffolgendes Zeichen + Z=1 --> CR gelesen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET_SIGN procedure + entry + calr GET_CHR + ret z !RUECKSPRUNG WENN ENDEKENNUNG (CR)! + cpb rl0, #' ' + jr nz, GET_SIGN !1. SPACE NACH DEM KOMMANDO SUCHEN! + calr GET_SIGNW + ret + end GET_SIGN + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET_SIGNW +aus Eingabepuffer INBFF ab Position INPTR (einschl.) erstes Zeichen ungleich +Space in rl0 bereitstellen +Output: rl0 - Zeichen + INPTR zeigt auf darauffolgendes Zeichen + Z=1 --> CR gelesen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET_SIGNW procedure + entry + calr GET_CHR !1. ZEICHEN DER PARAMETERFOLGE LESEN! + ret z !Zeichen=CR! + cpb rl0, #' ' + jr z, GET_SIGNW + ret !Z=0! + end GET_SIGNW + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET_SGNR +Einlesen (aus Eingabepuffer INBFF) und Konvertierung der Segmentnummer +Input: rl0 - 1. Zeichen der eingegebenen Adresse + INPTR zeigt auf darauffolgendes Zeichen +Output: r2 - Segmentnummer (Bit0-7=0 / Bit8-14=segnr / Bit15=1) + (falls kein Segmentnummer angegeben, dann r2=PC_SEG) + rl0 - 1. Zeichen der Offsetadresse + INPTR zeigt auf darauffolgendes Zeichen +Fehler, wenn unzulaessige Segmentnummer angegeben +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET_SGNR procedure + entry + ld r2, PC_SEG !implizite segnr! + set r2, #%0F !Setzen Bit15! + resb FLAG1, #%0 !Flag=0 --> keine Segmentnummer angegeben ???! + cpb rl0, #CR + ret z !Ende der Eingabezeile! + cpb rl0, #'<' !#SEGMENT IDENTIFIER ANF. ! + ret nz !keine Segmentnummer angegeben! + clr r3 +EKSN_N: + calr GET_CHR !rl0:=naechstes Zeichen aus INBFF! + jp z, ERROR !Zeichen=CR! + calr HTOB !Konvertierung rl0 hexa (ASCII)-->binaer! + jr c, EKSN_NHZ !keine Hexaziffer! + rldb rl0, rl3 !Binaerwert in rl3 schieben! + jr EKSN_N !naechstes Zeichen! + +EKSN_NHZ: + cpb rl0, #'>' !#SEGMENT IDENTIFIER ENDE! + jp nz, ERROR !segnr enthaelt unzulaessiges Zeichen! + calr GET_SIGNW !rl0:=Zeichen nach segnr ungleich Space! + ldb rh2, rl3 + clrb rl2 + set r2, #%0F !r2 := segnr! + setb FLAG1, #%0 !Flag=1 --> Segmentnummer angegeben ???! + ret + end GET_SGNR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET_HEXZ +Einlesen (aus Eingabepuffer INBFF) und Konvertierung einer Hexazahl +Input: rl0 - 1. Ziffer der eingegebenen Hexazahl + INPTR zeigt auf darauffolgendes Zeichen +Output: r3 - Hexazahl (binaer) - wurden mehr als 4 Ziffern angegeben, so + werden die letzten 4 Ziffern ausgewertet + rl0 - naechstes Zeichen aus Eingabepuffer ungleich Space nach + ausgewerteter Hexazahl + INPTR zeigt auf darauffolgendes Zeichen + C=1 --> keine Hexazahl angegeben + Z=1 --> CR gelesen +Fehler, wenn unzulaessige Hexazahl angegeben +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET_HEXZ procedure + entry + clr r3 + cpb rl0, #CR + setflg c + ret z +RD_HX: + calr HTOB !Konvertierung rl0 in Binaerwert! + jp c, ERROR !unzulaessige Hexaziffer! + rldb rl0, rl3 + rldb rl0, rh3 + calr GET_CHR !rl0 := naechste Ziffer! + ret z !CR gelesen (C=0 aus GET_CHR)! + cpb rl0, #' ' + jr nz, RD_HX !naechste Ziffer! + + calr GET_SIGNW !rl0:= naechstes Zeichen ungleich Space! + resflg c + ret !Z=1, wenn CR gelesen; sonst Z=0 + (aus GET_SIGNW)! + end GET_HEXZ + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET_ADR +Einlesen (aus Eingabepuffer INBFF) und Konvertierung einer Adresse +(eingegebene Adresse muss folgenden Aufbau haben: 'offset', wobei +die Segmentnummer fehlen kann) +Input: rl0 - 1. Zeichen der Adresse + INPTR zeigt auf darauffolgendes Zeichen +Output: rr2 - Adresse (binaer) + rl0 - naechstes Zeichen ungleich Space aus Eingabepuffer nach + ausgewerteter Adresse + INPTR zeigt auf darauffolgendes Zeichen + C=1 --> keine Adresse angegeben + Z=1 --> CR gelesen +Fehler, wenn ungueltige Hexaziffer angegeben +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET_ADR procedure + entry + calr GET_SGNR !r2 := Segmentnummer! + calr GET_HEXZ !r3 := Offset! + ret + end GET_ADR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET_PAR +Einlesen (aus Eingabepuffer INBFF) und Konvertierung der Parameterfolge: +'offset1 offset2 word', wobei fehlen kann +Output: c=1 wenn Parameterfolge unvollst. oder fehlerhaft + rr6 - 1. Adresse (binaer) + rr4 - 2. Adresse (binaer) + r3 - word (binaer) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET_PAR procedure + entry + calr GET_SIGN !1. ASCII-ZEICHEN IN RL0! + calr GET_ADR !rr2 := 1. Adresse! + jr z, RD_P2 !CR wurde gelesen! + ldl rr6, rr2 !rr6 := 1. Adresse! + calr GET_ADR !rr2 := 2. Adresse! + jr z, RD_P2 !CR wurde gelesen! + ldl rr4, rr2 !rr4 := 2. Adresse! + calr GET_HEXZ !r3 := word! + ret nc !kein Fehler! + +RD_P2: + setflg c !C=1, d.h. Fehler! + ret + end GET_PAR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE RD_DATA +Dateneingabe (PROMT-Zeichen (':') ausgeben, eingegebene Zeile aus PTYBFF + in INBFF speichern, auf Terminal ausgeben und 1. Datenwert der + Zeile auswerten) +Output: rr2 enthaelt Datenwert + Z=1, wenn keine Dateneingabe erfolgte bzw. 'Q' oder '-' eingegeben + C=1, wenn 'Q' oder '-' eingegeben (rl0 enthaelt dann 'Q' oder '-') + Z=0, wenn Dateneingabe erfolgte (rr2 enthaelt dann Datenwert) mit: + P/V=1, wenn CR nach Datenwert, + C=0, wenn Space nach Datenwert + INPTR zeigt auf 2 Zeichen nach der letzten Ziffer des Datenwertes +Fehler, wenn ungueltige Hexazahl eingegeben wurde +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + RD_DATA procedure + entry + ldb rl0, #':' + calr TYWR !Ausgabe ':' auf Terminal! + calr RD_LINE_INBFF !Zeile aus PTYBFF in INBFF speichern und + auf Terminal ausgeben! + calr GET_DATA + ret + end RD_DATA + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE GET_DATA +Dateneingabe (Einlesen des naechsten Datenwertes aus Eingabepuffer INBFF) +Input: INPTR zeigt auf das erste auszuwertende Zeichen des Datenwertes + bzw. auf Space davor +Output: rr2 enthaelt Datenwert + Z=1, wenn keine Dateneingabe erfolgte bzw. 'Q' oder '-' eingegeben + C=1, wenn 'Q' oder '-' eingegeben (rl0 enthaelt dann 'Q' oder '-') + Z=0, wenn Dateneingabe erfolgte (rr2 enthaelt dann Datenwert) mit: + P/V=1, wenn CR nach Datenwert, + C=0, wenn Space nach Datenwert + INPTR zeigt auf 2 Zeichen nach der letzten Ziffer des Datenwertes +Fehler, wenn ungueltige Hexazahl eingegeben wurde +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + GET_DATA procedure + entry + clr r2 + clr r3 + calr GET_SIGNW !rl0:=1. Zeichen des Datenwertes! + ret z !Z=1, kein Datenwert (CR)! + + cpb rl0, #'Q' !QUIT ? ! + jr z, K_Q + cpb rl0, #'-' + jr nz, K_LOOP +K_Q: + setflg c + ret !Z=1, C=1: 'Q' oder '-' eingegeben! + +K_LOOP: + calr HTOB !Konv. rl0 (Hexa-ASCII) --> rl0 (binaer)! + jp c, ERROR !keine Hexaziffer! + + rldb rl0, rl3 + rldb rl0, rh3 + rldb rl0, rl2 + rldb rl0, rh2 !Hexaziffer (binaer) in rr2 schieben! + calr GET_CHR !rl0:=naechstes Zeichen aus INBFF! + jr nz, K_1 !kein CR! + + setflg p, v + jr K_END !Z=0, P/V=1, wenn CR nach Datenwert! +K_1: + cpb rl0, #' ' + jr nz, K_LOOP !naechste Ziffer des Datenwertes! + + resflg c !Z=0, C=1, wenn Space nach Datenwert! +K_END: + resflg z + ret + end GET_DATA + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_R5_RDDATA +Eintragung des ASCII-konvertierten Inhaltes von r5 in Ausgabepuffer (OUTBFF); +Ausgabe des Ausgabepuffers auf Terminal; Ausgabe ':'; Eingabe des Datenwertes +Input: r5 - Adresse +Output: siehe Prozedur RD_DATA +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + WR_R5_RDDATA procedure + entry + calr BTOH16 !Eintragung r5 (ASCII) in OUTBFF! + inc OUTPTR, #1 !1 Leerzeichen! + calr WR_OBF_RDDATA + ret + end WR_R5_RDDATA + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE WR_OBF_RDDATA +Ausgabe des Ausgabepuffers auf Terminal; Ausgabe ':'; Eingabe des Datenwertes +Output: siehe Prozedur RD_DATA +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + WR_OBF_RDDATA procedure + entry + calr WR_OUTBFF !Ausgabe Inhalt OUTBFF! + calr RD_DATA !AUSGABE ':' + EINGABE NEUER INHALT! + ret + end WR_OBF_RDDATA + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE PUT_CHR +Eintragung eines Zeichens in Ausgabepuffer (OUTBFF) +Input: rl1 - einzutragendes Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + PUT_CHR procedure + entry + ld r2, OUTPTR + ldb OUTBFF(r2), rl1 + inc OUTPTR, #1 + ret + end PUT_CHR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE PUT_3C +Eintragung des Zeichens '<' in Ausgabepuffer (OUTBFF) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + PUT_3C procedure + entry + ld r1, #'< ' + calr PUT_1CHR + ret + end PUT_3C + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE PUT_1CHR +Eintragung eines Zeichens in Ausgabepuffer (OUTBFF) +Input: r1 - Zeichenkette aus 'Zeichen, Space' +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + INTERNAL + PUT_1CHR procedure + entry + calr PUT_2CHR !2 ZEICHEN IN DEN OUTPUT_PUFFER LADEN! + dec OUTPTR, #1 !PUFFERLAENGE DEKREMENTIEREN! + ret + end PUT_1CHR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE PUT_2CHR +2 Zeichen in Ausgabepuffer (OUTBFF) eintragen +Input: rh1 - 1. Zeichen + rl1 - 2. Zeichen +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + PUT_2CHR procedure + entry + push @r15, r4 + ld r4, OUTPTR + ldb OUTBFF(r4), rh1 + inc r4, #1 + ldb OUTBFF(r4), rl1 + inc OUTPTR, #%02 + pop r4, @r15 + ret + end PUT_2CHR + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE PUT_SEGNR +Konvertierung der Segmentnummer in HEXA-ASCII-Zahl (xx); +Eintragung von '' in Ausgabepuffer OUTBFF +Input: rl5 - Segmentnummer (binaer) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + PUT_SEGNR PROCEDURE + ENTRY + calr PUT_3C !Zeichen '<' in OUTBFF eintragen! + calr PUT_SGNR + ret + end PUT_SEGNR !Weiterlauf bei PUT_SGNR! + +!++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +PROCEDURE PUT_SGNR +Konvertierung der Segmentnummer in HEXA-ASCII-Zahl (xx); +Eintragung von 'xx>' in Ausgabepuffer OUTBFF +Input: rl5 - Segmentnummer (binaer) +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++! + + GLOBAL + PUT_SGNR PROCEDURE + ENTRY + resb rl5, #%07 + calr BTOH8 !Segmentnummer in OUTBFF eintragen! + ld r1, #'> ' + calr PUT_1CHR !Zeichen '>' in OUTBFF eintragen! + ret + end PUT_SGNR + +end p_term +