1
0
mirror of https://github.com/livingcomputermuseum/ContrAlto.git synced 2026-01-27 12:31:52 +00:00

A few fixes to DNS<- behavior and some tweaks to the disk controller. Boot code is progressing further.

This commit is contained in:
Josh Dersch
2015-11-03 16:21:12 -08:00
parent c0f23685b1
commit 39f077bf7a
10 changed files with 486 additions and 29 deletions

View File

@@ -41,6 +41,9 @@ namespace Contralto
{
_cpu.Reset();
_memBus.Reset();
_mem.Reset();
ALU.Reset();
Shifter.Reset();
_diskController.Reset();
}

View File

@@ -80,6 +80,7 @@ namespace Contralto.CPU
get { return _aluC0; }
}
public void Reset()
{
// Reset registers

View File

@@ -26,11 +26,18 @@ namespace Contralto.CPU
public static class Shifter
{
static Shifter()
{
Reset();
}
public static void Reset()
{
_op = ShifterOp.Invalid;
_count = 0;
_output = 0;
_magic = false;
_dns = false;
_dnsCarry = 0;
}
/// <summary>
@@ -71,6 +78,12 @@ namespace Contralto.CPU
/// <param name="dns"></param>
public static void SetDNS(bool dns, int carry)
{
// Sanity check
if (carry != 0 && carry != 1)
{
throw new InvalidOperationException("carry can only be 0 or 1.");
}
_dns = dns;
_dnsCarry = carry;
}
@@ -109,7 +122,16 @@ namespace Contralto.CPU
}
else if (_dns)
{
throw new NotImplementedException("DNS LSH 1");
//
// "Rotate the 17 input bits left by one bit. This has the effect of rotating
// bit 0 left into the carry position and the carry bit into bit 15."
//
// Put input carry into bit 15.
_output = (ushort)(_output | _dnsCarry);
// update carry
_dnsCarry = ((input & 0x8000) >> 15);
}
break;
@@ -124,7 +146,16 @@ namespace Contralto.CPU
}
else if (_dns)
{
throw new NotImplementedException("DNS RSH 1");
//
// "Rotate the 17 bits right by one bit. Bit 15 is rotated into the carry position
// and the carry bit into bit 0."
//
// Put input carry into bit 0.
_output |= (ushort)(_output | (_dnsCarry << 15));
// update carry
_dnsCarry = input & 0x1;
}
break;
@@ -138,8 +169,11 @@ namespace Contralto.CPU
}
if (_dns)
{
throw new NotImplementedException("DNS LCY");
{
//
// "Swap the 8-bit halves of the 16-bit result. The carry is not affected."
//
_output = (ushort)(((input & 0xff00) >> 8) | ((input & 0x00ff) << 8));
}
break;

View File

@@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using Contralto.Memory;
using Contralto.Logging;
namespace Contralto.CPU
{
@@ -61,6 +62,7 @@ namespace Contralto.CPU
{
case DiskF1.LoadKDATA:
// "The KDATA register is loaded from BUS[0-15]."
Log.Write(LogComponent.DiskController, "KDATA loaded with {0}", OctalHelpers.ToOctal(_busData));
_cpu._system.DiskController.KDATA = _busData;
break;
@@ -69,6 +71,7 @@ namespace Contralto.CPU
// in addition, it causes the head address bit to be loaded from KDATA[13]."
// (the latter is done by DiskController)
_cpu._system.DiskController.KADR = (ushort)((_busData & 0xfe) >> 1);
Log.Write(LogComponent.DiskController, "KADR bus data is {0}", OctalHelpers.ToOctal(_busData));
break;
case DiskF1.LoadKCOMM:
@@ -173,6 +176,10 @@ namespace Contralto.CPU
// "NEXT <- NEXT OR (IF disk not ready to accept command THEN 1 ELSE 0)
// for now, always zero (not sure when this would be 1 yet)
_nextModifier |= GetInitModifier(instruction);
if (!_cpu._system.DiskController.Ready)
{
_nextModifier |= 1;
}
break;
default:

View File

@@ -283,7 +283,7 @@ namespace Contralto.CPU
case 0x500:
case 0x600:
// NEG, INC, ADC, SUB, ADD, AND - invert the carry bit
if (ALU.Carry != 0)
if (_cpu._aluC0 != 0)
{
carry = (~carry) & 0x1;
}

View File

@@ -339,13 +339,19 @@ namespace Contralto.CPU
break;
}
// We always do the shifter operation; DNS may need its output.
//
Shifter.DoOperation(_cpu._l, _cpu._t);
//
// Write back to registers:
//
// Do writeback to selected R register from shifter output
// Do writeback to selected R register from shifter output.
//
if (_loadR)
{
_cpu._r[_rSelect] = Shifter.DoOperation(_cpu._l, _cpu._t);
{
_cpu._r[_rSelect] = Shifter.Output;
}
// Do writeback to selected R register from M

View File

@@ -96,6 +96,8 @@ namespace Contralto
_otherRegs.Rows[2].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.M, 6);
_otherRegs.Rows[3].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.IR, 6);
_otherRegs.Rows[4].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.ALUC0, 1);
//_otherRegs.Rows[4].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.Carry, 1);
//_otherRegs.Rows[4].Cells[1].Value = OctalHelpers.ToOctal(_system.CPU.Skip, 1);
_otherRegs.Rows[5].Cells[1].Value = OctalHelpers.ToOctal(_system.MemoryBus.MAR, 6);
_otherRegs.Rows[6].Cells[1].Value = OctalHelpers.ToOctal(_system.MemoryBus.MD, 6);
_otherRegs.Rows[7].Cells[1].Value = OctalHelpers.ToOctal(_system.MemoryBus.Cycle & 0x3f, 2);
@@ -183,9 +185,11 @@ namespace Contralto
_otherRegs.Rows.Add("M", "0");
_otherRegs.Rows.Add("IR", "0");
_otherRegs.Rows.Add("ALUC0", "0");
//_otherRegs.Rows.Add("CARRY", "0");
//_otherRegs.Rows.Add("SKIP", "0");
_otherRegs.Rows.Add("MAR", "0");
_otherRegs.Rows.Add("MD", "0");
_otherRegs.Rows.Add("MCycle", "0");
_otherRegs.Rows.Add("MCycle", "0");
_diskData.Rows.Add("Cycles", "0");
_diskData.Rows.Add("Cylinder", "0");
@@ -492,6 +496,8 @@ namespace Contralto
private void OnStepButtonClicked(object sender, EventArgs e)
{
StopExecThread();
SetExecutionState(ExecutionState.SingleStep);
ExecuteStep();
SetExecutionState(ExecutionState.Stopped);
@@ -499,6 +505,7 @@ namespace Contralto
private void OnAutoStepButtonClicked(object sender, EventArgs e)
{
StopExecThread();
//
// Continuously step (and update the UI)
// until the "Stop" button is pressed or something bad happens.
@@ -510,6 +517,7 @@ namespace Contralto
private void RunButton_Click(object sender, EventArgs e)
{
StopExecThread();
//
// Continuously execute, but do not update UI
// until the "Stop" button is pressed or something bad happens.
@@ -524,6 +532,7 @@ namespace Contralto
private void RunToNextTaskButton_Click(object sender, EventArgs e)
{
StopExecThread();
//
// Continuously execute until the next task switch but do not update UI
// until the "Stop" button is pressed or something bad happens.
@@ -546,6 +555,8 @@ namespace Contralto
/// <param name="e"></param>
private void NovaStep_Click(object sender, EventArgs e)
{
StopExecThread();
{
_execThread = new Thread(new System.Threading.ParameterizedThreadStart(ExecuteProc));
_execThread.Start(ExecutionType.NextNovaInstruction);
@@ -554,6 +565,27 @@ namespace Contralto
}
private void OnStopButtonClicked(object sender, EventArgs e)
{
StopExecThread();
Refresh();
}
private void ResetButton_Click(object sender, EventArgs e)
{
StopExecThread();
_system.Reset();
Refresh();
}
private void ExecuteStep()
{
StopExecThread();
_system.SingleStep();
Refresh();
}
private void StopExecThread()
{
if (_execThread != null &&
_execThread.IsAlive)
@@ -570,17 +602,6 @@ namespace Contralto
SetExecutionState(ExecutionState.Stopped);
}
private void ResetButton_Click(object sender, EventArgs e)
{
_system.Reset();
}
private void ExecuteStep()
{
_system.SingleStep();
Refresh();
}
private void ExecuteProc(object param)
{
ExecutionType execType = (ExecutionType)param;

View File

@@ -0,0 +1,329 @@
000:000000 - JMP 000
001:000345 - JMP 345 ; Entrypoint
002:000354 - JMP 354 ; Unused (version info, overwritten by disk status by microcode.
003:000403 - JMP .+3 ;(6) ; Ditto
004:120064 - COMC 1,0,SZR ; Build date
005:064330 - NIOP 1,30
006:004415 - JSR .+15 ;(23) ; JSR to zero-length routine at 23; side effect is loading 24 into AC3 (starting offset of data storage)
007:171000 - MOV 3,2 ; copy address 24 into AC2
010:020410 - LDA 0,.+10 ;(20) ; Load AC0 with 44120 ; disk command (command seal, check header, check label, read data, xfer on, drive 0)
011:024411 - LDA 1,.+11 ;(22) ; Load AC1 with 402 ; address ?
012:004540 - JSR .+140 ;(152) ; jump to subroutine at 152; copy label from 402 to 40 and 62.
013:020406 - LDA 0,.+6 ;(21) ; AC0 gets 400
014:041007 - STA 0,AC2+7 ; store 400 at 33
015:004210 - JSR 210 ; jump to subroutine at 210;
016:064401 - DIA 1,1 ; we die here; this is a JSRII instruction which indirects to 0... assume this should actually start real code
; data ?
017:176776 - SUBSC# 3,3,SEZ
; data
020:044120 - STA 1,120
021:000400 - JMP .+0 ;(21)
022:000402 - JMP .+2 ;(24)
023:005400 - JSR AC3+0 ; Return from zero-length routine
; Appear to be used as pointers to DCBs at 26 and 50; swapped by routine at 112
024:176217 - ADCR# 3,3,SBN
025:176175 - ADCLC# 3,3,SNR
; beginning of first DCB
026:176217 - ADCR# 3,3,SBN ; Pointer to next DCB
027:027400 - LDA@ 1,AC3+0 ; Disk Status
030:044130 - STA 1,130 ; Disk command
031:176205 - ADCR 3,3,SNR ; Header address
032:176207 - ADCR 3,3,SBN ; Label address
033:175550 - INCLO# 3,3 ; Data address (gets 400 (STA at 14))
034:000000 - JMP 0 ; non-error interrupt mask
035:000000 - JMP 0 ; error interrupt mask
036:000000 - JMP 0 ; reserved
037:000000 - JMP 0 ; disk address
; 1st copy of label block at 402 starts here
040:130374 - COMSC# 1,2,SZR ; 000400 - disk address (?)
041:000000 - JMP 0 ; 120374 - previous disk address
042:000000 - JMP 0 ; 000000 - blank
043:000000 - JMP 0 ; 001000 - num chars
044:176007 - ADC 3,3,SBN ; 000001 - page number
045:000001 - JMP 1 ; 000001 - version
046:000000 - JMP 0 ; 000000 - sn high
047:000176 - JMP 176 ; 000176 - sn low
; ends here
; beginning of 2nd DCB
050:000000 - JMP 0 ; Pointer to next DCB
051:000000 - JMP 0 ; Disk Status
052:044130 - STA 1,130 ; Disk command
053:176227 - ADCRZ 3,3,SBN ; Header address
054:176231 - ADCRZ# 3,3,SKP ; Label address
055:176150 - ADCLO# 3,3 ; Data address
056:000000 - JMP 0 ; non-error interrupt mask
057:000000 - JMP 0 ; error interrupt mask
060:000000 - JMP 0 ; reserved
061:130374 - COMSC# 1,2,SZR ; disk address
; 2nd copy of label block at 402 starts here (and magically matches
; what's already there!)
062:000400 - JMP .+0 ;(62) ; 000400 - disk address (?)
063:120374 - COMSC# 1,0,SZR ; 120374 - previous disk address
064:000000 - JMP 0 ; 000000 - blank
065:001000 - JMP AC2+0 ; 001000 - num chars
066:000001 - JMP 1 ; 000001 - page number
067:000001 - JMP 1 ; 000001 - version
070:000000 - JMP 0 ; 000000 - sn high
071:000176 - JMP 176 ; 000176 - sn low
; ends here
; temp locations used for return addresses, etc.
072:000000 - JMP 0
073:176016 - ADC# 3,3,SEZ
074:176147 - ADCLO 3,3,SBN
075:176310 - ADCS# 3,3
076:000536 - JMP .+136 ;(234)
; subroutine
077:055051 - STA 3,AC2+51 ; save return address
100:035000 - LDA 3,AC2+0 ; AC3 gets 26
101:021405 - LDA 0,AC3+5 ; AC0 gets 400 from 33
102:024717 - LDA 1,.+-61 ;(21) ; AC1 gets 400 from 21
103:123000 - ADD 1,0 ; AC0 gets AC0+AC1 (1000)
104:024404 - LDA 1,.+4 ;(110) ; AC1 gets -1000 (176777)
105:106032 - ADCZ# 0,1,SZC ; Add 1s cmpl of AC0 (176777) and AC1 (no writeback), skip if carry is zero
106:011051 - ISZ AC2+51 ; increment return address
107:003051 - JMP@ AC2+51 ; return to ret address (+1 added if carry is nonzero)
; data
110:176777 - SUBSC# 3,3,SBN
111:000420 - JMP .+20 ;(131)
; subroutine; apparently we're too cool to save our return address.
112:021000 - LDA 0,AC2+0 ; swap contents of locations 24 & 25
113:025001 - LDA 1,AC2+1
114:045000 - STA 1,AC2+0
115:041001 - STA 0,AC2+1
116:001400 - JMP AC3+0 ; return
; subroutine.
117:055050 - STA 3,AC2+50 ; save ret
120:176460 - SUBC 3,3 ; get zero
121:055046 - STA 3,AC2+46 ; write zero to 72
122:000551 - JMP .+151 ;(273) ; continue at 273
;subroutine
123:055050 - STA 3,AC2+50 ; save return address
124:035000 - LDA 3,AC2+0 ; AC3 gets DCB address (26 or 50)
125:021412 - LDA 0,AC3+12 ; AC0 gets word 0 of label block @ 40
126:025411 - LDA 1,AC3+11 ; AC1 gets word at 37 (disk address, word 11 of 1st DCB)
127:035001 - LDA 3,AC2+1 ; AC3 gets other DCB address (@25 - 50 or 26)
130:041411 - STA 0,AC3+11 ; write word 0 of label block to 61
131:045413 - STA 1,AC3+13 ; write zero to 63
132:102460 - SUBC 0,0 ; AC0 gets 0
133:041400 - STA 0,AC3+0 ; zero out 50, 51 (pointer to next DCB, disk status)
134:041401 - STA 0,AC3+1
135:041412 - STA 0,AC3+12 ; zero out 62, 66 (label words)
136:041416 - STA 0,AC3+16
137:005053 - JSR AC2+53 ; 77 ; do subroutine at 77; this appears to check if loading is done
140:000405 - JMP .+5 ;(145) ;
141:035001 - LDA 3,AC2+1 ; AC3 gets address of 2nd DCB (50 or 26)
142:041405 - STA 0,AC3+5 ; write 0 to DCB data address
143:057000 - STA@ 3,AC2+0
144:003050 - JMP@ AC2+50 ; return
; jumped here from 140
145:004752 - JSR .+-26 ;(117)
146:003047 - JMP@ AC2+47 ; wait, what? 47? return to.... caller of 210, at 16. This is the end of the loader routine.
; data
147:000521 - JMP .+121 ;(270) ; KBLK address (pointer to first DCB used by disk hardware)
; data
150:177756 - ANDSO# 3,3,SEZ
151:000377 - JMP 377
; subroutine: copy label block from 402 twice, to 40 and 62. Initialize DCBs at 26 and 50.
; on entry:
; AC0 contains disk command
; AC1 contains 402 (label address for sector 0, where microcode boot copied it originally)
; AC2 contains 24 (offset for all data)
; on exit:
; Label record at 402 (8 bytes long) copied to locs 40-47 and 62-71;
; DCB interrupt masks and addresses zeroed out (at 34-37, 56-61)
; loc 25 points to DCB at 50
152:055047 - STA 3,AC2+47 ; save return address @ 73
153:045051 - STA 1,AC2+51 ; write label address to 75 (AC1 loaded with 402 by caller)
154:015051 - DSZ AC2+51 ; decrement address at 75 (401)
155:041004 - STA 0,AC2+4 ; write 44120 to 30 ; DCB commands
156:041026 - STA 0,AC2+26 ; write 44120 to 52
157:034561 - LDA 3,.+161 ;(340) ; load AC3 with 2
160:055050 - STA 3,AC2+50 ; write 2 to 74 - loop counter used at 202
161:157000 - ADD 2,3 ; 24 + 2, result in AC3
162:055000 - STA 3,AC2+0 ; store 26 at 24 (top of data structure pointed by AC2)
; top of loop
163:102460 - SUBC 0,0 ; put a zero in AC0
164:041406 - STA 0,AC3+6 ; zero out values at 34, 35, 36, 37 and 56, 57, 60, 61 (DCB entries)
165:041407 - STA 0,AC3+7 ;
166:041410 - STA 0,AC3+10
167:041411 - STA 0,AC3+11
170:024417 - LDA 1,.+17 ;(207) ; AC1 gets 177770 (-10)
171:136400 - SUB 1,3 ; subtract AC3 from AC1, result in AC3 (26 minus -10 = 36) (calculate label offset)?
172:055773 - STA 3,AC3+-5 ; store AC3 in AC3-5 (31)
173:165400 - INC 3,1 ; inc AC3, store in AC1 (37)
174:125400 - INC 1,1 ; Inc AC1 (AC1 now AC3 + 2 = 40)
175:045774 - STA 1,AC3+-4 ; store AC1 at AC3-4 (32)
176:021051 - LDA 0,AC2+51 ; AC0 gets AC2+51 (24+51) ; blt source (label address -1 = 401)
177:034410 - LDA 3,.+10 ;(207) ; AC3 gets 177770 ; blt count (8 words)
200:166000 - ADC 3,1 ; AC1 gets complement of AC1+AC3 ; blt dest (47 or 61)
201:061005 - BLT ; block transfer -- copy label block from 402 to destination.
202:015050 - DSZ AC2+50 ; decrement copy counter at AC2+50 (74), skip next if zero
203:135401 - INC 1,3,SKP ; Increment AC1 (copy destination), stow in AC3, skip next instruction.
204:003047 - JMP@ AC2+47 ; RTS: exit from DSZ at 202, jump to AC2+47 (@73 -- return from subroutine)
205:055001 - STA 3,AC2+1 ; get here from 203; AC3 stored at AC2 + 1 (25 -- end address + 1 of copied label)
206:000755 - JMP .+-23 ;(163) ; loop back to 163...
207:177770 - ANDSC# 3,3 ; data - BLT word count (complement)
210:055047 - STA 3,AC2+47 ; save return address
211:004712 - JSR .+-66 ;(123) ; JSR to 123
212:004700 - JSR .+-100 ;(112) ; JSR to 112 - swap DCBs @ 24,25
; loop here; wait for disk
213:035000 - LDA 3,AC2+0 ; AC3 gets current DCB address
214:025412 - LDA 1,AC3+12 ; AC1 gets label data (previous disk address)
215:022732 - LDA@ 0,.+-46 ;(147) ; Load AC0 with contents KBLK (check controller status)
216:101014 - MOV# 0,0,SZR ; if zero (error or idle) then go to 199
217:000406 - JMP .+6 ;(225) ; not idle, go to 225
220:021401 - LDA 0,AC3+1
221:101014 - MOV# 0,0,SZR
222:000406 - JMP .+6 ;(230)
223:056724 - STA@ 3,.+-54 ;(147)
224:000767 - JMP .+-11 ;(213)
225:125014 - MOV# 1,1,SZR ; we get here when the disk controller is not idle; see if prev. addr is zero
226:000403 - JMP .+3 ;(231) ; not zero, go to 231
227:000764 - JMP .+-14 ;(213) ; zero, loop at 213.
230:004667 - JSR .+-111 ;(117)
231:004672 - JSR .+-106 ;(123) ; next DCB?
232:004665 - JSR .+-113 ;(117) ;
233:000757 - JMP .+-21 ;(212)
234:174400 - NEG 3,3
235:160000 - COM 3,0
236:024501 - LDA 1,.+101 ;(337)
237:034711 - LDA 3,.+-67 ;(150)
240:061005 - BLT
241:004416 - JSR .+16 ;(257)
; data
242:111111 - MOVL# 0,2,SKP
243:000006 - JMP 6
244:000000 - JMP 0
245:000015 - JMP 15
246:000200 - JMP 200
247:000012 - JMP 12
250:100022 - COMZ 0,0,SZC
251:000016 - JMP 16
252:000001 - JMP 1
253:000000 - JMP 0
254:100022 - COMZ 0,0,SZC
255:000040 - JMP 40
256:000001 - JMP 1
257:161000 - MOV 3,0
260:024765 - LDA 1,.+-13 ;(245)
261:034411 - LDA 3,.+11 ;(272)
262:061005 - BLT
263:020757 - LDA 0,.+-21 ;(242)
264:024457 - LDA 1,.+57 ;(343)
265:034663 - LDA 3,.+-115 ;(150)
266:061006 - BLKS
267:020451 - LDA 0,.+51 ;(340)
270:042621 - STA@ 0,.+-157 ;(111)
271:000400 - JMP .+0 ;(271)
;
272:177764 - ANDSC 3,3,SZR
; continuation of subroutine at 122
273:035000 - LDA 3,AC2+0
274:021401 - LDA 0,AC3+1
275:101015 - MOV# 0,0,SNR
276:000775 - JMP .+-3 ;(273)
277:024652 - LDA 1,.+-126 ;(151)
300:107405 - AND 0,1,SNR
301:003050 - JMP@ AC2+50 ; return
302:011046 - ISZ AC2+46
303:025046 - LDA 1,AC2+46
304:020433 - LDA 0,.+33 ;(337)
305:122532 - SUBLZ# 1,0,SZC
306:001052 - JMP AC2+52
307:102460 - SUBC 0,0
310:041401 - STA 0,AC3+1
311:041410 - STA 0,AC3+10
312:041412 - STA 0,AC3+12
313:041413 - STA 0,AC3+13
314:041414 - STA 0,AC3+14
315:041415 - STA 0,AC3+15
316:041416 - STA 0,AC3+16
317:020417 - LDA 0,.+17 ;(336)
320:107405 - AND 0,1,SNR
321:000403 - JMP .+3 ;(324)
322:056625 - STA@ 3,.+-153 ;(147)
323:000750 - JMP .+-30 ;(273)
324:054421 - STA 3,.+21 ;(345)
325:021411 - LDA 0,AC3+11
326:024412 - LDA 1,.+12 ;(340)
327:123400 - AND 1,0
330:125400 - INC 1,1
331:044413 - STA 1,.+13 ;(344)
332:004770 - JSR .+-10 ;(322)
; data
333:000000 - JMP 0
334:000000 - JMP 0
335:044002 - STA 1,2
336:000007 - JMP 7
337:000037 - JMP 37
340:000002 - JMP 2
341:000000 - JMP 0
342:000000 - JMP 0
343:000061 - JMP 61
344:000001 - JMP 1
345:102000 - ADC 0,0 ; set up first BLT of all memory to reset Parity
346:024110 - LDA 1,110
347:134000 - COM 1,3
350:061005 - BLT ; do BLT
351:056111 - STA@ 3,111 ; write R3 to 420, reset display list (disable display)
352:000003 - JMP 3 ; continue @3
353:000000 - JMP 0
354:000000 - JMP 0
355:000000 - JMP 0
356:000000 - JMP 0
; data
357:040463 - STA 0,.+63 ;(442)
360:044463 - STA 1,.+63 ;(443)
361:054476 - STA 3,.+76 ;(457)
362:004401 - JSR .+1 ;(363)
363:024471 - LDA 1,.+71 ;(454)
364:167000 - ADD 3,1
365:034470 - LDA 3,.+70 ;(455)
366:020470 - LDA 0,.+70 ;(456)
367:061005 - BLT
370:034466 - LDA 3,.+66 ;(456)
371:021605 - LDA 0,AC3+-173
372:040452 - STA 0,.+52 ;(444)
373:021665 - LDA 0,AC3+-113
374:040445 - STA 0,.+45 ;(441)
375:021640 - LDA 0,AC3+-140
376:101100 - MOVL 0,0
377:040446 - STA 0,.+46 ;(445)
400:102460 - SUBC 0,0

View File

@@ -6,6 +6,7 @@ using System.Threading.Tasks;
using Contralto.Memory;
using System.IO;
using Contralto.Logging;
namespace Contralto.IO
{
@@ -24,10 +25,7 @@ namespace Contralto.IO
_pack.Load(fs);
fs.Close();
// Wakeup the sector task first thing
_system.CPU.WakeupTask(CPU.TaskType.DiskSector);
fs.Close();
}
public ushort KDATA
@@ -36,7 +34,10 @@ namespace Contralto.IO
{
return _kData;
}
set { _kData = value; }
set
{
_kData = value;
}
}
public ushort KADR
@@ -53,6 +54,25 @@ namespace Contralto.IO
// "0 normally, 1 if the command is to terminate immediately after the correct cylinder
// position is reached (before any data is transferred)."
_dataXfer = (_kAdr & 0x2) != 0x2;
Log.Write(LogComponent.DiskController, "KADR set to {0} (Seal {1}, Header {2}, Label {3}, Data {4}, Xfer {5}, Drive {6})",
OctalHelpers.ToOctal(_kAdr),
OctalHelpers.ToOctal((_kAdr & 0xff00) >> 8),
OctalHelpers.ToOctal((_kAdr & 0xc0) >> 6),
OctalHelpers.ToOctal((_kAdr & 0x30) >> 4),
OctalHelpers.ToOctal((_kAdr & 0xc) >> 2),
_dataXfer,
_kAdr & 0x1);
Log.Write(LogComponent.DiskController, " Disk Address is C/H/S {0}/{1}/{2}, Drive {3} Restore {4}",
(_kData & 0x0ff8) >> 3,
(_kData & 0x4) >> 2,
(_kData & 0xf000) >> 12,
((_kData & 0x2) >> 1),
(_kData & 0x1));
Log.Write(LogComponent.DiskController, " Selected disk is {0}", ((_kData & 0x2) >> 1) ^ (_kAdr & 0x1));
}
}
@@ -148,15 +168,27 @@ namespace Contralto.IO
get { return _sectorClocks - _elapsedSectorTime; }
}
public bool Ready
{
get
{
// Not ready if we're in the middle of a seek.
return (_kStat & 0x0040) == 0;
}
}
public void Reset()
{
ClearStatus();
_recNo = 0;
_elapsedSectorTime = 0.0;
_cylinder = 0;
_cylinder = _destCylinder = 0;
_sector = 0;
_head = 0;
_kStat = 0;
_kData = 0;
_sendAdr = false;
_wdInhib = true;
_xferOff = true;
@@ -164,8 +196,13 @@ namespace Contralto.IO
_wdInit = false;
_diskBitCounterEnable = false;
_sectorWordIndex = 0;
_sectorWordTime = 0;
InitSector();
// Wakeup the sector task first thing
_system.CPU.WakeupTask(CPU.TaskType.DiskSector);
}
public void Clock()
@@ -219,11 +256,15 @@ namespace Contralto.IO
_cylinder--;
}
Log.Write(LogComponent.DiskController, "Seek progress: cylinder {0} reached.", _cylinder);
// Are we *there* yet?
if (_cylinder == _destCylinder)
{
// clear Seek bit
_kStat &= 0xffbf;
Log.Write(LogComponent.DiskController, "Seek to {0} completed.", _cylinder);
}
}
}
@@ -282,6 +323,8 @@ namespace Contralto.IO
{
throw new InvalidOperationException("STROBE while SENDADR bit of KCOM not 1. Unexpected.");
}
Log.Write(LogComponent.DiskController, "STROBE: Seek initialized.");
_destCylinder = (_kData & 0x0ff8) >> 3;
@@ -290,6 +333,8 @@ namespace Contralto.IO
if (_destCylinder > 202)
{
_kStat |= 0x0080;
Log.Write(LogComponent.DiskController, "Seek failed, specified cylinder {0} is out of range.", _destCylinder);
}
else
{
@@ -304,6 +349,8 @@ namespace Contralto.IO
// And figure out how long this will take.
_seekClocks = CalculateSeekTime();
_elapsedSeekTime = 0.0;
Log.Write(LogComponent.DiskController, "Seek to {0} from {1} commencing. Will take {2} clocks.", _destCylinder, _cylinder, _seekClocks);
}
}
@@ -380,7 +427,8 @@ namespace Contralto.IO
if (_wffo || _diskBitCounterEnable)
{
if (!_xferOff)
{
{
Log.Write(LogComponent.DiskWordTask, "Word {0} read into KDATA", OctalHelpers.ToOctal(diskWord));
_kData = diskWord;
}
@@ -403,6 +451,7 @@ namespace Contralto.IO
if (bWakeup)
{
Log.Write(LogComponent.DiskWordTask, "Sector task awoken.");
_system.CPU.WakeupTask(CPU.TaskType.DiskWord);
}

View File

@@ -1,4 +1,5 @@
using System;
using Contralto.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -9,6 +10,11 @@ namespace Contralto.Memory
public class Memory : IMemoryMappedDevice
{
public Memory()
{
Reset();
}
public void Reset()
{
_mem = new ushort[0x10000];
}
@@ -19,7 +25,8 @@ namespace Contralto.Memory
}
public void Load(int address, ushort data)
{
{
//Log.Write(LogComponent.DiskWordTask, "Word {0} written to {1}", OctalHelpers.ToOctal(data), OctalHelpers.ToOctal(address));
_mem[address] = data;
}