monroe_oc8820_r3.00.asm 87 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153
  1. ; ================================================================================
  2. ; Monroe OC8820 Boot ROM Disassembly - Version R3.00C
  3. ; ================================================================================
  4. ; Original file: monroe_oc8820_boot_prom_r3_00C_tms2516_ea751e22.bin
  5. ; ROM Type: TMS2516 (2KB EPROM)
  6. ; Disassembler: z80dasm 1.1.6
  7. ;
  8. ; This is the boot ROM for the Monroe OC8820 computer system.
  9. ; The system uses a Z80 CPU with bank-switched memory architecture.
  10. ;
  11. ; Memory Map:
  12. ; 0x0000-0x07FF : Boot ROM (this code)
  13. ; 0x3000-0x3FFF : Display memory
  14. ; 0xC000-0xFFFF : Banked RAM (controlled by I/O ports)
  15. ; 0xFF80-0xFFFF : System variables area
  16. ;
  17. ; I/O Port Map:
  18. ; 0x78-0x7B : Hard disk controller (DMA-based)
  19. ; 0xA0 : DART A (Dual Async Receiver/Transmitter) - Channel A data (printer)
  20. ; 0xA1 : DART A (Dual Async Receiver/Transmitter) - Channel A command
  21. ; 0xA2 : DART B (Dual Async Receiver/Transmitter) - Channel B data (keyboard)
  22. ; 0xA3 : DART B (Dual Async Receiver/Transmitter) - Channel B command
  23. ; 0xA4 : SIO A (Serial I/O) - Channel A data (comm)
  24. ; 0xA5 : SIO A (Serial I/O) - Channel A command
  25. ; 0xA6 : SIO B (Serial I/O) - Channel B data (RS-232C)
  26. ; 0xA7 : SIO B (Serial I/O) - Channel B command
  27. ; 0xA8 : CTC (Counter Timer Circuit) - Channel 0 (Communications baud)
  28. ; 0xA9 : CTC Channel 1 (AUX RS-232C baud)
  29. ; 0xAA : CTC Channel 2 (Printer baud)
  30. ; 0xAB : CTC Channel 3
  31. ; 0xB0-0xB3 : Floppy disk controller (WD179x family)
  32. ; 0xB0: Status/Command, 0xB2: Sector, 0xB3: Track
  33. ; 0xB4-0xB5 : Z80 PIO A data and control ports
  34. ; 0xB4: PIO A data (floppy INTRQ signal, DMA control), 0xB5: PIO A control
  35. ; 0xB8-0xB9 : CRT controller (6845 CRTC)
  36. ; 0xB8: Register select, 0xB9: Data
  37. ; 0xC0 : Floppy drive selection and control
  38. ; 0xC4 : Program map A base address (memory banking)
  39. ; 0xC5 : Program map B base address (memory banking)
  40. ; 0xC6 : DMA map A base address (floppy DMA control)
  41. ; 0xC7 : DMA map B base address (hard disk DMA control)
  42. ; 0xC8 : Map and system control register (banking enable/disable)
  43. ; 0xD4-0xD8 : Graphics and color control
  44. ; 0xFF : Hardware detection port
  45. ;
  46. ; Boot Device Selection System:
  47. ; The Monroe OC8820 features sophisticated multi-device boot capability:
  48. ;
  49. ; 1. HARDWARE AUTO-DETECTION (Port 0xFF):
  50. ; - Reading 0 = Floppy-only configuration
  51. ; - Reading 1 = Hard disk + floppy configuration
  52. ; - Reading 2+ = Advanced hard disk configuration
  53. ;
  54. ; 2. BOOT PRIORITY ORDER:
  55. ; - HARD DISK FIRST (when detected): Uses DMA controller at ports 0x78-0x7B
  56. ; - FLOPPY FALLBACK: Uses WD179x controller at ports 0xB0-0xB3 (PIO A at 0xB4-0xB5)
  57. ; - Systematic retry: Tests floppy drives 0-3 with 8 total attempts
  58. ; - Final recovery: Special commands 0x10/0x11 on Drive 0 only
  59. ;
  60. ; 3. DUAL OPERATING SYSTEM SUPPORT:
  61. ; - Monroe OS8 (proprietary system)
  62. ; - CP/M (industry standard)
  63. ; - Boot path selection via calculated jumps at 0x05D0
  64. ;
  65. ; Communication Specifications:
  66. ; DART A & B : High-speed serial (baud rate depends on system clock)
  67. ; SIO A & B : High-speed serial (same rate as DART ports)
  68. ; Printer Port : Lower-speed serial/parallel (baud rate depends on system clock)
  69. ; CTC Timing : Ch0/1: ÷16 prescaler, time const 3; Ch2: ÷256 prescaler, time const 78
  70. ; Number of memory banks to test
  71. ; CRT Display : 80 characters/line text mode (184 total horizontal timing)
  72. ; ================================================================================
  73. ; Constants
  74. displaymem: equ 0x3000 ; Start of display memory
  75. nomemchecks: equ 9 ; Number of memory banks to test (1-9)
  76. org 00000h
  77. ; ================================================================================
  78. ; RESET VECTOR AND BOOT SEQUENCE
  79. ; ================================================================================
  80. ; Z80 starts execution here after reset
  81. l0000h:
  82. di ;0000 Disable interrupts during boot
  83. ld sp,0ffa6h ;0001 Initialize stack pointer (top of RAM minus workspace)
  84. xor a ;0004 Clear A register (A=0)
  85. jp l_init ;0005 Jump to main initialization routine
  86. ; ================================================================================
  87. ; DISPLAY MESSAGE ROUTINE ENTRY POINT
  88. ; ================================================================================
  89. ; This routine is called to display text messages on screen
  90. ; Entry: DE = screen position, HL = message address
  91. ; Message format: first byte = length, followed by ASCII text
  92. display_entry:
  93. ld de,0303eh ;0008 Default screen position (row 3, col 62?)
  94. call cleartopline ;000b Clear the top line of display
  95. nop ;000e Padding
  96. nop ;000f Padding
  97. pop hl ;0010 Get return address (points to message)
  98. displaymsg:
  99. ld c,(hl) ;0011 Load message length from first byte
  100. inc hl ;0012 Point to message text
  101. ld b,000h ;0013 Clear B (BC now = message length)
  102. jp printroutine ;0015 Jump to print routine
  103. ; ================================================================================
  104. ; RST VECTOR TABLE (0x0018-0x003F)
  105. ; ================================================================================
  106. ; All RST vectors point to RST 38h (0x0038) - likely a common error handler
  107. ; The Z80 RST instructions provide fast calls to these addresses
  108. rst 38h ;0018 RST 18h -> RST 38h
  109. rst 38h ;0019
  110. rst 38h ;001a
  111. rst 38h ;001b
  112. rst 38h ;001c
  113. rst 38h ;001d
  114. rst 38h ;001e
  115. rst 38h ;001f
  116. rst 38h ;0020 RST 20h -> RST 38h
  117. rst 38h ;0021
  118. rst 38h ;0022
  119. rst 38h ;0023
  120. rst 38h ;0024
  121. rst 38h ;0025
  122. rst 38h ;0026
  123. rst 38h ;0027
  124. rst 38h ;0028 RST 28h -> RST 38h
  125. rst 38h ;0029
  126. rst 38h ;002a
  127. rst 38h ;002b
  128. rst 38h ;002c
  129. rst 38h ;002d
  130. rst 38h ;002e
  131. rst 38h ;002f
  132. rst 38h ;0030 RST 30h -> RST 38h
  133. rst 38h ;0031
  134. rst 38h ;0032
  135. rst 38h ;0033
  136. rst 38h ;0034
  137. rst 38h ;0035
  138. rst 38h ;0036
  139. rst 38h ;0037
  140. rst 38h ;0038 RST 38h - Common error handler
  141. rst 38h ;0039
  142. rst 38h ;003a
  143. rst 38h ;003b
  144. rst 38h ;003c
  145. rst 38h ;003d
  146. rst 38h ;003e
  147. rst 38h ;003f
  148. ; ================================================================================
  149. ; WARM BOOT AND RESTART VECTORS
  150. ; ================================================================================
  151. jp l0000h ;0040 Warm boot - restart system
  152. jp l0000h ;0043 Another restart vector
  153. ; ================================================================================
  154. ; MAIN SYSTEM INITIALIZATION
  155. ; ================================================================================
  156. ; This routine initializes all I/O controllers and system hardware
  157. l_init:
  158. out (0c0h),a ;0046 Clear floppy disk controller
  159. out (0c4h),a ;0048 Clear Program map A base address
  160. out (0c5h),a ;004a Clear Program map B base address
  161. out (0c6h),a ;004c Clear DMA map A base address
  162. out (0c7h),a ;004e Clear DMA map B base address
  163. out (0d4h),a ;0050 Clear Hi-res color control
  164. out (0d8h),a ;0052 Clear Hi-res graphics start address
  165. ld hl,PIOA_start ;0054 Point to I/O initialization data table
  166. jp l0562h ;0057 Jump to OTIR routine to initialize peripherals
  167. ; ================================================================================
  168. ; I/O CONTROLLER INITIALIZATION DATA TABLE
  169. ; ================================================================================
  170. ; This table contains initialization sequences for various Z80 peripheral chips
  171. ; Format: Port address, Count, Data bytes...
  172. ; Used by OTIR routine at 0562h
  173. ; BLOCK 'PIOA' (start 0x005a end 0x008b)
  174. PIOA_start:
  175. ; CRT Controller initialization (6845 compatible)
  176. defb 0b5h ;005a I/O port: CRT register select
  177. defb 004h ;005b Count: 4 bytes to follow
  178. defb 0cfh ;005c Reg 0: Horizontal Total = 207+1=208 chars/line
  179. defb 0b8h ;005d Reg 1: Horizontal Displayed = 184 (likely 80 char mode with wide timing)
  180. defb 037h ;005e Reg 2: Horizontal Sync Position = 55 (after visible)
  181. defb 0efh ;005f Reg 3: Sync Width = V:14 lines, H:15 chars
  182. ; PIO A Data Port
  183. defb 0b4h ;0060 I/O port: PIO A data
  184. defb 001h ;0061 Count: 1 byte to follow
  185. defb 001h ;0062 Data: Enable something
  186. ; DART A (Serial port A) initialization
  187. defb 0a1h ;0063 I/O port: DART A command
  188. defb 006h ;0064 Count: 6 bytes to follow
  189. defb 048h ;0065 Reset command
  190. defb 048h ;0066 Reset command (double reset)
  191. defb 004h ;0067 Write register 4: Clock/format control
  192. defb 044h ;0068 16x clock, 1 stop bit, no parity
  193. defb 005h ;0069 Write register 5: Transmit control
  194. defb 0eah ;006a DTR active, RTS active, Tx enable, 8 bits
  195. ; DART B (Serial port B) initialization
  196. defb 0a3h ;006b I/O port: DART B command
  197. defb 008h ;006c Count: 8 bytes to follow
  198. defb 048h ;006d Reset command
  199. defb 048h ;006e Reset command (double reset)
  200. defb 004h ;006f Write register 4: Clock/format control
  201. defb 044h ;0070 16x clock, 1 stop bit, no parity
  202. defb 001h ;0071 Write register 1: Interrupt control
  203. defb 000h ;0072 No interrupts enabled
  204. defb 003h ;0073 Write register 3: Receive control
  205. defb 0c1h ;0074 Rx enable, 8 bits per char
  206. ; SIO A (Serial I/O A) initialization
  207. defb 0a5h ;0075 I/O port: SIO A command
  208. defb 002h ;0076 Count: 2 bytes to follow
  209. defb 048h ;0077 Reset command
  210. defb 048h ;0078 Reset command (double reset)
  211. ; SIO B (Serial I/O B) initialization
  212. defb 0a7h ;0079 I/O port: SIO B command
  213. defb 002h ;007a Count: 2 bytes to follow
  214. defb 048h ;007b Reset command
  215. defb 048h ;007c Reset command (double reset)
  216. ; CTC (Counter Timer Circuit) initialization
  217. ; Used to generate baud rate clocks for serial communications
  218. ; CTC Channel 0 - Communications baud rate generator
  219. defb 0a8h ;007d I/O port: CTC CHANNEL 0
  220. defb 002h ;007e Count: 2 bytes to follow
  221. defb 003h ;007f Control: Timer mode, prescaler 16, auto-trigger
  222. defb 003h ;0080 Time constant: 3 (high-speed rate)
  223. ; CTC Channel 1 - Auxiliary RS-232C baud rate generator
  224. defb 0a9h ;0081 I/O port: CTC CHANNEL 1
  225. defb 002h ;0082 Count: 2 bytes to follow
  226. defb 003h ;0083 Control: Timer mode, prescaler 16, auto-trigger
  227. defb 003h ;0084 Time constant: 3 (same rate as channel 0)
  228. ; CTC Channel 2 - Printer baud rate generator
  229. defb 0aah ;0085 I/O port: CTC CHANNEL 2
  230. defb 002h ;0086 Count: 2 bytes to follow
  231. defb 057h ;0087 Control: Timer mode, prescaler 256, auto-trigger
  232. defb 04eh ;0088 Time constant: 78 (slower rate for printer)
  233. ; End of I/O initialization table
  234. defb 000h ;0089 Terminator: port 0 (invalid)
  235. defb 000h ;008a Terminator: count 0
  236. PIOA_end:
  237. ld ix,initcontinue ;008b Set continuation address after screen setup
  238. jp setupclearscreen ;008f Initialize display and clear screen
  239. ; ================================================================================
  240. ; INITIALIZATION CONTINUATION
  241. ; ================================================================================
  242. ; Returns here after display is initialized and cleared
  243. initcontinue:
  244. ld a,080h ;0092 Enable hi-res graphics, disable buzzer
  245. out (0d4h),a ;0094 Write to hi-res color control register
  246. ld de,displaymem ;0096 Point to start of display memory
  247. ld hl,TESTING_start ;0099 Point to "Testing." message
  248. jp displaymsg ;009c Display the message
  249. ; ================================================================================
  250. ; "TESTING." MESSAGE DATA
  251. ; ================================================================================
  252. ; BLOCK 'TESTING' (start 0x009f end 0x00a8)
  253. TESTING_start:
  254. defb 008h ;009f Message length: 8 characters
  255. defb 054h ;00a0 'T'
  256. defb 065h ;00a1 'e'
  257. defb 073h ;00a2 's'
  258. defb 074h ;00a3 't'
  259. defb 069h ;00a4 'i'
  260. defb 06eh ;00a5 'n'
  261. defb 067h ;00a6 'g'
  262. defb 02eh ;00a7 '.'
  263. TESTING_end:
  264. ; ================================================================================
  265. ; MEMORY DETECTION AND TEST INITIALIZATION
  266. ; ================================================================================
  267. ; This section detects memory size (128K vs 256K) and sets up memory testing
  268. ld a,005h ;00a8 DART B register 5 (transmit control)
  269. out (0a3h),a ;00aa Select register 5
  270. ld a,068h ;00ac Enable transmit, 7 bits, no break
  271. out (0a3h),a ;00ae Configure DART B transmit
  272. ld a,0f0h ;00b0 Memory mapping control value
  273. out (0c8h),a ;00b2 Set map and system control register
  274. ld ix,0c001h ;00b4 Point to banked memory + 1 (0xC001)
  275. ld bc,00c5h ;00b8 BC = 0x00C5 (memory map port in C)
  276. ld d,nomemchecks ;00bb D = 9 (number of memory banks to test)
  277. ; Memory size detection routine
  278. ld a,0a0h ;00bd Test value for 256K detection
  279. out (0c5h),a ;00bf Set program map B base to 0xA0
  280. ld (ix-001h),b ;00c1 Write test value (0x00) to 0xC000
  281. dec b ;00c4 B = 0xFF
  282. inc a ;00c5 A = 0xA1
  283. out (0c5h),a ;00c6 Set program map B base to 0xA1
  284. ld (ix-001h),b ;00c8 Write 0xFF to 0xC000 in new bank
  285. dec a ;00cb A = 0xA0 (back to first bank)
  286. out (0c5h),a ;00cc Switch back to first bank
  287. ld b,(ix-001h) ;00ce Read back value from 0xC000
  288. inc b ;00d1 Increment (0x00 becomes 0x01)
  289. jr z,skip256 ;00d2 If zero, we have 256K (0xFF+1=0x00)
  290. ld d,011h ;00d4 If not zero, set to test 17 banks (256K)
  291. skip256:
  292. ld b,d ;00d6 B = number of banks to test
  293. ld hl,memtesteval ;00d7 Point to memory test bank list
  294. ld de,0000h ;00da Clear error counters
  295. ; ================================================================================
  296. ; MAIN MEMORY TEST LOOP
  297. ; ================================================================================
  298. ; Tests each memory bank using rotating bit patterns
  299. beginmemtest:
  300. outi ;00dd Switch memory bank: output (HL) to port C(0xC5), HL++, B--
  301. jr z,memcmp ;00df If B=0, all banks tested - check results
  302. exx ;00e1 Switch to alternate register set
  303. ld b,055h ;00e2 Start with test pattern 0x55 (01010101)
  304. ld e,000h ;00e4 Clear local error accumulator
  305. ; Test loop for current memory bank using rotating patterns
  306. memtestloop:
  307. ld hl,0c000h ;00e6 Start of current memory bank
  308. ld c,b ;00e9 Copy test pattern to C
  309. ; Write test pattern to entire 16K bank
  310. memtestwriteloop:
  311. ld (hl),c ;00ea Write pattern to memory
  312. rlc c ;00eb Rotate pattern left (01010101 -> 10101010)
  313. inc l ;00ed Next byte (low address)
  314. jr nz,memtestwriteloop ;00ee Continue until L wraps to 0
  315. rlc c ;00f0 Rotate pattern again for next page
  316. inc h ;00f2 Next page (high address)
  317. jr nz,memtestwriteloop ;00f3 Continue until H wraps to 0
  318. ; Read back and verify test pattern
  319. ld h,0c0h ;00f5 Reset to start of bank
  320. ld c,b ;00f7 Restore original test pattern
  321. memtestreadloop:
  322. ld a,(hl) ;00f8 Read memory location
  323. xor c ;00f9 Compare with expected pattern
  324. or e ;00fa Accumulate errors in E
  325. ld e,a ;00fb Store error accumulator
  326. rlc c ;00fc Rotate expected pattern
  327. inc l ;00fe Next byte
  328. jr nz,memtestreadloop ;00ff Continue until L wraps
  329. rlc c ;0101 Rotate pattern for next page
  330. inc h ;0103 Next page
  331. jr nz,memtestreadloop ;0104 Continue until H wraps
  332. rlc b ;0106 Rotate base pattern for next iteration
  333. jr nc,memtestloop ;0108 Continue if not back to original (8 patterns)
  334. ; Process test results for this bank
  335. ld a,e ;010a Get error accumulator
  336. exx ;010b Switch back to main register set
  337. and a ;010c Test for errors
  338. jr z,memgood ;010d No errors - bank is good
  339. inc a ;010f Check if all bits failed (0xFF -> 0x00)
  340. jr z,memerror ;0110 Complete failure - count as bad bank
  341. or d ;0112 Partial failure - OR with global error flags
  342. ld d,a ;0113 Store combined error status
  343. jr memgood ;0114 Continue testing
  344. memerror:
  345. inc e ;0116 Increment bad bank counter
  346. memgood:
  347. ld a,b ;0117 Check remaining bank count
  348. cp 004h ;0118 Is this bank 4?
  349. jr nz,beginmemtest ;011a If not bank 4, continue testing
  350. ld a,020h ;011c FDC control: Drive B select (dual drive system)
  351. out (0c0h),a ;011e Write to floppy controller control register
  352. jr beginmemtest ;0120 Continue memory testing
  353. ; ================================================================================
  354. ; MEMORY BANK SELECTION TABLE
  355. ; ================================================================================
  356. ; This table contains the bank values written to port 0xC5 (Program map B base)
  357. ; Each value maps a different 16K memory bank into the 0xC000-0xFFFF address space
  358. memtesteval: ; Memory bank mapping values
  359. defb 0a1h ;0122 Bank count: 161 (actually used as counter)
  360. defb 0c1h ;0123 Memory bank 0xC1
  361. defb 0e1h ;0124 Memory bank 0xE1
  362. defb 000h ;0125 Memory bank 0x00
  363. defb 020h ;0126 Memory bank 0x20
  364. defb 040h ;0127 Memory bank 0x40
  365. defb 060h ;0128 Memory bank 0x60
  366. defb 080h ;0129 Memory bank 0x80
  367. defb 0a0h ;012a Memory bank 0xA0 (Start of 256KB test range)
  368. defb 0c0h ;012b Memory bank 0xC0
  369. defb 0e0h ;012c Memory bank 0xE0
  370. defb 001h ;012d Memory bank 0x01
  371. defb 021h ;012e Memory bank 0x21
  372. defb 041h ;012f Memory bank 0x41
  373. defb 061h ;0130 Memory bank 0x61
  374. defb 081h ;0131 Memory bank 0x81
  375. ; ================================================================================
  376. ; MEMORY TEST RESULTS EVALUATION
  377. ; ================================================================================
  378. ; Check if memory test found any errors and decide next action
  379. nop
  380. memcmp:
  381. xor a ;0133 Clear A register
  382. or d ;0134 Check global error flags in D
  383. or e ;0135 Check bad bank count in E - Any errors?
  384. jr z,floppystart ;0136 If no errors, proceed to floppy boot
  385. ld ix,memcheckdisplay ;0138 Memory errors found - prepare error display
  386. jp setupcrt ;013c Jump to CRT setup for error display
  387. ; ================================================================================
  388. ; MEMORY ERROR DISPLAY ROUTINE
  389. ; ================================================================================
  390. memcheckdisplay:
  391. ld de,displaymem ;013f Point to display memory
  392. ld hl,ERROR2_start ;0142 Point to error message
  393. jp displaymsg ;0145 Display "Error #2 :Call service."
  394. ; ================================================================================
  395. ; ERROR #2 MESSAGE DATA
  396. ; ================================================================================
  397. ; BLOCK 'ERROR2' (start 0x0148 end 0x0160)
  398. ERROR2_start:
  399. defb 017h ;0148 Message length: 23 characters
  400. defb 045h ;0149 'E' - "Error #2 :Call service."
  401. defb 072h ;014a 'r'
  402. defb 072h ;014b 'r'
  403. defb 06fh ;014c 'o'
  404. defb 072h ;014d 'r'
  405. defb 020h ;014e ' '
  406. defb 023h ;014f '#'
  407. defb 032h ;0150 '2'
  408. defb 020h ;0151 ' '
  409. defb 03ah ;0152 ':'
  410. defb 043h ;0153 'C'
  411. defb 061h ;0154 'a'
  412. defb 06ch ;0155 'l'
  413. defb 06ch ;0156 'l'
  414. defb 020h ;0157 ' '
  415. defb 073h ;0158 's'
  416. defb 065h ;0159 'e'
  417. defb 072h ;015a 'r'
  418. defb 076h ;015b 'v'
  419. defb 069h ;015c 'i'
  420. defb 063h ;015d 'c'
  421. defb 065h ;015e 'e'
  422. defb 02eh ;015f '.'
  423. ERROR2_end:
  424. halt ;0160 System halt - requires service intervention
  425. ; ================================================================================
  426. ; FLOPPY DISK BOOT INITIALIZATION
  427. ; ================================================================================
  428. ; Memory test passed - prepare for floppy disk boot
  429. floppystart:
  430. out (0c5h),a ;0161 Clear program map B base (A=0 from memcmp)
  431. out (0c8h),a ;0163 Clear map and system control (disable banking)
  432. dec hl ;0165 HL was pointing past end of memory test table
  433. dec hl ;0166 Move back to get the memory size indicator
  434. ld a,(hl) ;0167 Load memory configuration value
  435. floppystart2:
  436. rrca ;0168 Rotate right with carry to get MSB
  437. and 080h ;0169 Isolate bit 7 (128K vs 256K indicator)
  438. ld (0ff80h),a ;016b Store memory size flag: 0x80=256K, 0x00=128K
  439. ld de,0ffa6h ;016e Destination: high RAM workspace area
  440. ld hl,005beh ;0171 Source: ROM data block at 0x05BE
  441. ld bc,0005ah ;0174 Count: 90 bytes of runtime data
  442. ldir ;0177 Copy ROM constants to RAM workspace
  443. call setupclearscreen2 ;0179 Clear screen and setup display for boot
  444. ; ================================================================================
  445. ; DISK BOOT SEQUENCE WITH AUTO-RETRY
  446. ; ================================================================================
  447. ; ================================================================================
  448. ; BOOT DEVICE DETECTION AND PRIORITY SYSTEM
  449. ; ================================================================================
  450. ; Memory initialization complete - attempt to boot with device auto-detection
  451. ;
  452. ; BOOT PRIORITY ORDER:
  453. ; 1. Auto-detect controller type (port 0xFF) to determine available devices
  454. ; 2. If hard disk detected: Try hard disk FIRST (faster, larger capacity)
  455. ; 3. If hard disk fails or not present: Fall back to floppy disk drives
  456. ; 4. Try drives in order: Drive 0, 1, 2, 3 (up to 8 total attempts)
  457. readydiskloop:
  458. call readydisk ;017c Display "Ready For System Disk" message
  459. call sub_061ch ;017f *** CRITICAL *** Initialize disk controller & detect HDD vs floppy
  460. ld a,0ffh ;0182 Load 0xFF (default retry flag)
  461. jr c,skipinvert ;0184 Keep 0xFF if carry set (controller error - floppy only mode)
  462. cpl ;0186 Invert to 0x00 (normal operation - HDD detection successful)
  463. skipinvert:
  464. ld (0ff93h),a ;0187 Store boot device mode: 0xFF=floppy-only, 0x00=HDD+floppy available
  465. ld hl,00404h ;018a H=4 retries, L=4 track number?
  466. ld (0ff91h),hl ;018d Store retry count and track parameters
  467. or a ;0190 Test the boot device mode flag
  468. jr nz,l01c3h ;0191 If floppy-only mode (0xFF), skip HDD attempts, go to drive loop
  469. ; *** HARD DISK BOOT ATTEMPTS (when HDD controller detected) ***
  470. ; Normal boot mode: Try hard disk operations FIRST
  471. ld c,010h ;0193 Hard disk command 0x10 (seek track 0/recalibrate)
  472. call sub_065ah ;0195 Execute hard disk command through DMA
  473. jr c,l01abh ;0198 If HDD error, try alternate HDD command
  474. ld bc,00000h ;019a B=drive 0, C=track 0 (hard disk drive 0)
  475. call sub_040eh ;019d Attempt to read boot sector from hard disk
  476. jr c,l01abh ;01a0 If HDD read error, try alternate HDD approach
  477. call sub_03a2h ;01a2 Process successful HDD sector read
  478. ld a,(0ff8bh) ;01a5 Get boot validation result from HDD
  479. ld (0ff91h),a ;01a8 Store HDD boot result
  480. l01abh:
  481. ; *** ALTERNATE HARD DISK ATTEMPT ***
  482. ld c,011h ;01ab Hard disk command 0x11 (alternate seek/step command)
  483. call sub_065ah ;01ad Execute alternate hard disk command through DMA
  484. jr c,l01c3h ;01b0 If HDD command error, fall back to floppy drives
  485. ld bc,0000h ;01b2 B=drive 0, C=track 0 (hard disk drive 0)
  486. call sub_040eh ;01b5 Second attempt to read HDD boot sector
  487. jr c,l01c3h ;01b8 If HDD read still fails, fall back to floppy drives
  488. call sub_03a2h ;01ba Process successful HDD sector read
  489. ld a,(0ff8bh) ;01bd Get final HDD boot validation result
  490. ld (0ff92h),a ;01c0 Store HDD boot result flag
  491. ; ================================================================================
  492. ; FLOPPY DRIVE FALLBACK AND DRIVE SELECTION LOOP
  493. ; ================================================================================
  494. ; Reached when: 1) Hard disk not detected, 2) Hard disk boot failed, or 3) Force floppy mode
  495. ; Systematically tries all floppy drives (0-3) with multiple retry attempts
  496. l01c3h:
  497. ld a,001h ;01c3 Start with drive bit 0 (will create drive ID 0xA1)
  498. ld c,008h ;01c5 Retry counter: 8 attempts across all floppy drives
  499. driveloop:
  500. l01c7h:
  501. ; *** FLOPPY DRIVE SELECTION ***
  502. ; Drive encoding: 0xA1=Drive 0, 0xA2=Drive 1, 0xA4=Drive 2, 0xA8=Drive 3
  503. or 0a0h ;01c7 OR with 0xA0 base: creates floppy controller commands
  504. out (0c0h),a ;01c9 Select floppy drive via port 0xC0 (different from HDD ports 0x78-0x7B)
  505. ld b,a ;01cb Save current drive select value
  506. ; Wait for floppy drive ready status
  507. l01cch:
  508. in a,(0b0h) ;01cc Read floppy controller status register (port 0xB0, not HDD 0x79)
  509. rr a ;01ce Rotate right - check busy bit (bit 0) into carry
  510. jr c,l01cch ;01d0 Loop while floppy drive is busy (bit 0 = 1)
  511. in a,(0b0h) ;01d2 Read floppy status again
  512. add a,a ;01d4 Shift left - check ready bit (bit 7) into carry
  513. jr c,l01ddh ;01d5 If floppy drive ready (bit 7 = 1), continue to next drive
  514. call delayloop ;01d7 Floppy drive not ready - wait a bit
  515. call loadingdisk ;01da Display "Loading..." and attempt boot from this floppy drive
  516. ; *** DRIVE ADVANCEMENT AND RETRY LOGIC ***
  517. l01ddh:
  518. inc c ;01dd Increment attempt counter (8 total attempts across all drives)
  519. ld a,b ;01de Restore drive select value from previous iteration
  520. add a,a ;01df Shift left to advance to next drive: 0xA1->0xA2->0xA4->0xA8
  521. and 00fh ;01e0 Mask to keep only drive bits (removes 0xA0 base, leaves 1,2,4,8)
  522. jr nz,l01c7h ;01e2 Continue loop if more drives to try (bits 1,2,4,8 not all exhausted)
  523. ; ================================================================================
  524. ; ALL FLOPPY DRIVES EXHAUSTED - FINAL FALLBACK ATTEMPTS
  525. ; ================================================================================
  526. ; Reached when all floppy drives 0-3 have been tried and failed to boot
  527. ld a,(0ff93h) ;01e4 Load boot mode flag from memory
  528. or a ;01e7 Test if normal boot mode (0x00) or retry mode (0xFF)
  529. jr nz,l0204h ;01e8 If already in retry mode, skip to "No System Device" error
  530. in a,(0ffh) ;01ea Read hardware status port 0xFF (same port used for HDD detection)
  531. and 020h ;01ec Check bit 5 - unknown hardware condition/status
  532. jr nz,l0204h ;01ee If bit 5 set, skip directly to error message
  533. ; *** DESPERATE FINAL ATTEMPTS ON DRIVE 0 ONLY ***
  534. ; Special recovery commands specifically for Drive 0 as last resort
  535. ld c,010h ;01f0 Load floppy command 0x10 (likely recalibrate/restore)
  536. call sub_065ah ;01f2 Execute floppy controller command
  537. ld b,000h ;01f5 Force selection of Drive 0 specifically
  538. call nc,loadingdisk ;01f7 If command succeeded (no carry), try loading from Drive 0
  539. ld c,011h ;01fa Load floppy command 0x11 (likely seek home/step in)
  540. call sub_065ah ;01fc Execute second recovery command
  541. ld b,000h ;01ff Force Drive 0 selection again
  542. call nc,loadingdisk ;0201 If command succeeded, make final boot attempt from Drive 0
  543. ; ================================================================================
  544. ; BOOT FAILURE - DISPLAY ERROR AND RESTART BOOT SEQUENCE
  545. ; ================================================================================
  546. l0204h:
  547. call setupclearscreen2 ;0204 Clear screen and setup display for error
  548. ld bc,002a3h ;0207 B=2 bytes, C=0xA3 port (memory control?)
  549. ld hl,0061ah ;020a Source: ROM data at 0x061A
  550. otir ;020d Output 2 bytes to port 0xA3 (setup display controller)
  551. ld de,03000h ;020f Display memory base address
  552. ld hl,NOSYSTEM_start ;0212 Point to "No System Device On Line." message
  553. jp displaymsg ;0215 Display error message and wait
  554. ; ================================================================================
  555. ; "NO SYSTEM DEVICE ON LINE" MESSAGE AND RETRY LOOP
  556. ; ================================================================================
  557. ; BLOCK 'NOSYSTEM' (start 0x0218 end 0x0232)
  558. NOSYSTEM_start:
  559. defb 019h ;0218 Message length: 25 characters
  560. defb 04eh ;0219 'N' - "No System Device On Line."
  561. defb 06fh ;021a 'o'
  562. defb 020h ;021b ' '
  563. defb 053h ;021c 'S'
  564. defb 079h ;021d 'y'
  565. defb 073h ;021e 's'
  566. defb 074h ;021f 't'
  567. defb 065h ;0220 'e'
  568. defb 06dh ;0221 'm'
  569. defb 020h ;0222 ' '
  570. defb 044h ;0223 'D'
  571. defb 065h ;0224 'e'
  572. defb 076h ;0225 'v'
  573. defb 069h ;0226 'i'
  574. defb 063h ;0227 'c'
  575. defb 065h ;0228 'e'
  576. defb 020h ;0229 ' '
  577. defb 04fh ;022a 'O'
  578. defb 06eh ;022b 'n'
  579. defb 020h ;022c ' '
  580. defb 04ch ;022d 'L'
  581. defb 069h ;022e 'i'
  582. defb 06eh ;022f 'n'
  583. defb 065h ;0230 'e'
  584. defb 02eh ;0231 '.'
  585. NOSYSTEM_end:
  586. call delayloop ;0232 Wait for user to see message (~1 second)
  587. call delayloop ;0235 Additional delay (~1 second)
  588. call delayloop ;0238 Final delay (~1 second, total ~3 seconds)
  589. jp readydiskloop ;023b Restart entire boot sequence - infinite retry loop!
  590. ; ================================================================================
  591. ; CRITICAL ERROR HANDLER - SYSTEM HALT
  592. ; ================================================================================
  593. ; This routine is called for fatal hardware errors that require service
  594. l023eh:
  595. ld ix,returnsetupcrt1 ;023e Setup return address for CRT initialization
  596. jp setupcrt ;0242 Initialize CRT controller and return here
  597. returnsetupcrt1:
  598. call screenclearnetry2 ;0245 Clear screen and setup for error display
  599. rst 10h ;0248 RST 10h: Display message routine
  600. ; ================================================================================
  601. ; ERROR #0 MESSAGE DATA
  602. ; ================================================================================
  603. ; BLOCK 'ERROR0' (start 0x0249 end 0x0261)
  604. ERROR0_start:
  605. defb 017h ;0249 Message length: 23 characters
  606. defb 045h ;024a 'E' - "Error #0: Call service."
  607. defb 072h ;024b 'r'
  608. defb 072h ;024c 'r'
  609. defb 06fh ;024d 'o'
  610. defb 072h ;024e 'r'
  611. defb 020h ;024f ' '
  612. defb 023h ;0250 '#'
  613. defb 030h ;0251 '0'
  614. defb 03ah ;0252 ':'
  615. defb 020h ;0253 ' '
  616. defb 043h ;0254 'C'
  617. defb 061h ;0255 'a'
  618. defb 06ch ;0256 'l'
  619. defb 06ch ;0257 'l'
  620. defb 020h ;0258 ' '
  621. defb 073h ;0259 's'
  622. defb 065h ;025a 'e'
  623. defb 072h ;025b 'r'
  624. defb 076h ;025c 'v'
  625. defb 069h ;025d 'i'
  626. defb 063h ;025e 'c'
  627. defb 065h ;025f 'e'
  628. defb 02eh ;0260 '.'
  629. ERROR0_end:
  630. halt ;0261 System halt - requires service call
  631. ; ================================================================================
  632. ; DISK LOADING ROUTINE - MAIN BOOT SECTOR LOADER
  633. ; ================================================================================
  634. ; This routine displays "Loading" message and attempts to load the boot sector
  635. ; Input: B = drive number (0-3)
  636. ; Uses: All registers, modifies disk parameters at 0xFF81-0xFF82
  637. loadingdisk:
  638. push bc ;0262 Save BC (drive number and parameters)
  639. xor a ;0263 Clear A register (A = 0)
  640. ld (0ff81h),a ;0264 Clear disk status parameter 1
  641. ld (0ff82h),a ;0267 Clear disk status parameter 2
  642. rst 8 ;026a RST 8: Display message routine
  643. ; ================================================================================
  644. ; "LOADING " MESSAGE DATA
  645. ; ================================================================================
  646. ; BLOCK 'LOADING' (start 0x026b end 0x0274)
  647. LOADING_start:
  648. defb 008h ;026b Message length: 8 characters
  649. defb 04ch ;026c 'L' - "Loading "
  650. defb 06fh ;026d 'o'
  651. defb 061h ;026e 'a'
  652. defb 064h ;026f 'd'
  653. defb 069h ;0270 'i'
  654. defb 06eh ;0271 'n'
  655. defb 067h ;0272 'g'
  656. defb 020h ;0273 ' '
  657. LOADING_end:
  658. pop ix ;0274 Restore IX from stack (return address)
  659. call sub_04a1h ;0276 Initialize disk controller and seek to track 0
  660. jr c,l023eh ;0279 If seek error, jump to fatal error handler
  661. ld bc,0000h ;027b B=track 0, C=sector 0 (boot sector location)
  662. call sub_040eh ;027e Read boot sector from disk
  663. jr c,l02ddh ;0281 If read error, handle disk error
  664. ; Check disk status and system configuration
  665. ld hl,(0ff81h) ;0283 Load disk status parameters (2 bytes)
  666. ld a,l ;0286 Get low byte of status
  667. and a ;0287 Test if zero (no special conditions)
  668. jr z,l029ch ;0288 If zero, continue with normal boot process
  669. ld a,h ;028a Get high byte of status
  670. and 003h ;028b Mask bits 0-1 (configuration bits)
  671. in a,(0ffh) ;028d Read system status port 0xFF
  672. jr z,l0298h ;028f If masked value is zero, check bit 1
  673. bit 0,a ;0291 Test bit 0 of system status
  674. jr nz,l029ch ;0293 If bit 0 set, continue normal boot
  675. l0295h:
  676. jp l034bh ;0295 Jump to alternate boot routine
  677. l0298h:
  678. bit 1,a ;0298 Test bit 1 of system status
  679. jr z,l0295h ;029a If bit 1 clear, jump to alternate boot routine
  680. l029ch:
  681. call sub_03a2h ;029c Process and validate boot sector data
  682. jp c,l0343h ;029f If validation failed (carry set), handle error
  683. jr z,l02b6h ;02a2 If zero flag set, skip additional sector read
  684. call sub_040eh ;02a4 Read additional sector data if needed
  685. jr c,l02ddh ;02a7 If read error, handle disk error
  686. ; ================================================================================
  687. ; BOOT SECTOR VALIDATION AND EXECUTION SETUP
  688. ; ================================================================================
  689. ; Boot sector successfully read - now validate and prepare for execution
  690. ld hl,0401fh ;02a9 Point to boot sector signature/validity location
  691. bit 0,(hl) ;02ac Check boot sector validity bit 0
  692. jp nz,l034fh ;02ae If validity bit set, handle invalid boot sector
  693. call sub_040eh ;02b1 Read final sector data if needed
  694. jr c,l02ddh ;02b4 If read error, handle disk error
  695. l02b6h:
  696. exx ;02b6 Switch to alternate register set (BC',DE',HL')
  697. ld hl,0400eh ;02b7 Point to boot program load address in boot sector
  698. ld d,(hl) ;02ba Get high byte of load address
  699. inc hl ;02bb Move to next byte
  700. ld e,(hl) ;02bc Get low byte of load address
  701. push de ;02bd Save complete load address
  702. pop iy ;02be IY = target load address for boot program
  703. ld hl,04080h ;02c0 Point to boot sector parameter block
  704. ld c,(hl) ;02c3 Get boot parameter 1
  705. inc hl ;02c4 Skip reserved byte
  706. inc hl ;02c5 Point to next parameter
  707. ld d,(hl) ;02c6 Get parameter high byte
  708. inc hl ;02c7 Move to next
  709. ld e,(hl) ;02c8 Get parameter low byte
  710. inc hl ;02c9 Move to next
  711. ld a,(hl) ;02ca Get additional parameter byte
  712. inc hl ;02cb Move to final parameter
  713. ld l,(hl) ;02cc Get final parameter byte
  714. ld h,a ;02cd Combine A and L into HL
  715. ex de,hl ;02ce Exchange DE and HL registers
  716. push hl ;02cf Save HL on stack
  717. ld a,e ;02d0 Get low byte for calculation
  718. add a,0ffh ;02d1 Add 255 (effectively subtract 1 with carry)
  719. ld a,d ;02d3 Get high byte
  720. exx ;02d4 Switch back to main register set
  721. ld e,000h ;02d5 E = 0 for addition
  722. adc a,e ;02d7 Add high byte with carry from previous operation
  723. ld d,a ;02d8 D = calculated high byte for sector loading
  724. pop hl ;02d9 Restore HL from stack (boot program parameters)
  725. call sub_0414h ;02da Load complete boot program from disk into memory
  726. ; ================================================================================
  727. ; BOOT PROGRAM EXECUTION AND TRANSFER OF CONTROL
  728. ; ================================================================================
  729. ; Boot program successfully loaded - now transfer control to the loaded code
  730. l02ddh:
  731. jr c,l0347h ;02dd If disk load error (carry set), handle error
  732. ld a,(0ff8bh) ;02df Get boot completion status flag
  733. cp 002h ;02e2 Check if status = 2 (special boot mode)
  734. jr z,l02eeh ;02e4 If special mode, use alternate execution path
  735. ; Standard boot execution: Transfer control to loaded program
  736. xor a ;02e6 Clear A register (A = 0)
  737. ex af,af' ;02e7 Save AF to alternate AF' register
  738. exx ;02e8 Switch to alternate register set
  739. jp 0ffa6h ;02e9 *** TRANSFER CONTROL TO LOADED BOOT PROGRAM! ***
  740. ; ================================================================================
  741. ; ALTERNATE BOOT EXECUTION PATH
  742. ; ================================================================================
  743. ; Special boot mode handling (status = 2)
  744. l02ech:
  745. ex af,af' ;02ec Restore AF from alternate register
  746. adc a,c ;02ed Add C with carry for parameter processing
  747. l02eeh:
  748. push ix ;02ee Save IX register (return address)
  749. pop bc ;02f0 BC = return address from IX
  750. ld a,(0ff8bh) ;02f1 Get boot completion status flag
  751. ld de,00013h ;02f4 DE = 0x0013 (parameter constant)
  752. ld hl,0ff8dh ;02f7 HL = system parameter storage area
  753. jr nz,l033fh ;02fa If status not zero, jump to error 0x33
  754. cp 002h ;02fc Compare status with 2 (special boot mode)
  755. jp nz,0ffb8h ;02fe If not 2, jump to alternate boot entry point
  756. ; Special boot mode (status = 2) - setup system parameters
  757. push bc ;0301 Save return address
  758. bit 3,c ;0302 Test bit 3 of return address low byte
  759. jr nz,l030bh ;0304 If bit 3 set, skip disk flag setup
  760. ld a,0ffh ;0306 Set disk parameter flag
  761. ld (0ff81h),a ;0308 Store at disk parameter location
  762. l030bh:
  763. in a,(0ffh) ;030b Read system status port 0xFF
  764. ld c,a ;030d Save status in C
  765. xor a ;030e Clear A register (A = 0)
  766. bit 0,c ;030f Test bit 0 of system status
  767. jr z,l0315h ;0311 If bit 0 clear, skip
  768. ld a,00fh ;0313 Set A = 0x0F (enable low nibble)
  769. l0315h:
  770. bit 1,c ;0315 Test bit 1 of system status
  771. jr z,l031bh ;0317 If bit 1 clear, skip
  772. or 0f0h ;0319 Set high nibble (A |= 0xF0)
  773. l031bh:
  774. ld b,a ;031b B = combined system configuration mask
  775. ld a,(0ff81h) ;031c Get disk parameter flag
  776. cpl ;031f Complement (invert all bits)
  777. and a ;0320 Test if result is zero
  778. jr z,l0334h ;0321 If zero (was 0xFF), skip complex calculation
  779. ; Complex bit manipulation for drive/system configuration
  780. push bc ;0323 Save BC (config mask and status)
  781. push ix ;0324 Save IX
  782. pop bc ;0326 BC = IX (return address)
  783. ld a,c ;0327 Get low byte of return address
  784. sub 007h ;0328 Subtract 7 (adjust for calculation)
  785. ld b,a ;032a B = adjusted value
  786. ld a,080h ;032b Start with bit 7 set (0x80)
  787. ; Rotate bit pattern based on adjusted return address
  788. l032dh:
  789. rlca ;032d Rotate left with carry (shift bit pattern)
  790. rlca ;032e Rotate left again (2 positions per loop)
  791. djnz l032dh ;032f Decrement B and loop until B=0
  792. pop bc ;0331 Restore BC (config mask and status)
  793. and b ;0332 Mask with configuration bits
  794. rrca ;0333 Rotate right once (adjust final position)
  795. l0334h:
  796. xor b ;0334 XOR with configuration mask
  797. pop bc ;0335 Restore original BC (return address)
  798. ld (0ff81h),a ;0336 Store final calculated system parameter
  799. ld a,(0ff8bh) ;0339 Get boot completion status
  800. jp 0ffb8h ;033c Jump to final boot entry point in RAM
  801. ; ================================================================================
  802. ; BOOT ERROR CLASSIFICATION AND DISPLAY
  803. ; ================================================================================
  804. ; Various boot errors are classified and appropriate error messages displayed
  805. l033fh:
  806. ld a,033h ;033f Error code 0x33 (51 decimal) - set error number
  807. jr l0351h ;0341 Jump to error display routine
  808. l0343h:
  809. ld a,030h ;0343 Error code 0x30 (48 decimal) - validation error
  810. jr l0351h ;0345 Jump to error display routine
  811. l0347h:
  812. ld a,032h ;0347 Error code 0x32 (50 decimal) - disk read error
  813. jr l0351h ;0349 Jump to error display routine
  814. l034bh:
  815. ld a,039h ;034b Error code 0x39 (57 decimal) - system configuration error
  816. jr l0351h ;034d Jump to error display routine
  817. l034fh:
  818. ld a,031h ;034f Error code 0x31 (49 decimal) - invalid boot sector
  819. ; Common error display routine - converts error code to display
  820. l0351h:
  821. push ix ;0351 Save IX register (return address)
  822. push af ;0353 Save error code on stack
  823. call screenclearnetry2 ;0354 Clear screen and setup display
  824. push de ;0357 Save DE register
  825. rst 10h ;0358 RST 10h: Display message routine
  826. ; ================================================================================
  827. ; ERROR #10 MESSAGE DATA - INVALID SYSTEM DISK
  828. ; ================================================================================
  829. ; BLOCK 'INVALID' (start 0x0359 end 0x0382)
  830. INVALID_start:
  831. defb 028h ;0359 Message length: 40 characters
  832. defb 045h ;035a 'E' - "Error #10: Invalid System Disk in Drive "
  833. defb 072h ;035b 'r'
  834. defb 072h ;035c 'r'
  835. defb 06fh ;035d 'o'
  836. defb 072h ;035e 'r'
  837. defb 020h ;035f ' '
  838. defb 023h ;0360 '#'
  839. defb 031h ;0361 '1'
  840. defb 030h ;0362 '0'
  841. defb 03ah ;0363 ':'
  842. defb 020h ;0364 ' '
  843. defb 049h ;0365 'I'
  844. defb 06eh ;0366 'n'
  845. defb 076h ;0367 'v'
  846. defb 061h ;0368 'a'
  847. defb 06ch ;0369 'l'
  848. defb 069h ;036a 'i'
  849. defb 064h ;036b 'd'
  850. defb 020h ;036c ' '
  851. defb 053h ;036d 'S'
  852. defb 079h ;036e 'y'
  853. defb 073h ;036f 's'
  854. defb 074h ;0370 't'
  855. defb 065h ;0371 'e'
  856. defb 06dh ;0372 'm'
  857. defb 020h ;0373 ' '
  858. defb 044h ;0374 'D'
  859. defb 069h ;0375 'i'
  860. defb 073h ;0376 's'
  861. defb 06bh ;0377 'k'
  862. defb 020h ;0378 ' '
  863. defb 069h ;0379 'i'
  864. defb 06eh ;037a 'n'
  865. defb 020h ;037b ' '
  866. defb 044h ;037c 'D'
  867. defb 072h ;037d 'r'
  868. defb 069h ;037e 'i'
  869. defb 076h ;037f 'v'
  870. defb 065h ;0380 'e'
  871. defb 020h ;0381 ' '
  872. INVALID_end:
  873. pop hl ;0382 Restore HL register (display parameters)
  874. pop bc ;0383 Restore BC register (error code and return address)
  875. ld de,0008h ;0384 DE = 8 (offset for drive number display)
  876. add hl,de ;0387 HL += 8 (position for drive number)
  877. add hl,de ;0388 HL += 8 again (total offset = 16)
  878. inc hl ;0389 HL += 1 (final position for drive character)
  879. ld a,004h ;038a Memory bank 4 (display memory access)
  880. out (0c8h),a ;038c Select display memory bank
  881. ld (hl),b ;038e Store drive number/character in display
  882. xor a ;038f Clear A (bank 0)
  883. out (0c8h),a ;0390 Restore normal memory mapping
  884. call delayloop ;0392 Wait for user to see error message
  885. call delayloop ;0395 Additional delay
  886. call setupclearscreen2 ;0398 Clear screen and prepare for retry
  887. call readydisk ;039b Display "Ready For System Disk" again
  888. exx ;039e Switch to alternate register set
  889. pop bc ;039f Restore registers from stack
  890. scf ;03a0 Set carry flag (error condition)
  891. ret ;03a1 Return to caller
  892. ; ================================================================================
  893. ; BOOT SECTOR VALIDATION ROUTINE
  894. ; ================================================================================
  895. ; Validates boot sector contents and determines next actions
  896. ; Input: Boot sector loaded at 0x4000
  897. ; Output: Carry set if invalid, Z flag indicates additional reads needed
  898. sub_03a2h:
  899. ld a,003h ;03a2 Set boot status = 3 (validation in progress)
  900. ld (0ff8bh),a ;03a4 Store at boot status location
  901. ld hl,0401dh ;03a7 Point to boot sector validation byte
  902. ld a,(hl) ;03aa Load validation byte
  903. cp 0e5h ;03ab Check for 0xE5 (invalid marker 1)
  904. scf ;03ad Set carry flag (error)
  905. ret z ;03ae Return if invalid (0xE5)
  906. cp 06ch ;03af Check for 0x6C (invalid marker 2)
  907. scf ;03b1 Set carry flag (error)
  908. ret z ;03b2 Return if invalid (0x6C)
  909. add a,001h ;03b3 Add 1 to validation byte
  910. jr nc,l03bdh ;03b5 If no carry, continue validation
  911. ld hl,0ff8bh ;03b7 Point to boot status
  912. ld (hl),002h ;03ba Set status = 2 (special boot mode)
  913. ret ;03bc Return with status 2
  914. l03bdh:
  915. inc hl ;03bd Move to next boot sector parameter
  916. ld b,(hl) ;03be Get parameter 1
  917. ld a,b ;03bf Copy to A
  918. inc hl ;03c0 Move to next parameter
  919. ld c,(hl) ;03c1 Get parameter 2
  920. add a,001h ;03c2 Add 1 to parameter 1
  921. adc a,c ;03c4 Add parameter 2 with carry
  922. ld hl,0ff8bh ;03c5 Point to boot status
  923. ld (hl),002h ;03c8 Set status = 2 (default)
  924. jr z,l03d4h ;03ca If sum is zero, continue
  925. ld (hl),001h ;03cc Set status = 1 (normal boot)
  926. ld a,b ;03ce Get parameter 1 again
  927. or c ;03cf OR with parameter 2
  928. scf ;03d0 Set carry flag (error)
  929. ret z ;03d1 Return with error if both parameters are zero
  930. or a ;03d2 Clear carry flag (success)
  931. ret ;03d3 Return with success
  932. l03d4h:
  933. ld bc,0001h ;03d4 BC = 1 (additional sector needed)
  934. or a ;03d7 Clear carry flag (success, additional read needed)
  935. ret ;03d8 Return indicating additional sector read required
  936. ; ================================================================================
  937. ; "READY FOR SYSTEM DISK" MESSAGE DISPLAY
  938. ; ================================================================================
  939. ; Displays the ready message showing ROM version
  940. readydisk:
  941. ld de,displaymem ;03d9 DE = display memory base address
  942. rst 10h ;03dc RST 10h: Display message routine
  943. ; ================================================================================
  944. ; "READY FOR SYSTEM DISK" MESSAGE DATA
  945. ; ================================================================================
  946. ; BLOCK 'READY' (start 0x03dd end 0x03fb)
  947. READY_start:
  948. defb 01dh ;03dd Message length: 29 characters
  949. defb 052h ;03de 'R' - "R3-00C Ready For System Disk "
  950. defb 033h ;03df '3'
  951. defb 02dh ;03e0 '-'
  952. defb 030h ;03e1 '0'
  953. defb 030h ;03e2 '0'
  954. defb 043h ;03e3 'C'
  955. defb 020h ;03e4 ' '
  956. defb 052h ;03e5 'R'
  957. defb 065h ;03e6 'e'
  958. defb 061h ;03e7 'a'
  959. defb 064h ;03e8 'd'
  960. defb 079h ;03e9 'y'
  961. defb 020h ;03ea ' '
  962. defb 046h ;03eb 'F'
  963. defb 06fh ;03ec 'o'
  964. defb 072h ;03ed 'r'
  965. defb 020h ;03ee ' '
  966. defb 053h ;03ef 'S'
  967. defb 079h ;03f0 'y'
  968. defb 073h ;03f1 's'
  969. defb 074h ;03f2 't'
  970. defb 065h ;03f3 'e'
  971. defb 06dh ;03f4 'm'
  972. defb 020h ;03f5 ' '
  973. defb 044h ;03f6 'D'
  974. defb 069h ;03f7 'i'
  975. defb 073h ;03f8 's'
  976. defb 06bh ;03f9 'k'
  977. defb 020h ;03fa ' '
  978. READY_end:
  979. call delayloop ;03fb Wait briefly after displaying message
  980. ret ;03fe Return to caller
  981. ; ================================================================================
  982. ; INTERNAL DELAY ROUTINE (PART OF READY FUNCTION)
  983. ; ================================================================================
  984. ; This is part of the ready function flow, not a standalone delay routine
  985. ld b,00ah ;03ff B = 10 (outer loop counter)
  986. ld hl,0000h ;0401 HL = 0 (inner loop counter)
  987. l0404h:
  988. inc hl ;0404 Increment HL
  989. ld a,l ;0405 Test if HL reached 0x0000 again
  990. or h ;0406 (after wrapping around 65536 times)
  991. jr nz,l0404h ;0407 Continue inner loop until HL wraps to 0
  992. djnz l0404h ;0409 Decrement B and repeat outer loop
  993. jp memcmp ;040b Jump to memory compare routine
  994. ; ================================================================================
  995. ; DISK SECTOR READ ROUTINES
  996. ; ================================================================================
  997. ; Main disk I/O routines for reading boot sectors and program data
  998. sub_040eh:
  999. ld de,00100h ;040e DE = 0x0100 (256 bytes = 1 sector)
  1000. ld hl,04000h ;0411 HL = 0x4000 (sector buffer address)
  1001. sub_0414h:
  1002. push bc ;0414 Save BC (track/sector parameters)
  1003. push ix ;0415 Save IX
  1004. pop bc ;0417 BC = IX (return address)
  1005. ld a,c ;0418 Get low byte of return address
  1006. pop bc ;0419 Restore original BC
  1007. cp 010h ;041a Check if return address low byte < 0x10
  1008. jp nc,l06c1h ;041c If >= 0x10, jump to alternate routine
  1009. l041fh:
  1010. ld a,005h ;041f A = 5 (retry counter for disk operations)
  1011. l0421h:
  1012. ex af,af' ;0421 Save retry counter in AF'
  1013. push bc ;0422 Save BC (track/sector)
  1014. ex (sp),hl ;0423 Exchange HL with top of stack
  1015. ld a,l ;0424 Get low byte
  1016. and 00fh ;0425 Mask to lower 4 bits
  1017. push bc ;0427 Save BC again
  1018. push af ;0428 Save masked value
  1019. ld a,(0ff81h) ;0429 Get disk parameter flag
  1020. and a ;042c Test if zero
  1021. ld b,000h ;042d B = 0 (default sector offset)
  1022. jr z,l0433h ;042f If flag is zero, use offset 0
  1023. ld b,010h ;0431 B = 0x10 (alternate sector offset)
  1024. l0433h:
  1025. pop af ;0433 Restore masked value from stack
  1026. add a,b ;0434 Add sector offset (0 or 0x10)
  1027. inc a ;0435 Add 1 (sectors are 1-based)
  1028. out (0b2h),a ;0436 Write to floppy sector register
  1029. add hl,hl ;0438 HL *= 2 (shift left)
  1030. add hl,hl ;0439 HL *= 2 (shift left again)
  1031. add hl,hl ;043a HL *= 2 (shift left again)
  1032. add hl,hl ;043b HL *= 2 (total: HL *= 16 for track calculation)
  1033. cp 011h ;043c Compare sector with 17
  1034. ld a,h ;043e Get high byte (track number)
  1035. out (0b3h),a ;043f Write to floppy track register
  1036. jr c,l0453h ;0441 If sector < 17, skip extended handling
  1037. rra ;0443 Rotate right (divide by 2)
  1038. out (0b3h),a ;0444 Write modified track to floppy register
  1039. push ix ;0446 Save IX
  1040. pop bc ;0448 BC = IX
  1041. ld a,b ;0449 Get high byte of IX
  1042. jr nc,l044eh ;044a If no carry from rotate, skip
  1043. or 010h ;044c Set bit 4 (extended track flag)
  1044. l044eh:
  1045. ld (0ff82h),a ;044e Store drive control byte
  1046. out (0c0h),a ;0451 Write to floppy drive control register
  1047. l0453h:
  1048. pop bc ;0453 Restore BC (track/sector parameters)
  1049. pop hl ;0454 Restore HL (buffer address)
  1050. ld a,01dh ;0455 Floppy command 0x1D (read sector with retry)
  1051. call setfloppystatus ;0457 Execute floppy command and wait for completion
  1052. and 098h ;045a Check error bits: bit 7=not ready, 4=CRC error, 3=lost data
  1053. jr nz,l0486h ;045c If any error bits set, handle error
  1054. call sub_04c1h ;045e Setup DMA transfer parameters
  1055. ; Multi-sector read loop
  1056. l0461h:
  1057. ld a,(0ff82h) ;0461 Get drive control byte
  1058. bit 4,a ;0464 Test bit 4 (extended track flag)
  1059. ld a,082h ;0466 Floppy command 0x82 (read data)
  1060. jr z,l046ch ;0468 If bit 4 clear, use standard command
  1061. ld a,08ah ;046a Floppy command 0x8A (read data - extended)
  1062. l046ch:
  1063. call setfloppystatus ;046c Execute read command and wait
  1064. and 09ch ;046f Check error bits: bit 7=not ready, 4=CRC, 3=lost data, 2=record not found
  1065. jr nz,l0486h ;0471 If any error, handle it
  1066. inc h ;0473 Increment buffer high byte (next page)
  1067. inc bc ;0474 Increment sector count
  1068. dec d ;0475 Decrement remaining sector count
  1069. ret z ;0476 Return if all sectors read (D=0)
  1070. ld a,c ;0477 Get current sector number
  1071. and 00fh ;0478 Mask to lower 4 bits (sectors 0-15)
  1072. jr z,l041fh ;047a If wrapped to 0, start new track
  1073. in a,(0b2h) ;047c Read current sector register
  1074. inc a ;047e Increment to next sector
  1075. out (0b2h),a ;047f Write back to sector register
  1076. ld a,005h ;0481 Reset retry counter to 5
  1077. l0483h:
  1078. ex af,af' ;0483 Save retry counter
  1079. jr l0461h ;0484 Continue reading next sector
  1080. ; Error handling for disk read operations
  1081. l0486h:
  1082. scf ;0486 Set carry flag (error)
  1083. bit 7,a ;0487 Test bit 7 (drive not ready)
  1084. ret nz ;0489 Return immediately if drive not ready
  1085. ex af,af' ;048a Get retry counter
  1086. dec a ;048b Decrement retry count
  1087. jr nz,l0421h ;048c If retries left, try again
  1088. ex af,af' ;048e Restore error status
  1089. bit 4,a ;048f Test bit 4 (CRC error)
  1090. jr z,l049fh ;0491 If not CRC error, return failure
  1091. ld a,(0ff81h) ;0493 Get disk parameter flag
  1092. and a ;0496 Test if zero
  1093. jr nz,l049fh ;0497 If non-zero, return failure
  1094. cpl ;0499 Complement (0x00 -> 0xFF)
  1095. ld (0ff81h),a ;049a Store inverted flag (try alternate sectors)
  1096. jr l041fh ;049d Retry with alternate sector numbering
  1097. l049fh:
  1098. scf ;049f Set carry flag (permanent error)
  1099. ret ;04a0 Return with error
  1100. ; ================================================================================
  1101. ; DISK INITIALIZATION AND SEEK ROUTINE
  1102. ; ================================================================================
  1103. ; Initialize floppy controller and seek to track 0
  1104. sub_04a1h:
  1105. push bc ;04a1 Save BC register
  1106. push ix ;04a2 Save IX register
  1107. pop bc ;04a4 BC = IX (return address)
  1108. ld a,c ;04a5 Get low byte of return address
  1109. pop bc ;04a6 Restore original BC
  1110. cp 010h ;04a7 Check if return address low byte < 0x10
  1111. jp nc,l0788h ;04a9 If >= 0x10, jump to alternate routine
  1112. ld a,001h ;04ac Floppy command 0x01 (restore/recalibrate to track 0)
  1113. call setfloppystatus ;04ae Execute restore command
  1114. and 004h ;04b1 Check bit 2 (seek error/track 0 not found)
  1115. ret nz ;04b3 Return with error if seek failed
  1116. scf ;04b4 Set carry flag (error - unexpected!)
  1117. ret ;04b5 Return with error
  1118. ; ================================================================================
  1119. ; FLOPPY CONTROLLER COMMAND EXECUTION
  1120. ; ================================================================================
  1121. ; Sends command to floppy controller and waits for completion
  1122. ; Input: A = floppy command
  1123. ; Output: A = final status register
  1124. setfloppystatus:
  1125. out (0b0h),a ;04b6 Write command to floppy controller
  1126. ; Wait for controller ready (INTRQ signal)
  1127. l04b8h:
  1128. in a,(0b4h) ;04b8 Read PIO A data register
  1129. bit 4,a ;04ba Test bit 4 (floppy controller INTRQ signal)
  1130. jr z,l04b8h ;04bc Wait until INTRQ goes high (command complete)
  1131. in a,(0b0h) ;04be Read final status from floppy controller
  1132. ret ;04c0 Return with status in A
  1133. ; ================================================================================
  1134. ; DMA SETUP ROUTINES
  1135. ; ================================================================================
  1136. ; Configure Z80 DMA controller for floppy disk data transfers
  1137. sub_04c1h:
  1138. push bc ;04c1 Save BC register
  1139. ld bc,0b301h ;04c2 B=0xB3 (DMA port), C=0x01 (DMA command)
  1140. jr l04cbh ;04c5 Jump to common DMA setup
  1141. sub_04c7h:
  1142. push bc ;04c7 Save BC register
  1143. ld bc,07803h ;04c8 B=0x78 (different setting), C=0x03 (DMA command)
  1144. l04cbh:
  1145. ld a,b ;04cb Get DMA parameter
  1146. ld (0ff8ch),a ;04cc Store DMA configuration
  1147. ld a,c ;04cf Get DMA command
  1148. out (0b4h),a ;04d0 Write to PIO A data register (DMA control)
  1149. ld bc,006ach ;04d2 B=6 (loop counter), C=0xAC (DMA port)
  1150. ld a,0c3h ;04d5 DMA reset command
  1151. l04d7h:
  1152. out (c),a ;04d7 Send reset command to DMA controller
  1153. djnz l04d7h ;04d9 Repeat 6 times (ensure DMA is reset)
  1154. ld a,07dh ;04db DMA disable command
  1155. out (c),a ;04dd Send disable to DMA controller
  1156. out (c),l ;04df Send L register to DMA (low address byte)
  1157. out (c),h ;04e1 Send H register to DMA (high address byte)
  1158. out (c),e ;04e3 Send E register to DMA (low count byte)
  1159. out (c),d ;04e5 Send D register to DMA (high count byte)
  1160. push hl ;04e7 Save HL register
  1161. ld hl,004fbh ;04e8 Point to DMA parameter table
  1162. ld b,003h ;04eb Send 3 bytes
  1163. otir ;04ed Output 3 bytes from (HL) to port C
  1164. ld a,(0ff8ch) ;04ef Get stored DMA configuration
  1165. out (c),a ;04f2 Send to DMA controller
  1166. ld b,005h ;04f4 Send 5 more bytes
  1167. otir ;04f6 Output 5 bytes from (HL) to port C
  1168. pop hl ;04f8 Restore HL register
  1169. pop bc ;04f9 Restore BC register
  1170. ret ;04fa Return
  1171. ; DMA parameter table
  1172. inc d ;04fb DMA parameter byte 1
  1173. jr z,l0483h ;04fc DMA parameter bytes 2-3
  1174. adc a,d ;04fe DMA parameter byte 4
  1175. rst 8 ;04ff DMA parameter byte 5 (restart vector)
  1176. ld bc,087cfh ;0500 DMA parameter bytes 6-7-8
  1177. ; ================================================================================
  1178. ; SCREEN SETUP AND CLEAR ROUTINES
  1179. ; ================================================================================
  1180. ; Initialize CRT controller and clear display memory
  1181. setupclearscreen2:
  1182. pop ix ;0503 Get return address from stack
  1183. setupclearscreen:
  1184. ; Entry point during initialization with IX=0x0092
  1185. xor a ;0505 A = 0 (starting register number)
  1186. ld bc,00eb9h ;0506 C=0xB9 (CRT data port), B=14 (register count)
  1187. ld hl,0054fh ;0509 Point to CRT register table
  1188. setupclearloop:
  1189. out (0b8h),a ;050c Write register number to CRT register select
  1190. inc a ;050e Increment to next register number
  1191. outi ;050f Output (HL) to port C, increment HL, decrement B
  1192. jr nz,setupclearloop ;0511 Loop until B=0 (all 14 registers written)
  1193. ld de,03002h ;0513 DE = display memory + 2 (destination)
  1194. ld hl,displaymem ;0516 HL = display memory base (source)
  1195. ld bc,00ffeh ;0519 BC = 4094 bytes (2K display memory - 2)
  1196. ; RST 08 jumps here with different parameters: HL=300C, DE=300E, BC=004E, IX=032F
  1197. l051ch:
  1198. ld a,004h ;051c Memory bank 4 (display memory)
  1199. out (0c8h),a ;051e Select display memory bank
  1200. xor a ;0520 A = 0 (clear character)
  1201. ld (hl),a ;0521 Store 0x00 at display memory (character)
  1202. inc hl ;0522 Move to attribute byte
  1203. ld (hl),020h ;0523 Store 0x20 (space character attribute)
  1204. dec hl ;0525 Go back to character position
  1205. ldir ;0526 Copy pattern throughout display memory
  1206. xor a ;0528 A = 0 (normal memory bank)
  1207. out (0c8h),a ;0529 Restore normal memory mapping
  1208. jp (ix) ;052b Continue execution at IX
  1209. ; ================================================================================
  1210. ; CLEAR TOP LINE ROUTINE
  1211. ; ================================================================================
  1212. ; Clears a single line (80 characters) at the specified address
  1213. cleartopline:
  1214. push de ;052d Save original DE
  1215. ld l,e ;052e HL = DE (copy destination address)
  1216. ld h,d ;052f
  1217. inc de ;0530 DE += 2 (destination for copy)
  1218. inc de ;0531
  1219. ld bc,0004eh ;0532 BC = 78 words (80 chars - 2 = 78 more chars)
  1220. push ix ;0535 Save original IX
  1221. ld ix,clearlineend ;0537 Set return address to 0x053D
  1222. jr l051ch ;053b Jump to screen clear routine
  1223. ; Screen clear routine returns here
  1224. clearlineend:
  1225. pop ix ;053d Restore original IX
  1226. pop de ;053f Restore original DE
  1227. ret ;0540 Return to caller
  1228. ; ================================================================================
  1229. ; TEXT DISPLAY ROUTINE
  1230. ; ================================================================================
  1231. ; Displays text messages on screen using character/attribute pairs
  1232. ; Input: BC = character count, HL = message source, DE = screen target
  1233. printroutine:
  1234. ld a,004h ;0541 Memory bank 4 (display memory)
  1235. out (0c8h),a ;0543 Select display memory bank
  1236. printcharloop:
  1237. inc de ;0545 Skip to attribute byte (every other address)
  1238. ldi ;0546 Copy (HL) to (DE), increment both, decrement BC
  1239. jp pe,printcharloop ;0548 Continue while BC ≠ 0 (parity even = BC not zero)
  1240. xor a ;054b A = 0 (normal memory bank)
  1241. out (0c8h),a ;054c Restore normal memory mapping
  1242. jp (hl) ;054e Jump to address in HL
  1243. ; ================================================================================
  1244. ; CRT CONTROLLER REGISTER TABLE (6845 CRTC)
  1245. ; ================================================================================
  1246. ; 14-byte table of values for CRT controller registers R0-R13
  1247. CRT_REGISTER_TABLE:
  1248. defb 069h ;054f R0: Horizontal Total = 105 characters
  1249. defb 050h ;0550 R1: Horizontal Displayed = 80 characters
  1250. defb 056h ;0551 R2: Horizontal Sync Position = 86
  1251. defb 00bh ;0552 R3: Horizontal Sync Width = 11
  1252. defb 019h ;0553 R4: Vertical Total = 25 rows
  1253. defb 003h ;0554 R5: Vertical Total Adjust = 3
  1254. defb 018h ;0555 R6: Vertical Displayed = 24 rows
  1255. defb 018h ;0556 R7: Vertical Sync Position = 24
  1256. defb 000h ;0557 R8: Interlace Mode = 0 (non-interlaced)
  1257. defb 00bh ;0558 R9: Maximum Scan Line = 11 (12 lines per char)
  1258. defb 020h ;0559 R10: Cursor Start = 32 (cursor off)
  1259. defb 000h ;055a R11: Cursor End = 0
  1260. defb 000h ;055b R12: Start Address High = 0
  1261. defb 000h ;055c R13: Start Address Low = 0
  1262. CRT_TABLE_END:
  1263. ; ================================================================================
  1264. ; ADVANCED SCREEN CLEAR ROUTINES
  1265. ; ================================================================================
  1266. pop hl ;055d Restore HL register
  1267. jr l0562h ;055e Jump to screen clear loop
  1268. screenclearloop:
  1269. otir ;0560 Output B bytes from (HL) to port C
  1270. l0562h:
  1271. ld c,(hl) ;0562 Get I/O port number from table
  1272. inc hl ;0563 Move to count byte
  1273. ld b,(hl) ;0564 Get byte count
  1274. inc hl ;0565 Move to data
  1275. ld a,b ;0566 Test count
  1276. and a ;0567 Check if zero
  1277. jr nz,screenclearloop ;0568 If not zero, output data block
  1278. jp (hl) ;056a Jump to next routine
  1279. screenclearnetry2:
  1280. ld de,03100h ;056b DE = 0x3100 (display line 1 start address)
  1281. ld a,00fh ;056e CRT register 15 (cursor position low byte)
  1282. out (0b8h),a ;0570 Select CRT register 15
  1283. xor a ;0572 A = 0 (cursor position = 0)
  1284. out (0b9h),a ;0573 Write cursor position to CRT
  1285. in a,(0bbh) ;0575 Read from port 0xBB (keyboard status?)
  1286. or a ;0577 Test status
  1287. ret nz ;0578 Return if non-zero (key pressed?)
  1288. ld de,030a0h ;0579 DE = 0x30A0 (alternate display position)
  1289. ret ;057c Return
  1290. ; ================================================================================
  1291. ; DELAY LOOP ROUTINE
  1292. ; ================================================================================
  1293. ; Provides more precise timing delays using stack manipulation
  1294. delayloop:
  1295. ld hl,04600h ;057d HL = 17920 (delay counter)
  1296. l0580h:
  1297. dec hl ;0580 Decrement counter
  1298. ex (sp),hl ;0581 Exchange HL with top of stack (add delay)
  1299. ex (sp),hl ;0582 Exchange back (more delay)
  1300. ex (sp),hl ;0583 Exchange again (even more delay)
  1301. ex (sp),hl ;0584 Exchange back (maximum delay per loop)
  1302. ld a,l ;0585 Test if HL reached zero
  1303. or h ;0586
  1304. jr nz,l0580h ;0587 Continue loop until HL = 0
  1305. ret ;0589 Return after ~17920 * 4 clock cycles
  1306. pop ix ;058a Clean up stack (dead code?)
  1307. ; ================================================================================
  1308. ; CRT CONTROLLER INITIALIZATION
  1309. ; ================================================================================
  1310. ; Complete CRT setup with buzzer control and I/O initialization
  1311. setupcrt:
  1312. ld a,00fh ;058c CRT register 15 (cursor position low)
  1313. out (0b8h),a ;058e Select CRT register 15
  1314. xor a ;0590 A = 0 (cursor off)
  1315. out (0b9h),a ;0591 Write to CRT data register
  1316. in a,(0bbh) ;0593 Read keyboard/system status
  1317. and a ;0595 Test status
  1318. jr nz,l059ch ;0596 If non-zero, skip buzzer
  1319. ld a,081h ;0598 Buzzer control byte
  1320. out (0d4h),a ;059a Turn on buzzer/sound
  1321. l059ch:
  1322. ld bc,006cch ;059c B=6 bytes, C=0xCC (I/O port for system control)
  1323. ld hl,005b8h ;059f Point to I/O initialization table
  1324. otir ;05a2 Output 6 bytes to port 0xCC (system setup)
  1325. ld bc,0000h ;05a4 BC = 0 (delay counter)
  1326. ; Delay loop for system settling
  1327. l05a7h:
  1328. ex (sp),hl ;05a7 Exchange HL with stack top (timing delay)
  1329. ex (sp),hl ;05a8 Exchange back (more timing delay)
  1330. dec bc ;05a9 Decrement delay counter
  1331. ld a,b ;05aa Test if BC reached zero
  1332. or c ;05ab
  1333. jr nz,l05a7h ;05ac Continue delay loop
  1334. ld a,080h ;05ae Buzzer off command
  1335. out (0d4h),a ;05b0 Turn off buzzer
  1336. ld a,09fh ;05b2 System control value
  1337. out (0cch),a ;05b4 Final system control setup
  1338. jp (ix) ;05b6 Continue execution at IX
  1339. ; ================================================================================
  1340. ; I/O INITIALIZATION TABLE
  1341. ; ================================================================================
  1342. ; 6-byte table for system controller setup (port 0xCC)
  1343. IO_SETUP_TABLE:
  1344. defb 08eh ;05b8 I/O setup byte 1 (adc a,(hl) opcode)
  1345. defb 004h ;05b9 I/O setup byte 2 (inc b opcode)
  1346. defb 092h ;05ba I/O setup byte 3 (sub d opcode)
  1347. defb 0bfh ;05bb I/O setup byte 4 (cp a opcode)
  1348. defb 0dfh ;05bc I/O setup byte 5 (rst 18h opcode)
  1349. defb 0ffh ;05bd I/O setup byte 6 (rst 38h opcode)
  1350. ; ================================================================================
  1351. ; MEMORY COPY ROUTINE WITH BANKING
  1352. ; ================================================================================
  1353. ; Copies data using banked memory (used during boot program loading)
  1354. l05beh:
  1355. ld a,001h ;05be Memory bank 1
  1356. out (0c8h),a ;05c0 Select bank 1 for memory operations
  1357. l05c2h:
  1358. ex af,af' ;05c2 Save AF in alternate register
  1359. adc a,(hl) ;05c3 Load byte from source (HL)
  1360. ex af,af' ;05c4 Restore AF
  1361. inc hl ;05c5 Increment source pointer
  1362. dec de ;05c6 Decrement byte counter
  1363. ld a,e ;05c7 Test if DE reached zero
  1364. or d ;05c8
  1365. jr nz,l05c2h ;05c9 Continue copy loop if more bytes
  1366. out (0c8h),a ;05cb A=0, restore normal memory bank
  1367. jp l02ech ;05cd Jump back to boot execution routine
  1368. ;
  1369. ; ANALYSIS OF ALTERNATIVE BOOT PATH (0x05D0-0x0616):
  1370. ; ==================================================
  1371. ;
  1372. ; This represents a remarkable discovery of the Monroe OC8820's dual-OS boot capability.
  1373. ; The system implements support for two operating systems through calculated
  1374. ; indirect jumps, creating a sophisticated OS-selection boot system.
  1375. ;
  1376. ; OPERATING SYSTEM BOOT MODES:
  1377. ; ----------------------------
  1378. ; Mode 0/1: Standard boot path - Monroe OS8 (Monroe's proprietary operating system)
  1379. ; Mode 2: CP/M boot path - Industry standard OS for business applications
  1380. ; Mode 2+: Advanced Monroe OS8 features and configurations
  1381. ;
  1382. ; DUAL-OS ENTRY MECHANISM:
  1383. ; ------------------------
  1384. ; 1. Boot disk contains OS identification in banked memory (0xFF80-0xFF92 range)
  1385. ; 2. Main boot code reads OS type and calculates appropriate boot vector
  1386. ; 3. Address calculation: Base(4) + OS_Parameter + AdvancedFeatures = OS_BootVector
  1387. ; 4. Target address stored in IX via push BC/pop IX mechanism
  1388. ; 5. Later jp (ix) instruction jumps to OS-specific initialization code
  1389. ;
  1390. ; OS CONFIGURATION DATA STRUCTURE (in banked memory):
  1391. ; --------------------------------------------------
  1392. ; 0xFF80: Base OS configuration flag (combined with runtime parameters)
  1393. ; 0xFF81: OS-specific configuration byte (CP/M BIOS params or Monroe OS8 settings)
  1394. ; 0xFF8D: 4-byte OS parameter block #1 (disk geometry, memory layout)
  1395. ; 0xFF8F: OS validation signature (0x95 = validated Monroe OS8 disk with advanced features)
  1396. ; 0xFF91: OS boot data byte (entry points, system calls)
  1397. ; 0xFF92: OS boot data byte (additional OS parameters)
  1398. ;
  1399. ; CP/M vs MONROE OS8 BOOT DIFFERENTIATION:
  1400. ; ----------------------------------------
  1401. ; - If mode ≠ 2: Monroe OS8 boot (standard proprietary OS)
  1402. ; - If mode = 2 and parameter < 16: CP/M boot (industry standard)
  1403. ; - If mode = 2 and parameter ≥ 16: Check for Monroe OS8 advanced features
  1404. ; - If signature = 0x95: Monroe OS8 with advanced features (+1 offset)
  1405. ; - Final jump target = 4 + (OS_parameter-16) + advanced_features_bonus
  1406. ;
  1407. ; The final jp (iy) transfers control to the selected OS kernel!
  1408. ;
  1409. ;; ================================================================================
  1410. ; Entry point: 0x05D0 (reached via jp (ix) with calculated address from 0x05F2-0x05F3)
  1411. ; This represents a sophisticated secondary boot path for handling different system configurations
  1412. ;
  1413. ; Entry conditions:
  1414. ; - A register contains boot mode indicator
  1415. ; - C register contains configuration parameter
  1416. ; - System expects specific memory layout in banked memory
  1417. l05d0h:
  1418. cp 002h ;05d0 Compare A with 2 (OS boot mode check: 2 = CP/M selection)
  1419. ld a,001h ;05d2 Load memory bank 1 selector
  1420. out (0c8h),a ;05d4 Switch to memory bank 1 for OS-specific operations
  1421. jr nz,l05f5h ;05d6 If A≠2, use Monroe OS8 (native OS), skip CP/M setup
  1422. ; CP/M specific initialization (A was equal to 2)
  1423. ld a,(0ff81h) ;05d8 Load CP/M configuration byte from boot disk
  1424. ld (0022h),a ;05db Store CP/M config in system variable (BIOS parameters)
  1425. ld a,c ;05de Get CP/M parameter from C register
  1426. sub 010h ;05df Subtract 16 (check if parameter >= 16 for advanced CP/M)
  1427. jr c,l05f5h ;05e1 If C<16, use basic CP/M boot, jump to common path
  1428. ld c,a ;05e3 Update C with adjusted value (C = C-16)
  1429. jr z,l05eeh ;05e4 If result is zero (C was exactly 16), basic advanced CP/M
  1430. ; Advanced Monroe OS8 features when booting from CP/M mode
  1431. ld a,(0ff8fh) ;05e6 Load validation signature from boot disk
  1432. cp 095h ;05e9 Compare with Monroe OS8 advanced feature signature 0x95
  1433. jr nz,l05eeh ;05eb If not Monroe OS8 signature, use standard CP/M boot
  1434. inc c ;05ed Valid Monroe OS8 features: increment C (Monroe-specific CP/M extensions)
  1435. l05eeh:
  1436. ; Calculate OS-specific jump target address
  1437. ld a,004h ;05ee Base offset = 4
  1438. add a,c ;05f0 Add OS-derived offset to base
  1439. ld c,a ;05f1 C now contains calculated OS boot vector offset
  1440. push bc ;05f2 Push BC to stack
  1441. pop ix ;05f3 Pop into IX - now IX = OS boot vector (B×256 + OS_offset)
  1442. ; This creates the target address for OS-specific initialization
  1443. l05f5h:
  1444. ; Common path for both operating systems (Monroe OS8 and CP/M)
  1445. ; OS-specific data preparation and parameter setup
  1446. ld a,(0ff80h) ;05f5 Load base OS configuration from boot disk
  1447. or c ;05f8 Combine with OS-specific offset parameter
  1448. ld c,a ;05f9 Store combined OS configuration
  1449. ld a,(0ff91h) ;05fa Load OS boot parameter 1 from disk (entry points, BIOS vectors)
  1450. ld (de),a ;05fd Store to OS parameter area (DE points to system area)
  1451. inc de ;05fe Advance destination pointer
  1452. ; Copy 4-byte OS parameter block from boot disk
  1453. push bc ;05ff Save BC (OS configuration)
  1454. ld bc,00004h ;0600 Set count = 4 bytes
  1455. ldir ;0603 Copy 4 bytes: Monroe OS8 or CP/M system parameters
  1456. ; Set up for second OS parameter block copy
  1457. ld de,00023h ;0605 DE = destination address 0x0023 (OS parameter area)
  1458. ld hl,0ff8dh ;0608 HL = source in banked memory 0xFF8D (OS data block 2)
  1459. ld a,(0ff92h) ;060b Load OS boot parameter 2 (system vectors, disk geometry)
  1460. ld (de),a ;060e Store at 0x0023
  1461. inc de ;060f DE = 0x0024
  1462. ; Copy second 4-byte OS parameter block
  1463. ld bc,00004h ;0610 Set count = 4 bytes
  1464. ldir ;0613 Copy 4 bytes: Monroe OS8 system tables or CP/M BIOS tables
  1465. pop bc ;0615 Restore BC (OS configuration)
  1466. jp (iy) ;0616 Jump to selected OS kernel entry point! (Monroe OS8 or CP/M)
  1467. ; ================================================================================
  1468. ; DATA TABLE AND DISK CONTROLLER INITIALIZATION
  1469. ; ================================================================================
  1470. defb 005h ;0618 Controller parameter 1
  1471. defb 080h ;0619 Controller parameter 2 (0x80 = enable flag?)
  1472. defb 005h ;061a Controller parameter 3
  1473. defb 000h ;061b Controller parameter 4 (terminator?)
  1474. ; ================================================================================
  1475. ; DISK CONTROLLER SETUP AND STATUS CHECK ROUTINE
  1476. ; ================================================================================
  1477. ; Initializes the disk controller and waits for ready status
  1478. ; Uses the 4-byte parameter table above (0x0618-0x061B)
  1479. ; Returns: Carry set if timeout/error, clear if success
  1480. sub_061ch:
  1481. ld bc,002a3h ;061c B=2 bytes, C=0xA3 (port number for disk controller)
  1482. ld hl,00618h ;061f HL points to controller parameter table above
  1483. otir ;0622 Output 2 bytes from (HL) to port 0xA3, auto-increment HL
  1484. ld b,0ffh ;0624 B = 255 (timeout counter for controller ready)
  1485. l0626h:
  1486. ; Wait for disk controller ready status
  1487. in a,(079h) ;0626 Read disk controller status port
  1488. cp 0c7h ;0628 Compare with ready status value 0xC7
  1489. jr z,l0630h ;062a If ready (0xC7), continue with operation
  1490. djnz l0626h ;062c Decrement timeout counter, loop if not expired
  1491. scf ;062e Set carry flag (timeout error)
  1492. ret ;062f Return with error
  1493. l0630h:
  1494. ; Controller is ready - execute read operation
  1495. call reading ;0630 Execute disk read command
  1496. ret c ;0633 Return if read error occurred
  1497. ; Analyze controller response for configuration
  1498. in a,(0ffh) ;0634 Read controller configuration register
  1499. rra ;0636 Rotate right (check bit 0)
  1500. rra ;0637 Rotate right again (check bit 1)
  1501. and 007h ;0638 Mask to get lower 3 bits (configuration value 0-7)
  1502. ; *** BOOT DEVICE SELECTION LOGIC ***
  1503. ; Configuration value determines boot device priority:
  1504. ; 0 = Default (floppy-only system)
  1505. ; 1 = Hard disk + floppy system (hard disk priority)
  1506. ; 2+ = Advanced hard disk system (hard disk with extended features)
  1507. ld hl,007e2h ;063a Default: point to floppy-only configuration table
  1508. jr z,l064fh ;063d If value=0, use floppy-only mode, skip device selection
  1509. ld hl,007d6h ;063f Point to hard disk + floppy configuration table
  1510. dec a ;0642 Decrement configuration value
  1511. jr z,l0648h ;0643 If value was 1, use hard disk + floppy mode
  1512. ld hl,007cah ;0645 Point to advanced hard disk configuration (value ≥ 2)
  1513. l0648h:
  1514. call sub_076bh ;0648 Execute configuration-specific routine
  1515. call reading ;064b Execute another disk read
  1516. ret c ;064e Return if error
  1517. l064fh:
  1518. ; Copy configuration data to system memory
  1519. ld de,0ff8dh ;064f DE = destination in banked memory (system parameters)
  1520. ld bc,00004h ;0652 BC = 4 bytes to copy
  1521. ldir ;0655 Copy 4 bytes from (HL) to system memory
  1522. jp l077fh ;0657 Jump to next stage of disk initialization
  1523. ; ================================================================================
  1524. ; DISK COMMAND EXECUTION ROUTINE
  1525. ; ================================================================================
  1526. ; Executes specific floppy disk commands (0x10, 0x11) used during boot sequence
  1527. ; This routine handles low-level disk operations like recalibrate and seek
  1528. ; Input: C = disk command (0x10 = recalibrate, 0x11 = seek/position)
  1529. ; Output: Carry flag set if error, clear if success
  1530. sub_065ah:
  1531. push bc ;065a Save BC register
  1532. pop ix ;065b IX = BC (save original command for later use)
  1533. ld a,010h ;065d A = 0x10 (base command value)
  1534. sub c ;065f A = 0x10 - C (calculate command offset)
  1535. jr z,l0664h ;0660 If C=0x10 (recalibrate), use A=0 parameter
  1536. ld a,020h ;0662 A = 0x20 (seek command parameter)
  1537. l0664h:
  1538. ; Build disk command parameter block
  1539. ld hl,0ff83h ;0664 Point to disk parameter buffer in banked memory
  1540. ld b,004h ;0667 B = 4 (number of parameters to set)
  1541. ld (hl),008h ;0669 Store 0x08 (command type/drive select)
  1542. inc hl ;066b Move to next parameter slot
  1543. ld (hl),a ;066c Store command-specific parameter (0x00 or 0x20)
  1544. l066dh:
  1545. ; Clear remaining parameters
  1546. inc hl ;066d Move to next parameter slot
  1547. ld (hl),000h ;066e Clear parameter (set to 0x00)
  1548. djnz l066dh ;0670 Clear remaining 3 parameters (total 6 bytes)
  1549. ; Execute the disk command
  1550. call reading ;0672 Execute the prepared disk command
  1551. ret c ;0675 Return immediately if command failed
  1552. call moveoutreseta ;0676 Move/output result data
  1553. call reading2 ;0679 Read final status
  1554. and 002h ;067c Check bit 1 (error flag)
  1555. ret z ;067e Return success if bit 1 clear
  1556. scf ;067f Set carry flag (error)
  1557. ret ;0680 Return with error
  1558. ; ================================================================================
  1559. ; CRITICAL DISK ERROR HANDLER
  1560. ; ================================================================================
  1561. ; Handles severe disk system errors that prevent successful boot
  1562. ; This is called when disk controller hardware fails or becomes unresponsive
  1563. ; Displays Error #1 message and enters service mode
  1564. print_error1:
  1565. push bc ;0681 Save BC register state
  1566. call screenclearnetry2 ;0682 Clear screen and setup error display
  1567. rst 10h ;0685 RST 10h: Display error message (points to message below)
  1568. ; ================================================================================
  1569. ; ERROR #1 MESSAGE DATA - CRITICAL DISK SYSTEM ERROR
  1570. ; ================================================================================
  1571. ; "Error 1: Disk system error, Call Service" - 40 characters
  1572. ; This indicates hardware-level disk controller failure requiring service
  1573. ERROR1_start:
  1574. defb 028h ;0686 Message length: 40 characters
  1575. defb 045h ;0687 'E'
  1576. defb 072h ;0688 'r'
  1577. defb 072h ;0689 'r'
  1578. defb 06fh ;068a 'o'
  1579. defb 072h ;068b 'r'
  1580. defb 020h ;068c ' '
  1581. defb 031h ;068d '1'
  1582. defb 03ah ;068e ':'
  1583. defb 020h ;068f ' '
  1584. defb 044h ;0690 'D'
  1585. defb 069h ;0691 'i'
  1586. defb 073h ;0692 's'
  1587. defb 06bh ;0693 'k'
  1588. defb 020h ;0694 ' '
  1589. defb 073h ;0695 's'
  1590. defb 079h ;0696 'y'
  1591. defb 073h ;0697 's'
  1592. defb 074h ;0698 't'
  1593. defb 065h ;0699 'e'
  1594. defb 06dh ;069a 'm'
  1595. defb 020h ;069b ' '
  1596. defb 065h ;069c 'e'
  1597. defb 072h ;069d 'r'
  1598. defb 072h ;069e 'r'
  1599. defb 06fh ;069f 'o'
  1600. defb 072h ;06a0 'r'
  1601. defb 02ch ;06a1 ','
  1602. defb 020h ;06a2 ' '
  1603. defb 043h ;06a3 'C'
  1604. defb 061h ;06a4 'a'
  1605. defb 06ch ;06a5 'l'
  1606. defb 06ch ;06a6 'l'
  1607. defb 020h ;06a7 ' '
  1608. defb 053h ;06a8 'S'
  1609. defb 065h ;06a9 'e'
  1610. defb 072h ;06aa 'r'
  1611. defb 076h ;06ab 'v'
  1612. defb 069h ;06ac 'i'
  1613. defb 063h ;06ad 'c'
  1614. defb 065h ;06ae 'e'
  1615. ERROR1_end:
  1616. ; ================================================================================
  1617. ; ERROR RECOVERY AND SYSTEM RESTART
  1618. ; ================================================================================
  1619. ; After displaying the error, system performs cleanup and restart sequence
  1620. error1_recovery:
  1621. call delayloop ;06af Delay to allow user to read error message
  1622. call delayloop ;06b2 Additional delay for visibility
  1623. call delayloop ;06b5 Final delay before restart attempt
  1624. call setupclearscreen2 ;06b8 Clear screen and reinitialize display system
  1625. call readydisk ;06bb Attempt to ready disk system for retry
  1626. pop bc ;06be Restore BC register from stack
  1627. scf ;06bf Set carry flag (indicate error condition)
  1628. ret ;06c0 Return with error status
  1629. ; ================================================================================
  1630. ; DISK SECTOR READ WITH RETRY LOGIC
  1631. ; ================================================================================
  1632. ; Advanced disk read routine with automatic retry and error recovery
  1633. ; Input: D = sector count, BC = parameters, HL = buffer pointer
  1634. ; Output: Carry set if unrecoverable error, clear if success
  1635. l06c1h:
  1636. call sub_04c7h ;06c1 Setup disk operation parameters
  1637. ld a,b ;06c4 Get B register (track/cylinder)
  1638. ld (0ff85h),a ;06c5 Store track parameter in system memory
  1639. ld a,c ;06c8 Get C register (sector/head)
  1640. ld (0ff86h),a ;06c9 Store sector parameter in system memory
  1641. l06cch:
  1642. ld a,d ;06cc Get D register (sector count)
  1643. ld (0ff87h),a ;06cd Store sector count parameter
  1644. push bc ;06d0 Save BC registers (track/sector info)
  1645. push hl ;06d1 Save HL registers (buffer pointer)
  1646. call reading ;06d2 Execute disk read command
  1647. jp c,l06fbh ;06d5 If read error, jump to cleanup and return
  1648. ; Successful read - transfer parameter data
  1649. ld hl,0ff83h ;06d8 Point to disk parameter buffer
  1650. ld bc,00678h ;06db B=6 bytes to transfer, C=0x78 (I/O port for data)
  1651. l06deh:
  1652. ; Wait for controller ready and transfer data
  1653. in a,(079h) ;06de Read disk controller status port
  1654. and 041h ;06e0 Check bits 6 and 0 (ready and data request flags)
  1655. jr nz,l06deh ;06e2 Wait until controller indicates ready for transfer
  1656. outi ;06e4 Transfer byte: output (HL) to port C, increment HL, decrement B
  1657. jr nz,l06deh ;06e6 Continue until all 6 parameter bytes transferred
  1658. out (07ah),a ;06e8 Write final control byte to data port 0x7A
  1659. nop ;06ea Short timing delay for controller
  1660. l06ebh:
  1661. ; Wait for final status and complete operation
  1662. in a,(079h) ;06eb Read disk controller status
  1663. and 044h ;06ed Check bits 6 and 2 (completion status flags)
  1664. jr nz,l06ebh ;06ef Wait for completion status change
  1665. out (07bh),a ;06f1 Write completion status to control port 0x7B
  1666. call reading2 ;06f3 Read final operation status
  1667. and 002h ;06f6 Check bit 1 (error indication)
  1668. call nz,sub_06ffh ;06f8 If error bit set, call error recovery routine
  1669. l06fbh:
  1670. ; Cleanup and return
  1671. pop hl ;06fb Restore HL registers (buffer pointer)
  1672. pop bc ;06fc Restore BC registers (track/sector)
  1673. inc bc ;06fd Increment BC to next sector position
  1674. ret ;06fe Return to caller
  1675. ; ================================================================================
  1676. ; ADVANCED DISK ERROR RECOVERY ROUTINE
  1677. ; ================================================================================
  1678. ; Sophisticated error recovery with retry logic and validation
  1679. ; Called when initial read fails - attempts recovery and validation
  1680. ; Returns: Carry set if unrecoverable, clear if recovery successful
  1681. sub_06ffh:
  1682. call reading ;06ff Attempt another disk read operation
  1683. ret c ;0702 Return immediately if read still failing
  1684. ld a,003h ;0703 A = 3 (retry/recovery command code)
  1685. call moveout ;0705 Execute move/output operation with retry command
  1686. ld bc,00478h ;0708 B=4 bytes to read, C=0x78 (I/O data port)
  1687. ld hl,0ff89h ;070b Point to error recovery buffer in system memory
  1688. l070eh:
  1689. ; Read recovery data from controller
  1690. in a,(079h) ;070e Read disk controller status port
  1691. cp 00fh ;0710 Compare with 0x0F (ready for data transfer)
  1692. jr nz,l070eh ;0712 Wait until controller indicates ready (status = 0x0F)
  1693. ini ;0714 Input byte: read from port C to (HL), increment HL, decrement B
  1694. jr nz,l070eh ;0716 Continue until all 4 recovery bytes read
  1695. call reading2 ;0718 Read final status after recovery attempt
  1696. ld a,(0ff89h) ;071b Get first byte from recovery buffer
  1697. sub 098h ;071e Compare with expected recovery value 0x98
  1698. ret z ;0720 Return success (Z flag) if recovery data matches
  1699. scf ;0721 Set carry flag (recovery failed)
  1700. ret ;0722 Return with unrecoverable error status
  1701. ; ================================================================================
  1702. ; LOW-LEVEL DISK CONTROLLER COMMUNICATION ROUTINES
  1703. ; ================================================================================
  1704. ; Core routines for sending commands and reading status from disk controller
  1705. reading:
  1706. ; Initiate disk read command with timeout protection
  1707. in a,(079h) ;0723 Read disk controller status port
  1708. and 080h ;0725 Check bit 7 (controller ready flag)
  1709. scf ;0727 Set carry flag (assume error initially)
  1710. ret z ;0728 Return with error if controller not ready
  1711. ld a,001h ;0729 A = 1 (start read command)
  1712. out (079h),a ;072b Send start command to disk controller
  1713. ld b,0ffh ;072d B = 255 (timeout counter - ~255 loop iterations)
  1714. l072fh:
  1715. ; Wait for command completion with timeout
  1716. in a,(079h) ;072f Read controller status port
  1717. and 080h ;0731 Check ready bit (bit 7)
  1718. ret z ;0733 Return success (carry clear) if ready bit cleared
  1719. djnz l072fh ;0734 Decrement timeout counter and continue waiting
  1720. scf ;0736 Set carry flag (timeout error)
  1721. ret ;0737 Return with timeout error
  1722. reading2:
  1723. in a,(079h) ;0738 Read disk controller status
  1724. and 044h ;073a Check bits 6 and 2 (busy/status flags)
  1725. jr nz,reading2 ;073c Wait until both flags clear
  1726. in a,(078h) ;073e Read result from data port
  1727. ld b,a ;0740 Save result in B
  1728. l0741h:
  1729. in a,(079h) ;0741 Read controller status again
  1730. and 042h ;0743 Check bits 6 and 1 (different status bits)
  1731. jr nz,l0741h ;0745 Wait until these flags clear
  1732. in a,(078h) ;0747 Read final data byte
  1733. ld a,b ;0749 Restore original result to A
  1734. ret ;074a Return with status in A
  1735. ; ================================================================================
  1736. ; DISK COMMAND OUTPUT ROUTINES
  1737. ; ================================================================================
  1738. ; Send command sequences to disk controller
  1739. moveoutreseta:
  1740. ld a,000h ;074b A = 0 (reset command)
  1741. moveout:
  1742. call sub_0760h ;074d Send A to disk controller
  1743. ld a,(0ff84h) ;0750 Get stored command parameter
  1744. call sub_0760h ;0753 Send parameter to controller
  1745. ld a,000h ;0756 A = 0 (padding/terminator)
  1746. ld b,004h ;0758 B = 4 (send 4 zero bytes)
  1747. l075ah:
  1748. call sub_0760h ;075a Send zero byte to controller
  1749. djnz l075ah ;075d Repeat 4 times
  1750. ret ;075f Return
  1751. ; ================================================================================
  1752. ; LOW-LEVEL DISK CONTROLLER I/O
  1753. ; ================================================================================
  1754. ; Fundamental routine for sending bytes to disk controller
  1755. sub_0760h:
  1756. push af ;0760 Save byte to send
  1757. l0761h:
  1758. in a,(079h) ;0761 Read controller status
  1759. and 041h ;0763 Check bits 6 and 0 (ready/busy flags)
  1760. jr nz,l0761h ;0765 Wait until controller ready to receive
  1761. pop af ;0767 Restore byte to send
  1762. out (078h),a ;0768 Send byte to controller data port
  1763. ret ;076a Return
  1764. ; ================================================================================
  1765. ; DISK CONTROLLER DATA TRANSFER
  1766. ; ================================================================================
  1767. ; Transfers data block from controller
  1768. sub_076bh:
  1769. ld a,00ch ;076b A = 0x0C (data transfer command)
  1770. call moveout ;076d Send command to controller
  1771. ld bc,00878h ;0770 B=8 bytes, C=0x78 (data port)
  1772. l0773h:
  1773. in a,(079h) ;0773 Read controller status
  1774. cp 007h ;0775 Compare with 0x07 (data ready)
  1775. jr nz,l0773h ;0777 Wait until data ready
  1776. outi ;0779 Input byte: (HL) ← (C), HL++, B--
  1777. jr nz,l0773h ;077b Continue until 8 bytes transferred
  1778. jr reading2 ;077d Jump to read final status
  1779. ; ================================================================================
  1780. ; DISK ERROR RECOVERY AND ALTERNATE ROUTINES
  1781. ; ================================================================================
  1782. l077fh:
  1783. ld a,0e4h ;077f A = 0xE4 (error recovery command)
  1784. call steproutine ;0781 Execute step/recovery routine
  1785. ret z ;0784 Return if successful
  1786. jp print_error1 ;0785 Jump to disk error handler
  1787. l0788h:
  1788. call reading ;0788 Attempt disk read
  1789. ret c ;078b Return if error
  1790. ld a,001h ;078c A = 0x01 (step command)
  1791. call steproutine ;078e Execute step routine
  1792. ret z ;0791 Return if successful
  1793. jr print_error3 ;0792 Jump to alternate error handling
  1794. ; ================================================================================
  1795. ; DISK STEP/SEEK ROUTINE
  1796. ; ================================================================================
  1797. ; Executes disk step commands (seek operations)
  1798. steproutine:
  1799. call moveout ;0794 Send step command to controller
  1800. call reading2 ;0797 Read controller status
  1801. and 002h ;079a Check bit 1 (error flag)
  1802. ret ;079c Return with Z flag set if no error
  1803. ; ================================================================================
  1804. ; DISK MALFUNCTION ERROR HANDLER
  1805. ; ================================================================================
  1806. print_error3:
  1807. call screenclearnetry2 ;079d Clear screen and setup display
  1808. rst 10h ;07a0 RST 10h: Display error message
  1809. ; ================================================================================
  1810. ; ERROR #3 MESSAGE DATA - DISK MALFUNCTION
  1811. ; ================================================================================
  1812. ; BLOCK 'ERROR3' (start 0x07a1 end 0x07c9)
  1813. ERROR3_start:
  1814. defb 027h ;07a1 Message length: 39 characters
  1815. defb 045h ;07a2 'E' - "Error #3: Disk Malfunction, Call Service"
  1816. defb 072h ;07a3 'r'
  1817. defb 072h ;07a4 'r'
  1818. defb 06fh ;07a5 'o'
  1819. defb 072h ;07a6 'r'
  1820. defb 020h ;07a7 ' '
  1821. defb 033h ;07a8 '3'
  1822. defb 03ah ;07a9 ':'
  1823. defb 020h ;07aa ' '
  1824. defb 044h ;07ab 'D'
  1825. defb 069h ;07ac 'i'
  1826. defb 073h ;07ad 's'
  1827. defb 06bh ;07ae 'k'
  1828. defb 020h ;07af ' '
  1829. defb 04dh ;07b0 'M'
  1830. defb 061h ;07b1 'a'
  1831. defb 06ch ;07b2 'l'
  1832. defb 066h ;07b3 'f'
  1833. defb 075h ;07b4 'u'
  1834. defb 06eh ;07b5 'n'
  1835. defb 063h ;07b6 'c'
  1836. defb 074h ;07b7 't'
  1837. defb 069h ;07b8 'i'
  1838. defb 06fh ;07b9 'o'
  1839. defb 06eh ;07ba 'n'
  1840. defb 02ch ;07bb ','
  1841. defb 020h ;07bc ' '
  1842. defb 043h ;07bd 'C'
  1843. defb 061h ;07be 'a'
  1844. defb 06ch ;07bf 'l'
  1845. defb 06ch ;07c0 'l'
  1846. defb 020h ;07c1 ' '
  1847. defb 053h ;07c2 'S'
  1848. defb 065h ;07c3 'e'
  1849. defb 072h ;07c4 'r'
  1850. defb 076h ;07c5 'v'
  1851. defb 069h ;07c6 'i'
  1852. defb 063h ;07c7 'c'
  1853. defb 065h ;07c8 'e'
  1854. ERROR3_end:
  1855. halt ;07c9 System halt - requires service intervention
  1856. ; ================================================================================
  1857. ; DATA TABLES AND CONSTANTS
  1858. ; ================================================================================
  1859. ; Various data tables used by system routines
  1860. l07cah:
  1861. defb 001h ;07ca Data table entry 1
  1862. defb 032h ;07cb Data table entry 2
  1863. defb 004h ;07cc Data table entry 3
  1864. defb 001h ;07cd Data table entry 4
  1865. defb 031h ;07ce Data table entry 5
  1866. defb 000h ;07cf Data table entry 6
  1867. defb 040h ;07d0 Data byte
  1868. defb 00bh ;07d1 Data byte
  1869. defb 006h ;07d2 Data byte
  1870. defb 000h ;07d3 Data byte
  1871. defb 095h ;07d4 Data byte
  1872. defb 0ffh ;07d5 Data byte
  1873. defb 001h ;07d6 Data byte
  1874. l07d7h:
  1875. defb 032h ;07d7 Data byte
  1876. defb 002h ;07d8 Data byte
  1877. defb 001h ;07d9 Data byte
  1878. defb 031h ;07da Data table entry 1
  1879. defb 000h ;07db Data table entry 1
  1880. defb 040h ;07dc Data table entry 2
  1881. defb 00bh ;07dd Data table entry 2
  1882. defb 006h ;07de Data byte
  1883. defb 000h ;07df Data byte
  1884. defb 04ah ;07e0 Data byte
  1885. defb 0ffh ;07e1 Data byte
  1886. l07e2h:
  1887. defb 000h ;07e2 Data byte 'Q'
  1888. defb 000h ;07e3 Data byte (NOP padding)
  1889. defb 04ah ;07e4 Data byte (NOP padding)
  1890. l07e5h:
  1891. defb 0ffh ;07e5 Data byte 'J'
  1892. ; ROM unused space filled with RST 38h (0FFh) - typical EPROM pattern
  1893. defb 0ffh ;07e6 Unused ROM space
  1894. defb 0ffh ;07e7 Unused ROM space
  1895. defb 0ffh ;07e8 Unused ROM space
  1896. defb 0ffh ;07e9 Unused ROM space
  1897. defb 0ffh ;07ea Unused ROM space
  1898. defb 0ffh ;07eb Unused ROM space
  1899. defb 0ffh ;07ec Unused ROM space
  1900. defb 0ffh ;07ed Unused ROM space
  1901. defb 0ffh ;07ee Unused ROM space
  1902. defb 0ffh ;07ef Unused ROM space
  1903. defb 0ffh ;07f0 Unused ROM space
  1904. defb 0ffh ;07f1 Unused ROM space
  1905. defb 0ffh ;07f2 Unused ROM space
  1906. defb 0ffh ;07f3 Unused ROM space
  1907. defb 0ffh ;07f4 Unused ROM space
  1908. defb 0ffh ;07f5 Unused ROM space
  1909. defb 0ffh ;07f6 Unused ROM space
  1910. defb 0ffh ;07f7 Unused ROM space
  1911. defb 0ffh ;07f8 Unused ROM space
  1912. defb 0ffh ;07f9 Unused ROM space
  1913. defb 0ffh ;07fa Unused ROM space
  1914. defb 0ffh ;07fb Unused ROM space
  1915. defb 0ffh ;07fc Unused ROM space
  1916. defb 0ffh ;07fd Unused ROM space
  1917. defb 0ffh ;07fe Unused ROM space
  1918. defb 0ffh ;07ff End of 2K ROM - TMS2516 EPROM
  1919. ; ================================================================================
  1920. ; END OF ROM - MONROE OC8820 BOOT ROM R3.00C
  1921. ; ================================================================================
  1922. ; Total ROM size: 2048 bytes (0x0000-0x07FF)
  1923. ; Boot process complete - system transfers control to OS at 0xFFA6
  1924. ; ================================================================================