P8000/WEGA/src/cmd/BOOT0/boot0.ud.s

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