384 lines
8.1 KiB
ArmAsm
384 lines
8.1 KiB
ArmAsm
!******************************************************************************
|
|
*******************************************************************************
|
|
|
|
W E G A - Quelle (C) ZFT/KEAW Abt. Basissoftware - 1985
|
|
|
|
Standalone Module boot0.ud.s (primary bootstrapper)
|
|
|
|
|
|
Bearbeiter: P. Hoge
|
|
Datum: 04/01/87 11:20:40
|
|
Version: 1.1
|
|
|
|
*******************************************************************************
|
|
|
|
boot0 udos fuer einen Systemstart von den P8000-UDOS
|
|
Minidisketten
|
|
(primary bootstrapper)
|
|
|
|
bei automatischem boot bzw Eingabe von CR bei manuellem
|
|
boot nach der Meldung mit > wird das Programm boot
|
|
(secundary bootstrapper) von der Diskette des UDOS Systems
|
|
uber den Koppel-Kanal in den Speicher des U8000 Systems
|
|
(Segment 0, ab Adresse %8000) geladen.
|
|
Bei manuellem boot kann nach der Meldung mit > auch
|
|
ein anderer filename eingegeben werden.
|
|
boot0 benutzt den U8000 Monitor.
|
|
|
|
*******************************************************************************
|
|
******************************************************************************!
|
|
|
|
|
|
|
|
boot0_ud_s module
|
|
|
|
|
|
$SECTION boot0
|
|
|
|
|
|
constant
|
|
|
|
MOVE_ADR := %F800
|
|
LOAD_ADR := %8000
|
|
|
|
TTIN := %04
|
|
TTWR := %06
|
|
UDIN := %20
|
|
UDWR := %22
|
|
|
|
ESC := %1B
|
|
ETX := %03
|
|
ACK := %06
|
|
CAN := %18
|
|
STX := %02
|
|
EOT := %04
|
|
NAK := %15
|
|
|
|
typ := %01 !binary file!
|
|
|
|
|
|
global
|
|
|
|
!*---------------------------------------------------------------------------*!
|
|
!*
|
|
* eigentliches Programm von 8000 auf F800 moven
|
|
*!
|
|
!*---------------------------------------------------------------------------*!
|
|
|
|
|
|
START procedure
|
|
entry
|
|
ld r2, #%5800 !nonsegmented Systemmode!
|
|
ldctl FCW, r2 !fcw setzen!
|
|
ldb rh2, #(MOVE_ADR shr 8)
|
|
ldar r1, MAIN !Quelladr!
|
|
ld r15, r2
|
|
ld r14, #%200
|
|
ldirb @r2, @r1, r14
|
|
jp @r15
|
|
end START
|
|
|
|
!Dieses Programm ist voll relativ!
|
|
!Es wird auf MOVE_ADR gemoved!
|
|
|
|
|
|
!*---------------------------------------------------------------------------*!
|
|
!*
|
|
* Main Procedure
|
|
* Eingabe filename bei manuellem boot
|
|
* (bzw Standardname fuer secundary boot bei automatischem boot)
|
|
* Uebertragung filename an UDOS System, warten auf Bestaetigung
|
|
* dass file vorhanden, Start der blockweisen Fileuebertragung
|
|
* Laden ab Adr 8000 hex, Segment 0
|
|
* Starten des Programms
|
|
*!
|
|
!*---------------------------------------------------------------------------*!
|
|
|
|
MAIN procedure
|
|
entry
|
|
pushl @r15, rr6 !Monitor Parameter retten!
|
|
pushl @r15, rr4
|
|
test r4 !0=automatischer Boot!
|
|
jr nz, MAIN_LOOP !manueller Boot r14 ist 0!
|
|
|
|
ldar r14, MSG_BOOT !autom.:boot Kommando laden!
|
|
MAIN_LOOP:
|
|
ldar r8, MSG_PROMPT
|
|
calr PRINT_MSG
|
|
ldar r10, CON_BUFFER
|
|
ld r11, r10 !r11 Anf adr Puffer!
|
|
inc r11, #%0E !Ende Puffer!
|
|
MAIN3:
|
|
ld r12, r10 !r12 aktueller Puffer Pointer!
|
|
MAIN4:
|
|
calr GETA
|
|
cpb rl0, #%0A !lf = Ende der Eingabe!
|
|
jr z, MAIN5
|
|
cpb rl0, #'/' !Eingabe loeschen!
|
|
jr z, MAIN3 !Eingabe wiederholen!
|
|
|
|
ldb @r12, rl0 !Zeichen in Puffer!
|
|
inc r12, #%01 !Pointer inc!
|
|
cp r12, r11
|
|
jr ge, MAIN3 !Eingabe zu lang neu anfangen!
|
|
jr MAIN4 !naechstes Zeichen!
|
|
|
|
MAIN5: !Ende der Eingabe!
|
|
clrb @r12 !letztes Byte im Puffer = 0!
|
|
|
|
!boot file open!
|
|
|
|
ld r2, r10
|
|
calr udopen
|
|
test r1
|
|
jr nz, MAIN9
|
|
|
|
!boot file lesen!
|
|
|
|
lda r2, LOAD_ADR
|
|
ld r9, r2
|
|
calr udread !1. Block der file lesen!
|
|
test r1
|
|
jr nz, MAIN9 !Fehler!
|
|
|
|
cp @r9, #%E707 !Magic Nr!
|
|
!=nonsegmented, executable!
|
|
jr nz, MAIN7 !Fehler falsche Magic!
|
|
ld r11, %10(r9) !Entry Point des Programms!
|
|
ld r0, #%18 !size header!
|
|
add r0, %0A(r9) !size segment table!
|
|
ld r10, r9 !LOAD_ADR!
|
|
add r9, r0 !Anfangsadr Programmcode!
|
|
neg r0
|
|
add r0, r6 !%200-header-segmtable!
|
|
ldirb @r10, @r9, r0 !Move Code auf LOAD_ADR!
|
|
|
|
ld r2, r10
|
|
calr udread !alle weiteren Bloecke lesen!
|
|
test r1
|
|
jr nz, MAIN9 !Fehler!
|
|
|
|
!Ok!
|
|
ld r15, #MOVE_ADR - 8 !Stackpointer fuer Parameter neu setzen!
|
|
popl rr4, @r15 !Rueckladen der Monitor Parameter!
|
|
popl rr6, @r15
|
|
jp @r11 !Sprung zum geladenen Programm!
|
|
|
|
MAIN7:
|
|
calr uderror
|
|
ldar r8, MSG_ERROR !Fehler, neue Kommandoeingabe!
|
|
MAIN8:
|
|
calr PRINT_MSG
|
|
ldk r14, #0 !nanuel boot setzen!
|
|
jr MAIN_LOOP
|
|
|
|
MAIN9:
|
|
ldar r8, MSG_NO_LOAD
|
|
jr MAIN8 !Fehler!
|
|
end MAIN
|
|
|
|
internal
|
|
|
|
!*---------------------------------------------------------------------------*!
|
|
!*
|
|
* Ein- Ausgaben an UDOS System
|
|
*!
|
|
!*---------------------------------------------------------------------------*!
|
|
|
|
PRINT_MSG procedure
|
|
entry
|
|
ldb rl0, @r8
|
|
testb rl0
|
|
ret z !Ausgabe message bis 00!
|
|
calr PRINT_CHAR
|
|
inc r8, #%01
|
|
jr PRINT_MSG
|
|
end PRINT_MSG
|
|
|
|
SET_BOOT procedure
|
|
entry
|
|
ldar r14, MSG_BOOT
|
|
end SET_BOOT !laeuft in GETA weiter!
|
|
|
|
GETA procedure
|
|
entry
|
|
test r14
|
|
jr z, GETA1
|
|
ldb rl0, @r14 !Zeichen nicht ueber CON!
|
|
!sondern aus Message holen!
|
|
inc r14, #%01
|
|
jr GETA2
|
|
|
|
!Zeichen von CON holen!
|
|
|
|
GETA1:
|
|
push @r15, r3
|
|
sc #TTIN
|
|
ld r0, r3
|
|
pop r3, @r15
|
|
GETA2:
|
|
resb rl0, #%07 !reset bit 7!
|
|
cpb rl0, #%0D
|
|
jr nz, PRINT_CHAR !Zeichen ausgeben!
|
|
ldk r0, #%0A !cr in lf!
|
|
end GETA !laueft in PRINT_CHAR weiter!
|
|
|
|
PRINT_CHAR procedure
|
|
entry
|
|
cpb rl0, #%0A !Zeichen = LF ?!
|
|
jr nz, PUTA !nein noudal Ausgeben!
|
|
cp r12, r10 !r12=r10=kein Zeichen eingegeben!
|
|
jr z, SET_BOOT !Boot Kommando laden!
|
|
ldk r14, #%00 !Kommando ueber CON eingeben setzen!
|
|
ldk r0, #%0D !cr lf ausgeben!
|
|
calr PUTA
|
|
ldk r0, #%0A
|
|
end PRINT_CHAR
|
|
|
|
PUTA procedure
|
|
entry
|
|
push @r15, r3
|
|
sc #TTWR
|
|
pop r3, @r15
|
|
ret
|
|
end PUTA
|
|
|
|
!*---------------------------------------------------------------------------*!
|
|
!*
|
|
* Fileuebertragung mit UDOS System
|
|
*!
|
|
!*---------------------------------------------------------------------------*!
|
|
|
|
!input r2 Pointer zu filename string!
|
|
|
|
udopen procedure
|
|
entry
|
|
ldk r5, #0
|
|
ldr udflag, r5 !init udflag!
|
|
ldb rl0, #'S' !Kommando Send!
|
|
sc #UDWR
|
|
sc #UDIN !acknowledge von udos!
|
|
|
|
ldb rl0, #typ !file typ an udos!
|
|
sc #UDWR
|
|
sc #UDIN !acknowledge von udos!
|
|
|
|
!Ausgabe filename an udos!
|
|
ldb rh7, #10 !retries!
|
|
ld r5, r2
|
|
udo0: ldb rl7, #0 !Checksumme init!
|
|
ld r2, r5
|
|
ldb rl0, #STX !Start of Text!
|
|
sc #UDWR
|
|
|
|
udo1: ldb rl0 ,@r2 !Zeichen von filename!
|
|
inc r2, #1
|
|
cpb rl0, #0 !ende filename ?!
|
|
jr z, udo2
|
|
xorb rl7, rl0 !Checksumme berechnen!
|
|
sc #UDWR
|
|
jr udo1
|
|
|
|
udo2: ldb rl0, #ETX !end of text!
|
|
sc #UDWR
|
|
exb rl0, rl7
|
|
sc #UDWR !Checksumme ausgeben!
|
|
sc #UDIN !Warten auf Quittung!
|
|
resb rl3, #7
|
|
cpb rl3, #ACK
|
|
ldk r1, #0 !kein Fehler!
|
|
ret z !filename richtig uebertragen, file vorhanden!
|
|
cpb rl3, #CAN !Abbrechen ?!
|
|
jr z, uderror
|
|
dbjnz rh7, udo0 !naechster Versuch!
|
|
end udopen
|
|
|
|
uderror procedure
|
|
entry
|
|
ldb rl0, #CAN !Abbruch zurueck senden!
|
|
sc #UDWR
|
|
ld r1, #-1 !Error setzen!
|
|
end uderror
|
|
|
|
udclose procedure
|
|
entry
|
|
sc #UDIN
|
|
ret
|
|
end udclose
|
|
|
|
udread procedure
|
|
entry
|
|
ldb rh7, #10 !retries!
|
|
ldk r1, #0 !kein Fehler!
|
|
ldr r0, udflag
|
|
test r0
|
|
jr z, udr0 !Sprung 1.Aufruf!
|
|
ldb rl0, #ACK !Ack fuer letzen Aufruf!
|
|
sc #UDWR
|
|
|
|
udr0: ldb rl7, #0 !Checksumme init!
|
|
ld r5, r2 !Buffer Pointer retten!
|
|
sc #UDIN
|
|
resb rl3, #7
|
|
cpb rl3, #EOT
|
|
jr z, udclose !file fertig uebertragen!
|
|
|
|
cpb rl3, #CAN
|
|
jr z, uderror !udos gibt Abbruch!
|
|
cpb rl3, #ESC
|
|
jr z, uderror
|
|
|
|
cpb rl3, #STX !Start of text muss 1.Zeichen sein!
|
|
jr nz, udr2 !warten auf ETX und Uebertragung wiederholen!
|
|
|
|
sc #UDIN
|
|
ldb rh4, rl3 !high count!
|
|
sc #UDIN
|
|
ldb rl4, rl3 !low count!
|
|
ld r6, r4
|
|
udr1: sc #UDIN !Daten lesen!
|
|
ldb @r2, rl3 !in Buffer!
|
|
inc r2, #1
|
|
xorb rl7, rl3 !Checksumme berechnen!
|
|
djnz r4, udr1
|
|
|
|
udr2: sc #UDIN !warten auf ETX!
|
|
resb rl3, #7
|
|
cpb rl3, #ESC
|
|
jr z, uderror
|
|
cpb rl3, #CAN
|
|
jr z, uderror
|
|
cpb rl3, #ETX
|
|
jr nz, udr2
|
|
|
|
sc #UDIN !Checksumme!
|
|
cpb rl3, rl7 !uebertragene = berechnete ?!
|
|
jr nz, udr3
|
|
|
|
ldr r0, udflag
|
|
test r0
|
|
ldr udflag, r7 !r7 ist ungleich 0!
|
|
jr nz, udread !naechsten Block!
|
|
ret !nur nach 1. Block!
|
|
|
|
udr3: decb rh7, #1
|
|
jr z, uderror !Abbruch!
|
|
|
|
ldb rl0, NAK !n mal wiederholen!
|
|
ld r2, r5 !Buffer Pointer auf Anfang zurueck!
|
|
sc #UDWR
|
|
jr udr0
|
|
end udread
|
|
|
|
|
|
|
|
MSG_PROMPT array [* byte] := '> %00'
|
|
MSG_BOOT array [* byte] := 'boot%l'
|
|
MSG_ERROR array [* byte] := 'invalid file%l%00'
|
|
MSG_NO_LOAD array [* byte] := 'cannot load boot file%l%00'
|
|
|
|
udflag word
|
|
CON_BUFFER array [%0F byte]
|
|
|
|
end boot0_ud_s
|